Steered input can look like a standalone latest user request and drop unfinished task context
What variant of Codex are you using?
CLI 0.139.0
What issue are you seeing?
When I send a steer message while Codex is already working, Codex can treat the steer as the new main task and lose track of the unfinished task it was previously executing.
Minimal example:
- User asks Codex to do task B:
``text``
Inspect the repo, make the requested fix, run tests, and report the result.
- Codex starts task B and runs tools.
- Before task B finishes, user sends a steer message A:
``text``
Also make sure the final answer is in Chinese.
- Codex sends the next model request after receiving the steer.
Observed result: Codex may continue with only A in mind, or answer A, but fail to resume the unfinished parts of B.
Expected result: Codex should incorporate A without losing B. If A does not replace B, Codex should continue or resume B after applying A.
Suspected cause
Same-turn steer input is accepted as active-turn pending input and later drained into the next model request as user input. That preserves the raw message, but the model-facing history is too close to:
user: task B
assistant/tool: work in progress
user: steer A
The last message looks like a standalone latest user request. It does not clearly say that A arrived while Codex was already working on B, or that B may still be unfinished.
Suggested direction
When drained steer input is added to the next model request, it should carry explicit mid-turn follow-up semantics instead of looking like a bare standalone user message.
One possible shape:
<user_followup>
The user sent this while Codex was already working:
A
Apply this follow-up without dropping the current unfinished task unless it explicitly replaces that task.
</user_followup>
This should preserve the current cache-friendly behavior of appending new input near the next model-request boundary, without rewriting earlier history.
Areas to investigate in the existing code:
- active-turn steer input acceptance in
Session::steer_input; - pending input ownership and drain behavior in
InputQueue; - the path that records drained
TurnInput::UserInputbefore the next model request; - pending-input / steer tests that can assert the next model request contains wrapped follow-up text exactly once.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
A note on the duplicate warning: #28892 was my earlier, less focused report and has been closed. This issue is the narrower version focused on the active-turn steer path.
I looked through the current code path and the behavior appears to come from this flow:
Session::steer_inputaccepts same-turn steer input and appends it asTurnInput::UserInput.TurnInput::UserInputis recorded through the normal user-prompt path, so the next model request effectively sees:The issue is not that the steered text is lost. It is preserved, but it has no model-visible indication that it arrived while the agent was already working, or that the previous task may still be unfinished.
A narrow fix could be:
This would avoid rewriting earlier history and should keep the existing cache-friendly append-at-boundary behavior.
Would the maintainers be open to an invited PR scoped to this regression test and model-visible follow-up marker?