Skip to content

Declare plan support for ACP agents and translate it via session modes - #3040

Open
bradhallett wants to merge 1 commit into
get-bb:mainfrom
bradhallett:feat/acp-capability-parity
Open

Declare plan support for ACP agents and translate it via session modes#3040
bradhallett wants to merge 1 commit into
get-bb:mainfrom
bradhallett:feat/acp-capability-parity

Conversation

@bradhallett

@bradhallett bradhallett commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Human comments

I hit this running omp as an ACP provider day-to-day: plan-then-approve works on first-party providers and silently doesn't exist for ACP threads, which made the orchestration workflows I use bb for (scouts → review → implement) awkward to gate. The slop-cop repro matches what I saw before filing.

Two things I'd flag for reviewers: the capability only un-gates what the agent actually advertises (no-modes agents get byte-identical passthrough — that was a hard requirement for me, not a nice-to-have), and rewind is deliberately left undeclarable rather than approximated. Built agent-assisted; I reviewed the wire-shape decisions myself.

What was wrong

The plan action and edit-past-message gates were already capability-driven (composerActions: ["plan"], capabilities.fork), but ACP agents could not declare either: the ACP provider hardcoded composerActions to [] and typed AcpAgentDefinition.fork as none|tip, so every ACP agent was excluded by declaration shape rather than by capability. The bridge also dropped promptMode and discarded current-mode updates as noise. Reproduced independently by the slop-cop triage at base 43e3fc519 (report); fixes #3019.

What changed

  • AcpAgentDefinition gains supportsPlan (mirroring supportsManualCompaction), threaded through the customAgents setting and mapped to composerActions: ["plan"] in the declaration; acp-omp declares it.
  • The ACP bridge now reads the session modes agents advertise (session/new, session/load, session/fork results and current_mode_update notifications) and, when the agent advertises a plan mode, drives it with session/set_mode on plan turns, strips the /plan command mention from the prompt, and returns the session to its initial mode afterward; agents that report no modes keep byte-identical text passthrough.
  • Session rewind stays undeclarable for ACP agents: ACP v1 session/fork is tip-only with no fork-point selector and reports no per-turn checkpoints, so no shipped or custom ACP agent can honestly declare checkpoint rewind today.

How you verified

pnpm exec turbo run typecheck test lint --continue plus pnpm format:check. provider-bridge-acp typecheck clean, all 317 tests pass, including the new ones: declaration mapping (composerActions: ["plan"] only for agents declaring it), wire modes/current_mode_update parsing, and bridge plan-turn translation (set_mode "plan" precedes session/prompt with the mention stripped; a no-modes agent gets no set_mode and untouched text; the mode resets to the initial mode after the turn). Server suites that consume provider declarations pass solo (first-party-provider-plugins, plugin-install, plugin-update). Remaining failures are pre-existing on main f6868ad0c, each verified by stash-rerun on a clean tree: secret-storage concurrent-creators, server install-machine-script (macOS Abort trap: 6 on the spawned host-daemon), host-workspace workspace-diff/provisioning, and 183 files flagged by format:check from the pinned oxfmt 0.64.0 at head (formatter default drift); the new code matches the dominant committed style of the files it touches.

Fixes #3019

AGENT GENERATED

What was wrong: the plan action and edit-past-message gates were already
capability-driven (composerActions "plan"; capabilities.fork), but ACP
agents could not declare either: the ACP provider hardcoded composerActions
to [] and typed AcpAgentDefinition.fork as none|tip, so every ACP agent was
excluded by declaration shape rather than by capability.

What was changed: AcpAgentDefinition gains supportsPlan (mirroring
supportsManualCompaction), threaded through the customAgents setting and
mapped to composerActions ["plan"] in the declaration; acp-omp declares it.
The ACP bridge now reads the session modes agents advertise (session/new,
session/load, session/fork results and current_mode_update notifications)
and, when the agent advertises a plan mode, drives it with session/set_mode
on plan turns, strips the /plan command mention from the prompt, and
returns the session to its initial mode afterward; agents that report no
modes keep byte-identical text passthrough. Session rewind stays
undeclarable for ACP agents: ACP v1 session/fork is tip-only with no
fork-point selector and reports no per-turn checkpoints, so no shipped or
custom ACP agent can honestly declare checkpoint rewind today.

What was verified: pnpm exec turbo run typecheck test lint --continue plus
pnpm format:check. provider-bridge-acp typecheck is clean and all 317
tests pass, including the new ones: declaration mapping (composerActions
["plan"] only for agents declaring it), wire modes/current_mode_update
parsing, and bridge plan-turn translation (set_mode "plan" precedes
session/prompt with the mention stripped; a no-modes agent gets no set_mode
and untouched text; the mode resets to the initial mode after the turn).
The server suites that consume provider declarations pass solo
(first-party-provider-plugins, plugin-install, plugin-update). Remaining
failures are pre-existing on main f6868ad, each verified by stash-rerun
on a clean tree: secret-storage concurrent-creators, server
install-machine-script (macOS Abort trap: 6 on the spawned host-daemon),
host-workspace workspace-diff/provisioning, and 183 files flagged by
format:check from the pinned oxfmt 0.64.0 at head (formatter default
drift); the new code matches the dominant committed style of the files it
touches.

AGENT GENERATED
@willadamskeane

Copy link
Copy Markdown

I tested this against the shipped OpenCode ACP provider and found two follow-up gaps: acp-opencode is not opted into supportsPlan, and the host-daemon protocol is not advanced even though an older daemon will silently ignore the now-exposed promptMode. I opened a minimal four-file patch directly against this PR branch: bradhallett#1. Focused provider/contract tests and typechecks pass (133 tests total).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACP providers can't use plan mode: supportsPlan is never declared or translated from session modes

2 participants