Skip to content

Presentation Video UI Update Implementation Log

Created: 2026-05-20 07:06 UTC Updated: 2026-05-21 02:49 UTC

Status

Implemented. The setup flow now generates a VO Script Preview through the Mastra narrative path, suspends at narrative-review, and resumes downstream scene-detail generation from Go To Scene Details.

flowchart LR
  setup["Setup fields"] --> preview["generatePresentationNarrativePreview"]
  preview --> suspend["narrative-review suspended"]
  suspend --> review["VO Script Preview"]
  review --> resume["continuePresentationFromNarrative"]
  resume --> editor["Scene Editor"]

Decisions

  • Kept Payload schema unchanged and stored narrative review state in presentationStatusJson.setup.narrativeReview.
  • Made Set/Bot optional until after narrativeWorkflow; selected Set, Bot, and default Brand Kit are persisted on resume.
  • Kept generatePresentationVideoScenesWithWorkflow as a compatibility path by auto-resuming the new narrative review boundary for older callers.
  • Removed setup-stage Visuals from the UI and generation payload, while leaving scene-level upload, library selection, replacement, and removal paths intact.
  • Implemented the VO Script assistant as setup guidance editing plus narrative preview regeneration; it does not introduce a separate LLM refinement action before rerunning narrative.
  • Aligned the OpenAI web search tool key with the native Responses API tool name so Web Sources can be ingested during VO Script Preview generation without being serialized as a function tool choice.
  • Made the Go To Scene Details gate use the effective first available Set/Bot when content-store options have loaded but the auto-select state has not settled yet.
  • Preserved workflow metadata through narrativeWorkflow and added resume-step fallbacks from prepare-presentation-run, so narrative-review can persist selected identity after approval.
  • Changed web research ingestion to build RAG documents from native web-search text and citations instead of requiring structured model output, and surfaced failed workflow starts with their real error message.
  • Guarded Scene Editor background server-action polling so generation-status or RAG-status transport failures render as page errors instead of crashing the client after scenes are created.
  • Aligned the app-action presentation compiler with the Mastra compiler by using generic as the public config presentation.useCaseId fallback when no video use case is selected.
  • Updated the video detail dynamic route to await Next.js 15 params before reading id.
  • Fixed deep-linked Presentation Creation hydration so React Strict Mode cleanup does not cancel the first project load and then skip the retry for Step 2 or Step 3 links.
  • Fixed the video detail page hydration mismatch by replacing locale-dependent created/updated date rendering with a deterministic UTC formatter.
  • Hardened Presentation Creation and Scene Editor server-action calls so transport failures such as Failed to fetch render as page/panel errors instead of crashing through the Next.js overlay.
  • Surfaced persisted scene generation failures from compilerIssues as scene-level errors, including visual generation failures that previously only appeared as the generic job message.
  • Reduced Recent Videos and video detail Payload reads to direct relation hydration (depth: 1) to avoid walking nested presentation-compilation/media/source relationship graphs during server render.
  • Moved projectId deep-link hydration for Presentation Creation Step 2/3 into the server route so opening /app/create/presentation?projectId=...&step=3 no longer depends on an initial browser fetchServerAction call.
  • Added use case and content-store options to the server hydration payload and suppressed automatic selected-source status polling for the server-hydrated source set, reducing initial deep-link client server-action POSTs.
  • Routed Gemini/Imagen image generation models through the AI SDK Google image provider and aligned metering, queued visual-generation metadata, and regenerate-image action metadata to record the resolved image provider.
  • Switched the configured Google image model from the unsupported Gemini preview string to imagen-4.0-generate-001, because the AI SDK image provider uses Google's image predict endpoint rather than Gemini native generateContent image output.
  • Narrowed Presentation Creation deep-link hydration and RAG status refreshes to fetch only the presentation's selected RAG source IDs, and reduced setup-page relation depth for getPresentation, to avoid pulling the entire workspace source library during Step 2/3 loads.
  • Added a Google image-model fallback so stale runtime references to unsupported Gemini image-preview models retry with imagen-4.0-generate-001 instead of failing Scene Editor image regeneration.
  • Switched shared image generation back to OpenAI GPT Image after the hosted Google account rejected Imagen usage on the current plan.
  • Changed Go To Scene Details for existing presentations without an active suspended narrative run to start a fresh workflow-backed scene generation + compilation pass, replacing prior scene values instead of only recompiling the existing snapshot.
  • Stopped getPresentationGenerationStatus polling from rewriting scenes, compilation snapshots, and presentation records on every 2.5s client poll; it now returns derived scene/job state as a read-only status response.

Files Changed

  • Code:
  • src/app/(frontend)/app/presentation/actions.ts
  • src/app/(frontend)/app/videos/[id]/page.tsx
  • src/lib/ai/generate-image.ts
  • src/lib/ai/model-config.ts
  • src/lib/coins/metering.ts
  • src/components/anuvax/presentation-video/presentation-video-page.tsx
  • src/mastra/schemas/config.schema.ts
  • src/mastra/workflows/presentationvideo.workflow.ts
  • src/mastra/workflows/sub/narrative.workflow.ts
  • src/mastra/workflows/sub/rag.workflow.ts
  • src/mastra/tools/presentation/index.ts
  • src/mastra/tools/web/index.ts
  • Tests:
  • tests/integration/helpers/mock-runtime.ts
  • tests/integration/helpers/presentation-harness.ts
  • tests/integration/presentation-compile.integration.test.ts
  • tests/unit/generate-image-provider.test.ts
  • tests/unit/mastra-web-search-tool.test.ts
  • tests/e2e/presentation-video.e2e.spec.ts
  • Docs:
  • docs/core/PresentationVideoWorkflow.md
  • docs/state/CurrentImplementationMap.md
  • docs/state/ServerActionsMap.md
  • docs/state/WorkflowMap.md
  • docs/changes/2026-05-20-0706-presentation-video-ui-update/ImplementationPlan.md
  • docs/changes/2026-05-20-0706-presentation-video-ui-update/ImplementationLog.md

