Skip to content

fix(tui): queue prompts while the agent is busy#100123

Merged
steipete merged 1 commit into
mainfrom
codex/pr-89078-tui-queue-lifecycle
Jul 5, 2026
Merged

fix(tui): queue prompts while the agent is busy#100123
steipete merged 1 commit into
mainfrom
codex/pr-89078-tui-queue-lifecycle

Conversation

@steipete

@steipete steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Closes #89059
Closes #90012
Supersedes #89078. The reviewed contributor work is preserved with Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>.

What Problem This Solves

Fixes an issue where TUI users who submitted another prompt while an agent was busy were blocked with an “agent is busy” notice even when their configured queue mode should accept the prompt. Queued prompts could also lose cancellation, restart, or transcript ownership across the TUI and Gateway lifecycle.

Why This Change Was Made

Busy TUI sessions now forward prompts into the configured queue while admission is available. The Gateway tracks queued turns as first-class owners through abort, restart, collection, overflow summarization, and completion; session-wide stop preserves BTW side runs, with a compatibility retry for older Gateways.

User Impact

Users can keep typing in the TUI while a run is active and receive the configured followup or collect behavior. Esc and /stop cancel the intended queued or active turn without dropping unrelated work, and queued rows are removed when their run terminalizes.

Evidence

@steipete
steipete requested a review from a team as a code owner July 5, 2026 00:25
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts size: XL maintainer Maintainer-authored PR labels Jul 5, 2026
@steipete
steipete force-pushed the codex/pr-89078-tui-queue-lifecycle branch from 573fb89 to aa3de22 Compare July 5, 2026 00:26
@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: stale review; fresh review needed.

Summary
The latest durable ClawSweeper review was for head 0a9f304257e5bf8ba8a3b1728414ea88b562c8eb, but the PR head is now 7b8f573a38ccd5b8baf0854d3ac3884e8672be64. Its old verdict and PR readiness labels are no longer current.

Next step
Run or wait for a fresh ClawSweeper review on the current PR head.

Review history (3 earlier review cycles)
  • reviewed 2026-07-05T00:40:33.552Z sha aa3de22 :: needs real behavior proof before merge. :: [P2] Initialize queued-turn state in chat handler contexts
  • reviewed 2026-07-05T00:47:18.173Z sha 0a9f304 :: needs real behavior proof before merge. :: [P2] Check queued turns before cached chat.send results
  • reviewed 2026-07-05T00:53:06.465Z sha 0a9f304 :: needs real behavior proof before merge. :: [P2] Check queued turns before cached chat.send results | [P2] Preserve queued BTW turns during session stops

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 573fb891d9

ℹ️ 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".

Comment on lines +3893 to +3894
if (context.chatQueuedTurns?.has(clientRunId)) {
respond(true, { runId: clientRunId, status: "in_flight" as const }, undefined, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check queued turns before cached chat.send results

When a chat.send ACK is lost and retried after followup/collect queue admission, this new chatQueuedTurns branch is bypassed because the earlier chat:<runId> dedupe cache already returns the queued send as terminal ok while the queued turn is still pending. TUI treats ok as a terminal ACK, clears the optimistic pending state and reloads history, so the user's queued prompt can disappear even though it has not run yet; check the queued-turn map before returning the cached chat result, or avoid caching ok until the queued content is complete.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 5, 2026
@steipete
steipete force-pushed the codex/pr-89078-tui-queue-lifecycle branch from aa3de22 to 0a9f304 Compare July 5, 2026 00:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a9f304257

ℹ️ 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".

Comment on lines +4711 to +4715
queuedFollowupEnqueued = registerQueuedChatTurn({
chatQueuedTurns: ensureChatQueuedTurns(context),
runId: clientRunId,
controller: activeRunAbort.controller,
sessionId: backingSessionId ?? clientRunId,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve queued BTW turns during session stops

When a /btw prompt is admitted to the followup/collect queue, this queued-turn registration drops the turnKind that was computed for the chat.send. TUI session-scoped stops call chat.abort with preserveSideRuns: true, and the active/pre-registered abort paths skip BTW runs by checking turnKind, but queued turns have no such field so abortAuthorizedQueuedTurnsForSession still aborts them. This means pressing Esc or /stop to stop the main session can cancel an unrelated queued BTW question; carry turnKind into QueuedChatTurnEntry and apply the same preserve-side-runs filter there.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 5, 2026
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Land-ready proof for 7b8f573a38ccd5b8baf0854d3ac3884e8672be64:

Known proof gaps: none.

Allow busy TUI sessions to forward prompts into the configured queue while
keeping queued-turn admission, cancellation, restart, and transcript ownership
consistent across the TUI, Gateway, and followup queue.

Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
@steipete
steipete force-pushed the codex/pr-89078-tui-queue-lifecycle branch from 0a9f304 to 7b8f573 Compare July 5, 2026 01:04
@clawsweeper clawsweeper Bot removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b8f573a38

ℹ️ 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".

const abortsPendingRun = Boolean(
state.pendingChatRunId && runIds.includes(state.pendingChatRunId),
);
const abortsPendingRun = Boolean(state.pendingChatRunId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear pre-ACK pending submits after session abort

When Esc or /stop is pressed after addPendingUser() but before sendChat() has returned, pendingOptimisticUserMessage and pendingSubmitDraft are set while pendingChatRunId is still null. A session-scoped abort can still cancel that pre-registered queued send and return its run id, but this flag stays false, so the row may be dropped while the TUI remains in a pending/busy state until the original chat.send ACK arrives; if that ACK was the transport failure being recovered from, the user is stuck blocked after a successful abort. Treat the current pendingSubmitDraft/returned run ids as a pending abort target, not only pendingChatRunId.

Useful? React with 👍 / 👎.

@steipete
steipete merged commit 1b8d837 into main Jul 5, 2026
112 checks passed
@steipete
steipete deleted the codex/pr-89078-tui-queue-lifecycle branch July 5, 2026 01:15
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 5, 2026
Allow busy TUI sessions to forward prompts into the configured queue while
keeping queued-turn admission, cancellation, restart, and transcript ownership
consistent across the TUI, Gateway, and followup queue.

Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TUI sendMessage busy guard ignores queue mode setting TUI sendMessage blocks messages with 'agent is busy' regardless of /queue mode setting

1 participant