Vouch agent-initiated ACP turns so async job delivery renders - #2123
Vouch agent-initiated ACP turns so async job delivery renders#2123bradhallett wants to merge 2 commits into
Conversation
ACP agents can produce session updates with no prompt in flight (OMP async-job auto-delivery). The bridge gated all work updates on an active prompt, so the output was dropped and nothing reached the thread. The bridge now opens a turn itself when idle agent-work updates arrive, settles it on a quiet window, before the next bb-initiated turn, or on stop; non-work updates stay noise.
Fold the parallel spontaneousTurnOpen boolean into activePromptKind as an "agent" prompt kind, so every reader of the open-turn mirror — turn dispatch, permissions, error settlement, interrupts — treats agent- initiated turns (OMP async-job delivery) as real work: - The turn/start guard no longer rejects while a vouched turn is open; runTurn/startCompaction settle it (end_turn) before opening the next prompt. thread/stop interrupts it as cancelled via settleInterruptedPrompt. - An agent process exit or session error now settles the open vouched turn: emitSessionError emits the settling error delta for any open prompt kind (removeSession keeps clearing only the quiet timer), so the thread can never hang "working" after a crash mid-turn. - Permission requests raised inside a vouched turn are no longer auto-cancelled: full mode auto-allows and other modes forward to the user, like a prompted turn. - Derive the work-kind test from the visibility metadata (isAgentWorkUpdateKind) instead of a second hand-maintained map. Adds regression tests: agent exit mid vouched turn, a failing prompt settling an open vouched turn (error still surfaces), and a permission request inside a vouched turn, with matching fake-agent behaviors.
Rework addendum — reply to the review of #2123Rebased onto current
Also per §6.5: Verification:
|
39a8b2b to
d7b1ae6
Compare
|
Closing as superseded by #2220 — the vouched-turn approach landed there in better shape. The fake-agent wire shape from this PR is referenced in can1357/oh-my-pi#9157 for testing the omp-side capability when it lands. |
What was wrong
ACP agents can emit
session/updatework output with no prompt in flight — an agent-initiated turn (OMP's async-job auto-delivery is the concrete case: a background job settles, the agent resumes and streams a follow-up unprompted). ACP brackets no turn for that, and the bridge forwarded the updates unbracketed, so the translator classified themunhandled/onlyIfNoTurnand they never reached the thread: the agent's output was silently dropped. Root cause and evidence in #2122 (DB event gap, wire probe, pre-fix permalinks).What changed
plugins/provider-acp/src/bridge/bridge.ts— the bridge now vouches agent-initiated turns itself, the shapedocs/provider-bridge-protocol.mdturn lifecycle rule 3 sanctions (and the compaction path already uses):agent_message_chunk,agent_thought_chunk,tool_call,tool_call_update,plan) open a vouched turn via the existing bridge turn-started command →turn.open.SPONTANEOUS_TURN_IDLE_TIMEOUT_MS, 120 s, re-armed per chunk) settles the turn asend_turn; a still-open one settles before the next bb-initiated turn or compaction starts;thread/stopand session teardown cancel/clean it. A slow provider can split into multiple vouched turns; output is never lost.available_commands_update,usage_update, …) stay noise — no phantom turns.user_message_chunkstays classified as input-echo noise, so the replayed async result creates no phantom user row.No wire/protocol changes; translator untouched (stays context-free).
fake-acp-agent.mjsgainsspontaneous-stream:N(post-prompt unsoliciteduser_message_chunk+ N agent chunks) andspontaneous-noisebehaviors plus a follow-upusage_updatesignal;__setSpontaneousTurnIdleTimeoutForTestsshrinks the quiet window in tests.How you verified
src/bridge/bridge.test.ts(real bridge + real delta assembler, fake agent over stdio): vouched turn opens for unsolicited output and quiet-closes; a still-open vouched turn settles before the next user turn (3 started / 3 completed, stream intact, exactly oneinput.accepted); non-work idle updates open nothing.agent_message_chunkfrom the work-kind map fails both positive tests (and not the noise test).pnpm -C plugins/provider-acp test→ 184 passed (14 files);tsc --noEmitclean; eslint + prettier clean on touched files.Fixes #2122