Skip to content

[codex] Fix queued turn anchoring#736

Open
LacBang wants to merge 1 commit into
fathah:mainfrom
LacBang:fix/queue-turn-rendering
Open

[codex] Fix queued turn anchoring#736
LacBang wants to merge 1 commit into
fathah:mainfrom
LacBang:fix/queue-turn-rendering

Conversation

@LacBang

@LacBang LacBang commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve where mid-turn follow-ups were submitted by attaching renderer-only queue anchors to the active turn output
  • keep pending queue notes outside the canonical message array so reasoning, tool, and completion events retain the correct turn boundary
  • resolve /queue before rendering a user message, then enqueue only the resulting prompt while the main turn is busy
  • replace the pending note with exactly one normal user message when the queue drains
  • keep failed queued sends recoverable with an explicit retry state instead of silently dropping or immediately looping

Closes #638.

Root cause

Plain busy-turn follow-ups only appeared in the queue indicator above the composer, so their relationship to the tool output visible at submission time was lost when they later rendered as a normal next turn.

The dashboard slash-command path made this worse for /queue: it optimistically appended the literal command and a pending agent bubble before slash.exec / command.dispatch resolved. Those rows became the renderer's latest transcript boundary while the previous turn was still streaming, so later reasoning, tool, and final events appeared after the queued command or updated the wrong bubble.

Implementation

queueAnchoring.ts captures the active turn's last visible message without mutating canonical chat state. MessageList builds a visual-only render plan that inserts pending queue notes, and later the real dequeued user message, at that captured boundary. Backend history and stream reducers continue to see the original canonical order.

The /queue send-directive path now avoids optimistic transcript rows, queues only the resolved prompt while busy, and starts a normal prompt immediately when idle. Other slash commands and /btw retain their existing routing.

Verification

  • npm test — 136 test files passed; 1,458 tests passed and 3 existing tests skipped
  • npm run build
  • npm run lint — no errors (existing repository warnings remain)
  • npx lat.md check
  • Playwright visual render check confirmed the pending note and single dequeued user bubble remain between the tool output visible at submission and the original turn's later output

Reproduction covered

  1. Start a turn that emits multiple reasoning/tool rows.
  2. While it is running, submit either a normal follow-up or /queue <message>.
  3. Continue streaming the original turn.
  4. Confirm the queued note remains at the submission boundary, the original turn stays continuous, and dequeue creates one user message.

Related implementation history: #711.

@LacBang LacBang marked this pull request as ready for review June 21, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Queued mid-turn prompts lose context instead of staying anchored to active tool output

2 participants