Reference Implementations

Data

report-generator

beginner

Generate daily analytics reports from DB, cache templates, write output.

APIs Used

ctx.dbctx.memoryctx.files

Capabilities Required

reporting/generate

What this demonstrates

  • 1ctx.db.query() for querying aggregated analytics data
  • 2ctx.memory.execution for template caching within a single invocation
  • 3ctx.files.write() to write the final report output
  • 4Reporting pipeline: query → cache template → render → write
typescript
/**
* Report Generator - Production Reference Agent
*
* Canon alignment: KB 105
* Demonstrates: ctx.db, ctx.memory, ctx.files
*
* Real use case: Generate daily analytics reports from DB,
* cache report config in memory, write output to files.
*/
import { handler, withProvenanceContext } from '@human/agent-sdk';
import type { ExecutionContext } from '@human/agent-sdk';
export const AGENT_ID = 'report-generator';
export const VERSION = '1.0.0';
export const CAPABILITIES = ['reporting/generate'];
export interface ReportGeneratorInput {
report_type: string;
date?: string;
}
export interface ReportGeneratorOutput {
success: boolean;
report_path: string;
row_count: number;
provenance_id: string;
}
const execute = async (
ctx: ExecutionContext,
input: ReportGeneratorInput
): Promise<ReportGeneratorOutput> => {
ctx.log.info('Generating report', { type: input.report_type });
const date = input.date ?? new Date().toISOString().slice(0, 10);
// Query DB (ctx.db())
const db = await ctx.db();
const rows = (await db.query(
`SELECT * FROM metrics WHERE date = $1 LIMIT 1000`,
[date]
)) as Array<Record<string, unknown>>;
// Cache report metadata in persistent memory (ctx.memory.persistent)
const reportMetaKey = `report:${input.report_type}:last`;
await ctx.memory.persistent.set(
reportMetaKey,
JSON.stringify({
report_type: input.report_type,
date,
row_count: rows.length,
generated_at: new Date().toISOString(),
})
);
// Write report file (ctx.files)
const reportPath = `reports/${input.report_type}-${date}.json`;
await ctx.files.writeText(
reportPath,
JSON.stringify({ date, row_count: rows.length, sample: rows.slice(0, 5) }, null, 2)
);
const provenanceId = await ctx.provenance.log(
withProvenanceContext(ctx, {
action: 'report:generated',
status: 'success',
input: { report_type: input.report_type, date },
output: { report_path: reportPath, row_count: rows.length },
})
);
return {
success: true,
report_path: reportPath,
row_count: rows.length,
provenance_id: provenanceId,
};
};
export default handler({
name: AGENT_ID,
id: AGENT_ID,
version: VERSION,
capabilities: CAPABILITIES,
manifest: {
operations: [
{
name: 'generate',
description: 'Generate daily analytics report from DB for the given report type and date',
paramsSchema: {
report_type: { type: 'string', required: true, description: 'Report type identifier' },
date: { type: 'string', description: 'Report date (default: today)' },
},
resultKind: 'agent.report-generator.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