Skip to content

feat(frontend): stream/batch response channel switch for the agent playground#4861

Merged
mmabrouk merged 3 commits into
big-agentsfrom
fe-feat/agent-stream-batch-switch
Jun 25, 2026
Merged

feat(frontend): stream/batch response channel switch for the agent playground#4861
mmabrouk merged 3 commits into
big-agentsfrom
fe-feat/agent-stream-batch-switch

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Stacked on #4850 (agent config panel). Base is fe-feat/agent-config-panel-onbig so the diff is just this feature; it retargets/rebases onto big-agents once #4850 merges.

Context

The agent playground always spoke to the agent /messages endpoint over SSE. This adds a per-playground switch to use batch mode instead (a single JSON response), surfaced in the playground kebab menu next to the existing View options. Stream stays the default.

Changes

  • A Response group (Stream / Batch) in the playground kebab menu (PlaygroundVariantHeaderMenu), agent-only, mirroring the View group.
  • agentChannelModeAtom on the @agenta/playground controller (transport state, default stream). It is NOT revision config and is never persisted on the agent. buildAgentRequest reads it to set the request Accept header: text/event-stream for stream, application/json for batch.
  • AgentChatTransport (web/oss/src/components/AgentChatSlice/assets/AgentChatTransport.ts), a subclass of DefaultChatTransport. useChat has no batch mode (its transport contract is always a UIMessageChunk stream), so in batch mode this parses the WorkflowBatchResponse and replays the assistant message as a one-shot chunk sequence (start → start-step → text/reasoning/tool → finish-step → finish), so useChat paints it in one frame. Stream mode delegates to the default SSE parser unchanged.

For the agent service (Mahmoud / agents)

  • No backend change. The vercel adapter already content-negotiates (sdk/agents/adapters/vercel/routing.py): Accept: text/event-streamWorkflowStreamingResponse (SSE); anything else → WorkflowBatchResponse (JSON).
  • The FE relies on the batch data.outputs being a neutral Message {role, content} (content = a string or a list of content blocks), confirmed in QA. The chunk sequence is taken from sdk/agents/adapters/vercel/stream.py. If the batch outputs shape changes (a typed UIMessage, multiple messages, a wrapper), the single place to update is extractAssistantMessage / normalizeToParts in AgentChatTransport.ts (it already accepts UIMessage-with-parts, a list, {messages}, and a string as fallbacks).
  • Tool parts in batch mode are re-emitted best-effort (tool_use/tool_result content blocks → tool-input-available/tool-output-available chunks); only confirmed against text so far, so a tool-calling agent in batch is the thing to validate.

Tests / notes

  • agenta-playground package: tsc + eslint clean. oss: tsc + eslint clean on the changed files.
  • Verified live: toggled Response to Batch, sent a message, the reply rendered in one frame ({"role":"assistant","content":"Hi! How can I help you?"} → one text part). Stream mode unchanged.

What to QA

  • Agent playground kebab menu → Response → Batch. Send a message: the assistant reply renders (in one shot, not token-by-token).
  • Switch back to Stream: streams token-by-token as before (regression).
  • Tool-calling agent in Batch mode: confirm tool input/output render (best-effort path).

Adds a "Response" group (Stream / Batch) to the agent playground's kebab menu, next to the
existing View group. It writes a transport-level `agentChannelModeAtom` (default "stream") on
the @agenta/playground controller — not revision config — and `buildAgentRequest` reads it to
set the `/messages` Accept header: `text/event-stream` for stream, `application/json` for batch
(the backend already content-negotiates both).

Batch rendering (replaying the WorkflowBatchResponse as a one-shot UIMessage stream so useChat
can paint it) lands in the follow-up transport commit; until then batch is wired end-to-end on
the request side only. Stream remains the default and is unchanged.
…m (AgentChatTransport)

useChat has no batch mode — its transport contract is always a UIMessageChunk stream. When the
channel mode is `batch`, the backend returns a single WorkflowBatchResponse (JSON, because
buildAgentRequest sent Accept: application/json). AgentChatTransport overrides processResponseStream
to parse that JSON and replay the assistant message as a one-shot v6 chunk sequence (start →
text/reasoning/tool parts → finish), so useChat paints it in a single frame. Stream mode delegates
to the default SSE parser unchanged, and the mode is read from the same agentChannelModeAtom that
set the Accept header so the request channel and response handling always agree.

The agent `/messages` batch path returns `data.outputs` as a neutral Message `{role, content}`
(content = string or content blocks), confirmed in QA — not a Vercel UIMessage. The extractor
normalizes that (and the other plausible shapes: list / {messages} / UIMessage-with-parts / string)
into UIMessage parts before emitting the chunks.
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 25, 2026
@vercel

vercel Bot commented Jun 25, 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 25, 2026 11:20pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cc0b483a-2e4d-411a-9edb-1457ec3df37e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-feat/agent-stream-batch-switch

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.

@ardaerzin ardaerzin mentioned this pull request Jun 25, 2026
12 tasks
Pull #4850 (agent config panel) + the agent fix pass forward into the
stream/batch channel branch. Conflicts were in the agent-lane barrels and
AgentChatPanel.tsx, all where #4861 and the fix pass each added an adjacent
agent export / changed the transport; resolved by keeping BOTH:
- playground barrels export agentChannelModeAtom (this PR) AND
  agentShouldResumeAfterApproval (fix pass).
- AgentChatPanel uses AgentChatTransport (this PR) with the fix pass's
  agentShouldResumeAfterApproval resume predicate and F-033 error handling.
Backend/wire shape stays canonical (our side); the channel switch is purely
the Accept header + a batch JSON->UIMessage replay.

Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
@mmabrouk mmabrouk changed the base branch from fe-feat/agent-config-panel-onbig to big-agents June 25, 2026 23:19
@mmabrouk mmabrouk merged commit bc87043 into big-agents Jun 25, 2026
27 of 28 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-668d.up.railway.app/w
Project agenta-oss-pr-4861
Image tag pr-4861-60cde3f
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-06-25T23:28:08.371Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 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.

2 participants