mirror of
https://github.com/JackChen-me/open-multi-agent.git
synced 2026-10-19 01:29:57 -05:00
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.
This commit is contained in:
1 parent
71ac67a42f
commit
f62c7edbc3
2 files changed
+24
-3
No files matched your search
@@ -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({
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function Home() {
|
||||
|
||||
{isLoading && status === 'submitted' && (
|
||||
<div style={{ color: '#888', fontSize: 14, padding: '8px 0' }}>
|
||||
Agents are collaborating — this may take a minute...
|
||||
Agents are collaborating — this takes a few minutes...
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user