fix: address review feedback on research aggregation example

- Fix handleProgress: use underscore event types (task_start/task_complete)
  and correct property names (event.task/event.agent) per OrchestratorEvent
- Remove Task[] annotation (Task requires id, status, createdAt, updatedAt)
- Rename 13-research-aggregation.ts to 14-research-aggregation.ts
- Remove shared memory key references from prompts (framework handles this)
- Add header note differentiating from example 07 (runTasks vs AgentPool)
This commit is contained in:
Matt Van Horn 2026-04-07 18:22:31 -07:00
parent 34ca8602d0
commit 54bfe2ed2d
1 changed files with 24 additions and 22 deletions

View File

@ -1,23 +1,27 @@
/**
* Example 13 Multi-Source Research Aggregation
* Example 14 Multi-Source Research Aggregation
*
* Demonstrates:
* Demonstrates runTasks() with explicit dependency chains:
* - Parallel execution: three analyst agents research the same topic independently
* - Dependency chain: synthesizer waits for all analysts to finish
* - Shared memory: analysts write findings, synthesizer reads and cross-references
* - Dependency chain via dependsOn: synthesizer waits for all analysts to finish
* - Automatic shared memory: agent output flows to downstream agents via the framework
*
* Compare with example 07 (fan-out-aggregate) which uses AgentPool.runParallel()
* for the same 3-analysts + synthesizer pattern. This example shows the runTasks()
* API with explicit dependsOn declarations instead.
*
* Flow:
* [technical-analyst, market-analyst, community-analyst] (parallel) synthesizer
*
* Run:
* npx tsx examples/13-research-aggregation.ts
* npx tsx examples/14-research-aggregation.ts
*
* Prerequisites:
* ANTHROPIC_API_KEY env var must be set.
*/
import { OpenMultiAgent } from '../src/index.js'
import type { AgentConfig, OrchestratorEvent, Task } from '../src/types.js'
import type { AgentConfig, OrchestratorEvent } from '../src/types.js'
// ---------------------------------------------------------------------------
// Topic
@ -34,8 +38,7 @@ const technicalAnalyst: AgentConfig = {
model: 'claude-sonnet-4-6',
systemPrompt: `You are a technical analyst. Given a topic, research its technical
capabilities, limitations, performance characteristics, and architectural patterns.
Write your findings as structured markdown. Store your analysis in shared memory
under the key "technical_findings". Keep it to 200-300 words.`,
Write your findings as structured markdown. Keep it to 200-300 words.`,
maxTurns: 2,
}
@ -44,8 +47,7 @@ const marketAnalyst: AgentConfig = {
model: 'claude-sonnet-4-6',
systemPrompt: `You are a market analyst. Given a topic, research industry adoption
rates, key companies using the technology, market size estimates, and competitive
landscape. Write your findings as structured markdown. Store your analysis in
shared memory under the key "market_findings". Keep it to 200-300 words.`,
landscape. Write your findings as structured markdown. Keep it to 200-300 words.`,
maxTurns: 2,
}
@ -55,7 +57,6 @@ const communityAnalyst: AgentConfig = {
systemPrompt: `You are a developer community analyst. Given a topic, research
developer sentiment, ecosystem maturity, learning resources, community size,
and conference/meetup activity. Write your findings as structured markdown.
Store your analysis in shared memory under the key "community_findings".
Keep it to 200-300 words.`,
maxTurns: 2,
}
@ -64,9 +65,10 @@ const synthesizer: AgentConfig = {
name: 'synthesizer',
model: 'claude-sonnet-4-6',
systemPrompt: `You are a research director who synthesizes multiple analyst reports
into a single cohesive document. Read all findings from shared memory, then:
into a single cohesive document. You will receive all prior analyst outputs
automatically. Then:
1. Cross-reference claims across reports flag agreements and contradictions
1. Cross-reference claims across reports - flag agreements and contradictions
2. Identify the 3 most important insights
3. Produce a structured report with: Executive Summary, Key Findings,
Areas of Agreement, Open Questions, and Recommendation
@ -80,11 +82,11 @@ Keep the final report to 300-400 words.`,
// ---------------------------------------------------------------------------
function handleProgress(event: OrchestratorEvent): void {
if (event.type === 'task:start') {
console.log(` [START] ${event.taskTitle}${event.agentName}`)
if (event.type === 'task_start') {
console.log(` [START] ${event.task ?? ''}${event.agent ?? ''}`)
}
if (event.type === 'task:complete') {
console.log(` [DONE] ${event.taskTitle} (${event.success ? 'OK' : 'FAIL'})`)
if (event.type === 'task_complete') {
console.log(` [DONE] ${event.task ?? ''}`)
}
}
@ -103,25 +105,25 @@ const team = orchestrator.createTeam('research-team', {
// Tasks — three analysts run in parallel, synthesizer depends on all three
// ---------------------------------------------------------------------------
const tasks: Task[] = [
const tasks = [
{
title: 'Technical analysis',
description: `Research the technical aspects of ${TOPIC}. Focus on capabilities, limitations, performance, and architecture. Store findings in shared memory as "technical_findings".`,
description: `Research the technical aspects of ${TOPIC}. Focus on capabilities, limitations, performance, and architecture.`,
assignee: 'technical-analyst',
},
{
title: 'Market analysis',
description: `Research the market landscape for ${TOPIC}. Focus on adoption rates, key players, market size, and competition. Store findings in shared memory as "market_findings".`,
description: `Research the market landscape for ${TOPIC}. Focus on adoption rates, key players, market size, and competition.`,
assignee: 'market-analyst',
},
{
title: 'Community analysis',
description: `Research the developer community around ${TOPIC}. Focus on sentiment, ecosystem maturity, learning resources, and community activity. Store findings in shared memory as "community_findings".`,
description: `Research the developer community around ${TOPIC}. Focus on sentiment, ecosystem maturity, learning resources, and community activity.`,
assignee: 'community-analyst',
},
{
title: 'Synthesize report',
description: `Read all analyst findings from shared memory (technical_findings, market_findings, community_findings). Cross-reference claims, identify key insights, flag contradictions, and produce a unified research report.`,
description: `Cross-reference all analyst findings, identify key insights, flag contradictions, and produce a unified research report.`,
assignee: 'synthesizer',
dependsOn: ['Technical analysis', 'Market analysis', 'Community analysis'],
},