Summary
In @agentclientprotocol/codex-acp 1.11.0, a model-side call to functions.request_user_input_async returns {"accepted":true} and then nothing further ever happens. No asynchronous user message is delivered to the session, and no corresponding ACP traffic reaches the client.
The tool's own declaration states:
The tool returns immediately without ending the turn or waiting for a reply; any reply arrives asynchronously as a new user message.
The first half holds. The second does not.
Reproduction
- Start a fresh session through codex-acp 1.11.0 on a model that exposes the tool (see the model-gating note below — this matters, and cost us two invalid attempts).
- Have the model call
request_user_input_async.
- Keep the originating turn open — do not let it end.
- Wait and poll for the asynchronous reply.
Expected: the client receives an elicitation-shaped request it can render, and a subsequent user answer is routed back into the session as a new user message.
Actual:
- The native call returns
{"accepted":true}.
- The turn was held open ~4 minutes, with the client's inbox polled every 25–30s.
- No asynchronous user message arrived.
- No conversation or request identity was exposed by the tool response, so there is nothing for a client to correlate an answer against.
- The client's logs contain zero occurrences of
request_user_input_async and no elicitation entries at all — i.e. nothing appears to be emitted over ACP, rather than something being emitted and mishandled downstream.
Why we are confident the client side is not at fault
Before testing live, we drove our client's decoder directly against the actual compiled handler from this adapter version, offline. That path produces exactly one decoded question payload per notification, with thread/turn/item identity preserved, and there is exactly one decoder call site. So the shape is handled correctly when the event is present. Live, the event never arrives.
Two earlier attempts that proved nothing, recorded so others do not repeat them:
- A resumed session — its tool surface was fixed before the capability existed, so the tool's absence was meaningless.
- A short-lived worker session — it had the tool and accepted the call, but the turn ended and the conversation was disposed before any answer could route back. Any async mechanism would fail this test by construction.
Only the third setup — fresh session, turn deliberately held open — is a valid test, and it still produced nothing.
Secondary observation: the capability is model-gated, not adapter-gated
With identical adapter, host and session freshness, changing only the model:
gpt-6-astra — functions.request_user_input_async is present
gpt-5.6-sol — absent; only functions.request_user_input is offered, whose declaration reads "This tool is only available in Plan mode." while the session was in Default mode
This may be intended, but it is not documented anywhere we could find, and it means a client cannot assume the capability from the adapter version alone. If it is intended, saying so in the tool docs would save others the same investigation.
Possibly related
#344 — request_user_input is aborted immediately when autoResolutionMs is omitted — is a different tool and a much older version line, but the failure shape is notably similar: the call is accepted and then silently resolves to nothing, via a timing path that wins a race before the client can participate. If the async variant shares that ancestry, the cause may be in the same area.
Environment
@agentclientprotocol/codex-acp 1.11.0
- Client: a third-party ACP host implementing the elicitation surface
- We have since pinned back to 1.10.0, where the capability is absent but nothing misbehaves.
Not tested: 1.11.1-preview.1 / 1.11.1-preview.2, which are published but which we have not evaluated. If this is already addressed there, please say so and we will retest.
Summary
In
@agentclientprotocol/codex-acp1.11.0, a model-side call tofunctions.request_user_input_asyncreturns{"accepted":true}and then nothing further ever happens. No asynchronous user message is delivered to the session, and no corresponding ACP traffic reaches the client.The tool's own declaration states:
The first half holds. The second does not.
Reproduction
request_user_input_async.Expected: the client receives an elicitation-shaped request it can render, and a subsequent user answer is routed back into the session as a new user message.
Actual:
{"accepted":true}.request_user_input_asyncand no elicitation entries at all — i.e. nothing appears to be emitted over ACP, rather than something being emitted and mishandled downstream.Why we are confident the client side is not at fault
Before testing live, we drove our client's decoder directly against the actual compiled handler from this adapter version, offline. That path produces exactly one decoded question payload per notification, with thread/turn/item identity preserved, and there is exactly one decoder call site. So the shape is handled correctly when the event is present. Live, the event never arrives.
Two earlier attempts that proved nothing, recorded so others do not repeat them:
Only the third setup — fresh session, turn deliberately held open — is a valid test, and it still produced nothing.
Secondary observation: the capability is model-gated, not adapter-gated
With identical adapter, host and session freshness, changing only the model:
gpt-6-astra—functions.request_user_input_asyncis presentgpt-5.6-sol— absent; onlyfunctions.request_user_inputis offered, whose declaration reads "This tool is only available in Plan mode." while the session was in Default modeThis may be intended, but it is not documented anywhere we could find, and it means a client cannot assume the capability from the adapter version alone. If it is intended, saying so in the tool docs would save others the same investigation.
Possibly related
#344 —
request_user_input is aborted immediately when autoResolutionMs is omitted— is a different tool and a much older version line, but the failure shape is notably similar: the call is accepted and then silently resolves to nothing, via a timing path that wins a race before the client can participate. If the async variant shares that ancestry, the cause may be in the same area.Environment
@agentclientprotocol/codex-acp1.11.0Not tested:
1.11.1-preview.1/1.11.1-preview.2, which are published but which we have not evaluated. If this is already addressed there, please say so and we will retest.