Reference Implementationsintermediate
Research
multi-source-researcher
Query multiple sources in parallel, synthesize into a coherent result.
APIs Used
ctx.call.parallel()ctx.llmctx.memory.sessionCapabilities Required
research/multi_sourceWhat this demonstrates
- 1ctx.call.parallel() to fan out to multiple data sources concurrently
- 2ctx.llm for synthesis across multiple retrieved results
- 3ctx.memory.session for intermediate results within a single execution
- 4Fan-out / fan-in parallel call pattern
Source
View on GitHubtypescript
/** * Multi-Source Researcher - Production Reference Agent * * Canon alignment: KB 105 * Demonstrates: ctx.call.parallel(), ctx.llm, ctx.memory.session * * Real use case: Query multiple sources in parallel, synthesize results. */
import { handler, withProvenanceContext } from '@human/agent-sdk';import type { ExecutionContext } from '@human/agent-sdk';
export const AGENT_ID = 'multi-source-researcher';export const VERSION = '1.0.0';export const CAPABILITIES = ['research/multi_source'];
export interface MultiSourceResearchInput { query: string; sources?: string[];}
export interface MultiSourceResearchOutput { success: boolean; synthesized_summary: string; source_count: number; provenance_id: string;}
const execute = async ( ctx: ExecutionContext, input: MultiSourceResearchInput): Promise<MultiSourceResearchOutput> => { ctx.log.info('Running multi-source research', { query: input.query });
const sources = input.sources ?? ['source_a', 'source_b', 'source_c'];
// Parallel agent calls (ctx.call.parallel) - fan out to source-specific research agents const parallelCalls = sources.map((source) => ({ agent: `research/${source}`, input: { query: input.query, source }, }));
let sourceResults: Array<{ data: { summary?: string } }>; try { sourceResults = await ctx.call.parallel<{ summary?: string }>(parallelCalls); ctx.log.info('All parallel research calls completed', { count: sourceResults.length }); } catch (err) { // Log failure and continue with partial results if possible. // In production, ctx.call.parallel may return partial results // for sources that succeeded. Here we handle total failure. ctx.log.warn('Parallel research calls failed', { error: err instanceof Error ? err.message : String(err), sources, }); sourceResults = []; }
// Store intermediate results in session memory (ctx.memory.session) // Session memory persists for the user's session, enabling follow-up queries await ctx.memory.session.set('research:query', input.query); await ctx.memory.session.set('research:sources', JSON.stringify(sources)); await ctx.memory.session.set('research:raw_count', String(sourceResults.length));
// Synthesize with LLM (ctx.llm) const sourceSummaries = sourceResults .map((r, i) => `Source ${i + 1}: ${r.data.summary ?? 'No summary available'}`) .join('\n');
const synthesisResult = await ctx.llm.complete({ prompt: [ { role: 'system', content: 'Synthesize research findings into a brief, coherent summary. Highlight agreements and contradictions between sources.', }, { role: 'user', content: `Query: ${input.query}\n\nFindings from ${sourceResults.length} sources:\n${sourceSummaries}\n\nCreate a synthesized summary.`, }, ], temperature: 0.5, maxTokens: 500, });
const provenanceId = await ctx.provenance.log( withProvenanceContext(ctx, { action: 'research:synthesized', status: 'success', input: { query: input.query }, output: { source_count: sourceResults.length }, }) );
return { success: true, synthesized_summary: synthesisResult.content, source_count: sourceResults.length, provenance_id: provenanceId, };};
export default handler({ name: AGENT_ID, id: AGENT_ID, version: VERSION, capabilities: CAPABILITIES, manifest: { operations: [ { name: 'research', description: 'Query multiple sources in parallel and synthesize results', paramsSchema: { query: { type: 'string', required: true, description: 'Research query' }, sources: { type: 'array', description: 'Source identifiers to query' }, }, resultKind: 'agent.multi-source-researcher.result', }, ], }, execute,});Run the tests
From monorepo root
$ pnpm test:agents:reference
$ pnpm test:agents:reference:verbose
The reference suite runs all 23 agents with createMockExecutionContext(), verifying every ctx.* API call and output shape.
See Also
SDK Reference
Patterns