App server: add an atomic thread-level interrupt API
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Problem
A host UI Stop control cannot safely use the current strict turn/interrupt({ threadId, turnId }) API when the renderer-held turn id can become stale between the click and request handling. In that race, the host receives an error such as:
expected active turn id <old> but found <new>
Retrying from the renderer is not safe: selecting a newer turn after the original Stop request can cancel work that began after the user pressed Stop.
Requested API
Add a thread-level operation with server-owned selection, for example:
thread/interrupt({ threadId }) -> { turnId: string | null }
Required semantics:
- The app server atomically captures the active turn for the requested thread when it handles the request.
- If the thread is idle, respond immediately with
{ turnId: null }. - If a turn was captured, abort only that captured turn, guarded so a later turn is never aborted.
- Resolve the request only from that captured turn's terminal event.
This lets a UI reliably mean “stop the work that was active when the server processed Stop,” without parsing errors or guessing which turn to target. Existing turn/interrupt can remain for callers intentionally targeting a specific turn.
Relation to existing issue
This is related to #36926, which covers an interrupted turn incorrectly remaining active and leaving a repeated turn/interrupt pending. That issue is a distinct server-state bug. This request is about the API contract needed when a host has only a thread-level Stop action and its client-side turn snapshot is inherently stale-prone.
Implementation evidence
We implemented and tested this contract in a downstream Codex vendor fork: the app server captured the active turn, core abort was guarded to that captured ID, idle threads returned immediately, and integration tests covered active and idle cases. The fork history is divergent from current upstream, so it is not a directly applicable patch; this issue is intended to provide the behavior and rationale for a native upstream implementation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the app server's existing turn/interrupt request handling and the core abort path, then inspect how active turns and terminal events are represented. Implement the server-owned thread-level selection and verify the captured-turn guard, idle response, and terminal-event resolution with integration tests covering active and idle threads.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100