fix(multi-agent-chat): fix sub-agent rendering, hydration, and added documentation#424
fix(multi-agent-chat): fix sub-agent rendering, hydration, and added documentation#424
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes runtime issues in the multi-agent-chat example related to sub-agent tool streaming/rendering, React hydration, and streaming-induced render loops, and updates the orchestrator prompt + documentation accordingly.
Changes:
- Pin
aito6.0.116to prevent incompatible client/server stream chunk validation and unblock sub-agent rendering. - Fix hydration mismatch by deferring
localStoragethread reads to an effect, and prevent streaming render loops by decoupling persistence from sidebar refresh. - Update orchestrator system prompt, conversation starters, and rewrite README to document the multi-agent streaming architecture.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
pnpm-lock.yaml |
Reflects dependency graph updates from pinning ai and lock regeneration. |
examples/multi-agent-chat/package.json |
Pins ai to 6.0.116 to eliminate version skew with @ai-sdk/react. |
examples/multi-agent-chat/src/hooks/use-threads.ts |
Avoids SSR hydration mismatch and separates persistence from thread list refresh. |
examples/multi-agent-chat/src/app/page.tsx |
Persists messages without state churn and refreshes threads only when streaming completes. |
examples/multi-agent-chat/src/app/api/chat/route.ts |
Tightens orchestrator prompt to delegate UI/visual tasks to analytics_subagent immediately. |
examples/multi-agent-chat/src/components/conversation-starters.tsx |
Reorients starters toward analytics sub-agent driven UI generation. |
examples/multi-agent-chat/src/components/chat-header.tsx |
Updates UI title to match the example’s new positioning. |
examples/multi-agent-chat/src/app/layout.tsx |
Updates app metadata title. |
examples/multi-agent-chat/README.md |
Rewrites docs to explain the multi-agent, async-generator sub-agent streaming flow. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - [OpenUI Lang overview](https://www.openui.com/docs/openui-lang/overview) — Library, Prompt Generator, Parser, Renderer | ||
| - [Vercel AI SDK docs](https://ai-sdk.dev/) — `streamText`, `useChat`, `tool()` | ||
| - [`@openuidev/react-lang` package](../../packages/react-lang) | ||
| - `[@openuidev/react-lang` package](../../packages/react-lang) |
There was a problem hiding this comment.
The link text is malformed (unbalanced backticks), so it won’t render as intended in Markdown. Update the link text to either wrap the package name in balanced backticks or remove the stray backtick.
| - `[@openuidev/react-lang` package](../../packages/react-lang) | |
| - [`@openuidev/react-lang` package](../../packages/react-lang) |
|
|
||
| export const metadata: Metadata = { | ||
| title: "Vercel AI Chat", | ||
| title: "Multi Agent Chat", |
There was a problem hiding this comment.
The title uses "Multi Agent" without a hyphen, but the README uses "Multi-Agent". Please standardize the naming across metadata/header/README to avoid inconsistent branding and searchability.
| title: "Multi Agent Chat", | |
| title: "Multi-Agent Chat", |
Fixes three runtime bugs in the
multi-agent-chatexample that caused sub-agent responses to never render, a hydration mismatch on page load, and an infinite re-render loop during streaming. Also improves the orchestrator prompt for more reliable sub-agent delegation and rewrites the README for the multi-agent architecture.Bug Fixes
1. Sub-agent responses stuck on loading spinner
The
aipackage resolved to two different versions in the workspace: the server usedai@6.0.141(from^6.0.116) while@ai-sdk/reactinternally depended onai@6.0.116. The newer version added aproviderMetadatafield totool-output-availablestream chunks, but the older client usedz.strictObject()for validation — rejecting the unknown field and silently breaking the stream. Tool parts never transitioned tooutput-available, so the UI stayed on the loading spinner.Fix: Pin
aito6.0.116inpackage.jsonto match@ai-sdk/react's internal dependency.2. Hydration mismatch in Sidebar
useThreadsinitializedthreadsstate by callinggetThreads()(which readslocalStorage) during theuseStateinitializer. On the server,localStorageis unavailable so it returned[]. On the client, it returned actual threads — causing a hydration mismatch.Fix: Initialize
threadsas[]and defer thelocalStorageread to auseEffect.3. Maximum update depth exceeded during streaming
persistMessagescalledrefreshThreads()→setThreads(getThreads())inside auseEffectthat depended onmessages. During streaming, each re-render saw a newmessagesreference fromuseSyncExternalStore, causing the effect to fire repeatedly in a tight loop.Fix:
persistMessagesnow only writes tolocalStoragewithout triggering state updates. A separate effect callsrefreshThreads()only whenstatustransitions to"ready"(streaming complete).Improvements
analytics_subagentimmediately, without text preamble.Changed Files
package.jsonaito exact6.0.116src/hooks/use-threads.tsrefreshThreadsfrompersistMessagessrc/app/page.tsxsrc/app/api/chat/route.tssrc/components/conversation-starters.tsxREADME.mdpnpm-lock.yamlaiversion