Narrative Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Narrative Engine is a specialized component within the M31 Autonomous system designed to transform low-level technical events and tool executions into human-readable progress descriptions. It serves as the primary translation layer between the internal workflow states—such as file reads, LLM calls, and bash commands—and the user-facing Terminal User Interface (TUI). By categorizing and templating these events, the engine provides users with a cohesive narrative of the AI's "thought process" and active operations.
The engine handles events from all phases of the M31A workflow, ensuring that technical metrics and raw logs are presented with appropriate priority and visual formatting. This system is critical for maintaining transparency during autonomous execution, allowing the user to follow complex implementation steps without parsing raw debug logs.
Sources: README.md:144-146, internal/engine/narrative/templates.go:11-15
Architecture and Core Logic
The Narrative Engine operates by consuming RawEvent data and processing it through a TemplateResolver. This resolver maps specific NarrativeType identifiers to pre-defined templates, which are then populated with dynamic metadata from the event.
Event Flow
The data flow follows a specific pipeline from the workflow engine to the TUI display:
The diagram shows the transformation of a technical message into a user-facing narrative object.
Sources: internal/ui/tui/narrative_test.go:106-120, internal/engine/narrative/templates.go:65-90
Component Overview
| Component | Description |
|---|---|
| TemplateResolver | Stateless component that maps NarrativeType to text templates and extracts parameters from RawEvent data. |
| NarrativeObject | The final structured output containing the rendered text, category, priority, and display instructions. |
| NarrativeType | A unique key identifying a specific kind of event (e.g., NarrativeReadingFile, NarrativeTestsPassed). |
| Category | Functional grouping used for TUI labels (e.g., Orienting, Executing, Alerting). |
Sources: internal/engine/narrative/templates.go:11-30, internal/ui/tui/narrative_test.go:189-204
Template Resolution and Rendering
The engine uses a placeholder substitution system to inject metadata into narrative strings. This allows for dynamic messages such as "Reading {file}" or "Verification passed ({test_count} tests)".
Template Mapping
Templates are registered with specific metadata that governs their behavior in the UI:
- Priority: Determines the importance (e.g.,
PriorityPhase,PriorityTask,PriorityActionRequired). - Display: Controls where the narrative appears (e.g.,
DisplaySidebar,DisplayToast,DisplayBoth). - Duration: Specifies how long a message should persist if it is transient.
tr.templates[NarrativeTestsPassed] = templateEntry{
template: "Verification passed ({test_count} tests)",
category: CategoryVerifying,
priority: PriorityPhase,
display: DisplayBoth,
duration: 3000,
}
Sources: internal/engine/narrative/templates.go:73-86, internal/engine/narrative/templates.go:210-216
Dynamic Placeholder Substitution
The render function performs simple {placeholder} substitution. If a string value is not found in the event data, the engine attempts to fetch an integer value or preserves the placeholder as a fallback.
Sources: internal/engine/narrative/templates.go:93-118
Narrative Categories and Phase Mapping
Narratives are organized into logical categories that align with the seven-phase workflow of M31A.
| Category | Typical Events | TUI Label |
|---|---|---|
| Orienting | Project analysis, preflight checks, session restoration. | init |
| Understanding | Codebase mapping, reading project structure. | info |
| Executing | Implementing tasks, writing files, running commands. | exec |
| Verifying | Running tests, build status, verification results. | verify |
| Recovering | Self-healing attempts, recovery success/failure. | heal |
| Shipping | Preparing commits, changelog generation. | ship |
| Alerting | Provider errors, loop detection, configuration reloads. | alert |
Sources: internal/engine/narrative/templates.go:121-280, internal/ui/tui/narrative_test.go:195-200
TUI Integration and State Management
In the TUI, the NarrativeState maintains the current active narrative and a history of previous events.
State Transitions
When a new NarrativeObject is received, the TUI updates the Active slot and moves the previous active object into the History buffer. This buffer is capped by MaxHist to prevent memory bloat.
The sequence shows how narratives move from creation to the TUI state buffer.
Sources: internal/ui/tui/narrative_test.go:17-50, internal/ui/tui/narrative_test.go:110-120
Visual Rendering
The narrative engine provides data for two main TUI components:
- Sidebar: A vertical list of recent activity and the current task.
- Footer: A status bar showing the most recent high-priority activity.
Sources: internal/ui/tui/narrative_test.go:158-185
Demonstration and Walkthrough Generation
Beyond real-time updates, the Narrative Engine concepts extend into the "Ship" phase. The system generates a demonstration walkthrough—a post-completion document—using the same event history and task results. This document summarizes what was built, architectural decisions made, and technical file paths modified during the session.
Sources: internal/engine/workflow/ship.go:410-440, internal/engine/workflow/ship.go:452-475
Summary
The Narrative Engine is the bridge between the autonomous technical execution of M31A and the human operator. By utilizing a robust templating system and a priority-based display logic, it ensures that every action taken by the AI is transparently communicated through the terminal interface. This module allows the project to maintain its "terminal-native" philosophy while providing a rich, narrative-driven user experience.
Sources: README.md:144-146, internal/engine/narrative/templates.go:11-15