Skip to content

feat(frontend): queue agent chat messages typed during a stream#4903

Merged
ardaerzin merged 8 commits into
big-agentsfrom
fe-feat/agent-chat-message-queue-onbig
Jun 28, 2026
Merged

feat(frontend): queue agent chat messages typed during a stream#4903
ardaerzin merged 8 commits into
big-agentsfrom
fe-feat/agent-chat-message-queue-onbig

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Stacked on #4902 — review/merge that first. Base is fe-perf/agent-chat-long-conversation-onbig so this PR shows only the queue diff.

Problem

While an agent turn was streaming, the composer silently dropped anything the user typed (Ant Design X gates onSubmit on !loading, and the panel passed loading={busy}). You could type but not send.

Change

Messages typed during a turn are now queued and sent one at a time after the turn settles.

  • Release gate (@agenta/playground, pure + unit-tested): canReleaseQueuedMessage / isHitlPending. The trap is human-in-the-loop — a tool-approval gate ends the stream (status: "ready") while the turn is really paused on the user's approve/deny, and useChat auto-resumes after. The gate never releases mid-HITL, and composes agentShouldResumeAfterApproval so the pre-resume window is held too. It also holds on error rather than firing follow-ups into a failed turn. 13 unit tests.
  • useAgentChatQueue: owns the queue and a release effect that emits exactly one message per clean settle (ref-guarded, StrictMode-safe).
  • Composer: handleSubmit queues when busy or mid-approval. The Sender drops loading={busy} (so the send button stays live and routes to the queue) and gains a footer. A collapsed count pill → popover manages the queue at a fixed footprint regardless of size; previews use a 3-line clamp + full text on hover so long messages stay identifiable. The footer is HITL-aware: Streaming… [Stop] vs Waiting for approval.

This branch also carries the AgentChatPanel copy of the stable-onRewind fix from #4902 (the primary surface had the same re-render bug the perf PR fixed on the contract-v1 surface).

Testing

  • tsc --noEmit + eslint clean; 13/13 new unit tests pass (agentMessageQueue.test.ts).
  • Manually verified: queueing during a stream, one-by-one release, removal/clear, and the HITL hold during a tool-approval prompt.

Previously the composer dropped anything typed while a turn was in flight
(Ant X gates onSubmit on !loading). Now those messages are queued and sent
one-by-one after the turn settles.

- canReleaseQueuedMessage / isHitlPending (@agenta/playground, +13 unit tests):
  the release gate. Never releases mid human-in-the-loop — a tool-approval
  gate ends the stream (status "ready") while the turn is really paused on the
  user's approve/deny, and useChat auto-resumes after. Composes
  agentShouldResumeAfterApproval so the pre-resume window is held too. Holds on
  error rather than firing follow-ups into a failed turn.
- useAgentChatQueue: queue state + a release effect that emits exactly one
  message per clean settle (ref-guarded, StrictMode-safe).
- AgentChatPanel: handleSubmit queues when busy or mid-approval; the Sender
  drops loading={busy} so the send button stays live and routes to the queue,
  with Stop + a queued count moved to the footer; QueuedMessages shows the
  removable pending chips.
- Also stabilizes the panel's handleRewind (useCallback + refs) so memo'd
  AgentMessage rows aren't re-rendered on every streamed token — the same fix
  the perf branch applied only to the contract-v1 surface.
The inline chip strip grew with the queue and truncated long messages to
unhelpful stubs. Replace it with a fixed-footprint count pill in the composer
footer that opens a popover to manage the queue.

- QueuedMessages: a "N queued" pill (count only — no truncation on the trigger)
  opening a popover list with order number, remove, and Clear all. Previews use
  a 3-line clamp + break-words + full text on hover, so long messages stay
  identifiable; the list scrolls past ~3 instead of growing the composer.
- Footer is now HITL-aware: "Streaming… [Stop]" while busy, "Waiting for
  approval" when the turn is paused on a tool approval (busy false but messages
  still held), so the queue count stays visible and the hold is explained. The
  footer now renders for busy || queued.length > 0, not just busy.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. Feature Request New feature or request Frontend labels Jun 28, 2026
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e7ed1087-589b-49d8-af5c-4b2bcb02c364

📥 Commits

Reviewing files that changed from the base of the PR and between bcc1b6d and 1576ab3.

📒 Files selected for processing (2)
  • web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts
  • web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added queued sending for agent chat messages, so messages can be held and sent one at a time when the conversation is ready.
    • Added a queue popover to review, remove, or clear pending messages, including attachment previews.
  • Bug Fixes

    • Improved chat controls for streaming and approval states, with clearer status indicators and stop/retry behavior.
    • Made rewind actions more reliable during streaming updates and preserved prior input when rewinding to earlier turns.

Walkthrough

Adds queued agent-chat submissions with HITL-aware release gating. The queue hook, queued-message popover, and AgentChatPanel wiring now coordinate submission, release, rewind, and footer state. The gating helpers are exported through the state modules and covered by unit tests.

Changes

Agent chat queued-message sending with HITL gating

Layer / File(s) Summary
HITL release-gate logic and exports
web/packages/agenta-playground/src/state/execution/agentMessageQueue.ts, web/packages/agenta-playground/src/state/execution/index.ts, web/packages/agenta-playground/src/state/index.ts, web/packages/agenta-playground/src/index.ts, web/packages/agenta-playground/tests/unit/agentMessageQueue.test.ts
New queue-gating helpers detect HITL approval states on the last assistant turn, decide when queued messages may release, re-export the helpers through the state modules, and cover the gating behavior with unit tests.
useAgentChatQueue hook
web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts
The hook stores queued user messages with ids, text, and optional file parts, enqueues or sends immediately based on the release gate, removes or clears queued items, and releases one queued message at a time when the stream becomes ready.
QueuedMessages popover component
web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx
The new memoized component renders a queued-count pill, an Ant Design popover with a scrollable queued list, per-item removal, clear-all control, attachment tiles, and empty-message fallback text.
AgentChatPanel integration
web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
The panel adds queue and stop controls, keeps stable refs for submit and rewind flows, routes submissions through the queue hook, and renders queued, streaming, and approval footer states.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Agenta-AI/agenta#4859: The queued-message release gate calls the same HITL resume predicate and shares related stream-error handling.
  • Agenta-AI/agenta#4902: Both PRs stabilize handleRewind/onRewind with refs and useCallback in the same chat component path.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: queuing agent chat messages typed during a stream.
Description check ✅ Passed The description is detailed and directly describes the queued-message behavior and related implementation changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 60.00%.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-feat/agent-chat-message-queue-onbig

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.

@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jun 28, 2026 12:12pm

Request Review

@ardaerzin ardaerzin changed the base branch from fe-perf/agent-chat-long-conversation-onbig to big-agents June 28, 2026 11:18
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: acf9e698-e2ac-486f-a8de-d06c84e33bd4

📥 Commits

Reviewing files that changed from the base of the PR and between 27228f1 and 1953ebc.

📒 Files selected for processing (8)
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts
  • web/packages/agenta-playground/src/index.ts
  • web/packages/agenta-playground/src/state/execution/agentMessageQueue.ts
  • web/packages/agenta-playground/src/state/execution/index.ts
  • web/packages/agenta-playground/src/state/index.ts
  • web/packages/agenta-playground/tests/unit/agentMessageQueue.test.ts

Comment thread web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx Outdated
Comment thread web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
Comment thread web/packages/agenta-playground/tests/unit/agentMessageQueue.test.ts
Review follow-up on the message-queue branch.

- handleSubmit had its own send-vs-queue decision (busy || hitlPending) that
  drifted from the release effect's gate, so a new message could jump ahead of
  held queued items or fire into an errored turn. Replace both with a single
  hook-owned submit() that uses canReleaseQueuedMessage — one decision point,
  one sender (sendQueued), and no duplicated payload building.
- Footer guard now includes hitlPending, so "Waiting for approval" renders
  during a HITL pause even when the queue is empty.
- Add the deny-path assertion to the pre-resume gate test (approve AND deny
  both resume, so both must hold the queue).
The queue popover showed only a file count. Render each attachment as a small
24px tile — an image thumbnail (from the inline data: URL) or a type icon for
audio/video/other — so a queued message's attachments are identifiable at a
glance. Filenames stay as hover titles only. Also tightens the popover density
(2-line text clamp, smaller padding, 300px width).
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ba37045-7deb-4567-9ecb-684fa9112158

📥 Commits

Reviewing files that changed from the base of the PR and between 1953ebc and bcc1b6d.

📒 Files selected for processing (4)
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts
  • web/packages/agenta-playground/tests/unit/agentMessageQueue.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/packages/agenta-playground/tests/unit/agentMessageQueue.test.ts
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx

Comment thread web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx Outdated
Comment thread web/oss/src/components/AgentChatSlice/components/QueuedMessages.tsx Outdated
Comment thread web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts Outdated
Comment thread web/oss/src/components/AgentChatSlice/hooks/useAgentChatQueue.ts Outdated
Second review round on the message-queue branch.

- submit could direct-send twice when two submits landed in the same render
  before status left "ready", breaking FIFO. Share the release latch
  (releasingRef) across both send paths and read the live queue length via a
  ref, so the first send closes the window and the next message queues behind it.
- Non-image attachment tiles exposed no accessible name (title is mouse-only):
  add role="img" + aria-label and mark the decorative icon aria-hidden.
- Collapse the multi-line comments that exceeded the one-line rule.
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ardaerzin ardaerzin merged commit aad6e5d into big-agents Jun 28, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Request New feature or request Frontend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant