Repository navigation
KohakuTerrarium v2.2.0
2.1 made agents run across machines and sessions. 2.2 is about what an agent can show you and how cleanly the code underneath it is laid out. Agents can now draw: widgets and small apps inside the chat, in a VS Code tab, and in the terminal. Extensions can add their own dashboard panels. There is a standalone MCP tool server. Sessions run on KohakuVault 1.0 and a long list of hot paths got faster. And the source tree was reorganised so that no directory holds a long run of files with a shared prefix, which is why this is a minor release and not a patch: some import paths moved (see Upgrading).
This release includes everything shipped in the 2.1.1 to 2.1.9 patch releases.
Full changelog: v2.1.0...v2.2.0
Upgrading from 2.1
- Module paths moved. Families of files that shared a prefix became packages with the prefix dropped (
core/agent_compact.py→core/agent/history/compact.py,llm/codex_auth.py→llm/codex/auth.py, and so on). There are no compatibility shims. The moved paths that plugins, tools and packages commonly import are listed in Module layout in 2.2. Built-in tools can be looked up without a module path throughkohakuterrarium.builtins.tool_catalog.get_builtin_tool(name). - Task sub-agents narrowed. The built-in task presets are now
exploreandcritic, both bounded and inspection-only.worker,plan,researchandcoordinatorare gone; give substantial work to graph creatures or define a sub-agent of your own. show_uiis replaced by inline<ui>blocks in the reply, andui.declarativeandui.appsare on by default.json_readandjson_writemoved out of the built-in tools intoexamples/.- Dependency floors:
kohakuvault>=1.1.0,<2,anthropic>=1.0.0,<2,mcp>=1.28.1,<2, pluspathspec>=1.1.1,<2; the desktop app usespywebview 6.2.1. - Packages: the first-party packages are released against 2.2 and require it:
kt-biome4.1.0,kt-qqbot0.2.1,kt-claude-code0.3.0,kt-template0.2.0 (framework: ">=2.2.0,<3.0.0"). Older versions keep their old ranges, so a 2.1 install keeps resolving the releases that suit it.
✨ New Features
Rich UI: widgets, apps and extensions
kt.uideclarative widgets: a widget spec with an expression language and a text fallback, rendered in the web chat, in the CLI and TUI (terminal text profile), and reported through renderer capabilities so the model only sees what the client can draw- Inline
<ui>blocks in the reply draw components in the chat, backed by a two-tier component reference served throughinfo("ui:<name>") - Instant apps: the
show_apptool andui.appsplugin open full-page apps (kt.apprenderer), with a gated## Presenting your answerprompt section that teaches the forms an answer can take - Widget service on the output bus: widget frames and
client_helloover the WebSocket, widget events recorded and rebuilt on resume, a side-panel host for chat widgets, and a canvas that holds generated images, widgets and pins - UI extension packages: a
ui:manifest slot, an extension SDK with loader and mount points, owner RPC and pushes, a UI owner interface for plugins, tools and triggers, live budget usage in the dashboard, andkt extension new --uito scaffold one - Plugins can contribute tools, pin and unpin context messages, and serve their own
info("<prefix>:<topic>")documentation - VS Code extension: a secured local chat with the shared transcript viewport, media, commands, model selection, slash completion, branch recovery, and inline UI, diagrams and apps in editor tabs; the chat has host seams so other hosts can embed it
- Cross-surface attention indicators with opt-in external channels, reading-size controls, and a one-screen Lab home that leads with session summaries
MCP tool server
- A standalone tool server with a persistent ingress lifecycle, workspace setup, isolated running configuration and explicit workspace routing
- Secret rotation for stopped workspaces, and delegation of work to local creatures and sub-agents
LLM & Providers
- Antigravity reuses your local
agycredentials and mirrors theagyCLI agent catalog and limits; Gemini presets moved to the 4 Argon line and retired presets redirect to their successors - Grok subscription media support and usage in account settings; Codex Spark preset and subscription web search; direct DeepSeek Search and Fetch
- Package-provided LLM backends through an
llm_backends:manifest slot, shown in Settings - New presets (
gpt-6-astrawith context-window variants, Daybreak Blue); explicit Responses reasoning replay for model aliases - Recovery from size and content rejections on every transport; the Responses WebSocket learns the frame ceiling on a 1009 close and sticks to HTTP; tool-argument progress streams to the status line
Prompt, context & tools
- Every framework section of the system prompt is gated (a block whose subject does not exist is not emitted) and tool documentation is tiered (
brief,standard,full) - One model-visible tool catalog, gated on the renderers attached; the prompt rebuilds when they change
- Pinned context messages that survive compaction, and tools that shorten their old call arguments after compaction
- Tools declare a media policy;
readreferences images in place and encodes PDF pages as the smaller of PNG and JPEG;file://references are inlined at the provider boundary - The sandbox checks declared file-path arguments of any tool; triggers learn their host creature (
bind_host) - New tools:
canvas_image(promote a local file onto the Studio canvas)
Sub-agents & Terrarium
- Context forks and non-interrupting
btwside conversations with titled dialogs and their own progress, forwarded across the terrarium and titled by session summaries - Spawned creatures inherit the creator's model; parent links keep a child in its parent's graph;
group_spawn_childcreates no link channel; a stopped creature restarts when the user messages it; start and stop a creature in place over the API - Per-creature token usage from the backend in graph and info views; a
host_resourcesengine flag; sub-agent conversations surface across trace events - Drive panels in the web, CLI and TUI: goals, per-creature groups, drive-triggered turns marked in every transcript
Sessions & branching
- Continue a selected idle branch; keep settled tool results when continuing; preserve multimodal edits and replay complete multimodal assistant rounds
- Default-off controlled metadata reads and preflight metadata selection; session store moved to KohakuVault 1.0
Desktop, CLI & packaging
- Theme-aware Windows title bar with native resizing; the desktop app overlaps backend and window startup and shows a loading shell first
- The CLI raises the soft file-descriptor limit and configures UTF-8 at startup; opt-in startup tracing
- Patch releases are cut automatically when stable falls behind main, and release notes are published as a plain commit list
Code layout & tests
- Files are capped by AST statement count (500 soft, 1000 hard) instead of lines; families of prefixed files are packages; large classes are pseudo-class packages (mixins per concern assembled in one module) with READMEs describing each layer
- Test suite review: assertions check behaviour, not shape; mock-only tests moved onto real engines; deadline-based waits replace fixed polling budgets;
kohakuterrarium.testing.llm_seamis the one place that replaces LLM providers; ruff now rejects text I/O without an explicit encoding
🚀 Improvements
- Persistence: events and activity persist on a per-store affinity thread, native metadata keys are selected before decoding, resume event-table scans drop from 3 or 4 to 1, and replay indexes and branch paths are reused
- Studio and API: session-index, viewer and live-registry reads are batched and single-flighted; unbounded history payloads are rejected; log reads are bounded and moved off the event loop
- Chat: history replay is linear, streaming scroll updates are coalesced, long-session dashboard stalls are reduced, open code fences defer highlighting, and the trace timeline renders rasterised
- Tools: file-tree walks use
os.scandirwith carried stats and anchored gitignore matching - Startup: public, CLI and web imports are deferred
- Overlapping frontend polls and reconciles share one in-flight request
🐛 Bug Fixes
- Sessions: replay keeps user messages typed mid-turn; branch views resolve across turns without a user message; branch selection survives forks and successors; compaction coverage is respected when restoring tool history; writable opens are gated on strict format metadata; resume admission waits stay off the event loop
- Core: a user message folded behind a channel message opens its turn; awaited turns are isolated and cancellation is scoped; replaced model providers are closed when the agent stops; background handoffs are fenced
- LLM: every
_kt_*message field is stripped before Chat Completions; Anthropic cache reads are reported as cached tokens; Gemini thought signatures round-trip; parallel streamed tool calls stay apart whenindexis absent; credential paths resolve at call time; Grok CLI refreshes cannot run twice - Terrarium and Drive:
group_channel wirerefuses an undeclared channel; graph merges stop re-appending legacy events; creature removal is scoped and errored agents stop; wake policy is per registration; a drive pauses when the user interrupts its turn; stale transactions heal instead of poisoning the connection - Lab: rollback cleanup completes before cancellation propagates; remote streams stay open on payload error fields; worker creature configurations and package references resolve on the selected worker
- Desktop and CLI: DPI startup, theme races and frame blending; window icons on Windows; hidden API-key input; conflicting session flags rejected; heartbeat intervals coerced as floats
- Tools: grep and glob honour scoped gitignore rules and bound their reads;
prepare_diris guarded against out-of-boundary directories - …plus several hundred more stability, frontend and CI fixes
Cluster upgrade requirement: recoverable session stop
Upgrade the controller and every worker together before using remote session
stop with this release. The controller requires the worker's
terrarium.session/unload operation to preserve saved creature IDs and Drive
ownership. Mixed deployments with older workers do not support this stop path.
An unsupported operation, timeout, or lost reply causes stop to report failure.
The saved dormant marker remains in place; it does not prove that the worker has
stopped. Upgrade the worker and retry stopping the same session. The controller
never falls back to permanent creature deletion, which would orphan Drives.
See the Drive identity recovery guide
for existing orphaned goals and offline repair.