Skip to content

feat(ai-fal): migrate falVideo onto the typed-duration contract #817

Description

@tombeckenham

Summary

The typed-duration contract (TModelDurationByName generic + availableDurations() / snapDuration() introspection, plus the shared snapToDurationOption util) landed on main via #624 (commit 8fa6cc56, 2026-06-17). But only Gemini Veo actually adopted it. The fal video adapter still sits on the base-class defaults (availableDurations() → { kind: 'none' }, snapDuration() → undefined, duration?: number), so fal callers get no per-model duration typing and the introspection helpers are inert.

This issue tracks migrating falVideo onto the contract.

Current state on main

Adapter On the typed-duration contract?
geminiVideo ✅ Yes (overrides availableDurations/snapDuration)
falVideo ❌ No — base defaults
openaiVideo (Sora) ❌ No — base defaults (descoped from #641 at the time)
openRouterVideo ✅ Yes (added on the #707 branch, matching the Veo pattern)

What to do

  • Add FalVideoModelDurationByName (per-model duration unions) and a getFalVideoDurationOptions(model) returning DurationOptions, following packages/ai-gemini/src/video/video-provider-options.ts and packages/ai-openrouter/src/video/video-provider-options.ts.
  • Wire the sixth BaseVideoAdapter generic in packages/ai-fal/src/adapters/video.ts, narrow createVideoJob's duration, and override availableDurations() / snapDuration().
  • fal durations are heterogeneous (discrete enums, '8s'-style keyword-with-unit strings, ranges like Wan 2…15, and kind: 'none' for Minimax/Hunyuan), so the DurationOptions mapping must cover discrete / range / mixed / nonesnapToDurationOption already handles all of those.
  • Unit tests for the duration table + snap behavior; update docs (docs/media/video-generation.md provider table) and the ai-core/media-generation SKILL.

Prior art / context

Refs: #534, #538, #624, #641, #707

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions