Skip to content

feat(acp): steer prompts during active turns - #91

Open
amadad wants to merge 1 commit into
svkozak:mainfrom
amadad:fix/in-flight-pi-steering
Open

feat(acp): steer prompts during active turns#91
amadad wants to merge 1 commit into
svkozak:mainfrom
amadad:fix/in-flight-pi-steering

Conversation

@amadad

@amadad amadad commented Jul 29, 2026

Copy link
Copy Markdown

Summary

  • add Pi's documented steer command to the RPC process wrapper
  • route a concurrent ACP prompt through Pi steering once the agent loop is active, instead of waiting for the full run to finish
  • preserve the existing client-side queue for the narrow startup/settlement race where no Pi agent loop is active yet
  • resolve steered ACP prompt requests with the shared run and preserve cancellation behavior

Closes #7.

Why

A corrective prompt arriving while Pi is executing tools currently waits in turnQueue until agent_end. That prevents an ACP client from redirecting an active run even though Pi RPC already provides the intended steering primitive.

The adapter now keeps the decision at the session boundary: active Pi loop means steer; pending ACP request without an active loop keeps the existing queue behavior.

Verification

  • node --import tsx --test test/component/session-events.test.ts test/component/session-queue-cancel.test.ts
  • npm test — 96 passed
  • npm run typecheck
  • npm run lint
  • npm run build
  • npm run smoke — ACP handshake, session creation, prompt streaming, and completion passed against Pi 0.82.1

Signed-off-by: Ali Madad <ali@scty.org>
@0xDarkMatter

Copy link
Copy Markdown

Live-tested this branch against pi 0.83.0 (openai-codex/gpt-5.4-mini), driving the adapter over raw ACP stdio: one session/prompt running three sequential sleep 4 bash calls, a second session/prompt injected ~4s in, mid-tool-call.

It works as designed. Pi's session file confirms the steered message was delivered as a user message at the first turn boundary (after tool result 1, before the next LLM call). Both ACP requests resolved together at agent_settled with the shared stopReason — vs current main, where the same injection sits in the client-side queue until the whole run settles.

Notes from the review:

  • Branch is based on 0.0.32; it conflicts with current main (0.0.33) in test/component/session-events.test.ts — needs a rebase.
  • Test suite on the branch: 94/96 pass; both failures are pre-existing on main in my environment (platform-specific path assertions), unrelated to this PR.
  • Edge worth a thought: if inAgentLoop flips false between the check and pi accepting the steer (settlement race), proc.steer rejects and the ACP request errors. Falling back to the queue on that specific rejection would make it seamless — fine as a follow-up.

This unblocks turn-boundary injection for headless ACP harnesses (our use case), not just editor UX. Would love to see it land.

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.

Map prompts during streaming to pi steer command

2 participants