Proposal: session/inject for mid-turn queue + steer #1220
Replies: 2 comments
-
|
Hi Kenneth! This is a great start! I think you've encapsulated the problem nicely here and I think this is generally going in the right direction (or by right i mean, it matches my gut feeling, having not tried to implement it in ACP yet 😄 ) I'm trying to work out some kinks for the plumbing of v2 so we can start experimenting with the new prompt lifecycle and stuff like this, but if you want to open an RFD I'd be happy to put it in the v2 bucket! Also happy to hop on a call to say hi and also talk more if you like |
Beta Was this translation helpful? Give feedback.
-
|
Drafted as PR #1261 ( |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
TL;DR: Two adjacent inputs — queue (buffer for next turn) and steer (deliver mid-turn at next break-point) — have converged across most public coding-agent UIs, but ACP has no surface for either. Filing here per the RFD process before drafting a PR. Looking for a champion who'd like to co-design this as a follow-on to the v2 prompt lifecycle.
What converged
Enter-steer (opt-in via/experimental) is the most fleshed-out implementation. The Codex codebase has its own pending-steers queue, requeue-on-turn-complete, pause-on-usage-limits, and a separate stop-reason / replay edge-case surface — see PRs #12569, #15235, #22226, #22879 and issues #19975, #22815.ACP today
session/cancel+ a freshsession/promptis the only mid-turn lever, and it discards in-flight context.stopReasonhas no value for steer-interrupted turns.The v2 prompt lifecycle RFD already calls out queueing as future work: "Queueing messages (still an ongoing discussion) would also fit much nicer in this pattern... potentially the agent could decide whether it cancels the current turn and inserts it immediately, or inserts it at the next convenient break point." The substrate this needs — short-lived
session/prompt,user_messageecho notification,state_changerunning/idle/requires_action — is the v2 prompt lifecycle. So this is intended as a v2 follow-on, not a v1 patch.Adjacent RFDs in motion that this composes with: message-id (handle for ack and revocation), multi-client attach #533 (who's allowed to inject), session rewind #1214 (destructive-history sibling), turn-complete signal #644 (queue-flush barrier).
Sketch
One method, two modes:
{ "jsonrpc": "2.0", "id": 42, "method": "session/inject", "params": { "sessionId": "sess_abc", "mode": "steer", "content": [{ "type": "text", "text": "stop using the legacy auth path, see auth_v2.go" }] } }Response carries the
messageIdper the v2 prompt lifecycle pattern. Capability:{ "agentCapabilities": { "session": { "inject": { "modes": ["queue", "steer"] } } } }Agent advertises which modes it supports. Streaming-only agent:
["queue"]. Tool-loop agent that can break safely:["queue", "steer"].Semantics
steer: delivered as the next user message at the earliest safe break-point. Mid-tool-call: complete the call, then deliver. Mid-stream with no tool call in flight: agent-defined — interrupt and re-prompt, or finish the stream and deliver.queue: buffered, delivered as the next user message afterstate_change: idle. FIFO.user_messagenotification at the moment of delivery, so multi-client observers see consistent history andsession/loadreplays in order.Open questions for the discussion
$/cancel_requeston the inject request keyed bymessageId? Steered messages once handed to the LLM are not revocable.session/cancelinteraction: cancel-during-steer ordering — Codex #22815 is a real bug surface if left implicit.session/request_permissioninteraction: while blocked on permission, queue accumulates; steer rejected or queued (agent-defined, capability bit).cancelledfor steer-interrupted LLM calls — no new reason needed.ContentBlockarray, same shape assession/prompt.params.prompt.session/load.Looking for
A core-team champion willing to co-design this as a v2 follow-on. Happy to draft the RFD PR once direction is agreed — or rework if a different framing (e.g. two separate methods, or rolling queue into the v2 prompt lifecycle RFD itself) is preferred.
Process note: I workshopped this draft with a coding agent for structure and prior-art digging — happy to take feedback on framing, or to hop on Zulip / a call if a maintainer wants to talk it through live.
Beta Was this translation helpful? Give feedback.
All reactions