Repository navigation
v0.213.0
This release adds subscription usage tracking for Claude and Codex OAuth accounts (ADR 0122), detached /api/chat turns that the fleet hub now uses for long member turns, and linked file artifacts. Subagents now inherit the lead's read tools. It also includes media-link and log-redaction security fixes and a set of fleet and console fixes.
Upgrading
- Subagents inherit the lead's read tools (#4327, ADR 0117 amendment). A subagent with a non-empty
toolsallowlist now also gets the lead's read-classified tools: known core reads, plus plugin tools that declaremetadata.access=read. Write tools, unannotated tools,tools.subagent_onlytools, and control, HITL, shell and code-execution tools are never inherited, so they still need an explicitsubagents.<name>.toolsgrant. To keep a narrow role at exactly its allowlist, setinherit_read_tools: falseon it. An emptytoolslist also disables inheritance. - Delegation can now be refused before it starts (#4327, #4472). If a
task/task_batchprompt names a tool the chosen subagent won't have, the lead getsNot dispatched: …instead of a subagent run that comes back "blocked". In a batch, only that item fails. This includes a prompt that only mentions a tool ("don't useread_file"), so re-send the prompt without the name. A background spawn of a subagent whose declared tools are all unbound on this agent is also refused up front. - Registering a project name already held by another path is refused (#4425).
onboard_projectandregister_local_projectnow reject the name and ask for an explicitname=. Re-onboarding an already-registered repo now acts on the registered checkout instead of cloning a shadow copy. - Fleet member ports (#4423). If another process holds a member's recorded port, starting the member moves it to a free port, records that port and reports
port_moved_from. New members are never assigned :7871, the dev sandbox's default port. - Desktop stays awake during scheduled runs (#4308). The desktop app holds a platform sleep assertion while a scheduler fire is running. Set
PROTOAGENT_KEEP_AWAKE=0to opt out. - Gateway session header value changed (#4463).
x-litellm-session-idis now a 32-hex sha256 prefix of the thread id instead ofprotoagent:<hash>, because LiteLLM rejected the colon. If a gateway rule matches the oldprotoagent:prefix, update it. The native ChatGPT/Codex client no longer sends this header. - httpx/httpcore logging is capped at WARNING (#4446). Their INFO request lines printed full URLs, including signed-media signatures. If you relied on those lines for debugging, they no longer appear.
Added
-
Subscription usage (ADR 0122; #4431–#4435). Claude and Codex OAuth usage windows are tracked, including model-scoped and weekly limits. Data comes from rate-limited polling (at most once a minute, five minutes after a 429) and from passive response-header capture. Credentials are read only; OAuth tokens are never refreshed. The data is available from:
GET /api/usageand theusage.snapshotopGET /api/usage/fleet, a hub rollup deduplicated by accountprotoagent usage [--json] [--account] [--fleet] [--warn-at PCT]- a usage meter under each connected account in Settings → Providers
A disconnected or failing provider reports
unknown, and after a restart the last snapshot is shown marked stale. Quota-aware routing is designed in the ADR but not part of this release. -
Detached
/api/chatturns (#4277).POST /api/chatwithdetach: truereturns202 {turn_id, session_id, state}immediately. You pollGET /api/chat/sessions/{session_id}/turns/{turn_id}for the result, and the turn keeps running if the client disconnects. Concurrent detached turns are capped; over the cap you get a 429 (#4446). Non-detached calls are unchanged. -
Linked file artifacts (#4370).
save_file_artifact(..., link=True)references a document inside a registered filesystem project instead of copying it, with its ownmax_linked_kbcap (200 MB default). A linked artifact is read-only. Each time it is served, its path is checked against the live project fence and its size/mtime/hash stamp. Unregistering the project returns 403, and a changed or missing file returns 409. The Artifact panel shows these states over the stored text preview. -
Inline tables beside HITL prompts (#4405).
ask_human,request_user_inputandrun_commandapprovals can carry an optional boundeddisplaytable (scalar cells only, fixed size limits). The console renders it with the DS Table next to the prompt. An invalid table is dropped, and the prompt and resume values stay the same. -
Re-minting expired media links (#4274).
POST /api/media/remintexchanges an expired signed media link that this box minted for a fresh one. The HMAC must still verify, and the normal bearer is required. In hub-console history, a member image whose link has expired now re-mints itself once and repaints. -
show_configreportsself_url(#4424). It returns{local, public, preferred}so an agent can find its own console URL without probing ports.publicfollows theA2A_PUBLIC_URL→public_console_urlprecedence used byconsole_url(#4446).
Changed
- Fleet hub proxies long member chat turns by polling (#4277). A hub-proxied
POST /agents/<slug>/api/chatis sent to the member as a detached turn, and the hub polls until the turn finishes, with a ceiling of 3600 s. Callers get the same response shape as before. Turns longer than 600 s no longer 504, and a dropped hub↔member connection no longer cancels the turn. If the console client disconnects, the hub still sends Stop. Members on an older core are passed through unchanged. - Responsive switchers use the DS Menu (#4406). On a phone, the Settings section switcher and the collapsed
responsivetab strips open a themed Menu instead of a native<select>.@protolabsai/uiis now 0.68.3. - Attachments with distinct explicit names stay separate (#4274), even when their bytes are identical.
Fixed
- Background subagents bind their plugin tools (#4472). With
tools.deferred.enabled, a backgroundtask()orsdk.spawn_backgroundsubagent could not see its fenced tools, so for examplecampaign_producerreported its tools unavailable. Background runs now bind the same tools as a foreground run. - Codex direct model calls with a system message no longer return 400 (#4444). This affected the goal verifier,
sdk.complete(system=...)and the soul judge, so goals on Codex agents can now be judged met. - Gateway session affinity reaches every in-session call (#4463), including one-shot auxiliary calls made during a turn.
- Hub history keeps text/tool interleaving (#4274) for member turns whose answer contains rewritten, expiring media links.
- Paused-turn file handoffs (#4274). Attachments are delivered when a pause is answered with another owner credential. When a credential mismatch withholds attachments, the warning now says they are withheld and parked rather than dropped (#4446).
- Console layout: the idle background-work strip no longer leaves a blank band above the composer (#4458), and Work tab overview cards no longer overlap in a short rail (#4422).
Security
- Signed media links are redacted from logs (#4274, #4446).
sigis scrubbed from the uvicorn access log on every media path (core/media/, fleet/agents/<slug>/media/and artifact media) regardless of which plugins are enabled. Hub-proxied upstream URLs are also redacted in httpx output and proxy error messages.
Internal
- ADR 0122: subscription usage model and routing (#4430).
- Chat scrollback (#4421): DPR-2 diagnostic browser coverage was added, and committed screenshot binaries were removed from the repository. This release contains no runtime change for the reported blank-paint issue.
What's Changed
- fix(work): overview cards no longer overlap in a short rail by @mabry1985 in #4422
- fix(fleet): a member whose port another process holds moves to a free one by @mabry1985 in #4423
- feat: show_config exposes the agent's own console URL:
self_url(bound host:port + public URL when set) (#4424) by @mabry1985 in #4426 - feat: Redact media signatures (sig=/exp=) on ALL media paths in the uvicorn.access log, not just /plugins/artifact/media/ (#4274 item 6) by @mabry1985 in #4427
- feat: Finished answer with an inline frame paints blank below the fold after scrolling back up; verify #4298 follow-stream live (#4421, #4298) by @mabry1985 in #4440
- feat: Park-time file stash: warn (naming the turn) when a paused turn's files are dropped on a credential mismatch (#4274 item 1) by @mabry1985 in #4441
- feat: onboard_project: resolve an already-registered project by repo/name instead of root/; refuse a name collision at a different path (#4425) by @mabry1985 in #4429
- feat: /api/chat detach: submit a long turn, get a turn id, poll it; the turn survives the client and shows in /turns + live_task_id (#4277 slice 1) by @mabry1985 in #4439
- feat: Fail fast at dispatch when a delegated subagent's prompt names tools it won't have (#4327, fail-fast half only) by @mabry1985 in #4428
- feat: Desktop: keep the machine awake while a scheduled run is in flight (macOS caffeinate/IOPM assertion, release on run end) (#4308) by @mabry1985 in #4443
- feat: Reproduce #4421 at DPR 2 with failing paint evidence, then repair scrollback by @mabry1985 in #4447
- feat: Harden detached chat turns: admission cap, cancellation outcomes and incognito retention (#4446 item 2) by @mabry1985 in #4449
- feat: attach_file: two attachments with distinct explicit names but identical bytes stay two entries (#4274 item 2) by @mabry1985 in #4442
- feat: Remove committed #4440 PNG evidence and reconcile #4421 closure after real repair by @mabry1985 in #4451
- feat: usage U1: ADR 0122, Subscription usage model and routing (#4430) by @mabry1985 in #4452
- feat: Fleet proxy: long member /api/chat turns go detach+poll, so the hub stops 504ing at 600 s and a hub disconnect never stalls the member (#4277 slice 2) by @mabry1985 in #4448
- fix(codex): hoist system messages into instructions for every caller by @mabry1985 in #4445
- feat: self_url public origin follows A2A_PUBLIC_URL fallback (#4446 item 3; fill-in) by @mabry1985 in #4453
- feat: Hub history keeps text/tool interleaving for member turns with media links: fingerprint normalised text (link query strings stripped) (#4274 item 3) by @mabry1985 in #4450
- feat: Media: an authenticated operator can re-mint an EXPIRED signed link this box minted (POST /api/media/remint), reachable through the fleet hub (#4274 item 4, server half) by @mabry1985 in #4454
- feat: Security: redact hub upstream signed-media URLs in httpx and proxy errors (#4446 item 1) by @mabry1985 in #4455
- feat: HITL display 1: bounded table payload validation and interrupt passthrough (Refs #4405) by @mabry1985 in #4457
- feat: usage U2a: tolerant Claude/Codex usage fetchers into the ADR 0122 model + non-refreshing token read (#4431 part 1) by @mabry1985 in #4456
- feat: Console: an expired media image in chat history re-mints its link on load error and repaints (#4274 item 4, console half) by @mabry1985 in #4459
- feat: Parked-file mismatch warning says withheld, not dropped (#4446 item 4; fill-in) by @mabry1985 in #4462
- feat: HITL display 2: inert DS table beside host-rendered approval buttons (Refs #4405) by @mabry1985 in #4461
- fix(web): the idle background-work strip takes no space above the composer by @mabry1985 in #4458
- feat: usage U2b: usage cache/store + ops.usage.snapshot() + GET /api/usage + provider.usage topic (#4431 part 2) by @mabry1985 in #4460
- feat: web: adopt the DS Menu-based
responsiveTabs/SideNav switcher (ds-o0k release) — Settings phone SideNav + e2e (Refs protoContent#609) by @mabry1985 in #4406 - feat: usage U5: hub GET /api/usage/fleet, fan-out deduped by account_key (#4434) by @mabry1985 in #4465
- feat: usage U3: passive rate-limit header capture on Claude/Codex calls into the usage cache (#4432, HIGH risk) by @mabry1985 in #4467
- feat: usage U4:
protoagent usage [--json] [--account] [--fleet] [--warn-at]CLI (#4433) by @mabry1985 in #4464 - feat: Subagent inheritance 1: read/write tool classifier + SubagentConfig.inherit_read_tools (Refs #4327) by @mabry1985 in #4468
- feat: HITL display 3: browser proof of inert table and unchanged pause resume by @mabry1985 in #4469
- feat: Subagent inheritance 2: wire read-tool inheritance + write opt-in into all dispatch paths, fail fast on missing write tools (closes 4327) by @mabry1985 in #4471
- feat: Linked file artifact 1: save_file_artifact(link=true) stores a fenced reference, no blob (#4370) by @mabry1985 in #4470
- feat: Linked file artifact 2: blob route serves linked versions through the live fence on every request (#4370) by @mabry1985 in #4473
- feat: Linked file artifact 3: panel shows linked docs in place with a changed/missing/revoked state (#4370) by @mabry1985 in #4474
- feat: usage U6: Providers-panel usage meter under OAuthAccountCard + live provider.usage updates (#4435, UI) by @mabry1985 in #4466
- fix(gateway): session-affinity id in LiteLLM's shape, session fallback, off for Codex (#4463) by @mabry1985 in #4476
- fix: background-spawned subagents bind their declared plugin tools (#4472) by @mabry1985 in #4475
Full Changelog: v0.212.0...v0.213.0