Skip to content

V2/ACP: switching agent/mode (e.g. brainstormer → build) does not update the toolset; write/edit tools stay unavailable #37348

Description

@omryMen

Description

Switching agent/mode in the V2 ACP path (e.g. brainstormerbuild) never updates the durable session agent, so the tool loop keeps materializing the previous agent's toolset. Switching from a read-only agent like brainstormer to build (our code mode) leaves write/edit tools unavailable — the model can't write code even though the UI shows build selected.

This is the tools/permissions counterpart to the (closed) #18620, which described the same root cause for the model. It lives in the V2 ACP adapter tracked by #35457.

Root cause

The mode switch updates only ACP-local, in-memory state and relies on a prompt field that the protocol drops. The durable session.agent — which drives tool materialization — is never changed:

  1. ACP setSessionConfigOption / setSessionMode (packages/opencode/src/acp/service.ts:438-463) only call session.setMode(...), which writes to the in-memory ACP session store (packages/opencode/src/acp/session.ts:149). This is ACP-local, not durable.
  2. On prompt, ACP puts agent: modeId into the SDK session.prompt payload (service.ts:516).
  3. The session.prompt protocol endpoint payload has only id, prompt, delivery, resumeno agent field (packages/protocol/src/groups/session.ts:207-212). The agent value is silently dropped at the HTTP boundary.
  4. The runner resolves agents.select(session.agent) (packages/core/src/session/runner/llm.ts:182) then tools.materialize(agent.info?.permissions) (llm.ts:203) from the durable session row, which was never updated. So the old agent's tools/permissions (and system prompt) persist.

The durable agent is only updated by the separate session.switchAgent endpoint (packages/server/src/handlers/session.ts:108; exercised in packages/sdk-next/test/embedded.test.ts:177), which ACP never calls.

Impact

Any agent/mode switch in the TUI/ACP is a no-op for tools, permissions, and system prompt. Most visible when switching away from a restricted agent (brainstormer) to build: write/edit tools stay unavailable and the model cannot modify files.

Steps to reproduce

  1. Start a session in brainstormer mode.
  2. Switch mode to build (code mode).
  3. Ask it to write or edit a file.
  4. Observe it cannot — the toolset is still brainstormer's read-only set.

Proposed fix

  • Fix A (targeted): In ACP's mode-switch handlers (setSessionConfigOption for configId === "mode" and setSessionMode), also call input.sdk.session.switchAgent({ sessionID, agent: modeId }) so the durable agent updates. Minimal, reuses the existing endpoint. (Mirrors the model fix approach discussed in ACP: session/set_mode does not activate the agent's configured model #18620.)
  • Fix B (broader): Thread an optional agent through the session.prompt protocol endpoint and store so a per-prompt agent emits session.next.agent.switched before admission. More invasive (protocol regen).

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions