Handle Codex steer requests during turn finalization - #331
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e2ecb4a37c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!nativeSteerAvailableRef.current) { | ||
| await handleEnqueue(); | ||
| return; |
There was a problem hiding this comment.
Preserve steering for Codex turns observed through polling
When this view is opened during an already-running Codex turn, or when the server starts a queued turn headlessly, the component receives activity through the runtime/event pollers rather than its own SSE, so nativeSteerAvailableRef never becomes true. Cmd/Ctrl+Enter therefore calls handleEnqueue() here and silently converts the requested steer into a later follow-up; with an empty composer and a queued item, it does nothing at all. The server already determines whether turn/steer raced finalization, so the client should still send the steer request for these active polled turns.
Useful? React with 👍 / 👎.
| if (outcome === "steered") { | ||
| if (options.queuedMessageId) { | ||
| await options.removeQueuedMessage(options.queuedMessageId); |
There was a problem hiding this comment.
Serialize promoted-message removal with queue advancement
When turn/steer succeeds just as the current turn completes, finalization can dequeue the promoted item before this separate removal acquires the queue lock. The promoted text is then both accepted as a steer and started as the next queued turn, while removeQueuedMessage silently reports no removal and this function still returns steered. The ownership transfer needs to be atomic with dequeue/advancement, or at least verify that the item was actually removed before claiming it was steered.
Useful? React with 👍 / 👎.
Summary
Root cause
Codex clears its active turn when
run.completedorrun.failedarrives, while the client remains in streaming mode until the later SSEdoneevent. A steer submitted during that interval was rejected after the client had already cleared the composer and rendered an unpersisted user message.Validation
git diff --check: passedCloses #330