Skip to main content
Enrichments attach key-value metadata to sessions. They appear as a table on the session page and can power dashboard filters. Register enrichments with app.enrich() in your evals file:
app.enrich('session-overview', ({ stats }) => ({
  'Turns': stats.turnCount,
  'Tool Calls': stats.toolCallCount,
  'Models': stats.models.join(', ') || 'none',
}));

Return type

Enrichments return a flat key-value map:
type EnrichmentResult = Record<string, string | number | boolean>;
Each key becomes a row label in the enrichments panel on the session page.

Context

Enrichments receive the same EvalContext as evals:
FieldTypeDescription
entriesobject[]Raw JSONL entries (session + subagents)
statsEvalLogStatsComputed stats
projectNamestringProject name
sessionIdstringSession ID
sourcestring"session" or "agent-{id}"

Examples

Session overview

app.enrich('overview', ({ stats }) => ({
  'Turns': stats.turnCount,
  'Tool Calls': stats.toolCallCount,
  'Subagents': stats.subagentCount,
  'Duration': stats.duration,
  'Models': stats.models.join(', ') || 'none',
}));

Token and cost breakdown

app.enrich('token-usage', ({ entries }) => {
  const input = entries.reduce((s, e) => s + (e.usage?.input_tokens || 0), 0);
  const output = entries.reduce((s, e) => s + (e.usage?.output_tokens || 0), 0);
  return {
    'Input Tokens': input,
    'Output Tokens': output,
    'Total Tokens': input + output,
    'Est. Cost': `$${((input * 0.003 + output * 0.015) / 1000).toFixed(4)}`,
  };
});

Conditional enrichment

Use condition to skip an enrichment when it doesn’t apply. Skipped enrichments show as “skipped” in the UI.
// Only compute when errors exist
app.enrich('error-analysis',
  ({ entries }) => {
    const errors = entries.filter(e => e.is_error === true);
    return {
      'Total Errors': errors.length,
      'Error Rate': `${((errors.length / entries.length) * 100).toFixed(1)}%`,
    };
  },
  { condition: ({ entries }) => entries.some(e => e.is_error === true) }
);

Subagent metadata

app.enrich('subagent-info',
  ({ stats }) => ({
    'Subagent Count': stats.subagentCount,
  }),
  { condition: ({ stats }) => stats.subagentCount > 0 }
);

Options

OptionTypeDefaultDescription
conditionConditionFunction-Per-enrichment gate. Returns false → skipped. Throws → errored.
scope'session' | 'subagent' | 'both''session'Whether to run at session level, subagent level, or both
subagentTypestring-Only run for subagents of this type (e.g. 'Explore')

Caching

Enrichment results are cached per session, the same way eval results are. See Caching.