Repository navigation
Preserve chat inputs through uncertain delivery and Stop - #32267
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough
Merge Risk:
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments: 1
src/main/native-chat/agent-session-journal/journal-queued-messages.ts: 1
74-74: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
revision()now does O(items + submissions) work on every call.
list()callsrevision()first, so everyget,listand publication read pays this cost.workViewKey()callsworking(). That call runsjournal.runningTurn(), which scans all journal items. It also iterates all submissions twice and builds a new current-work object throughrecoveryWork().Previously
revision()was O(1). During streaming, each publish and eachgetin a loop, such as inwithdraw, repeats this scan.Memoize the work-view part. Key it on
lastSequence,queue.revision, and a cheap signal that heldSends changed. Alternatively, computeworkViewKey()only on a cache-miss path.
ℹ️ Review info
⚙️ Run configuration
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
db4ae28d-7fd6-4fa1-9a0a-40c62c697bc0
📒 Files selected for processing: 69
mobile/src/session/use-mobile-structured-native-chat-send-bridge.test.tsmobile/src/session/use-mobile-structured-native-chat-send-bridge.tsmobile/src/session/use-mobile-structured-queued-edit.tsmobile/src/session/use-mobile-structured-sends.test.tsxmobile/src/session/use-mobile-structured-sends.tssrc/main/codex/codex-dispatch-receipt-correlation.tssrc/main/codex/codex-history-import-plan.tssrc/main/codex/codex-history-journal-view.tssrc/main/codex/codex-structured-dispatch-echo.tssrc/main/codex/codex-structured-journal-contracts.tssrc/main/codex/codex-structured-journal-items.tssrc/main/codex/codex-structured-session-acquire.tssrc/main/codex/codex-structured-session-adapter.tssrc/main/codex/codex-structured-session-journal.tssrc/main/codex/codex-structured-session-start.tssrc/main/codex/codex-structured-session-state.tssrc/main/codex/codex-structured-sign-in.test.tssrc/main/codex/codex-structured-thread-catch-up.tssrc/main/codex/codex-structured-thread-history-pages.tssrc/main/codex/codex-structured-turn-cancellation.tssrc/main/codex/codex-structured-turn-end-settlement.test.tssrc/main/codex/codex-structured-turn-end-settlement.tssrc/main/codex/codex-structured-turn-start.tssrc/main/native-chat/agent-session-journal/journal-lifecycle-batch-appender.tssrc/main/native-chat/agent-session-journal/journal-queue-events.tssrc/main/native-chat/agent-session-journal/journal-queue-fold.tssrc/main/native-chat/agent-session-journal/journal-queue-retention.tssrc/main/native-chat/agent-session-journal/journal-queued-messages.tssrc/main/native-chat/agent-session-journal/journal-reducer.tssrc/main/native-chat/agent-session-journal/journal-store-contracts.tssrc/main/native-chat/agent-session-journal/journal-unconfirmed-recovery.test.tssrc/main/native-chat/agent-session-journal/journal-unconfirmed-recovery.tssrc/main/native-chat/agent-session-journal/journal-unsent-send-hold.spec.tssrc/main/native-chat/agent-session-journal/journal-unsent-send-hold.tssrc/main/native-chat/agent-session-journal/queued-message-pause.tssrc/main/native-chat/agent-session-journal/queued-message-table.tssrc/main/native-chat/agent-session-wire/structured-agent-session-client-delivery.tssrc/main/native-chat/agent-session-wire/structured-agent-session-current-work.tssrc/main/native-chat/agent-session-wire/structured-agent-session-dead-generation-settlement.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host-current-work.tssrc/main/native-chat/agent-session-wire/structured-agent-session-leftover-settlement.tssrc/main/native-chat/agent-session-wire/structured-agent-session-opening-send.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-edit.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-publication.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-wiring.tssrc/main/native-chat/agent-session-wire/structured-agent-session-start-failure-row.tssrc/main/native-chat/agent-session-wire/structured-agent-session-status-journal-projection.tssrc/main/native-chat/agent-session-wire/structured-agent-session-taken-stop-settle.tssrc/main/native-chat/agent-session-wire/structured-agent-session-turns-cancel.tssrc/main/native-chat/agent-session-wire/structured-agent-session-unopened-send-withdrawal.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-unopened-send-withdrawal.tssrc/main/runtime/structured-agent-session-codex-turn-end-settlement.test.tssrc/main/runtime/structured-agent-session-dispatch-followups.tssrc/renderer/src/components/native-chat/NativeChatComposer.tsxsrc/renderer/src/components/native-chat/NativeChatMessageRow.tsxsrc/renderer/src/components/native-chat/NativeChatResolvedView.tsxsrc/renderer/src/components/native-chat/NativeChatUserMessageRow.tsxsrc/renderer/src/components/native-chat/native-chat-composer-types.tssrc/renderer/src/components/native-chat/use-native-chat-composer-handle.tssrc/renderer/src/components/native-chat/use-native-chat-pending-delivery.test.tsxsrc/renderer/src/components/native-chat/use-native-chat-pending-delivery.tssrc/renderer/src/components/native-chat/use-native-chat-pty-composer-send.tssrc/renderer/src/components/settings/ChatBehaviorSetting.test.tsxsrc/renderer/src/components/settings/chat-behavior-search.tssrc/renderer/src/i18n/locales/en.jsonsrc/shared/agent-session-failure-copy.tssrc/shared/agent-session-failure-words.tssrc/shared/agent-session-failure.tssrc/shared/structured-agent-session-dispatch-rejection.ts
💤 Files with no reviewable changes: 1
- src/main/native-chat/agent-session-wire/structured-agent-session-unopened-send-withdrawal.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
a77e6930-6c8f-4dec-a8f6-8350549de96a
📒 Files selected for processing: 51
mobile/src/session/mobile-native-chat-draft-store.tsmobile/src/session/mobile-native-chat-payload-ownership.test.tsmobile/src/session/use-mobile-native-chat-file-attachments.tsmobile/src/session/use-mobile-native-chat-image-attachments.test.tsmobile/src/session/use-mobile-native-chat-image-attachments.tsmobile/src/session/use-mobile-native-chat-session-lane.tsmobile/src/session/use-mobile-structured-queued-edit.test.tsxmobile/src/session/use-mobile-structured-queued-edit.tssrc/main/codex/codex-dispatch-receipt-correlation.tssrc/main/codex/codex-history-journal-view.tssrc/main/codex/codex-structured-dispatch-echo.test.tssrc/main/codex/codex-structured-dispatch-echo.tssrc/main/codex/codex-structured-thread-catch-up-echo.spec.tssrc/main/codex/codex-structured-thread-catch-up.test.tssrc/main/codex/codex-structured-thread-catch-up.tssrc/main/codex/codex-structured-thread-history-pages.tssrc/main/codex/codex-structured-turn-start.tssrc/main/native-chat/agent-session-journal/journal-context-rewind.tssrc/main/native-chat/agent-session-journal/journal-epoch-controller.tssrc/main/native-chat/agent-session-journal/journal-epoch-replacement.tssrc/main/native-chat/agent-session-journal/journal-epoch-rollover.tssrc/main/native-chat/agent-session-journal/journal-input-obligations.tssrc/main/native-chat/agent-session-journal/journal-queue-fold.tssrc/main/native-chat/agent-session-journal/journal-queue-retention.tssrc/main/native-chat/agent-session-journal/journal-queued-messages.tssrc/main/native-chat/agent-session-journal/journal-reducer.tssrc/main/native-chat/agent-session-journal/journal-rewind-submission-retirement.tssrc/main/native-chat/agent-session-journal/journal-store.spec.tssrc/main/native-chat/agent-session-journal/journal-store.tssrc/main/native-chat/agent-session-journal/journal-submission-fold.tssrc/main/native-chat/agent-session-journal/journal-unconfirmed-recovery.test.tssrc/main/native-chat/agent-session-journal/journal-unconfirmed-recovery.tssrc/main/native-chat/agent-session-wire/structured-agent-session-attach-orchestration.tssrc/main/native-chat/agent-session-wire/structured-agent-session-attach-publish.tssrc/main/native-chat/agent-session-wire/structured-agent-session-client-delivery.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host-current-work.tssrc/main/native-chat/agent-session-wire/structured-agent-session-provider-open.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-publication.tssrc/main/native-chat/agent-session-wire/structured-agent-session-restart-resume-progress.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-send-settlement.tssrc/main/native-chat/agent-session-wire/structured-agent-session-stopped-history-selection.tssrc/main/runtime/rpc/methods/structured-agent-session-wire-contracts.test.tssrc/renderer/src/components/native-chat/native-chat-composer-types.tssrc/renderer/src/components/native-chat/native-chat-observed-send.tssrc/renderer/src/components/native-chat/native-chat-pending.tssrc/renderer/src/components/native-chat/native-chat-pty-send-queue.tssrc/renderer/src/components/native-chat/native-chat-recovery-ownership.test.tsxsrc/renderer/src/components/native-chat/native-chat-runtime-image-send.tssrc/renderer/src/components/native-chat/native-chat-runtime-send.tssrc/renderer/src/components/native-chat/use-native-chat-pending-delivery.tssrc/renderer/src/components/native-chat/use-native-chat-pty-composer-send.ts
💤 Files with no reviewable changes: 2
- src/main/native-chat/agent-session-journal/journal-context-rewind.ts
- src/main/native-chat/agent-session-journal/journal-rewind-submission-retirement.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
Keep original Stop and Resume coordinates while retaining matching warm failure evidence in the journal owner. Keep historical fixture authoring separate from current production writes.
…9-codex-prompts Main 974bb4a (#32267, uncertain delivery and Stop). History reads now carry both sides' reader facts: the settled-body capability chooses each row's form and budget, and an older queued-image reader keeps its snapshot and queue sources. The host's history takes main's reader before the PR's settled-body flag; the PR's history method module passes both, and the subscribe input keeps both sides' fields. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The problem
When Orca sends a chat message and doesn't hear back in time (a slow agent, a dropped connection, a Stop at the wrong moment), it can't know whether the agent got the message. Before this change, the desktop gave up after 30 seconds, removed the message bubble and put the text back in the composer with a red notice. The agent often had received it, so pressing Send again sent it twice. Queued follow-ups had the same weakness: after a Stop or a restart, a held or edited follow-up could lose its place, its edit, or the record of whether it had already gone out. And when a Codex chat was continued outside Orca, a reconnect could drop the whole newly fetched history if one turn had changed between two reads.
What changes for users
How it works
Each chat's saved journal is the single source of truth for what was sent, queued, held, refused or confirmed. Accepted queued follow-ups are recorded in one transaction before dispatch. Ordinary sends that have not been admitted remain in memory, and later proof (a reply, a receipt, a journal row) is matched to the original message. Historical receipt replay requires exact client IDs. Live Codex replies without a client message ID use a constrained match on text, image count and pending-send order. Anything Orca shows about recovery (which original a reply belongs to, which queued card replaced which) is worked out from that saved record when needed rather than saved separately. This is the common pattern for agent chat apps.
The saved format is main's current chat format. This PR adds one optional saved value: the point a rewind moved the conversation to, saved only after a rewind (or an imported history) that actually moves it. Chats written by the previous storage that are changed for the first time get the existing "written by a newer build" marker. Background maintenance of the journal uses main's compactor unchanged. Deleted and already-sent follow-ups stay in the chat's record (so a late reply still matches its original), and the checked send, Stop, publish and reconnect paths avoid rebuilding that retained history. The 19-phase operation-count tests cover 10 versus 100 withdrawn and dispatched cards; tree navigation can grow logarithmically, and cold opening still reads saved history. Existing current-chat status rendering remains a separate cost already on main.
Intended differences
Temporary follow-ups
Verified in the running app
Mac, real Claude and Codex through the team's load balancers, test copies with throwaway homes. The targeted rewind, edited-queue, restart and Resume run below passed on
9953fa9f6067d6a681e8803e92f0e59a6bbf94b6. The existing table records earlier app runs carried forward for their unchanged flows; those runs were not repeated on this head.In the targeted run, both agents completed real replies before an idle, empty-queue rewind. Rewind retained the earlier reply, removed the selected later turn and returned its exact text to the composer; after clearing that draft normally, a distinct new message received a real reply. While each agent was working, two follow-ups were queued, the first was edited through Edit/Save, and Stop read "Interrupted". One graceful restart of the same test profile preserved the original waiting card IDs, edited text, saved options and order, without submitting anything. Reopened queues read "Queued · 2" with no header Resume. In each chat, one fresh real turn followed by Stop exposed "Paused · 2"; clicking its header Resume once sent the edited first card and then the second, each once, with real successful replies and an empty queue. The earlier reply remained, the rewound turn stayed absent, and no earlier or deleted card was replayed. Claude's first card had no explicit saved effort; its second saved Medium. Codex saved High for both.
This run did not exercise ordinary provider-failure chronology or a rewind with cards still queued; those remain contract evidence. Codex needed a correction to the disposable test profile's unreachable provider endpoint and two bounded preparation retries; only the final held pair is restart/Resume proof. The preserved initial interrupted run was traced to an accepted renderer Stop, with an extra driver Escape strongly supported as its cause rather than directly captured. No attributable PR defect was established by that interruption.
Not exercised in the app: a phone draft typed at the exact moment of the phone's timeout, and creating a chat while no proof at all has arrived; tests cover both. Saving across all older chat formats, refusal sets for each older reader, compaction of saved records and the operation counts at 10× scale are covered by tests.
Tracked in STA-11448, STA-11165 and STA-11117 case A. The Codex history repair is tracked in STA-13077. Includes image recovery from #28650.
Author: @BrennanKB5