Repository navigation
[Bug]: ACP instruction block (incl. collaborative browser) is lost after context compaction and never re-injected #21036
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Run
t3 serveand start a thread with an ACP agent (e.g. OpenCode) with thet3-codeMCP server attached. - Let the thread run long enough that the agent compacts/summarizes its own context (OpenCode's native compaction, or T3's own "Compact idle threads" from feat(server): compact idle threads before the prompt cache expires #19662).
- Check the agent's active context for the T3 instructions (e.g. ask the agent to quote the section titled "T3 Code collaborative browser", or simply ask it to use the browser).
Expected behavior
The <t3_code_instructions> block — in particular T3_CODE_BROWSER_TOOL_INSTRUCTIONS — stays effective for the life of the thread: after a compaction the agent still knows that the product-native browser is the preview_* server-browser tools, not the host agent's built-in browser tools. (The Codex path effectively does this: restoreAdditionalContext re-injects the saved instruction entries after a compaction.)
Actual behavior
The instruction block is sent exactly once — with the first user prompt, or only when interactionMode or hasT3Mcp changes (t3AcpPromptWithInstructions, packages/provider-core/src/server/orchestrationInstructions.ts:72-94). After a compaction the one-shot message is summarized away and nothing re-sends the block:
resolvePromptParts(packages/provider-acp/src/server/adapter.ts:6304-6328) computes the instruction state per turn frominteractionMode+hasT3Mcpand compares it against the per-sessionpromptInstructionStatesref. Compaction is not part of that state and no compaction event resets it.- The
compaction_update/compaction_summary_chunkhandling in the ACP adapter only projects a "Context compacted" timeline item; there is no re-injection.
Observed on T3 0.1.0 with an OpenCode ACP thread: after the thread's context was compacted, the active context contained no "T3 Code collaborative browser" section (the installed 0.1.0 binary ships it), although the t3-code MCP server stayed attached throughout and no mode/MCP state change occurred. When the user then asked about the browser, the agent reached for OpenCode's built-in browser.* tools and got [browser.disconnected] — a dead end by design, because T3 never attaches a browser host to OpenCode and the preview_* server browser is the product-native path, which the agent only knew from the lost instruction block. The only recovery was a new thread.
Related (checked, not duplicates)
- [Bug]: Codex threads receive the T3 orchestration instructions with the middle truncated #18411 / fix(server): Codex threads get the whole T3 orchestration instructions #18415 — Codex-specific: Codex caps each
additionalContextvalue at ~1000 tokens, so the middle of the orchestration instructions is truncated; the Codex path re-injects after compaction viarestoreAdditionalContext. Different provider, different mechanism. - [Bug]: Claude Code threads get T3 instructions meant for other agents #16465 / fix(server): Claude threads no longer get ACP and Codex tool instructions #16482 — wrong provider-specific instructions delivered to Claude Code threads.
- [Bug]: With agent browser/device access off, the agent still sees every preview_* and device_* tool #17202 — inverse visibility problem:
preview_*tools visible even when agent browser access is off. - Built-in browser does not render or navigate on v0.0.46 nightlies; desktop browser tools report "No desktop browser is connected to this session" #17009 / Agent browser tools report a never-attached browser as a permanent failure with no recovery path #19977 — OpenCode's built-in browser never attaches in some environments; the
[browser.disconnected]error semantics are OpenCode-side (closed as duplicate of Built-in browser does not render or navigate on v0.0.46 nightlies; desktop browser tools report "No desktop browser is connected to this session" #17009). - feat(server): compact idle threads before the prompt cache expires #19662 — T3's own idle-compaction feature makes this much more likely: the threads T3 itself compacts are exactly the threads whose one-shot ACP instruction block gets summarized away.
Impact
Major degradation or frequent failure
Version or commit
0.1.0 (observed) / main @ 07cb902 (source analysis, 2026-10-17)
Environment
LXC container (Linux, Debian-based), t3 serve --host 0.0.0.0 running as root, agent: OpenCode over ACP, T3 0.1.0
Logs or stack traces
No stack trace — silent instruction loss. Observable symptom:
agent → browser.tabs.open (OpenCode built-in)
result → [browser.disconnected] ...
while on the same thread preview_status / preview_open (the t3-code MCP server) work normally.
Workaround
No reliable one. An agent can still discover the preview_* tools by searching the tool catalog, and re-triggering an instruction state change (toggling the interaction mode, or detaching/attaching the MCP server) forces a re-injection — but neither is something a user can reasonably do per thread. A new thread always starts with the full block.
Suggested direction (maintainer's call)
Treat compaction completion as an instruction state change: when a compaction_update for the session reports the summary, invalidate that session's promptInstructionStates entry so the next user prompt re-prepends the full <t3_code_instructions> block. This mirrors what the Codex path already does with restoreAdditionalContext and is a small change in packages/provider-acp/src/server/adapter.ts plus a state field in T3AcpInstructionState.
Activity
juliusmarminge commentedon Oct 17, 2026
Note
Grok responding on behalf of Julius.
Confirmed on main. The ACP adapter sends the
<t3_code_instructions>block only wheninteractionModeorhasT3Mcpchanges. Nothing resetspromptInstructionStatesafter compaction, whether nativecompaction_*updates or/compact, so after compaction the block is never sent again. The Codex adapter does restore its instructions after compaction throughrestoreAdditionalContext. The ACP path puts the block only in the user prompt, so this is on our side, not OpenCode's. It's not a duplicate of #18411, #18415, #20222 or #20236. Keeping this open as a bug.fix(server): re-inject T3 instructions into ACP sessions after compac…