Repository navigation
feat(native-chat): image messages wait in the queue like text - #28655
Conversation
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
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to
|
…2025/queue-images # Conflicts: # src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
be8734c4-e11d-4b97-bf0a-4bd7eeeb1850
📒 Files selected for processing: 36
src/main/ipc/desktop-renderer-runtime-capabilities.tssrc/main/native-chat/agent-session-journal/journal-unsent-send-hold.tssrc/main/native-chat/agent-session-wire/agent-session-subscriber-frame-fields.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host-mutations.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-send.tssrc/main/native-chat/agent-session-wire/structured-agent-session-subscribers.tssrc/main/runtime/orca-runtime-tests/repository-project-operations-part-02.spec.tssrc/main/runtime/rpc/methods/structured-agent-session-queued-image-capability.test.tssrc/main/runtime/rpc/methods/structured-agent-session-queued-image-capability.tssrc/main/runtime/rpc/methods/structured-agent-session-send-compatibility.tssrc/main/runtime/rpc/methods/structured-agent-session-wire-contracts.test.tssrc/main/runtime/rpc/methods/structured-agent-session.tssrc/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsxsrc/renderer/src/components/native-chat/NativeChatQueuedMessageEditor.tsxsrc/renderer/src/components/native-chat/NativeChatTranscriptChrome.tsxsrc/renderer/src/components/native-chat/native-chat-image-label.tssrc/renderer/src/components/native-chat/structured-agent-session-queue-request.test.tssrc/renderer/src/components/native-chat/structured-agent-session-queue-request.tssrc/renderer/src/components/native-chat/structured-agent-session-queued-cards.tssrc/renderer/src/components/native-chat/use-structured-agent-session-sends.test.tsxsrc/renderer/src/components/native-chat/use-structured-agent-session-sends.tssrc/renderer/src/i18n/en-runtime-required.jsonsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/fr.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/web/web-runtime-client-capabilities.tssrc/renderer/src/web/web-runtime-client.test.tssrc/shared/agent-session-queued-message-wire.tssrc/shared/electron-remote-runtime-client-capabilities.tssrc/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.
|
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 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 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 For Brennan's review Same inputs, whole-window main-versus-PR captures:
Edit preserves B's image; main has no waiting B to edit: Delete before and after; main sends the image immediately:
Remaining whole-window QA captures (workspace, working turn, queued text, transcript and isolated rig)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
























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:107expects an agent without modes to be allowed, andagent-chat-permission-host-support.test.ts:32expects no legacy mode. Both tests still use Grok. The CI merge included maind963f2a23ad162d169709de47b38fd593e557df4; 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 headc5d5bb1a842149ad591df7a88ed7e1e02d73ef08passed 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.
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
Notes
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