* fix(agents): make memory-flush append-only write honor the write outputSchema
The memory-flush append-only write wrapper inherits the base write tool (and its declared outputSchema) via spread, but returned {path, appendOnly} details. The code-mode bridge validates results against the declared schema and rejected the call AFTER the append side effect had landed (reported as the outputSchema variant in #120385).
Return {changed: true, created: <bool>} via a best-effort pre-append existence probe; sandbox-bridged appends omit created rather than guess. Exports WriteToolOutputSchema for the new contract test.
* fix(agents): memory-flush append-only write returns outputSchema-conforming details
Address ClawSweeper review findings on #120404:
P1 - Update the remaining append-only wrapper expectations.
Three test sites still asserted the removed `{ path, appendOnly }` /
`created` shapes and would have failed after the return expression changed:
- src/agents/agent-tools.workspace-paths.test.ts (2 assertions)
- src/agents/embedded-agent-runner/run/attempt.memory-flush-forwarding.test.ts
- src/agents/agent-tools.memory-flush-append-write.test.ts
All now assert `{ changed: true }` and are included in focused validation.
P2 - Avoid reporting a non-authoritative created flag.
Removed the pre-append existence probe entirely rather than narrowing it.
The probe ran before the append, so another writer could create or remove
the target in between while the result still claimed `created` - a TOCTOU
guess the append path cannot make authoritatively. The inherited write
outputSchema permits the bare `{ changed: true }` shape, so the wrapper now
reports only what the call actually knows. This also deletes the
sandbox/non-sandbox divergence the probe introduced.
Net effect: -31 lines. The fix is now purely subtractive on the source side.
Validation: 7 test files, 85 passed / 2 skipped; oxlint clean on all touched files.
* test(agents): validate memory-flush schema via public tool
* fix(agents): condense memory flush result contract comment
* test(agents): use narrow write-tool barrel
---------
Co-authored-by: Grynn <grynn@users.noreply.github.com>
* feat(gateway): carry machine class through session moves
Profile move targets accept an optional machineClass with new-session
parity: validated in the protocol, persisted on the durable move intent
(bare nullable column, lazy same-version ALTER), replayed exactly by
restart recovery, and selectable from the Control UI move dialog.
Moving to the current profile with a different class resizes the
session's worker.
* fix(gateway): project placement facts on chat startup
chat.startup and chat.history built sessionInfo without the placement
projection sessions.list applies, so clients merging that row erased a
live worker placement and its move intent — the Runs on Cloud chip
disappeared after any turn until a full reload.
Reuse the canonical ensureColumn helper for the move table's additive
column instead of a hand-rolled PRAGMA read.
Keep provider-scoped onboarding metadata resolution limited to the selected provider, preventing fallback OpenAI loading when Ollama is chosen without a configured model.
Refs #125373 and #125363.
Scope onboarding model discovery to the selected provider so browsing no longer loads unrelated provider setup surfaces while preserving route variants and global browsing behavior.
Fixes#125363.
Keep embedded mobile Side chat inside its tabbed panel so the main composer and shared controls stay tappable.
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* feat(agents): unify agent status into a durable progress_card
Replace the write-only update_plan to-do tool and the fragmented plan
rendering with one durable status artifact per session: progress_card
({plan?, markdown?}, replace-on-write, 8 KiB markdown / 50-step caps).
Cards persist in a lazy-additive session_progress_cards table in the
per-agent DB (no schema-version bump), broadcast progressCard.changed,
and render from the store with exactly one live placement per view
(session rail when visible, else the composer-adjacent bar); transcripts
collapse to one-line receipts, and the sidebar hovercard shows other
sessions' cards inline (markdown + <progress>, DOMPurify allowlist, no
iframes). The three stream-derived plan renderers and their dedup
heuristics are deleted.
Codex runs disable the native plan tool per thread
(tools.update_plan.enabled=false) and receive progress_card via the
dynamic-tool bridge; compaction restore now reinjects the card (steps +
bounded markdown). Card writes still emit the legacy plan stream event so
native apps and channels keep working until their per-platform
migrations. Policy names map update_plan -> progress_card; the shipped
tools.updatePlan=false kill switch is honored.
Net -277 production LOC; -480 test LOC.
* test(agents): regenerate Codex prompt snapshots for update_plan thread-config disable
* chore(protocol): allowlist progressCard.changed for native apps pending card migration
* fix(ci): repair progress card integration checks
* fix(codex): canonicalize native progress cards
* test(gateway): reconcile progress card method order
* test(codex): stabilize native approval fixture
One-time maintainer-authorized bootstrap landing for the exact reviewed head. This direct merge replaces the broken self-hosted verifier so subsequent pull requests can return to the native review, prepare, and merge workflow.
The default OpenAI Responses compact_threshold was 70% of contextWindow alone; for gpt-5.6-sol (1.05M window, 272k active budget) that resolved to 735,000, above the ~252k prompt budget the runtime admits, so provider compaction never fired before local overflow handling. Threshold now uses 0.7 x min(contextTokens, contextWindow) (190,400 for Sol) on both the payload-policy and host-preflight paths; explicit responsesCompactThreshold still wins.
* docs: document three-layer session ownership
User documentation for the session-ownership feature landed in #125057:
the immutable creator / assignable owner / participant-history model, the
Assign-to-me and Assign-to session menu actions, the sessions tool
assign_owner action, the sidebar Owners facet with Involving-me, the
pair-stack owner avatar, and agent-spawned session receipts (sessionUrl +
owner acknowledgement). Adds the sessions.assignOwner method and ownership
row projections to the protocol reference and a zh-CN glossary entry for
the new link label.
* docs: drop nonexistent header facepile overflow count
The chat header receives the already 4-capped participant projection and no
total count, so its overflow branch cannot render. Describe up to four
avatars instead (ClawSweeper P2).
* fix(agents): preserve contextual reply correlation
Carry prepared reply policy into embedded and CLI message tools so targetless direct replies retain transport correlation and Reef thread identity.\n\nCloses #125279
* fix(reef): preserve unthreaded reply correlation
Keep reply-only inbound messages unthreaded unless the transport supplies a thread, while still anchoring new exchanges to their initiating envelope.\n\nRefs #125279