fix: handle terminal chat send acknowledgements#91049
Merged
openclaw-clownfish[bot] merged 37 commits intoJun 22, 2026
Merged
Conversation
Contributor
Author
|
@clawsweeper re-review |
Contributor
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
openclaw-clownfish
Bot
merged commit Jun 22, 2026
3ff0c29
into
openclaw:main
202 of 212 checks passed
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jun 23, 2026
* test: cover terminal chat send acknowledgements * test: cover Swift terminal chat send acknowledgement * fix: handle terminal chat send acknowledgements * fix: align terminal ack web lifecycle options * test: fix Android terminal ack style * fix: tidy Android terminal ack helpers * fix: clear mic pending run after terminal ack * fix: handle terminal talk mode chat send acks * fix: handle terminal tui chat send acks * fix: handle terminal acp chat send acks * test: add Swift chat message text helper * test: cover steer terminal chat send acknowledgements * fix: handle terminal steer chat send acks * test: cover terminal realtime consult send acks * fix: reject terminal realtime consult send acks * test: cover Swift terminal ok chat send ack * fix: clear Swift pending run on terminal ok ack * test: cover terminal ack helper callers * fix: preserve terminal ack helper semantics * fix: narrow terminal ack type guard * test: cover mic terminal ack statuses * fix: preserve mic terminal ack status * fix: keep mic ack contract internal * test: fix mic ack import order * test: cover acp terminal ok ack * test: narrow acp ok ack assertion * test: cover redirect terminal acknowledgements * fix: handle redirect terminal acknowledgements * fix: settle terminal ack reconnect prompts * fix: surface Android terminal ack timeouts * fix(tui): handle detached terminal chat acknowledgements * fix(tui): report terminal timeout send failures * fix: satisfy iOS talk-mode SwiftFormat * fix: keep iOS talk logs compile-safe
This was referenced Jun 23, 2026
This was referenced Jun 30, 2026
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.
Summary
chat.sendACK status (ok,timeout,error) through clients/helper paths that previously reduced the response to "has a run id"./btw, queued/steer,/redirectviasessions.steer, Android chat/mic/Talk flows, native Talk flows, TUI, ACP, and the Skill Workshop forwarded schema./btw//sideACKs now clear local BTW tracking, and detached accepted-runId replacements rekey local tracking instead of being misclassified later.timeout/errorACKs surface failed-send state instead of looking accepted.Terminal ACKs are part of the
chat.sendcontract. If a client treats one as an accepted active run, a message, mic turn, or queued command can get stuck or disappear without failure copy.Clients branch on ACK status instead of only checking
runId: active statuses keep the existing pending-run flow, while terminal statuses clear pending state, restore retryable queue/draft state where appropriate, or surface failure copy.Redesigning the public SDK
Session.sendAPI shape.Standardizing every cross-client terminal-timeout message/toast policy.
Broader lifecycle cleanup races not introduced by this PR.
Whether each touched consumer preserves
runIdandstatusuntil the final caller branches.Whether terminal
ok/timeout/errorbranches clear or restore pending state without breaking non-terminalstarted/in_flightbehavior.Whether Android chat/mic and Swift chat now surface terminal timeout/error as failed-send state.
Linked context
Closes #91048
Related #84176
Related #84306
No direct maintainer request; this follows the terminal ACK contract through additional consumers and addresses the Android terminal-timeout feedback.
Real behavior proof (required for external PRs)
Behavior or issue addressed:
Terminal
chat.send/ forwarded ACKs withstatus: "ok" | "timeout" | "error"should not be treated as accepted active runs. Live proof exercises terminaltimeout; current9cd2b839bbf4a50882564024fbc3f9c003818e89preserves the Android/Swift/TUI follow-ups and is clean against latestmain.Real environment tested:
Local Linux checkout using repo test runners, Android JVM/Robolectric, and a real local Gateway server + WebSocket RPC harness driving Control UI
sendChatMessageagainst a terminaltimeoutACK. Hosted checks on603380bfc4fbc1604ac16cb6915837191a36ad53covered macOS Swift, Android build/test, lint, production/test types, and the real-behavior proof checker. Current head adds CI-red triage plus the iOS SwiftFormat and compile-safe logger fixes.Exact steps or command run after this patch:
Gateway/Control UI live proof still applies because later heads changed Android/Swift/TUI clients only. Current head
9cd2b839bbf4a50882564024fbc3f9c003818e89is the current conflict-repair head and remains clean against latestmain; it preserves the normal TUI timeout/error failure copy afterloadHistory().Focused suite output from this branch:
Current-head local validation on
9cd2b839bbf4a50882564024fbc3f9c003818e89:Live Gateway + Control UI terminal-ACK proof from head
c18e743ba4ced535ec5351ba536a542db3d7621ffor the unchanged Gateway/Control UI path:Copied proof artifact from that run:
{"terminalStatus":"timeout","gatewayTerminalAck":{"runId":"00000000-0000-4000-8000-000000091049","status":"timeout"},"uiResult":null,"uiStateAfter":{"chatSending":false,"chatRunId":null,"chatStream":null,"lastError":"The run ended before the message was accepted."}}Hosted PR checks on broad-validation head
603380bfc4fbc1604ac16cb6915837191a36ad53:macos-swift,android-build-play,android-test-play,android-test-third-party,check-lint,Real behavior proof, andAuto responsewereSUCCESS(runs: https://github.com/openclaw/openclaw/actions/runs/27089311492, https://github.com/openclaw/openclaw/actions/runs/27089323348, https://github.com/openclaw/openclaw/actions/runs/27089323350).Observed result after fix:
Focused suites cover protocol schema, gateway Talk, TUI, ACP, slash commands, Android chat, and Android mic. Live Gateway proof shows terminal
timeoutover WebSocket to Control UIsendChatMessage; after ACK, pending state is cleared and failure copy is set. TUI tests cover detached/btw//side, accepted-runId rekeying, and normal-send timeout/error failure copy afterloadHistory(). Current-head validation adds latest-base stale-failure replays, clean merge-tree, diff check, focused TUI checks, TUI oxlint, core-test typecheck, and the iOS SwiftFormat/logger fixes.What was not tested:
Full browser/device manual UI testing was not performed. The live proof exercises the Control UI controller source and Gateway WebSocket transport, not a screenshot-driven browser session.
Proof limitations or environment constraints:
The live proof controls the agent reply boundary through the repository Gateway test seam so
chat.abortcan deterministically produce a terminaltimeoutACK. Gateway transport, idempotency caching, terminal ACK payload, and the Control UI controller cleanup path are real source code. The temporary proof harness was not committed to the feature branch. Swift execution was validated by hostedmacos-swift, not by the local Linux checkout.Before evidence (optional but encouraged):
Focused RED tests were used during development for Web helper callers, Android chat timeout/error acceptance, Android mic terminal timeout, ACP terminal
ok, and/redirectterminal ACK handling before the fixes were applied.Tests and validation
Focused JS suite listed in the Real behavior proof section.
Focused Android JVM/Robolectric ACK suites for
ChatSendAckTest,ChatControllerTerminalAckTest, andMicCaptureManagerTest.pnpm tsgo:corepnpm tsgo:test:uipnpm tsgo:test:packagesTouched TypeScript oxlint.
git diff --checkHosted PR checks listed above on head
603380bfc4fbc1604ac16cb6915837191a36ad53.Focused TUI ACK suite on
9cd2b839bbf4a50882564024fbc3f9c003818e89: 66 tests passed, covering normal timeout/error/ok, detached/btw//side, rekeying, and timeout feedback afterloadHistory().Current-head gates: previous TUI conflict checks plus latest-base CI-red direct replays; iOS line 1045 now uses
self.waitForChatCompletion; logger status messages no longer concatenateOSLogMessage.Web direct send, queued send, detached
/btw, queued/steer, and/redirectterminal ACK behavior.Android ACK parsing, chat controller terminal ACK handling, and mic terminal ACK handling.
Swift chat terminal timeout feedback.
Gateway Talk terminal ACK rejection before realtime subscription.
ACP terminal
okparity with terminal timeout/error.TUI terminal ACK send-result handling, including normal-send timeout/error failure copy, detached
/btw//sideterminal ACK cleanup, and detached accepted-runId rekeying.Skill Workshop forwarded ACK schema accepting the widened terminal statuses.
RED coverage showed terminal ACK helper callers, Android chat, and Android mic handling could still collapse, accept, or discard terminal statuses after the initial propagation work.
/redirectalso treated terminal forwarded ACKs as a successful redirect with a tracked run id.Tests were added or updated for the main status-preserving branches. Swift source changes include test updates; hosted
macos-swiftpassed on the final head.Risk checklist
Yes. Clients now clear, restore, or fail pending state when the gateway returns a terminal ACK instead of waiting for future run events.
No.
No.
Session/chat lifecycle state: clearing pending or optimistic state too early could hide a message, while not clearing it leaves clients stuck.
The patch preserves non-terminal
started/in_flightbehavior, keepsrunIdremapping where needed, restores retryable draft/queue state on terminal failure, and adds regression coverage for the changed branches.Current review state
Review the status-preserving ACK branches, Android/Swift timeout follow-up, TUI detached ACK cleanup, normal TUI timeout feedback, and current head
9cd2b839bbf4a50882564024fbc3f9c003818e89.9cd2b83hosted run has executed yet.603380bfc4fbc1604ac16cb6915837191a36ad53; heade5b96a8c970630618d71b665388c1b924fd07863adds local focused TUI validation for the detached ACK follow-up.9cd2b839bbf4a50882564024fbc3f9c003818e89is merge-tree clean against latestmain; latest-base stale-failure replays passed; the iOS SwiftFormat/logger targets are fixed.