Verification

  • pnpm exec biome check --write ... on touched code/test files: passed.
  • pnpm typecheck: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/mastra-web-search-tool.test.ts: passed, 4 tests.
  • pnpm exec biome check src/mastra/tools/web/index.ts tests/unit/mastra-web-search-tool.test.ts src/app/(frontend)/app/presentation/actions.ts: passed.
  • pnpm exec biome check src/components/anuvax/presentation-video/presentation-video-page.tsx: passed.
  • pnpm typecheck after Scene Editor polling guard: passed.
  • pnpm exec biome check src/components/anuvax/presentation-video/presentation-video-page.tsx after Scene Editor polling guard: passed.
  • pnpm exec biome check src/mastra/workflows/presentationvideo.workflow.ts src/mastra/workflows/sub/narrative.workflow.ts: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts: passed, 8 tests.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after generic use-case polling regression: passed, 9 tests.
  • pnpm typecheck after generic use-case fallback: passed.
  • pnpm exec biome check src/app/(frontend)/app/presentation/actions.ts tests/integration/presentation-compile.integration.test.ts: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/videos/[id]/page.tsx': passed.
  • pnpm typecheck after video detail route params fix: passed.
  • pnpm exec biome check src/components/anuvax/presentation-video/presentation-video-page.tsx after deep-link hydration fix: passed.
  • pnpm typecheck after deep-link hydration fix: passed.
  • pnpm exec biome check src/components/anuvax/videos/video-project-detail-page.tsx after video detail timestamp hydration fix: passed.
  • pnpm typecheck after video detail timestamp hydration fix: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/presentation/actions.ts' 'src/components/anuvax/presentation-video/presentation-video-page.tsx' tests/integration/presentation-compile.integration.test.ts after server-action transport guards and scene error mapping: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after scene error mapping regression: passed, 9 tests.
  • pnpm typecheck after server-action transport guards and scene error mapping: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/videos/actions.ts' 'src/app/(frontend)/app/videos/[id]/page.tsx' 'src/components/anuvax/videos/video-project-detail-page.tsx' after video detail Payload depth reduction: passed.
  • pnpm typecheck after video detail Payload depth reduction: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/create/presentation/page.tsx' 'src/components/anuvax/presentation-video/presentation-video-page.tsx' 'src/app/(frontend)/app/presentation/actions.ts' after server-side create-page deep-link hydration: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after server-side create-page deep-link hydration: passed, 9 tests.
  • pnpm typecheck after server-side create-page deep-link hydration: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/create/presentation/page.tsx' 'src/components/anuvax/presentation-video/presentation-video-page.tsx' after expanded create-page server hydration: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after expanded create-page server hydration: passed, 9 tests.
  • pnpm typecheck after expanded create-page server hydration: passed.
  • pnpm exec biome check --write src/lib/ai/generate-image.ts src/lib/ai/model-config.ts src/lib/coins/metering.ts src/mastra/tools/presentation/index.ts 'src/app/(frontend)/app/presentation/actions.ts' tests/unit/generate-image-provider.test.ts after Gemini image provider routing: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/generate-image-provider.test.ts: passed, 1 test.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/ai-coin-metering.test.ts: passed, 8 tests.
  • pnpm typecheck after Gemini image provider routing: passed.
  • pnpm exec biome check --write src/lib/ai/model-config.ts tests/unit/generate-image-provider.test.ts docs/changes/2026-05-20-0706-presentation-video-ui-update/ImplementationLog.md after switching to Imagen model id: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/generate-image-provider.test.ts after switching to Imagen model id: passed, 1 test.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/ai-coin-metering.test.ts after switching to Imagen model id: passed, 8 tests.
  • pnpm typecheck after switching to Imagen model id: passed.
  • pnpm exec biome check src/lib/ai/generate-image.ts tests/unit/generate-image-provider.test.ts after Google image-model fallback: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/generate-image-provider.test.ts after Google image-model fallback: passed, 2 tests.
  • pnpm typecheck after Google image-model fallback: passed.
  • pnpm exec biome check src/lib/ai/model-config.ts tests/unit/generate-image-provider.test.ts after switching back to OpenAI GPT Image: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/unit/generate-image-provider.test.ts after switching back to OpenAI GPT Image: passed, 2 tests.
  • pnpm typecheck after switching back to OpenAI GPT Image: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/presentation/actions.ts' 'src/components/anuvax/presentation-video/presentation-video-page.tsx' 'tests/integration/presentation-compile.integration.test.ts' after existing-presentation rerun path: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after existing-presentation rerun path: passed, 10 tests.
  • pnpm typecheck after existing-presentation rerun path: passed.
  • pnpm exec biome check 'src/app/(frontend)/app/presentation/actions.ts' after read-only generation-status polling change: passed.
  • pnpm exec vitest run --config ./vitest.config.mts tests/integration/presentation-compile.integration.test.ts after read-only generation-status polling change: passed, 10 tests.
  • pnpm typecheck after read-only generation-status polling change: passed.
  • pnpm test:int: presentation integration tests passed, but the full script failed on tests/unit/anuva-orchestration-service.test.ts at an existing artifact metadata assertion.
  • pnpm exec playwright test tests/e2e/presentation-video.e2e.spec.ts: blocked because playwright.config.ts imports missing package dotenv.

Remaining Risks

  • The full pnpm lint command is still blocked by existing repository-wide Biome issues in docs and generated files outside this change.
  • Playwright coverage could not run until the local dependency issue for dotenv is resolved.
  • The VO Script assistant reruns narrative from updated guidance, but does not yet have a dedicated server-side VO-guidance refinement action.