Repository navigation
native chat: /clear sent while the agent works waits in line (rebuild of #26730) - #27928
Closed
brennanb2025 wants to merge 4 commits into
Closed
brennanb2025 wants to merge 4 commits into
brennanb2025 wants to merge 4 commits into
Conversation
…t when refused A context clear run from a /clear card withdraws that card in the same transaction (rolling back if the card is gone) and leaves the cards queued after it alone. An immediate clear that finds an unsettled /clear card is that card's clear and cuts the queue at it the same way. A clear run from its card (the drain or its Send) writes a Resume row before the clear's pause, so a Stop or reopen pause lifts as it does for a turn, while the cards ahead of it stay held as the old context's; a typed /clear lifts no pause, as on main. A card the host runs itself can be returned with its refusal without a hand-off.
The /clear RPC stays one ledger plan: its run asks the queue's accept rule first, as /compact does, and answers with the card; otherwise it clears at once. When the drain reaches a /clear card, or the person presses its Send, the host runs the same clear on the session's lane instead of handing it to the agent, and commits the clear's record receipt alone; a Send records its own receipt after it. Refused at its turn, the card is returned with the refusal and the cards behind it hold until Send or Delete.
…n line Both clients now ask the host to hold a /clear sent while the agent works as a card, under the same gate as /compact. Card rendering is unchanged: a /clear card is a command card like a queued /compact.
…says it is being sent Desktop now lets /clear wait in line like /compact, which moved a /clear pressed while this window's own message is still on its way onto /compact's quiet hold (nothing said, text kept). /clear keeps main's words there: "Your earlier message is still being sent. Run /clear once it has gone." The mid-turn gating test now expects /clear to ask the host to wait.
Contributor
Author
|
Review loop status (head Problem. In native chat, User-facing change. Fixed during review:
Deferred:
Verified:
Not verified:
|
This was referenced Oct 12, 2026
Contributor
Author
|
Closing: we're keeping main's refusal for /clear while the agent works. #28101 records the reason in the code. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
In native chat, typing
/clearwhile the agent is still working is refused today: "The agent is still working. Run /clear when it's done." Nothing is kept, so you have to remember to come back and type it again.With this change,
/clearwaits in line like any other message you send. It shows up as a "/clear" card in the queue above the composer. When its turn comes, Orca clears the chat's context itself, in the same chat and tab, and anything you queued after the/clearthen runs in the fresh context, in the order you sent it.This supersedes #26730, which built the same feature with a much larger "wait for background tasks" machine. This rebuild is about a fifth of its production size (see "Why this is smaller" below). #26730 stays open until we decide to close it.
What Changed
What you see (desktop and phone)
/clearwhile a reply is running/compact: Delete, no Edit, never steers into the running reply, no Send while the agent works/clear: "Background tasks are still running. Wait for the background tasks to finish." Cards behind it wait ("a message ahead needs attention", existing caption). You stop the tasks from the task strip and press Send on the card, which clears; or press Delete, and the cards behind it run without the clear/clearruns and clears that exchange too/clearwhile idleNo new strings, notices, captions or controls. Every word shown is one main already uses.
How it works (all on the execution host, so local, SSH and WSL behave the same)
/clearrequest now asks the queue first, through the same accept rule a queued/compactuses. If the agent is working, the request becomes a command card ({ text: '/clear', command: { name: 'clear' } }, the existing card shape) and answers "queued". Otherwise the immediate clear runs exactly as on main./clearcard, it never hands the card to the agent. It runs main's existing clear on the session's lane: check that a clear is allowed, stop the agent, check again, then commit. Send on a held/clearcard runs the same code. That code moved out ofstructured-conversation-command.tsintostructured-conversation-clear.tsso the request, the drain and Send share it./clearcard, and rolls back entirely if the card is gone, so a card never runs twice and never disappears without its clear. Only cards queued before the/clearcard are treated as old context (main's existing pause and withdrawal); cards after it are left alone, so they drain into the fresh context. A clear run from its card also lifts the queue's pause the way a sent turn would, so the cards behind it continue; a typed/clearstill never lifts your Stop, as on main.command === 'compact'condition, so/clearasks to wait in line under exactly the same gate as/compact. Card rendering is unchanged: a/clearcard is an ordinary command card.Wire compatibility. No new capability, method or published field. Clients send
delivery: 'queue-if-active'with/clearonly when the host advertises bothagent-session.queued-commands.v1andagent-session.queued-messages.v1, the same gate/compactuses.queued-messages.v1is still dark (no shipped host advertises it), so an older host never receivesdeliveryon/clear, and an older client never sends it. Ordering rule: this PR must land beforequeued-messages.v1is turned on. A host advertising it without this change would refuse a newer client's/clear. The rule is written beside thequeued-messages.v1note inprotocol-version.ts.Why
Queueing
/clearis an Orca product choice. The common pattern refuses a context clear while the agent is busy, or has no in-place clear at all.Which parts follow the common pattern:
/clearcard itself when its turn comes. It's the smallest way to give the queue a context change, and it reuses main's clear unchanged.Return, not wait. At the card's turn, the common pattern doesn't make the queue wait for background work. When the clear is refused, this rebuild returns the card rather than holding it in a new waiting state.
Why this is smaller than Native chat: /clear waits in line while the agent works #26730. Native chat: /clear waits in line while the agent works #26730 was +1,087/−339 production lines across 53 files. This is +377/−110 raw across 19 files, about 210 net code lines, four of them comment-only. These are gone:
agent-session.queued-clear.v1;What's left is what has to exist: accept as a card, run on the drain or on Send, scope the clear to the cards before it, and return on refusal.
Differences, labelled:
/clearrequest (immediate or queued) still records its acceptance in the operation ledger./compacthas moved to the newer command receipts (native chat: queued-message actions and question answers accept through their own receipt #26988). Moving/cleartoday would put two record-store receipts in one write, which loses the first. Follow-up: move it when the ledger co-write marked TEMPORARY instructured-agent-session-command-receipt.tsis retired./clearcard waits reaches the agent first and is then cleared. Follow-up: images join the queue./clearat its turn uses the same refusal rule as an immediate/clear. That keeps one rule for both paths. Whether/clearmay run beside background tasks is a separate decision for both paths./clear. It's the same rule as every held card. In live QA, the existing "Send message?" dialog didn't tell the testers that the held item is a/clearthat will clear their new exchange. A possible follow-up is to name the held/clearin that dialog.Linked Issue
N/A, maintainer follow-up. Supersedes #26730 (which superseded #25842).
Visual Proof
Before (main):
/clearwhile the agent works is refused with "The agent is still working. Run /clear when it's done." under the composer, and nothing is kept (unchanged on main; no new UI here, so no before-shot was taken).After, real Claude and real Codex on a hidden rig. The queued-messages feature was turned on with a local, uncommitted edit, since it's still off by default.
/clearsent mid-turn waits as a card (Claude)/clearclears it tooTesting
structured-agent-session-queued-clear.test.ts(20 cases). It covers:/clearwith a held clear card (spends only that card and keeps your Stop);/clearwith and without background tasks (unchanged from main).structured-agent-session-queued-compact.test.ts(a/clearasking to wait is now a card), the desktopstructured-conversation-command-send.test.ts, and the phonemobile-structured-composer-command.test.ts.check:code-quality:changed, andorca-ci-checks.orca-ci-checks: 22 of 24 checks pass. The two failures don't come from this branch: the local buntypecheck:cistep fails with "Script not found" (the regularpnpm run typecheckpasses), and the mobileno-cyclewarnings are in files this branch doesn't touch.8fab421118a, with both real Claude and real Codex:/clearbecomes a card; at its turn, one divider in the same tab, follow-ups in order, no memory/clearis immediate; idle/clearwith a background task is refused (as on main)/clearclears it (intended; see below)Final head
be9b737f368differs from the tested head only in round 2 and 3 fixes. None of them are on these rows' paths, and unit tests cover them.Real
~/.codexand~/.claudeconfig hashes were unchanged throughout.QA findings, all P3:
CI on
be9b737f368: green.I manually tested these changes locally
Automated tests added/updated, or explained why not below
Review
/clearcard lost the fresh context, because two record writes were composed into one;/clear, or Send on a held card, could strand the cards behind it.be9b737f368): a/clearpressed while this window's own earlier message is still being sent had become silent. It now says "Your earlier message is still being sent. Run /clear once it has gone." again, as on main.queued-messages.v1)./clearaccept is refused instead of queued (not reproduced);/clearjust spent answers "withdrawn".Agent skill upstream boundary
Notes
deliveryand render cards.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)