Reference Implementationsbeginner
Business
expense-report-generator
Aggregate expenses by category, generate formatted reports, cache templates.
APIs Used
ctx.dbctx.filesctx.memoryctx.llmCapabilities Required
finance/expense/reportWhat this demonstrates
- 1ctx.db.query() to aggregate expense records from a database
- 2ctx.memory for caching report templates across invocations
- 3ctx.files.write() to persist report output
- 4ctx.llm for narrative summary generation
Source
View on GitHubtypescript
/** * Expense Report Generator - Production Reference Agent * * Canon alignment: KB 105 (Agent SDK) * Demonstrates: ctx.db, ctx.files, ctx.memory, ctx.llm * * Real use case: Aggregate expenses by category, generate PDF-style reports, * cache report templates in memory. */
import { handler, withProvenanceContext } from '@human/agent-sdk';import type { ExecutionContext } from '@human/agent-sdk';
export const AGENT_ID = 'expense-report-generator';export const VERSION = '1.0.0';export const CAPABILITIES = ['finance/expense/report'];
export interface ExpenseReportInput { /** Date range start (ISO) */ start_date: string; /** Date range end (ISO) */ end_date: string; /** Output format */ format?: 'markdown' | 'text';}
export interface ExpenseReportOutput { success: boolean; report_path: string; total_amount: number; categories: Array<{ name: string; amount: number; count: number }>; provenance_id: string;}
const execute = async ( ctx: ExecutionContext, input: ExpenseReportInput): Promise<ExpenseReportOutput> => { ctx.log.info('Generating expense report', { start: input.start_date, end: input.end_date, });
// Fetch aggregated data from DB (ctx.db()) const db = await ctx.db(); const rows = (await db.query( `SELECT category, SUM(amount) as total, COUNT(*) as count FROM expenses WHERE date >= $1 AND date <= $2 GROUP BY category`, [input.start_date, input.end_date] )) as Array<{ category: string; total: number; count: number }>;
const categories = rows.map((r) => ({ name: r.category, amount: Number(r.total), count: Number(r.count), })); const totalAmount = categories.reduce((sum, c) => sum + c.amount, 0);
// Cache report config in memory (ctx.memory.persistent) const lastReportKey = `expense_report:last_config`; await ctx.memory.persistent.set(lastReportKey, JSON.stringify({ start_date: input.start_date, end_date: input.end_date, generated_at: new Date().toISOString(), }));
// Generate report content (ctx.llm with Message[] - best practice for structured prompts) const summary = await ctx.llm.complete({ prompt: [ { role: 'system', content: 'You are a financial analyst. Summarize expense data in one concise sentence.', }, { role: 'user', content: `Summarize: $${totalAmount.toFixed(2)} total across ${categories.length} categories (${categories.map((c) => `${c.name}: $${c.amount.toFixed(2)}`).join(', ')}).`, }, ], temperature: 0.3, maxTokens: 100, });
const format = input.format ?? 'markdown'; let reportContent: string;
if (format === 'markdown') { reportContent = `# Expense Report\n\n${summary.content}\n\n`; reportContent += `**Total:** $${totalAmount.toFixed(2)}\n\n`; reportContent += '| Category | Amount | Count |\n|----------|--------|------|\n'; for (const c of categories) { reportContent += `| ${c.name} | $${c.amount.toFixed(2)} | ${c.count} |\n`; } } else { reportContent = `Expense Report\n\n${summary.content}\n\nTotal: $${totalAmount.toFixed(2)}\n\n`; for (const c of categories) { reportContent += `${c.name}: $${c.amount.toFixed(2)} (${c.count} items)\n`; } }
// Write report to files (ctx.files) const reportPath = `reports/expense-${input.start_date}-${input.end_date}.${format === 'markdown' ? 'md' : 'txt'}`; await ctx.files.writeText(reportPath, reportContent);
const provenanceId = await ctx.provenance.log( withProvenanceContext(ctx, { type: 'expense_report:generated', status: 'success', metadata: { input: { start_date: input.start_date, end_date: input.end_date }, output: { report_path: reportPath, total_amount: totalAmount }, }, }) );
return { success: true, report_path: reportPath, total_amount: totalAmount, categories, provenance_id: provenanceId, };};
export default handler({ name: AGENT_ID, id: AGENT_ID, version: VERSION, capabilities: CAPABILITIES, manifest: { operations: [ { name: 'generate', description: 'Aggregate expenses by category and generate a report for the date range', paramsSchema: { start_date: { type: 'string', required: true, description: 'Date range start (ISO)' }, end_date: { type: 'string', required: true, description: 'Date range end (ISO)' }, format: { type: 'string', description: 'Output format: markdown or text' }, }, resultKind: 'agent.expense-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