Skip to content

feat(pi): add active-turn steering via native steer RPC - #3752

Open
mcowger wants to merge 1 commit into
getpaseo:mainfrom
mcowger:implement-steering-for-pi
Open

feat(pi): add active-turn steering via native steer RPC#3752
mcowger wants to merge 1 commit into
getpaseo:mainfrom
mcowger:implement-steering-for-pi

Conversation

@mcowger

@mcowger mcowger commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds active-turn steering for pi, completing the provider matrix started for Claude (#3394), Codex, and OpenCode (#3580). Sending a message into a running pi agent now delivers it into the live turn via pi's native steer RPC instead of interrupting and restarting.

Changes

  • rpc-types / runtime / cli-runtime: add the steer command variant and steer(message, images) on PiRuntimeSession, sending pi's native {"type": "steer"} RPC frame.
  • Provider adapter (agent.ts): implement PiRpcAgentSession.steerActiveTurn():
    • Reports unavailable when the expected turn isn't the active one, when the prompt is a slash command (pi rejects extension commands on the steer path, so those keep the interrupt-and-replace fallback), or when an older binary answers Unknown command: steer (COMPAT(piSteerFallback)). Any other RPC failure throws, leaving the steer's fate unambiguous.
    • Re-checks admission after the RPC resolves so a steer queued into a turn that already moved on can't trigger a replacement of the wrong turn.
    • Honors the permission contract: with clearPendingPermissions, denies each pending extension_ui_request after admission, using the same denial message as the other adapters.
    • Correlates the user-message echo with the right clientMessageId via a pending-submission list matched by text in admission order (pi's steer RPC takes no message ID, unlike OpenCode's), consumed by the PASEO_SUBMITTED_USER_ENTRY extension marker and dropped on every turn-teardown path.
  • Tests: 8 new PiRpcAgentSession steering cases (accepted steer + echo correlation, multi-steer FIFO order, stale/idle turn, slash-command fallback, unknown-command fallback, ambiguity surfacing, permission denial with/without the flag, stale correlation dropped at turn end) and 2 steer-frame tests in cli-runtime.test.ts; FakePi gains steer() recording.
  • Docs: docs/providers.md steering section now covers pi's RPC path, the text-correlation constraint, and the queue-clearing limitation below.

Testing

  • New unit tests above against FakePi; full pi provider suite passes (91 tests), plus repo-wide typecheck/lint/format.
  • Verified pi's steer RPC contract directly against the installed pi 0.84.2 package (docs/rpc.md, rpc-mode.js, agent-session.js, pi-agent-core's steering queue).

Notes / Follow-ups

  • Known limitation: pi exposes no RPC to clear its steering queue, so a steer pi hasn't read when the turn is interrupted is delivered at the start of the next turn. Documented in docs/providers.md.
  • Worth one real-binary smoke run (Send and steer into a running pi agent) before marking this ready for review.

@mcowger
mcowger marked this pull request as ready for review August 23, 2026 17:53
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.

1 participant