Repository navigation
Releases: Bilal-Junaid-Jiwani/agentkai
Release list
agentkai 0.6.5
Fixed
- Security:
transcribe_audioinput files are now confined to the agent workspace. The tool accepted an unconstrainedaudio_path, so a model could point it at any audio file on the host and have the transcript fed back to it. Inputs are now confined like the media tools: relative paths resolve against<home>/workspace, absolute paths must already live inside it, and..traversal or symlink escapes are refused with a clearERROR:(the gateway hookpreprocess_voice_noteis unchanged). 8 new tests intests/test_voice.py.
Docs
docs/voice.md: added a Path confinement note fortranscribe_audio/speak_text.
Full test suite: 450 passed, 4 skipped. PyPI: agentkai 0.6.5.
v0.6.4
Fixed
- Security:
speak_textoutput paths are now confined to the agent's voice directory. The low-riskspeak_texttool accepted an unconstrainedout_path, so a model could point it at any process-writable file (e.g.~/.bashrc) and have it overwritten with synthesized audio bytes. Output paths are now confined exactly like the media tools: relative paths resolve against<home>/voice, absolute paths must already live inside it, and..traversal or symlink escapes are refused with a clear error (surfaced asERROR: ...by the tool). The default output location is unchanged (<home>/voice/tts-<stamp>-<id>.wav). Seven new tests intests/test_voice.pycover absolute-path, traversal, tilde, and symlink escapes plus inside-voice-dir acceptance and the default path.
Full suite: 443 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.6.4/
v0.6.3
Fixed
- Security:
edit_imageinput files are now confined to the agent workspace. Theimageandmaskarguments were previously resolved against the raw filesystem, so a model could point the tool at an arbitrary file (e.g.~/.ssh/id_rsa,/etc/passwd) and have its bytes exfiltrated to the remote image-editing provider. Input paths are now confined exactly like the file/shell tools: relative paths resolve againsthome/workspace, absolute paths must already live inside it, and..traversal or symlink escapes are refused with a clear error. The tool's description documents the confinement. Six new tests intests/test_media.pycover absolute-path, traversal, symlink, and mask escapes plus inside-workspace acceptance.
Full suite: 437 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.6.3/
agentkai v0.6.2
Fixed
- Permission gate: the in-memory audit log no longer grows without bound.
PermissionGate._auditappended one entry per tool decision for the whole process lifetime — and gateway agents (plus their gates) live as long as the gateway runs, so a long-running gateway leaked memory on every tool call (verified: 50,000 decisions -> 50,000 in-memory entries). The in-memoryaudit_log()now keeps the most recentAUDIT_CAP = 2000decisions with oldest-first eviction, the same window used for the WhatsApp bridge's seen-id cache; whenaudit_pathis configured, the JSONL file remains the durable, complete record of every decision. Two new tests intests/test_core.pyverify the bound/eviction and that the JSONL file still records everything.
Full suite: 432 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.6.2/
v0.6.1
agentkai 0.6.1
Fixed
- WhatsApp bridge: the seen-message-id dedup cache no longer grows without bound.
WhatsAppBridge._seencollected every sidecar event id it ever dispatched, so a gateway left running for weeks would keep the full history in memory forever. The cache is now capped atSEEN_CAP = 5000ids with oldest-first eviction (safe: the sidecar only returns events at/after thesincewatermark). New test intests/test_channels.pycovers the bound, oldest-first eviction, and within-window dedup.
Tests: 430 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.6.1/
v0.6.0
agentkai 0.6.0 — browser request gate
0.5.6 closed the navigation-time SSRF gap but left a documented limitation: redirect hops, subresources, XHR/fetch, and websockets fired by a loaded page were followed by Chromium itself with no re-validation. This release closes it:
BrowserSessionnow registers a context-wide Playwright route handler (**/*, covering all tabs) that aborts any request to a non-public or unresolvable host — the same_assert_public_host()boundary asfetch_url— hop by hop.file://requests are aborted at the network layer too, so a page can never read the local disk, even via iframe/subresource.- Harmless schemes (
data:,blob:,about:,chrome:…) pass through untouched; the handler fails closed. - 11 new tests; full suite green (429 passed, 4 skipped).
A prompt-injected page can no longer steer the browser at http://169.254.169.254/, 127.0.0.1, or 192.168.x.x and read the response back into the agent's context.
agentkai v0.5.6
Fixed
- Browser navigation now refuses non-public hosts (SSRF gap closed).
fetch_urlhas long refused hosts that resolve to loopback, private, link-local, or otherwise non-public addresses, but the real-Chromium browser tool's URL validation only checked the scheme and rejected credentials-in-URL — sobrowser_goto http://169.254.169.254/...(the cloud metadata endpoint),http://127.0.0.1:8501/, orhttp://192.168.1.10/...loaded happily (verified with a repro: all three passed validation whilefetch_urlrefused them). A prompt-injected page could have steered the browser at internal services or metadata URLs and the response would have landed in the agent context. The non-public-host check is now extracted fromtools._validate_urlinto a shared_assert_public_host()helper and enforced bybrowser._validate_url, sobrowser_goto(andnew_tabwith a URL, which routes through the same gate) refuses unresolvable hosts and every non-public address class with the same messages asfetch_url. Five new tests intests/test_browser.pycover private, loopback, and link-local (metadata IP) refusals, unresolvable hosts, and the public-host allow path; the suite's DNS is now fully mocked so browser navigation tests never touch real DNS. Known limitation, unchanged: redirects within an already-loaded page are followed by Chromium itself and are not re-validated hop-by-hop the wayfetch_urldoes.
Full suite: 419 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.5.6/
agentkai v0.5.5
Fixed
--pinon skill installs now actually checks out the pinned commit. The 0.5.2 supply-chain hardening added--pin/pinto pin a remote skill install to a commit SHA, but the implementation only comparedgit clone --depth 1's HEAD against the pin afterwards and never checked the pin out — so pinning to any non-HEAD commit always failed with "pin mismatch" (verified with a repro against a real 3-commit git repo), and the feature's whole point (install the exact commit you reviewed) was silently broken.install_skill()now fetches the pinned commit andgit checkout --detachs it before recordingcommit_shain the manifest; the pin must be a full 40-hex SHA (required for fetch-by-SHA, and the strict shape also rules out option injection through the pin value), and an unfetchable commit fails the install with the half-cloned directory cleaned up, as before. Four new tests intests/test_skills.pycover pinning to an older commit (checked-out tree, manifest SHA, and clean load), pinning to HEAD, invalid pin formats, and unfetchable commits.
Full suite: 414 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.5.5/
agentkai 0.5.4
Fixed
- Media
out_pathcan no longer escape the media directory. Thegenerate_image,generate_video, andedit_imagetools joined a relativeout_pathto~/.agentkai/media/but never checked the result, so a path like../../pwned.pngwrote the generated file outside the media dir (verified with a repro: a stub provider wrote three files outside the dir). The traversal guard ingenerate_imagewas dead code — after joining, the path was always absolute, so the check could never fire — and the other two functions had no guard at all, quietly bypassing the filesystem sandbox the file/shell tools enforce. All three now resolve the path through one helper that collapses..segments and symlinks and refuses anything landing outside the media dir; relative subdirectories (e.g.campaigns/hero.png) still work and get their parents created, and absolute paths are accepted only inside the media dir. Seven new tests intests/test_media.pycover../traversal, absolute-path escape, symlink smuggling, and the legitimate cases.
Full suite: 410 passed, 4 skipped. PyPI: https://pypi.org/project/agentkai/0.5.4/
v0.5.3 — skill manifest verification fails closed
Fixed
- Skill manifest verification now fails closed. The 0.5.2 integrity check silently skipped verification whenever an installed user skill's
manifest.jsonwas unreadable, invalid JSON, or missing itscontent_sha256— so corrupting the manifest switched the drift check off and let tamperedtools.pycode execute (verified with a repro before the fix).SkillLoader.load()now refuses such skills with aSkillErrorbefore any skill code runs, andagentkai skills listflags the broken manifest instead of showing the skill as healthy. Skills with no manifest at all (manually copied directories) keep loading as before.
Upgrade note: skills installed by agentkai ≤ 0.5.1 carry a manifest without an integrity hash and must be reinstalled once (agentkai skills install <source> --force) to stamp one.
Five new tests in tests/test_skills.py; full suite 403 passed, 4 skipped.