Skip to content

feat(native-chat): image messages wait in the queue like text - #28655

Merged
brennanb2025 merged 10 commits into
mainfrom
brennanb2025/queue-images
Oct 17, 2026
Merged

brennanb2025 merged 10 commits into
mainfrom
brennanb2025/queue-images

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 12 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​455 $\color{#cf222e}{\Huge{\mathbf{−}}}$​128 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​327
Prod 40 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​411 $\color{#cf222e}{\Huge{\mathbf{−}}}$​115 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​296

ELI5

An image sent while the agent works used to skip waiting text messages. This makes image messages use the same ordered queue as text, with an image name and count on each card and images preserved when its text is edited.

Queueing remains disabled by the existing host capability switch. This PR prepares image support; it does not enable that switch or change the default.

What Changed

The desktop asks to queue a complete message, including images. The execution host admits it through the existing queue, retains its full body and attachment claims, and hands cards to the agent in order. Image-only cards show a filename or image count; text edits retain their images.

Older desktops and phones cannot safely edit an image card because their editor copies only the text and deletes the card. The host therefore withholds image cards from readers without image-card support. Filtering happens before the phone frame budget, so a hidden image cannot hide later eligible text. The host retains the canonical queue and ordering.

Sender support is checked separately: an older phone or desktop that asks to queue an image keeps its existing immediate-send behavior, avoiding pending work that its sender cannot see. Direct image sends interrupted before delivery retain their existing failed-send behavior. An image already accepted as a queued card returns to that original card through ordinary failed-handoff settlement.

Why

This follows the common pattern: retain the complete input in one host-owned queue rather than add a separate image queue or attachment lifecycle. Text and images share ordering, editing and handoff. Sender negotiation protects older clients, and reader projection preserves the host's complete queue without exposing destructive editing controls.

Linked Issue

N/A — maintainer PR.

Visual Proof

Final-head real-agent Electron QA remains pending with the lane owner. The independent final source review passed, and the latest correction makes the image-name tooltip keyboard accessible. The QA worker must use current head b20ded87dc06a3395c0e108d3660673336d56c6a, compare main and branch, and verify that Tab reveals filenames on a multi-image card. Historical stand-in captures and earlier evidence without isolation proof are excluded.

Testing

Current head is b20ded87dc06a3395c0e108d3660673336d56c6a. Four review rounds plus independent verification of both final main merges and the narrow accessibility correction are complete, with no open high-severity findings. The last commit adds only keyboard focus and the documented focus ring to the existing image-name tooltip; pre-commit checks passed. No queue, ownership, recovery or wire behavior changed in that correction.

Current-head PR Checks is blocked by two stale tests on main after Grok gained chat permission modes: structured-chat-host-permission.test.ts:107 expects an agent without modes to be allowed, and agent-chat-permission-host-support.test.ts:32 expects no legacy mode. Both tests still use Grok. The CI merge included main d963f2a23ad162d169709de47b38fd593e557df4; its production change gives Grok modes while these expectations remain unchanged. The separate correction is tracked in #29888 and #29887. The image PR does not change these files. Static analysis/typecheck, cross-version wire compatibility, relay integration and the other three test shards passed. The earlier head c5d5bb1a842149ad591df7a88ed7e1e02d73ef08 passed the full workflow; that does not qualify the current head as green.

The contracts cover ordered image handoff, capability-selected reader projection before frame sizing, old-phone immediate admission, baseline direct-image recovery, renderer queue requests and attachment-preserving edits. Runtime timing and memory were not measured.

  • Fresh rendered QA complete
  • Automated tests added/updated
  • Full PR workflow green on current head after main's fix

Review

Four review rounds and final independent source verification are complete. A later accessibility thread was independently confirmed and fixed: keyboard users can focus the image-count indicator to reveal its filenames, with a visible focus ring. The thread is resolved. The single status comment will receive the finished-review marker only after current-head CI is green and qualifying real-agent QA/screenshots are available. This PR is not ready to merge.

Agent skill upstream boundary

  • Not applicable; no upstream skill-installer material is copied or translated.

Notes

  • Intended: an unsupported sender keeps immediate image sends; unsupported readers see text cards only. Hidden image cards remain ordered and can be managed from an updated desktop. A hidden failed image can hold later cards without an attention caption on an older reader.
  • Temporary: phone image-card display and editing remain a separate follow-up, PR4b. Phone clients do not advertise support here. Mixed client/server versions remain supported; developer host downgrades are outside the agreed scope.
  • Intended: all direct-image failed-send recovery stays unchanged. Recovery is expanded only for images that were already accepted as queue cards.
  • Intended: uploads belong to the retained chat. Delete removes the waiting message, and closing a tab retains the chat record; neither promises immediate file deletion. Existing cleanup applies after the last owning chat record disappears.
  • Intended: local image files are read when sent. Editing or removing the file while it waits can change or fail delivery; capturing files at drop remains separate work.
  • Intended: queued sends preserve transcript scroll position. Explicit Send/Steer/Resume actions keep their existing behavior.
  • Intended: cards show image names/counts rather than thumbnails; the sent transcript renders the image.

The queue, attachment ownership and execution remain on the execution host for local, paired and SSH chats. Folder workspaces do not require Git. No saved field, required wire field, opcode, schema migration or new minimum server version is introduced. Performance review establishes bounded source work; timing and memory use were not measured.

Checklist

A message with images now queues behind the running turn and the cards
ahead of it, instead of skipping the queue. Cards show an image icon and
count, an image-only card names its image, and editing a card's text keeps
its images. The host publishes no card holding an image to a client that
has not advertised agent-session.queued-image-cards.v1, since released
clients edit by copying a card's text and deleting the card.
…ages

# Conflicts:
#	src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.ts
#	src/main/runtime/rpc/methods/structured-agent-session-send-compatibility.test.ts
#	src/shared/protocol-version.ts
…ages

# Conflicts:
#	src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.test.ts
#	src/renderer/src/i18n/en-runtime-required.json
#	src/renderer/src/i18n/locales/en.json
#	src/renderer/src/i18n/locales/es.json
#	src/renderer/src/i18n/locales/fr.json
#	src/renderer/src/i18n/locales/ja.json
#	src/renderer/src/i18n/locales/ko.json
#	src/renderer/src/i18n/locales/zh.json
#	src/renderer/src/web/web-runtime-client-capabilities.ts
#	src/renderer/src/web/web-runtime-client.test.ts
#	src/shared/electron-remote-runtime-client-capabilities.ts
@brennanb2025
brennanb2025 marked this pull request as ready for review October 16, 2026 23:03
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 98257e31-f601-43d3-af0f-5189a6fee7f2
📥 Commits

Reviewing files that changed from the base of the PR and between c5d5bb1 and aac8b71.

📒 Files selected for processing: 32
  • src/main/acp/acp-structured-launch-resolution.test.ts
  • src/main/ai-vault/structured-chat-cli-fork.ts
  • src/main/ipc/desktop-renderer-runtime-capabilities.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-mutations.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
  • src/main/native-chat/agent-session-wire/unhandled-provider-frame.ts
  • src/main/node-runtime/runtime-archive-download.test.ts
  • src/main/runtime/agent-launch-scope-runtime.test.ts
  • src/main/runtime/revisioned-state.ts
  • src/main/runtime/rpc/methods/structured-agent-session-wire-contracts.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session.ts
  • src/main/runtime/runtime-pane-admission.ts
  • src/main/runtime/terminal/launch/mobile-terminal-chat-fork-create.ts
  • src/main/runtime/terminal/launch/mobile-terminal-chat-fork.test.ts
  • src/main/runtime/terminal/launch/mobile-terminal-chat-fork.ts
  • src/main/runtime/terminal/launch/mobile-terminal-owned-create.ts
  • src/main/runtime/terminal/launch/mobile-terminal-renderer-create.ts
  • src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx
  • src/renderer/src/hooks/ipc-events/terminal-presentation-ipc-bridge.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/web/web-runtime-client-capabilities.ts
  • src/renderer/src/web/web-runtime-client.test.ts
  • src/shared/electron-remote-runtime-client-capabilities.ts
  • src/shared/rpc-contract/session-tabs-schemas-params.ts
  • src/shared/session-tabs-runtime-capabilities.ts
  • tests/e2e/cross-version-wire/cross-version-stop-note-test-rig.ts
🚧 Files skipped from review as they are similar to previous changes: 8
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-mutations.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/ja.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

📝 Walkthrough

Image-bearing messages can now enter the queue when the sender advertises queued-image-card support. History and queue publications are projected according to reader capability. Queued cards preserve image references and display image labels or counts, with localized count strings. Tests cover queue admission, capability-based projections, and image-send behavior for older mobile clients.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to aac8b

Keyboard users can reach the queued image names. No actionable merge-blocking risk remains in the reviewed changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 40 functions across 45 files. (6 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: image messages now wait in the native-chat queue like text messages.
Description check Passed The description is detailed, on-topic, and covers the user impact, implementation, rationale, compatibility behavior, testing status, and known limitations. It identifies that fresh visual QA and curr…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is detailed, on-topic, and covers the user impact, implementation, rationale, compatibility behavior, testing status, and known limitations. It identifies that fresh visual QA and current-head full workflow success are still pending, but the required sections are present and the remaining gaps are explicitly documented.

Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 40 functions across 45 files. (6 skipped: 6 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…2025/queue-images

# Conflicts:
#	src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: be8734c4-e11d-4b97-bf0a-4bd7eeeb1850
📥 Commits

Reviewing files that changed from the base of the PR and between c4c03e8 and c5d5bb1.

📒 Files selected for processing: 36
  • src/main/ipc/desktop-renderer-runtime-capabilities.ts
  • src/main/native-chat/agent-session-journal/journal-unsent-send-hold.ts
  • src/main/native-chat/agent-session-wire/agent-session-subscriber-frame-fields.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-mutations.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-send.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
  • src/main/runtime/orca-runtime-tests/repository-project-operations-part-02.spec.ts
  • src/main/runtime/rpc/methods/structured-agent-session-queued-image-capability.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-queued-image-capability.ts
  • src/main/runtime/rpc/methods/structured-agent-session-send-compatibility.ts
  • src/main/runtime/rpc/methods/structured-agent-session-wire-contracts.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session.ts
  • src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx
  • src/renderer/src/components/native-chat/NativeChatQueuedMessageEditor.tsx
  • src/renderer/src/components/native-chat/NativeChatTranscriptChrome.tsx
  • src/renderer/src/components/native-chat/native-chat-image-label.ts
  • src/renderer/src/components/native-chat/structured-agent-session-queue-request.test.ts
  • src/renderer/src/components/native-chat/structured-agent-session-queue-request.ts
  • src/renderer/src/components/native-chat/structured-agent-session-queued-cards.ts
  • src/renderer/src/components/native-chat/use-structured-agent-session-sends.test.tsx
  • src/renderer/src/components/native-chat/use-structured-agent-session-sends.ts
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/web/web-runtime-client-capabilities.ts
  • src/renderer/src/web/web-runtime-client.test.ts
  • src/shared/agent-session-queued-message-wire.ts
  • src/shared/electron-remote-runtime-client-capabilities.ts
  • src/shared/runtime-capability-constants.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

Comment thread src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx Outdated
@brennanb2025

brennanb2025 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor Author

When a chat was busy, image follow-ups could bypass waiting text: sending A (text), B (text + image), then C (image only) produced B → C → A. Images were excluded from the queue admission path even though the existing queue can retain a complete message.

This PR makes image follow-ups wait in the same ordered queue as text. Waiting cards show an image icon/count, or the filename for an image-only message. Edit changes the text while preserving its images; Delete removes the waiting message without sending it. The existing host queue capability remains gated; this PR changes no default.

Review result: four completed rounds, followed by fresh independent verification of the final main merge at aac8b71f3bdd3d8424799268f1f5d92ab2eb9e9f. No open P0/P1 or new merge findings. Local desktop, paired desktop and browser retain both image-card support and snapshot catch-up. The subscriber retains both policies, and the input type alias preserves the former structure. No code changed during this final verification.

Fixed during review: unsupported image cards are filtered before phone frame limits so later text stays visible; older senders retain immediate image sends instead of creating waiting work hidden from themselves; queued image names are reachable through keyboard focus with a visible focus ring. Direct image failure recovery retains its existing behavior.

Intended limits: uploads retain their existing chat-owned lifetime, so Delete cancels a message without promising immediate upload deletion. Local files are still read when sent and can change or disappear while waiting; capturing them at drop time is deferred product work. Temporary limit: phone image-card controls remain a separate follow-up; unsupported readers show eligible text cards only. Developer-only server downgrade recovery is outside this change; ordinary mixed-version contracts remain covered by CI.

Verified: the complete PR workflow passed on this exact head, including PR checks passed, static analysis/typecheck, all five test shards, relay integration, packaging and cross-version compatibility. GitHub reports CLEAN, the PR is out of draft, and all review threads are resolved. The separately reported network-flaked persistence job also passed after rerun.

Real Electron QA compared main 861258881626c7746a02fe94642979dd38146072 with the exact PR head, using signed-in Codex and a Codex UI driver on this Mac under qa-gate ticket 132, because the remote machines were unavailable. Main sent B/C ahead of A; the PR queued A/B/C, kept B's image through Edit, automatically drained A → edited B → C with both images, and deleted another image card without delivery. Explorer-to-composer dragging used the real handlers. Setup matched with the optional initial agent deselected on both arms. I read the QA report, inspected 12 key whole-window captures, and verified the evidence archive SHA-256: c439e45451a2fc9a937a54edd572905030915871229b706a52c089ce67622eee.

Coverage and isolation limits: default initial-agent tab ordering was not compared and is untouched by this PR. Runtime multi-image keyboard tooltip behavior, packaged apps, other agents, Windows/Linux, SSH/folder workspaces and old phones were not exercised by this QA. Identical QA-only patches advertised the gated queue capability and pinned ports on both arms. A driver briefly opened Codex as a terminal before Chat UI was enabled; it was closed without input, and monitored configuration hashes were unchanged immediately afterward. Codex later added its own trust entries for the test folders to ~/.codex/config.toml; the changed ~/.claude.json hash remains unattributed with concurrent agents on this shared Mac. Hooks, Claude settings, Orca configuration hashes and Codex auth metadata stayed unchanged. The known one-time “Orca now runs Codex without its shared server” toast and background shell command after Stop predate this PR. Main's workload was interrupted for comparison; its complete final answer is not claimed. Main's extra stopped chat/idle primary shell explain baseline tab/status differences. No new performance timing or heap measurements are claimed.

For Brennan's review

Same inputs, whole-window main-versus-PR captures:

Flow Main PR
Setup output; no initial agent main-03-setup-output.png pr-03-setup-output.png
B: text + image main-06-B.png pr-06-B.png
C: image only main-07-C.png pr-07-C.png
Delivery order: B/C/A → A/B/C main-08-drained.png pr-08-drained.png

Edit preserves B's image; main has no waiting B to edit:

pr-11-B-edited.png

Delete before and after; main sends the image immediately:

Before Delete After Delete
pr-12-delete-before.png pr-13-delete-after.png
Remaining whole-window QA captures (workspace, working turn, queued text, transcript and isolated rig)

main-00-checkpoint.png

main-01-workspace.png

main-02-setup.png

main-04-working.png

main-05-queued-A.png

main-09-transcript.png

main-10-rig-env.png

pr-01-workspace.png

pr-02-setup.png

pr-04-working.png

pr-05-queued-A.png

pr-09-transcript.png

pr-10-rig-env.png

Three source spots for judgment:

…ages

# Conflicts:
#	src/main/ipc/desktop-renderer-runtime-capabilities.ts
#	src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
#	src/renderer/src/web/web-runtime-client-capabilities.ts
#	src/renderer/src/web/web-runtime-client.test.ts
#	src/shared/electron-remote-runtime-client-capabilities.ts
@brennanb2025
brennanb2025 merged commit 32a53d3 into main Oct 17, 2026
56 of 57 checks passed
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.

1 participant