Skip to content

Queue UX: channel and inbox queues act through each recipient's owner like the DM view - #1417

Merged
trissim merged 1 commit into
mainfrom
ccr-b17367e7-4095oh
Nov 2, 2026
Merged

trissim merged 1 commit into
mainfrom
ccr-b17367e7-4095oh

Conversation

@trissim

@trissim trissim commented Nov 2, 2026

Copy link
Copy Markdown

Summary

1 commit, 5 files. This is the Toad half of Tristan's queue unification: channel and CLI-inbox queues get the DM view's send-now and clear. The Core half is agent-comms#3883, which must merge first because this PR imports its QueueActionRuntimeRequest.

Before / after

Before                                    After
QueueSource(ABC)                          QueueSource(ABC)   actions take the captured QueueEvidence
  ReadOnlyQueueSource  ← refuses            NoQueueSource      only before a chat view's source loads
    BusQueueSource      channels, inbox     NativeQueueSource  DM: the view's ACP agent (unchanged)
  NativeQueueSource     DM                  BusQueueSource     channels, inbox: each recipient's owner
MailboxSessionSources(BusQueueSource, OperationalSessionSources)
  → MRO resolved the refusal first          → resolves owner actions
  • BusQueueSource no longer inherits a read-only parent. Send-now and clear go to every recipient still holding a visible message, meaning its DeliveryProgress.consumed is false. The new NotificationStatus.queued_recipients answers that: empty by default, and the checked status lists unconsumed recipients. Each owner is asked through Core's declared send_now / clear_queue requests (QueueActionRuntimeRequest.at_owner). A refusal names each recipient that refused.
  • The family's actions take QueueEvidence, the same captured read the popup displays, instead of only the presentation. QueueEvidence gains service, the view's Core service, read at action time.
  • CommsChatView holds NoQueueSource until its WireSource arrives.

Evidence

  • Imports: toad.submission_queue, toad.screens.queue, toad.widgets.comms_chat, toad.session_presentation, toad.conversation_submission import cleanly against agent-comms#3883.
  • tests/textual/test_message_notifications.py test_message_notification_title.py test_queue_inspection.py test_wire_message_lines.py: 5 passed and 8 failed, with the same 8 failing on main in this container. All 8 raise GitVersionUnsupported because the container has Git 2.43 and Core requires 2.44. So the app-level tests are unrun here.
  • The real check is after install, in a channel with a busy Pi agent: Send now delivers its queued message, and Clear empties that agent's queue.

Still to do on this overhaul

  • Inline controls and keys. pi-ui-colleague's trace (56875): MessagePrompt.sync_turn is a no-op, and SubmitNowAction.available asks ACP readiness instead of the source capability. Ctrl+Enter / Ctrl+Y and the inline queue controls should ask queue_source.queue_actions_available.
  • CLI agents. Claude Code records its own queue in its transcript (queue-operation enqueue/dequeue/remove). Core's bridge declares that record but keeps none of its fields (claude_protocol.py:1152). The inbox should show that queue through this same source.

Assumed: clearing a channel recipient's queue clears that agent's whole queue, the same queue the DM view clears, not only this channel's items. Per-item withdrawal uses the existing ID-targeted cancel later.


Generated by Claude Code

…DM view

BusQueueSource no longer inherits a read-only parent: its send-now and clear
ask the owner of every recipient that has not yet taken a visible message
(DeliveryProgress.consumed), through Core's declared owner requests. The
family's actions take the captured QueueEvidence, so the popup acts on what
it showed. The read-only member survives only as NoQueueSource, the source a
chat view holds before its wire source arrives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016gZLdttfQjtizEYZGek9Gh
Copilot AI balanced review requested due to automatic review settings November 2, 2026 16:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

debt-src at c61b5c0 blocks on 5 lines:

grew BroadSwallow:src/toad/submission_queue.py +1
grew TypeErrors:src/toad/submission_queue.py +3
found BroadSwallow:src/toad/submission_queue.py at src/toad/submission_queue.py:156
found TypeErrors:src/toad/submission_queue.py at src/toad/submission_queue.py:17 (Module "agent_comms.runtime_requests" has no attribute "ClearQueueRuntimeRequest"  [attr-defined]) src/toad/submission_queue.py:17 (Module "agent_comms.runtime_requests" has no attribute "QueueActionRuntimeRequest"  [attr-defined]) src/toad/submission_queue.py:17 (Module "agent_comms.runtime_requests" has no attribute "SendNowRuntimeRequest"; maybe "SetGoalRuntimeRequest"?  [attr-defined])
introduced BroadSwallow:src/toad/submission_queue.py at lines [156]
Warn-only, never blocks (2)
src/toad/submission_queue.py: LintFindings +1
found LintFindings:src/toad/submission_queue.py at src/toad/submission_queue.py:2 (I001 [*] Import block is un-sorted or un-formatted)

@trissim
trissim merged commit ea62139 into main Nov 2, 2026
1 of 2 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.

3 participants