Repository navigation
fix(codex): queue a differing model/effort pick as a fresh turn instead of steering #889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,6 +67,11 @@ type Active = { | |
| steering: Promise<void>; | ||
| reply: Request; | ||
| finished: boolean; | ||
| /** What the turn runs on, once resolved; a differing pick queues a turn. */ | ||
| model?: string; | ||
| effort?: string; | ||
| /** A later turn is queued behind this one, so steering would reorder. */ | ||
| queued?: true; | ||
| workspace: string; | ||
| signal: AbortSignal; | ||
| version: number; | ||
|
|
@@ -423,7 +428,16 @@ export class CodexRuntime { | |
| request.failActivity("Codex was stopped"); | ||
| return; | ||
| } | ||
| if (active.finished) { | ||
| // Steering cannot carry a model or effort, so a differing pick | ||
| // waits for this turn and runs as the next one. Everything after | ||
| // it queues too: steering now would run later messages first. | ||
| if ( | ||
| active.finished || | ||
| active.queued || | ||
| (request.model && request.model !== active.model) || | ||
| (request.effort && request.effort !== active.effort) | ||
| ) { | ||
| active.queued = true; | ||
| this.start(request, text, key, lane, entry); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [P2] Keep later follow-ups behind a queued model/effort pick While turn 1 is active, send A with a differing model/effort, then B with no pick (or a pick matching turn 1). A takes this early return and queues behind Once a differing pick is queued, route subsequent follow-ups behind that queue boundary rather than continuing to steer the old turn. Add a regression test for differing-pick → plain-follow-up ordering. |
||
| return; | ||
| } | ||
|
|
@@ -776,6 +790,8 @@ export class CodexRuntime { | |
| [request.effort, settings.effort].find( | ||
| (level) => level && supported.includes(level), | ||
| ) ?? selected.defaultReasoningEffort; | ||
| active.model = model; | ||
| active.effort = effort; | ||
| const mcp = Object.fromEntries( | ||
| Object.entries(normalized.config.mcp_servers ?? {}).map( | ||
| ([name, server]) => [ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P2] Keep the queue barrier until the lane backlog drains
queuedbelongs to the currentActive, butexecute()creates the next one without it (lines 685–701). After a differing-model request A and then a plain request B queue behind the original turn, A starts withqueuedunset even though B is still onlane.tail. A later plain/matching request C therefore takesturn/steerinto A and runs before B. This leaves the ordering issue unresolved across turn transitions; a follow-up depending on B can execute before B has run. Track pending work at the lane level, or otherwise carry the barrier across active-turn replacement until no earlier jobs remain. Extend the new regression to deliver C while A is active and B is still queued.