Repository navigation
🛠️ agents-go workbench v0.6.0 — a run you can talk to
v0.4.4 handed the model its own context; v0.6.0 keeps the conversation open while the model works. 245 commits since v0.4.4; 596 files changed, +31.8k/−10.3k lines. Three arcs run through it: a live run takes your next message — queued, steered or sent as a follow-up — and a paused one yields to it, with an approvals inbox, approve-all, a reject that carries a reason, and three approval modes in place of a checkbox grid; the trace tells the truth — one time column, each span's verdict, cache figures, partial output and how it ended, the image it was shown, the moment a queued input was read, and a failed turn that says in words what failed with Replay one click away; and the SDK sheds what OpenAI is retiring and tracks what its providers ship — stored prompts, the compaction session, the Retry and Todo middleware go; openai-go and anthropic-sdk-go are followed at their latest; Anthropic effort becomes adaptive thinking; a retry never replays a stateful request into the dark. Underneath: GitHub sign-in beside Google, a sidebar that folds to a rail, a session that exists only once you say something, custom headers for E2B-compatible services, and the release pipeline that tags the library modules in lockstep and refuses a patch that breaks the API.
This release carries everything since v0.4.4. v0.5.0 was tagged on 2026-10-03 with its library modules but its notes were never published; v0.5.1 was tagged on a commit that never got its release commit — the library modules were not tagged at that version and the root's go.mod requires did not name it — so do not depend on it: v0.6.0 is the version to take, for the root and for every submodule.
Workbench database (since v0.4.4): unchanged — a v0.4.4 database opens as is (SQLite and PostgreSQL).
Breaking changes
Batched per decisions §5.8 — public API compatibility begins at v1.0.0. No schema moved, so the database needs no rebuild this time.
SDK
Agent.Promptis gone, withPromptProvider,StaticPrompt,agents.Prompt,ModelRequest.Prompt,modelkit.FeaturePromptandexamples/prompt: OpenAI shuts down reusable prompts on 2026-11-30. Put the text inInstructions.middleware.Retryis gone. Retry the model call withagents.NewRetryModel; a whole-run retry is aRunMiddlewareof your own.middleware.Todois gone withTodoItem,TodoStatusandDefaultTodoInstructions, andDefaultReadOnlyToolsno longer liststodo_write: a checklist belongs to whoever renders it (decisions §5.82);examples/planmodebuilds one withagents.NewTool.openai.CompactionSessionis gone withexamples/compaction,session.CompactionArgs.OffChainItems,RunState.OffChainHistoryandsession.GuardedReplacer;RunStateSchemaVersionis1.8. Compaction isRunOptions.Compactionwith a strategy fromagents/compaction.RunItemStreamEvent.Nameis gone — branch onItem.Kind.PlanPhase.OnUnlockisfunc(plan string) errorand receives the approved plan.agents.NewDynamicOutputSchemareturns(OutputSchema, error), andOutputType[T]panics at construction for a type whose schema cannot be expressed, instead of at the first run.tasks.LaunchRequest.WakeandParentRunIDare gone.- The provider SDKs are tracked at their latest — openai-go v3.73.0 and anthropic-sdk-go v1.79.1, in every module; decisions §5.5b now says so. A consumer that named
function_call_output'sCallIDas astringmeetsparam.Opt[string]. - Anthropic:
Reasoning.Effortsends adaptive thinking (thinking: {type: adaptive}plusoutput_config.effort) andReasoningEffortNone/Xhigh/Maxexist. Claude Haiku 4.5 and older models take a budget instead:Provider.WithBudgetThinking(true)in code, Thinking mode on the agent in the workbench (decisions §5.76). Thinking blocks written before this release no longer replay; the first request after the upgrade thinks from scratch. - A new default: the runner caps the text of every tool result at 64 KiB (
ExecOptions.ToolOutputLimit;-1restores the old behaviour).
Workbench, on the wire
- An agent's
tools,skills,handoffsandapproval.approve_toolsare arrays — the string form is400;skills: nullstill means "every skill" (decisions §5.67).resilience.fallback_modelsis[{provider_id, model}]and an entry carries no key; a row from before reads back with the endpoint it named and the build resolves it to a provider the agent may reference, with a warning (decisions §5.69).session.prompt_id/prompt_versionare gone withAgent.Prompt. - Approvals are a mode.
approval.approval_modeisnever|on_change|always;approve_toolsonly ever adds a question, and"*"beside a mode that asks is400(decisions §5.85).todo_writeis off unlessbehavior.checklistis set: an agent that had the tool loses it until the switch is turned on. - A session's timeline loads whole:
GET /sessions/:id/messagesdropslimitandbefore_idand returns every entry oldest first;GET /sessions/:id/runsis removed. - Firing a disabled trigger is
409;PUT /sessions/:id/owneranswers204with no body, like every other/owner. A trigger faster than one minute is refused,CRON_TZ=included. A PAT mints never-expiring only when the expiry is left blank.--dboutranksAGENTS_DB.
Highlights
The conversation stays open while a run works (protocol.md)
- Queue, steer, follow up. Enter during a run queues the message for that run; Send after this run makes it a follow-up;
POST /runs/:id/inject(steer|next_turn|follow_up) is the REST twin. The run announces where it read the input withrun.injected, the live view splits its turn there, and a message the run never read returns to the box. In the SDK an injected input passes the input guardrails before it is recorded, whateverBlockingsays (decisions §5.78). - A newer message abandons a paused run (decisions §5.68, invariant 19). A send or a cancel while the run waits on a tool decision ends it: the calls persist as
not_runannotations with the reason,run.cancelled {reason: superseded | stopped}goes out, and the composer no longer waits. A cancel of a paused run used to be a silent no-op. - Approvals, as an inbox and as a mode.
GET /approvalslists what waits across sessions;POST /sessions/:id/approvals/approve-allanswers every pending call of a pause but a plan, a workflow save, a memory proposal or a task's; Reject is a split button whose Reject with reason… hands the reason to the model as that call's output; a focused card takesyandn; a turn awaiting a decision hides Fork, Regenerate and the attempt switcher. The agent form's eighteen-box grid is gone: Never ask / Ask before changes / Always ask, where "a change" is exactly what plan mode would refuse — one read-only set for planning and for asking, MCP tools included through the server's newread_only_tools(decisions §5.85, invariants 89–90). An exact decision for one call outranks an "always" for its tool (decisions §5.74). - Status comes from the server.
GET /sessionsandGET /sessions/:idcarry a derivedstatus(idle|running|requires_action|failed),live_run_idandpending_count;session.statusannounces changes; the sidebar bars, the(2) waiting · agents-gopage title, the spoken line and an opt-in desktop notification all render it and derive nothing (invariant 86), so a reload and a second tab agree. - Work a trigger started runs on its own grants (decisions §5.75): a gated
exec_commandasks until a card of that run says same or all, whatever the session holds; a trigger refuses to fire while the target session waits on an approval (409,last_error). A webhook's payload reaches the model inside an<external source trigger>block followed by one fixed not-the-person line, and a task's report closes with the same statement (decisions §5.80). - Plans and checklists are the session's. Keep planning… sends a plan back with a reason; an approved plan is written to session memory as
approved-plan.md, read-only to the model (invariant 87). With Checklist on, a Checklist c/n chip sits above the composer, the latesttodo_writecard alone opens by default, each accepted list is the run'schecklist.md— a background run's progress signal, visible on the task's page — and a reset carries it along.
The trace tells the truth
- One time column. Every waterfall row is label, duration, and a time column equal on every row, headed by round ticks, so the same instant sits at the same x; a parent's bar carries its children's extents in their colours, so a collapsed row shows the run's shape and a gap is runner or bridge time no child explains; a span under one percent of the range is drawn as a 2px tick instead of vanishing; a run paused for approval gets one timeline per stretch, the later one headed by how long it waited; an MCP transport child folds under its tool.
- Spans record what happened (spec §2.11e): a generation's
status,incomplete_reason,request_idandmodel_used(a newModelResponse.Model, filled by both adapters), itscached_tokens,cache_write_tokens,reasoning_tokensandfallback_index; a stream that failed mid-message keeps its completed items and the text in flight aspartial_text; an agent span says how it ended —final_output,handoff,interruptionwith the pending tools,stop; a handoff names its target; each guardrail consulted carries its verdict, and the tool stages get spans of their own. The panel shows each of these on its row, underlines an input figure served partly from cache, and lists the image attachments a generation was shown as thumbnails (invariant 70) — an image-only message used to render as raw JSON. - A queued input has a row on the trace at the moment the run read it, opening to its text, and the card carries an N queued tag; a failed turn's card says in words what failed by its error code (
provider_errorandcontext_overfloware new), the original under Details, with Retry, Open failing span and — on an overflow — Compact; every turn has Replay…, which opens the replay dialog on the turn's last model call. - Providers test and list. Test connection on a provider (
POST /providers/:id/test) spends no tokens and echoes no key, URL or body; the agent form's Model box offers the provider's live list (GET /providers/:id/models, cached ten minutes), and an Anthropic model fills its context window on pick.GET /agents/:id/toolsnames each tool'ssourceandread_only. The Context panel's profile counts the plan preamble while planning and the background suffix, and gains three rows for them.
SDK: what the providers ship, and nothing OpenAI is retiring
- Replay-safe retries with their own clocks (decisions §5.83). A request carrying
PreviousResponseIDorConversationIDis retried only when the server answered it or the dial failed;RetryPolicygainsAttemptTimeout(released once a stream commits) andIdleTimeout(between a stream's events), each surfacing asErrAttemptTimeout/ErrIdleTimeoutand never mistaken for the caller's cancellation. MCP'stools/callis retried only when it was never sent, so a tool does not run twice; a shared connection that died heals itself and the redial repeats no call (decisions §5.21). - Anthropic:
Respondis served from the stream, so a largemax_tokensis no longer refused client-side; anoverloaded_errorinside a 200 stream is retried; a tool call cut off bymax_tokensends the stream incomplete instead of erroring; every thinking request carriesthinking.block_bindingwithdrop_block, so an edited prefix costs a block, not the run (decisions §5.77); and each thinking block remembers a fingerprint of the system text and tools it was bound to, so the adapter leaves out what the API would reject (decisions §5.84); consecutive requests from one run extend one prefix; a mid-history system message rides in a user turn now that the API has droppedmid_conv_system. The workbench skips the budget notice for an Anthropic agent (invariant 83) and keeps reasoning across a Claude-to-Claude model switch while dropping it across backend families (invariant 88). - OpenAI: an echoed assistant message leaves its
logprobsbehind — a gateway fronting two upstreams killed every conversation that touched both (decisions §5.73); an API error's text carries the endpoint and the body again. - The runner: a refused
Terminateturn is saved whole with each tool output replaced by a fixed notice, so the record that the tools ran survives the guardrail (decisions §5.79); a call naming no tool is an error output in call order and trips the loop valve; concurrent guardrails report in declaration order and the first declared Replace wins;StopAfterTurnis asked at the save point and outranks a late injection; strict-schema conversion visits each node once (a twenty-level doubly-referenced chain went from exponential to linear) under a 65,536-node / 64-hop ceiling;Plan.ReadOnlySet().Admitsis the one exported predicate for "usable while planning".spawn_tasknames a task's agent from the spawning agent's handoff graph — itself or atransfer_to_*target, anything else refused with the targets listed (decisions §5.72); the workbench hands the SDK the built config id, so a same-named private agent cannot capture a handoff wired to a global one (invariant 75). - Sandboxes:
read_filepages by line (offset/limit); a retired docker instance whose container a successor adopted detaches instead of stopping it (decisions §5.66); a shell session's read error arrives after the output that preceded it; an exec whose attachment was severed waits a bounded 2 s for its copy. E2B-compatible services (spec §2.7u):Options.Headersrides every control-plane and envd request for a service that authenticates with its own header; the lease extends throughconnectalone;Statusconfirms arunningrecord through the daemon's/health, so a service that reports a paused sandbox as running no longer offers Stop on one just stopped (decisions §5.71); and a Public URL dialog names where a sandbox's ports are already public — an address to copy, nothing proxied (decisions §5.70). - Sessions:
agents/session/sessiontestis public —StorageConformanceandRepoConformance, the suites the SDK's own backends pass, for a backend written outside the repository (decisions §5.87);NewandNewRepocap a SQLite pool at one connection asNewSQLitealready did; every task store answers a compare-and-set on an unknown id withErrNotFound. Deferred tools stay a runner-side filter and reach the wire as a shorter list; no adapter renders a provider-native deferral yet (decisions §5.88).
Sign in, settle in
- GitHub sign-in beside Google (
--oauth-github-client-id/--oauth-github-client-secret), admitted by the same verified-email allowlist — the account's primary verified address, never an organization or a handle (decisions §5.64). The theme follows the system unless you pin Light or Dark; the full@primer/cssbundle is gone. - A session is made by its first message, never by New (invariant 69): New opens an empty composer, the send creates the session, a cancelled trigger or Run form leaves nothing behind, and a trigger's session is named after what it starts. The sidebar folds into a 48px icon rail when dragged inside its minimum and snaps back past a wider point (invariant 68); it reads a hundred sessions at a time with Show more and searches server-side by name or first message (
GET /sessionstakeslimit,beforeandq; withoutlimitit still returns the whole list); a rename, a pin or the generated title no longer carries a session to the top (invariant 76); browser Back and Forward move between views and close Settings; every machine-made name is clipped by one rule at 40 characters (invariant 78). - An agent can override the system prompt, empty included —
behavior.override_system_promptsends the agent's own text alone, the only way to say "nothing but its tools" (decisions §5.65). The Memory panel shows one scope at a time, and deleting an agent deletes its memory over the API too. A sandbox form can insert a working agreement into its prompt. - Settings, smaller and straighter: a single boolean is a
ToggleRow(invariant 66); a scoped tab opens on Mine; a numeric field holds what you typed until save (invariant 80); a list that failed to load says so and offers Retry instead of an empty state (invariant 79); an edited form asks before it is discarded; a selected MCP server or skill that no longer exists is named in the form and dropped on save; an agent without an endpoint says so inline and on its failed turn, and a workbench with no agent shows the three steps to a first reply. Every label a person reads says session (invariant 74). - Housekeeping on the server: a hidden session exists only as a task's child and is collected hourly once orphaned, and
task_session_retention_daystakes a finished task's transcript with its row (invariant 72); a session transfers or branches only at rest, the whole tree fenced against runs (invariant 82); a task ended by a shutdown is swept as an orphan on the next start and its parent told; a reconnect never leaves a loaded session stale (invariant 73).
Hardening
- Auth and headers: a credential the store cannot resolve is
503, never401, and does not charge the guess budget (invariant 71); every response carries the security headers; an empty request path gets the index instead of a panic; a numeric query parameter that is not a non-negative integer is400; an admin running a member's private agent is told403;proxy_urlreads back with itsuser:passmasked and the storage settings read admin-only; user labels are admin-only, logout leaves a PAT standing, a chosen token is never logged; a run's event stream is never gzipped. - Runs and the hub: a run segment releases a resume's agent itself and a panic still ends it properly; a broadcast resolves its session on a detached, bounded context; the delete mark lifts once the cascade ends, committed or not; an expired task approval ends the paused hub run; a reopened run record takes the resume's owner, agent and project; a fork's boundary must be a row of the source; deleting a session hands the attachments only it referenced to the reaper;
max_terminals_per_sandboxcounts terminals per sandbox; startup probes every unique index by shape. - Frontend, after a four-way review: hover-only controls reach touch and keyboard users; status shown as colour alone gets its words; the narrow layout's drawer closes on Escape; an OAuth sign-in opens its popup on the click, with a link for a blocked one; a replay never appends to the delta preview; a reconnect re-reads the open session and forgets the rest; a paused background task no longer locks the composer; lost-connection toasts say so; the session timeline is typed end to end and the shared response cache is its own module; the task router, the durable-row merge, the socket client, the composer's keys and the approval card's tiers have tests.
Release engineering and docs
- Releases are one tag. A person pushes the root tag;
release.ymltags the five library modules in lockstep on the same commit (scripts/release-prep.sh --tag-modules), checks that everygo.modrequires the version, states on the release header whether the previous release's database opens on SQLite and PostgreSQL (scripts/schema-compat.sh --pg), and refuses a patch whose exported API breaks the previous tag's (scripts/release-check.sh, apidiff).scripts/consumer-smoke.shthengo gets and builds every module as a consumer, after each release and weekly; CI builds against the latest openai-go as well as the floor. - The positioning is written down. scope §1.1 names who the workbench is for and how the roadmap is filtered (SEE / REPLAY / FORK / OWN); §1.2 records what it is not — a coding agent, a hosted service, an adapter for the Codex app-server or the Agents API (decisions §5.86); CLAUDE.md asks every model-facing default to state its measured gain. Editing a sent message, added and then removed inside this window, is a recorded non-goal: a fork covers it.
- Three documents, sixty corrections. spec, decisions and the workbench invariants were read against the code and corrected where they described intent rather than behaviour; every invariant fits six lines and points at its code;
protocol.mdkeeps meaning and the OpenAPI document says what the handlers do; the runtime-settings table is generated from the registry and its test fails when stale;upstream_watch.mdis backfilled to openai-agents-python v0.23.0. New: decisions §5.64–§5.88, workbench invariants 66–91, spec §2.7u, and §6.3 opens token and deadline budgets as a question.
Changelog
Fixes
- 6e6d5b2 fix(agents-server): deleting an agent deletes its memory over the API too
- 4f31aeb fix(ui): a restored draft opens with the caret at its end
- 10f9359 fix(agents-server): a run's event stream is never gzipped
- db6cbce fix(agents-server): a credential the store cannot resolve is 503, never 401
- 4c95bf3 fix(agents-server): proxy_url reads with its user:pass masked, storage settings read admin-only
- d7c646d fix(agents-server): user labels are admin-only, logout leaves a PAT standing, a chosen token is not logged
- 9e73932 fix(agents-server): audit lines say which scope a flip set, which repository moved, what an import created
- 578391b fix(agents-server): a store fault is not an absence, an MCP listing is bounded, a name is capped at bind
- 0df1e18 fix(agents-server): max_terminals_per_sandbox counts terminals per sandbox
- b5adb6a fix(agents-server)!: a disabled trigger fires 409, a session transfer answers 204
- 869c942 fix(bridge): a reopened run record takes the resume's owner, agent and project
- b2d8663 fix(bridge): an expired task approval ends the paused hub run; a withdrawn resume keeps a stop's ending
- 6d73e6b fix(bridge): a decision refused by a session's delete does not restore the approval row
- 412b932 fix(bridge): a refused attachment id stays out of the failed turn; drop the launcher's unused wake fields
- b5f0ea2 fix(sandbox): a retired instance whose container a successor adopted detaches instead of stopping it
- 8af330b fix(agents-server): deleting a session hands the attachments only it referenced to the reaper
- 19cc009 fix(agents-server): a fork's boundary must be a row of the source, and a row that does not decode is left out of the copy
- da28842 fix(agents-server): the plan phase is addressed by generation, deleting an agent takes its triggers, and the two unused DeleteBySession go
- 33fc078 fix(agents-server): startup probes every unique index by shape, and sessions are indexed by project
- 8b302f7 fix(ui): the Context panel confirms a memory delete in the shared dialog
- 48fee8e fix(ui): hover-only controls reach touch and keyboard users
- 6e7d9cc fix(ui): status shown as color alone gets its words
- accba57 fix(ui): one word for a session, and copy that agrees with the code
- 4042acb fix(ui): the sandbox form freezes exactly the identity fields, and only while projects live on it
- a7fbe01 fix(ui): admin tables name an owner by name and email
- d70f5b3 fix(ui): a keyed mutateData reaches every consumer, and the sidebar list is keyed
- cc30463 fix(ui): a reconnect re-reads the open conversation and forgets the rest
- 55ebf8b fix(ui): a replay never appends to the delta preview
- dd12a78 fix(ui): four small holes in the chat's edges
- bfe5546 fix(ui): a paused background task no longer locks the composer
- 3ef19e6 fix(ui): a failed first load offers a retry instead of a permanent skeleton
- 8414ab0 fix(ui): an edited settings form asks before it is discarded
- 4f83da6 fix(ui): lost-connection toasts say so, and the new invariants are numbered 71-74 without gaps
- 8d75edd fix(agents-server): three lint findings on the review branch
- a50053c fix(agents-server): a fallback entry holds its provider like a primary, and a graceful stop abandons a paused run
- 4c09515 fix(ui): an abandoned run's cancel leaves its successor live, a reconnect keeps the replayed preview, and a new fallback row is editable
- 75f5c56 fix(e2b): the lease refresh falls back to /connect where /timeout is not implemented
- af28f1e fix(e2b): extend the lease through connect alone, keep Options.Headers under the client's own headers, and answer Address with ErrNoSandbox
- 7723996 fix(agents-server): validate e2b headers and api_key at save, keep one credential list, and hand the public address to the owner only
- 8ca464a fix(ui): one headers codec for the sandbox and MCP forms, and no Public URL item without a sandbox
- ad3ac07 fix(e2b): Status confirms a running record through the daemon
- 7b8807e fix(agents-server): a rename, a pin or the generated title no longer moves a session up the sidebar
- 22bda57 fix(ui): the agent and project picked in a New composer follow the session its first message creates
- 215ec73 fix(ui): the top bar title takes the bar less the badge's room and shows the full name on hover
- 88545a2 fix(agents): an echoed assistant message leaves its logprobs behind
- 07b13e1 fix(agents): concurrent guardrails report in declaration order, and the first declared Replace wins
- 903f62f fix(agents): a call naming no tool is an error output in call order, and trips the loop valve
- cbc953e fix(tasks): every store answers a compare-and-set on an unknown id with ErrNotFound
- ba96cbc fix(mcp): a heal the redial cooldown skipped is retried once after it
- 44642d3 fix(anthropic): a tool call cut off by max_tokens ends the stream incomplete
- a51cede fix(sandbox): a shell session's read error arrives after the output read before it
- 90ceee9 fix(sandbox/docker): bound the wait for an exec's output copy once its attachment is severed
- bdfcb50 fix(sessions): New and NewRepo cap a SQLite pool at one connection
- d22e60f fix(agents-server): a refused ChatGPT token exchange reports the endpoint's answer
- dd069f5 fix(ui): a list that failed to load says so and offers Retry
- 6007e0d fix(ui): a scope flip, a section clear and leaving an edited form all confirm first
- 982a7e7 fix(ui): a numeric field keeps what is typed until save
- 3afcfc1 fix(ui): the terminal panel's close control says it hides, and its resizer and tabs work from the keyboard
- 061e016 fix(ui): an OAuth sign-in opens its popup on the click, with a link for a blocked one
- b6089ce fix(ui): a refused approval that names no session rebuilds the one on screen
- 53365f6 fix(ui): the narrow layout's sidebar drawer closes on Escape
- c120f79 fix(agents-server): a transfer or a branch move fences the whole session tree against runs
- fc0c74f fix(agents-server): the delete mark lifts once the cascade ends, committed or not
- e37e72c fix(agents-server): a run segment releases a resume's agent itself, and a panic still ends it properly
- 245f01b fix(agents-server): a broadcast resolves its session on a detached, bounded context and logs a miss
- 96e39b4 fix(agents-server): an admin running a member's private agent is told 403
- bf410b8 fix(agents-server): a numeric query parameter that is not a non-negative integer is a 400
- e1c4422 fix(agents-server): an unnamed local zone prints its offset once
- dbfd8c6 fix(agents-server): every response carries the security headers
- 5ef8141 fix(agents-server): an empty request path gets the index instead of a panic
- 67f1288 fix(agents): compile against openai-go v3.54+ without raising the floor
- 7dd544c fix(agents-server): skip the budget notice for anthropic agents
- d4e5b6e fix(models/anthropic): retry an overload reported inside a 200 stream
- 96579ff fix(models/anthropic): serve Respond from the stream
- bd763f2 fix(agents): ask the caller's stop at the save point
- 768e08d fix(middleware): Loop passes a paused run through
- 5c8015f fix(agents): an exact approval decision outranks a standing one
- dd64c8b fix(agents-server): refuse an inexpressible output schema at save
- 323d946 fix(web): a PAT expiry box refuses non-positive input
- d75f586 fix(agents-server): a time-zone prefix no longer bypasses the
@everyminimum - bbb99a2 fix(agents-server): AGENTS_DB falls back for --db
- e20ade7 fix(agents-server): a trigger turn refuses while an approval is pending
- c7d7638 fix(agents-server): work a trigger started does not inherit standing command trust
- 4a9972b fix(ui): your own send re-pins the log, and the pin follows late-rendered blocks
- 99d8a8a fix(agents-server): a generated session title carries no markdown
- f76cdcc fix(agents-server,middleware): plan mode refuses tools and hides only handoffs
- adc16f2 fix(agents-server): a trigger-started run honors only the grants made on its own cards
- 69cb393 fix(tasks): a task notification says it is another agent's report
- 2302674 fix(agents-server): a trigger payload reaches the model as framed data
- c298f31 fix(release): the module list check walks the tree instead of asking git
- 51de577 fix(agents-server): an input a run read stays in the transcript when the run stops
- a105e1b fix(agents-server): an answered task approval and a withdrawn run republish the status
- de80e2c fix(ui): a steered run's live view survives a resync, a replay and a second input
- bca297d fix(ui): the reject reason box keeps its reason and its keys
- fee31dc fix(ui): queued input is never stranded, and attention signals survive an outage
- c71751c fix(agents)!: output schemas fail at construction
- 0c6d255 fix(agents-server): a task ended by shutdown is swept as an orphan
- 25859ed fix(web): the agent editor counts dangling MCP and skill references
- cf2905d fix(web): forms and lists follow invariants 74/79/80
- e3b53df fix(agents-server): say forks share the project's files
- 4d70612 fix(agents-server): keep reasoning across a Claude model switch
- 317955a fix(anthropic): drop reasoning bound to an older system prompt or tool set
- 60b2a56 fix(ui): browser Back and Forward move between views and close Settings
- 120761e fix(agents-server): the context profile counts what plan mode actually sends
- 51f8480 fix(agents): strict schema conversion visits each node once
- aede7b0 fix(mcp): retry tools/call only when it was never sent
- 967b893 fix(web): a queued input's row on the trace opens like a span's
- afa3154 fix(web): shorter labels for the notification switch and the Replay button
- 7ef1e12 fix(models/openai): put the endpoint and error body back into an API error's text
- 572a7b4 fix(models/anthropic): carry a misplaced mid-history system message in a user turn
Changes
- ace803b feat(agents-server): github sign-in beside google, admitted by the same verified email
- b7bf290 feat(ui): the login button spells GitHub the way GitHub does
- 0f87835 feat(agents-server): a single boolean in a settings form is a toggle row
- df6e623 feat(ui): a scoped settings tab opens on Mine
- c008240 feat(agents-server): an agent can override the system prompt, empty included
- b4057e5 feat(ui): the Memory panel shows one scope at a time
- eb45b93 feat(ui): a trace span's bar carries its children's extents
- c143b6f feat(ui): a paused run's trace gives each stretch its own timeline
- 32777cf feat(ui): a span too short for the trace's scale is drawn as a tick
- 4f345b0 feat(ui): the trace waterfall aligns its bars in one time column
- 1703c06 feat(ui): the sidebar folds into an icon rail below its minimum width
- 870c529 feat(ui): a conversation is made by its first message, never by New
- 5c881b4 feat(agents): spans record the provider's verdict, cache usage, partial output and how a stage ended
- cbf0234 feat(agents-server): a trace span lists the image attachments its input references, and the panel shows them
- ac0ed15 feat(ui): trace rows show what each span recorded
- 7b04daf feat(ui): the trace timeline drops its tick-label row
- 141e2e5 refactor(bridge): a resume runs on the agent the approval path rebuilt, building it once
- 9725dad feat(agents-server): hidden sessions no task names are collected hourly, and finished task transcripts after a retention window
- 56c8409 refactor(store): every model field comment is one factual line, and the stale ones say what the code does
- 28ab3b1 feat(ui): a workbench with no agent shows the three steps to a first reply
- 0f1bdaf feat(ui): an agent without an endpoint says so in the form and on the failed turn
- cb9ccca feat(ui): Approve tools is a checklist, and an MCP server need not be connected to be picked
- a0da6f0 refactor(ui): the session timeline is typed end to end
- 12aa2a3 refactor(ui): drop exports nothing imports
- c4b8ee6 refactor(ui): the shared response cache is its own module
- 3f1b276 refactor(agents-server)!: an agent's tools, skills, handoffs and approve_tools are arrays on the wire
- c038849 refactor(agents-server)!: a fallback entry names a provider, and the chain is a typed array
- 08c74e8 feat(agents-server): a newer message abandons a run paused for approval
- c0475a3 refactor(agents-server): comments say what the code does and point at the one home of why
- 538efd7 refactor(ui): comments point at the invariant instead of restating it
- 40a7e5f refactor(agents-server): the three segment-failure codes are protocol constants, mirrored in the client table
- 54f2888 feat(e2b): custom headers on both planes, for a service that authenticates with its own header
- 3fd0cdd feat(agents-server): a Public URL dialog names where an e2b sandbox's ports are public
- 6e5a21a feat(tasks): spawn_task names a task's agent from the handoff graph
- 176b4ea feat(agents-server): spawn_task lists the entry agent's handoff targets and resolves them by built id
- 0a9bf2f refactor(agents-server): every machine-made session name is clipped by one rule
- b921429 refactor(agents-server)!: a session's timeline loads whole, in one read
- 1853877 refactor(ui): the secret mask is one constant
- 86b1115 refactor(agents): deprecate Agent.Prompt ahead of OpenAI's 2026-11-30 shutdown
- 8882be1 feat(models/anthropic)!: map reasoning effort to adaptive thinking
- 5898e83 feat(models/anthropic): let the API drop a thinking block bound to an edited prefix
- aab5898 feat(agents): screen injected input with the input guardrails
- ee2be49 feat(agents): a refused Terminate turn keeps the record that its tools ran
- faecc31 feat(agents-server): server-derived session status and an approvals inbox
- 31a43c8 feat(agents-server): an approval can be rejected with a reason the model reads
- 4863a44 feat(agents-server): REST twin of run.inject
- eea55e9 feat(agents-server): queue and steer while a run is live
- 71373cf feat(ui): a session that needs you is counted in the title and announced
- 5fed1fc feat(agents-server)!: checklist is an opt-in agent behaviour
- cc96267 refactor(middleware): deprecate Todo
- 5c0c9c1 feat(agents-server): plan review takes a reason and keeps the plan
- e5f387d refactor(middleware)!: remove Retry
- 5795246 refactor(agents)!: a run item event carries its item, not a name
- 031ebd4 refactor(middleware)!: remove Todo
- 462438c feat(middleware)!: OnUnlock receives the approved plan
- f79b0b4 refactor(openai)!: remove CompactionSession
- c1bdd26 feat(agents): retries respect replay safety and per-attempt timeouts
- 3bffd25 feat(sandbox): read_file pages by line
- 878e283 feat(agents-server): page the session list
- afcb73e feat(ui): approval cards take y/n and hide branching while pending
- 2788e5a feat(agents-server): approve every pending call of a pause at once
- 82a67cd feat(agents-server): error cards say what failed, and replay is one click from the turn
- da890a4 feat(ui): edit a message and resend it as a new branch
- b3bd4d3 feat(agents-server): test a provider and pick its models from the live list
- d667f1b feat(ui): the theme follows the system unless you pick one
- ae2e749 feat(agents-server): an MCP server names the tools plan mode admits
- 7e9a02f feat(middleware): export the read-only predicate plan mode denies by
- 20ce3c5 feat(agents-server): approval modes replace the per-tool checkbox grid
- 851fa4b feat(web): a sandbox form can insert a working agreement
- 2d97663 feat(agents-server): the checklist outlives compaction and reaches background runs
- 97fadc8 refactor(ui): import only Primer CSS's base and markdown layers
- d0c5196 refactor(agents-server)!: drop the stored prompt fields
- 6a1ab2c refactor(agents)!: remove Agent.Prompt
- 0ef5bca feat(session): public sessiontest conformance suites
- c4f82d6 feat(agents): cap tool output at the runner
- d96e681 feat(web): a trace shows where a run read a queued input
- a298a41 refactor(web): drop editing a sent message; a fork covers it
- 9a97a26 refactor(models)!: track the latest openai-go and anthropic-sdk-go
Full Changelog: v0.4.4...v0.6.0