From f62c7edbc3a2dfede1ab3d0dd6bab34a918660db Mon Sep 17 00:00:00 2001 From: Jack Chen Date: Mon, 7 Sep 2026 18:04:52 +0800 Subject: [PATCH] fix(examples): keep the Vercel AI SDK route on the team topology (#589) Anyone following this example got a blank article back. The route read the team's answer from agentResults.get('coordinator'), but a goal this short is routed to the single-agent path, where the orchestrator publishes the answer under the winning agent's own name instead. The lookup returned undefined, the ?? '' fallback swallowed it, and the app streamed an empty Team Output section. - Pass an explicit mode: 'team' so the demo runs the topology this example teaches. Explicit mode outranks the router. - Read the terminal agent as a fallback so the route returns the article under either topology. - Check success before streaming. A plan validation failure leaves the coordinator's unparsed plan under the 'coordinator' key, so testing for an empty string would stream planning scratch as the article. - Raise maxDuration to 360 and say "a few minutes" in the placeholder, to match the measured team path: seven runs on deepseek-v4-flash took 137 to 311 seconds, median 217, from one machine. --- .../with-vercel-ai-sdk/app/api/chat/route.ts | 25 +++++++++++++++++-- .../with-vercel-ai-sdk/app/page.tsx | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/core/examples/integrations/with-vercel-ai-sdk/app/api/chat/route.ts b/packages/core/examples/integrations/with-vercel-ai-sdk/app/api/chat/route.ts index de4264d..5b3d73b 100644 --- a/packages/core/examples/integrations/with-vercel-ai-sdk/app/api/chat/route.ts +++ b/packages/core/examples/integrations/with-vercel-ai-sdk/app/api/chat/route.ts @@ -3,7 +3,7 @@ import { createOpenAICompatible } from '@ai-sdk/openai-compatible' import { OpenMultiAgent } from '@open-multi-agent/core' import type { AgentConfig } from '@open-multi-agent/core' -export const maxDuration = 120 +export const maxDuration = 360 // --- DeepSeek via OpenAI-compatible API --- const DEEPSEEK_BASE_URL = 'https://api.deepseek.com' @@ -69,9 +69,30 @@ export async function POST(req: Request) { const teamResult = await orchestrator.runTeam( team, `Research and write an article about: ${lastText}`, + // Execution routing sends a short goal down the single-agent path. An + // explicit mode outranks the router, so this keeps the demo on the + // researcher + writer team topology. + { mode: 'team' }, ) - const teamOutput = teamResult.agentResults.get('coordinator')?.output ?? '' + // The team path publishes the synthesized answer under 'coordinator'; the + // single-agent path publishes it under the winning agent's own name. Read + // both so this route survives whichever topology runs. + const teamOutput = + teamResult.agentResults.get('coordinator')?.output + ?? teamResult.agentResults.get('writer')?.output + ?? '' + + // A failed run still leaves the coordinator's unparsed plan under + // 'coordinator', so check `success` rather than testing for an empty string. + if (!teamResult.success || teamOutput === '') { + return new Response( + `The agent team did not produce an article: ${ + teamResult.errorInfo?.message ?? teamResult.status?.code ?? 'unknown error' + }`, + { status: 500 }, + ) + } // --- Phase 2: Stream result via Vercel AI SDK --- const result = streamText({ diff --git a/packages/core/examples/integrations/with-vercel-ai-sdk/app/page.tsx b/packages/core/examples/integrations/with-vercel-ai-sdk/app/page.tsx index f51ab6f..b5dfedf 100644 --- a/packages/core/examples/integrations/with-vercel-ai-sdk/app/page.tsx +++ b/packages/core/examples/integrations/with-vercel-ai-sdk/app/page.tsx @@ -50,7 +50,7 @@ export default function Home() { {isLoading && status === 'submitted' && (
- Agents are collaborating — this may take a minute... + Agents are collaborating — this takes a few minutes...
)}