Explanation Generation
Overview
The Explanation Generation step synthesizes findings from temporal, pattern, and correlation analysis into a coherent human-readable narrative.
File: steps/explanation.step.ts
What It Does
- Aggregates findings from all prior analysis steps
- Builds context including user notes (if available)
- Generates narrative using explanation agent (or template fallback)
Input
Requires outputs from prior steps:
{
objective: string,
temporal?: TemporalOutput,
pattern?: PatternOutput,
correlation?: CorrelationOutput,
domain?: DomainOutput,
// Extended context for richer explanations
compactedRows?: Array<{ Value?: string; Kind?: string }>,
selectedNotes?: Array<{ date: string; label: string; note: string }>,
weeklySummaries?: Array<WeeklySummary>
}
Output
{
explanation: {
narrative: string, // Main explanation text
keyPoints: string[] // Bullet-point highlights
}
}
Agent Payload
The explanation agent receives rich context:
const payload = {
objective: inputData.objective,
temporal: inputData.temporal,
pattern: inputData.pattern,
correlation: inputData.correlation,
domain: inputData.domain,
dataContext: {
dayCount: number,
datasetCount: number,
seriesCount: number,
hasUserNotes: boolean,
isLargeDataset: boolean
},
userNotes?: string[], // Up to 30 pre-selected notes
weeklySummaries?: object[] // Weekly aggregations
};
Fallback Generation
When no agent is available, template-based generation:
function buildFallbackExplanation(inputData): ExplanationOutput {
const narrativeParts: string[] = [
`Objective: ${inputData.objective}`
];
if (inputData.temporal?.summary) {
narrativeParts.push(`Temporal: ${inputData.temporal.summary}`);
}
if (inputData.pattern?.matches?.length) {
narrativeParts.push(`Patterns: ${inputData.pattern.matches.join('; ')}`);
}
if (inputData.correlation?.summary) {
narrativeParts.push(`Correlations: ${inputData.correlation.summary}`);
}
const keyPoints = [
...(inputData.temporal?.insights ?? []),
...(inputData.pattern?.detectedPatterns?.map(p => p.detail) ?? []),
...(inputData.correlation?.insights ?? [])
].slice(0, 8);
return { narrative: narrativeParts.join('\n'), keyPoints };
}
Example Output
{
"explanation": {
"narrative": "Over the past 30 days, your stress levels have shown a notable upward trend, increasing from an average of 2.5 to 4.1. This coincides with a moderate decline in sleep quality. The data reveals a strong negative correlation between stress and mood (r=-0.78), suggesting that managing stress could have positive effects on your overall emotional wellbeing.\n\nYour energy levels, while showing some day-to-day variation, appear closely tied to sleep quality (r=0.71). The patterns suggest that prioritizing consistent sleep could help stabilize both energy and mood.",
"keyPoints": [
"Stress increased 64% over the analysis period",
"Strong inverse relationship between stress and mood",
"Sleep quality directly impacts next-day energy",
"Weekend stress levels are notably lower than weekdays",
"Consider stress management as primary intervention"
]
}
}
Large Dataset Handling
For datasets with many check-ins, the step uses pre-processed data:
- selectedNotes: High-value notes scored and deduplicated
- weeklySummaries: Aggregated weekly metrics
- Up to 30 notes included (vs 10 for standard datasets)
Skip Conditions
This step is skipped if:
stepPlanexists and doesn't include'explanation'