Skip to content

fix: keep idle steering fallback host-owned - #441

Closed
fontanierh wants to merge 1 commit into
agentclientprotocol:mainfrom
fontanierh:fix/host-owned-steering
Closed

fontanierh wants to merge 1 commit into
agentclientprotocol:mainfrom
fontanierh:fix/host-owned-steering

Conversation

@fontanierh

Copy link
Copy Markdown

Lifecycle

active turn  -> inject                 -> original session/prompt completes
idle + opt-in -> promptRequired        -> host starts owned session/prompt
idle default  -> startedNewTurn        -> existing behavior

Adds the promptRequired opt-in already shipped by claude-agent-acp in #919. Invalid idle policies fail closed.

Tests cover idle, the completion race, legacy behavior, and malformed metadata.

Fixes #440.

srid added a commit to juspay/olai that referenced this pull request Sep 6, 2026
Sending another message while Codex was working opened an overlapping
ACP prompt. Older requests could remain unanswered after Codex finished,
leaving the panel stuck on “Codex is working…”. Busy sends now use
steering when the agent advertises steering without a prompt queue;
queue-capable agents retain their existing behavior.

Keep codex-acp 1.10.0 / Codex 0.153.3 and use Nix `fetchpatch` to
backport [upstream PR
#441](agentclientprotocol/codex-acp#441), pinned
to its commit and content hash. If a turn finishes before steering
arrives, the adapter returns the message to Olai to start a tracked
prompt. The upstream PR remains open; its branch is based on an older
adapter release.

Browser coverage exercises multiple busy sends, completion,
cancellation, refused-steering retry, and completion/cancellation races.
Chat documentation is updated.

Validation:

- Full `just ci` passed on `274a7f483`: 49 successful jobs, including
all 1,485 browser scenarios.
- The packaged build includes 10 upstream steering tests.
- Passed on rerun without code changes; earlier attempts hit
intermittent conversation-restoration timeouts.
@fontanierh fontanierh closed this Oct 5, 2026
EugeneTheDev pushed a commit that referenced this pull request Oct 28, 2026
If a Codex turn finishes just before `_session/steering` reaches it, the
adapter starts another turn and returns `startedNewTurn`. The client
never receives that new prompt's final response. If the original prompt
is still waiting for plan approval, steering waits too, which can block
clients that process steering and permission replies serially.

This adds the opt-in requested in #440:

```json
{"_meta":{"steering":{"idleBehavior":"promptRequired"}}}
```

Live turns still receive the input through native steering. When no turn
can accept it, the adapter returns `promptRequired` with `reason:
"noRunningTurn"`, leaving the input unconsumed and starting no new turn.
The client can answer any pending approval, wait for the original prompt
to finish, then send the input through a normal `session/prompt`. Calls
without the option behave as before.

This builds on @fontanierh's patch in #441, cherry-picked with the
original author and source reference preserved. I added regression tests
for pending plan approval, malformed metadata tests, and usage
documentation.

Fixes #440.

## Testing

- 33 targeted tests passed. The pending-plan-approval steering tests
timed out before the fix.
- Typecheck, build, and all six standalone binary targets passed.
- Tested idle, live-turn steering, and pending plan approval with real
Codex. Steering returned in 1 ms while approval was pending; rejecting
implementation completed the original prompt with its stop reason,
usage, and quota.
- Full suite on Windows: 1,205 passed, 19 failed, 36 skipped. All 19
failures reproduced on unmodified main at `4583cb3`, in history,
attachment, and path assertions.

The real Codex tests used temporary local runners, adapted for the
removed `authRequired()` call in the repository's test script.
Cancellation dispatch has unit coverage; the real test used the
reject-plan path.

For clients: `promptRequired` is a steering result, not completion of
the original prompt or its approval request. The existing
`_meta.steering.supported` flag also does not distinguish support for
this option, so clients need to check the adapter version.

---------

Co-authored-by: jim <[email protected]>
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.

Steering should support a host-owned idle fallback

1 participant