Reference Implementations

Research

multi-source-researcher

intermediate

Query multiple sources in parallel, synthesize into a coherent result.

APIs Used

ctx.call.parallel()ctx.llmctx.memory.session

Capabilities Required

research/multi_source

What 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
typescript
/**
* 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