Narrative Agent Split Change Breakdown
Created: 2026-05-29 07:32 UTC
Summary
This change splits the current narrative stage into two explicit contracts and two workflow phases:
- a preview-only narrative pass that produces reviewable voiceover sentences
- a post-approval expansion pass that derives scene semantics needed by visuals, slides, direction, and compile
The main architectural goal is to make narrative-review the real human approval boundary instead of a UI pause over a payload that already contains downstream scene semantics. The current codebase already has the suspend/resume boundary, but the narrative agent, schema, persisted review payload, and workflow step ordering still treat preview text and scene semantics as one artifact.
Target Flow
flowchart TD
prepare["prepare-presentation-run"] --> intakeGate{"Need IntentAgent?"}
intakeGate -->|No, request already explicit| ragGate
intakeGate -->|Yes| intent["intent-agent"]
intent --> ragGate
ragGate{"Need KnowledgeOrchestrator?"} -->|uploaded-only| rag["retrieve persisted/uploaded RAG context"]
ragGate -->|mixed or remote sources| knowledge["ragWorkflow"]
knowledge --> rag
rag --> preview["generatePreviewSentences"]
preview --> suspend["narrative-review suspend with preview-only payload"]
suspend --> approve["approved preview sentences"]
approve --> expand["expandSceneDetails"]
expand --> visuals["visualsWorkflow"]
visuals --> slides["slidesWorkflow"]
slides --> direction["directionWorkflow"]
direction --> compile["compile"]
Current Touchpoints
src/mastra/agents/presentationvideo-agent-contracts.tsCurrentnarrativedefinition still advertisesagent.narrative.generateScenesreturningVoiceoverScriptJson/NarrativeSceneList.src/mastra/agents/narrative.agent.tsCurrent narrative agent description says it generates scene-level voiceover and semantics together.src/mastra/schemas/scene.schema.tsnarrativeSceneSchemacurrently bundles preview fields with semantic-expansion fields such ascaption,sceneQuery,recommendedVisualType, andvisualGenerationPrompt.src/mastra/workflows/sub/narrative.workflow.tsCurrent subworkflow builds one prompt, runs one agent step, and normalizes one combinedNarrativeSceneList.src/mastra/workflows/presentationvideo.workflow.tsCurrent master workflow already suspends atnarrative-review, but the suspend payload stores fullnarrativeScenesrather than a preview-only contract.src/mastra/workflows/sub/rag.workflow.tsCurrent knowledge flow always runs theknowledge-agentbefore collecting sources, even for uploaded-only runs.src/mastra/tools/presentation/index.tspersistNarrativeReviewToolpersists fullnarrativeScenesintopresentationStatusJson.setup.narrativeReview.src/app/(frontend)/app/presentation/actions.tsgeneratePresentationNarrativePreviewparses the suspended payload asvoiceoverPreview + narrativeScenes, andcontinuePresentationFromNarrativeresumes with approved scenes plus identity selection.src/lib/anuva/contracts-v1.tsVoiceoverScriptJsonalready exists as a preview-friendly voiceover-only contract and is a likely candidate for one side of the split.docs/core/PresentationVideoWorkflow.md,docs/state/WorkflowMap.md,docs/state/ServerActionsMap.mdCurrent docs already describenarrative-reviewas a VO preview boundary, but code-level contracts still over-deliver richer scene semantics before approval.
Current Behavior Snapshot
narrativeWorkflowcurrently returns aNarrativeSceneListwhere each scene includes both:- preview fields:
sceneId,index,text,estimatedDurationSec - downstream semantic fields:
caption,sceneQuery,recommendedVisualType,visualGenerationPrompt presentationVideoWorkflowsuspends after narrative generation, but the review payload persists the full scene list rather than a narrower preview artifact.ragWorkflowalways invokesKnowledgeOrchestratorfirst, even when the source set may already deterministically implyuploadedonly.intent-agentalways runs in the master workflow, even when the create action already passes stablename,prompt, and VO guidance.visualsWorkflow,slidesWorkflow, anddirectionWorkflowall currently consume the post-narrativescenesobject as if semantic expansion is already complete.
Grouped Changes
1. Split the narrative contract into preview and expansion artifacts
Explanation:
The current NarrativeSceneList is doing two jobs. It acts as the UI approval payload and the downstream semantic scene model at the same time. That makes narrative-review a weak approval boundary because captions, scene queries, and visual prompts are already locked in before the user approves the spoken script.
The change should introduce explicit schema boundaries for:
- preview sentences only
- expanded scene details
- final voiceover JSON where needed by compilation and runtime contracts
Likely affected code:
src/mastra/schemas/scene.schema.tssrc/lib/anuva/contracts-v1.tssrc/lib/anuva/voiceover-script.tssrc/mastra/agents/presentationvideo-agent-contracts.ts
2. Split the narrative stage into two agent actions with a hard approval boundary
Explanation:
The current agent.narrative.generateScenes step should be decomposed into:
- a preview generation action such as
agent.narrative.generatePreviewSentences - an expansion action such as
agent.narrative.expandSceneDetails
The key constraint is that expansion must treat approved preview sentences as hard input. It should fill missing semantic fields without re-authoring the approved voiceover text unless that is an explicit product capability.
Likely affected code:
src/mastra/agents/narrative.agent.tssrc/mastra/agents/presentationvideo-agent-contracts.tssrc/mastra/workflows/sub/narrative.workflow.tssrc/mastra/workflows/presentationvideo.workflow.ts
3. Narrow the narrative-review suspend payload and persisted review state
Explanation:
The current suspend payload and persistNarrativeReviewTool both store narrativeScenes, which already include downstream semantic fields. After the split, the suspend state should persist only the preview artifact plus any metadata needed to safely resume expansion. That keeps the review UI aligned with the actual approved artifact and reduces drift between what the user approved and what downstream workflows consume.
Likely affected code:
src/mastra/workflows/presentationvideo.workflow.tssrc/mastra/tools/presentation/index.tssrc/app/(frontend)/app/presentation/actions.ts- any types describing
presentationStatusJson.setup.narrativeReview
4. Add preview-mode branch rules for skipping intent and knowledge planning
Explanation:
The requested product flow wants deterministic shortcuts:
- skip
IntentAgentwhenvideoName,description, and VO guidance are already explicit enough - skip
KnowledgeOrchestratorwhen the source set is uploaded-only
This should not be implemented as ad hoc UI branching alone. The workflow needs explicit gating rules so API, worker, and CLI callers can share the same behavior. The implementation plan will need to define whether the skip logic is:
- derived from input heuristics inside
presentationVideoWorkflow - encoded as explicit workflow flags
- or handled by a
prepareRunStepnormalization output that later steps consume
Likely affected code:
src/mastra/workflows/presentationvideo.workflow.tssrc/mastra/workflows/sub/rag.workflow.tssrc/mastra/tools/presentation/index.tssrc/app/(frontend)/app/presentation/actions.ts
5. Retarget downstream workflows to consume expanded scene details, not preview payloads
Explanation:
visualsWorkflow, slidesWorkflow, directionWorkflow, compile, and scene persistence currently rely on the narrative output already containing semantic scene fields. After the split, those consumers must clearly depend on the post-approval expanded artifact, while preview-only steps and UI payloads depend on the narrower contract.
This is also where reveal or slide-planning hints need ownership clarification. If those hints are still narrative-owned, they belong in expansion. If they are really slide-planning responsibilities, they should move there explicitly rather than remaining implied in the narrative payload.
Likely affected code:
src/mastra/workflows/sub/visuals.workflow.tssrc/mastra/workflows/sub/slides.workflow.tssrc/mastra/workflows/sub/direction.workflow.tssrc/mastra/tools/compiler/index.tssrc/mastra/tools/presentation/index.ts
6. Align docs and workflow maps with the real contract boundary
Explanation:
Current docs already describe narrative-review as a VO preview checkpoint, but the code still persists a richer scene payload. After the implementation, the docs should explicitly distinguish:
- preview-generation contract
- approved preview persistence
- expansion contract
- downstream consumers of expanded scene details
Likely affected docs:
docs/core/PresentationVideoWorkflow.mddocs/state/WorkflowMap.mddocs/state/ServerActionsMap.mddocs/state/KnownGaps.md- this change folder’s
ImplementationPlan.mdandImplementationLog.md
Affected Product Surfaces
- Create presentation flow
- VO Script Preview step
Go To Scene Detailsresume path- Mastra narrative and RAG subworkflows
- persisted
presentationStatusJson.setup.narrativeReviewreview state - downstream scene semantic generation for visuals, slides, direction, and compile
Likely Affected Code Paths
src/mastra/agents/presentationvideo-agent-contracts.tssrc/mastra/agents/narrative.agent.tssrc/mastra/workflows/sub/narrative.workflow.tssrc/mastra/workflows/sub/rag.workflow.tssrc/mastra/workflows/presentationvideo.workflow.tssrc/mastra/schemas/scene.schema.tssrc/mastra/schemas/config.schema.tssrc/mastra/tools/presentation/index.tssrc/app/(frontend)/app/presentation/actions.tssrc/lib/anuva/contracts-v1.tssrc/lib/anuva/voiceover-script.ts- tests covering narrative preview, resume, and workflow contract behavior
Risks And Dependencies
- Semantic drift: Expansion can diverge from the approved preview unless the preview text is passed through as immutable or strongly constrained input.
- Contract overlap: Introducing both preview and expanded scene schemas can create ambiguity unless each downstream consumer has one clear contract owner.
- Workflow branching complexity: Skip rules for intent and knowledge planning can become fragile if they are based on loose heuristics rather than explicit readiness criteria.
- Persistence compatibility:
Existing UI and server actions already parse
narrativeScenesfrom suspended payloads and persisted review state, so schema changes will ripple through resume behavior. - Slide/reveal ownership: Some downstream assumptions may still treat narrative output as the place where reveal hints originate.
- Test coverage gaps: Current docs describe the review boundary more cleanly than the contracts implement it, which is usually a sign that tests may not yet fully pin the desired split behavior.
Out Of Scope
- Implementing the split in code during this planning phase
- Reworking Step 3 scene editing beyond what is required to consume the new approved-preview artifact
- Redesigning final audio generation, render handoff, or scene edit partial recompilation outside the narrative boundary change
- Broad Payload collection redesign unless new persistent fields are proven necessary
- General Mastra platform upgrades unrelated to the narrative split
Open Questions
Q1. Should the preview approval UI allow sentence-level edits before approval, or should it remain approve/regenerate-only for this change?
Answer: It should remain approve/regenerate-only for this change.
Q2. Should the post-approval expansion artifact be a new schema such as NarrativeSceneDetails, or should it normalize directly into the existing VoiceoverScriptJson plus separate scene-semantic structures?
Answer: Use a new post-approval schema such as NarrativeSceneDetails. VoiceoverScriptJson should remain the narrow voiceover-only contract for preview and approved script persistence. The expansion step should output a separate schema that preserves the approved sentences while adding caption, sceneQuery, recommendedVisualType, visualGenerationPrompt, and any other narrative-owned semantic fields needed downstream.
Q3. Should the workflow skip IntentAgent and KnowledgeOrchestrator through explicit input flags, or should it infer skipping entirely from normalized request/source shape?
Answer: Skip behavior should be inferred from normalized request and source shape, not driven primarily by caller-supplied flags. The workflow should decide whether intent and knowledge planning are necessary based on deterministic criteria derived during prepareRunStep or equivalent normalization. Internal booleans may still be produced for downstream branching, but they should be workflow-owned derived state so UI, API, CLI, and worker entry points all behave consistently.
Q4. Are sceneQuery, recommendedVisualType, and visualGenerationPrompt definitely expansion-owned, or should some of those fields move to visualsWorkflow instead of remaining part of narrative output?
Answer: sceneQuery should remain expansion-owned because it is a semantic retrieval/grounding field derived directly from the approved narrative. recommendedVisualType and visualGenerationPrompt should move to visualsWorkflow rather than remain narrative-owned. That creates a cleaner boundary where narrative expansion owns scene meaning and visualsWorkflow owns visual execution strategy.
Q5. When resuming from narrative-review, should the workflow accept edited approved preview sentences from the UI, or only the original generated preview payload plus an approval boolean?
Answer: For this change, resume should accept only the original generated preview payload plus approval and identity selections, not user-edited sentences.