import type { ProviderRouteId } from './types.js'; /** * Declarative, single-sourced capability envelope for one provider route. * * The numeric/enum values here are NOT re-derived heuristics — they mirror the * limits the transports already enforce: * - dreamina-useapi: `src/video/providers/dreamina-useapi.ts` * (DREAMINA_MAX_IMAGE_REFS / _VIDEO / _AUDIO, resolutionFor(), clampDuration()). * - runway-useapi: `src/video/providers/runway-useapi.ts` * (RUNWAY_MAX_IMAGE_REFS / _VIDEO, clampDuration(), default mode 'explore'). * - seedance-direct: `src/video/native-seedance.ts` * (REFERENCE_BUDGET images/videos/audios via assertReferenceBudget). * - veo-useapi: `src/video/native-veo.ts` (veoRatio landscape/portrait/square; * conservative defaults — UseAPI enforces the rest server-side). * * This matrix is the read-only contract used by `assertRouteRequestValid` to * fail fast (or warn under VCLAW_ALLOW_UNSAFE_MODELS) BEFORE a provider submit. * Keep it in sync with the transport limits above — do not let it drift. */ export interface RouteCapabilities { /** Submission modes the route understands (e.g. 'explore' | 'credits'). */ modes: string[]; /** Output resolutions the route can deliver (e.g. '720p', '1080p'). */ resolutions: string[]; /** * Discrete clip durations (seconds) the route accepts/clamps to. An empty * array means the transport enforces no client-side duration set (the * provider applies model-specific limits server-side), so duration is not * checked for this route. */ durationsSec: number[]; /** Maximum number of image reference inputs per submission. */ maxImageRefs: number; /** Maximum number of video reference inputs per submission. */ maxVideoRefs: number; /** Maximum number of audio reference inputs per submission. */ maxAudioRefs: number; /** Whether the route can attach/generate audio. */ audioCapable: boolean; /** When a capability is gated to a region (e.g. '1080p is CA-only'). */ regionGated?: string; /** Free-form operator notes carried into warnings/diagnostics. */ notes?: string[]; } /** * Capability matrix for the four live provider routes. `veo-direct` is * intentionally absent — it was an adapter-only phantom route with no native * transport and has been removed from `ProviderRouteId`. */ export declare const ROUTE_CAPABILITIES: Record; /** * A request to validate against a route's capability envelope. Every field is * optional: an absent field is simply not checked (so callers that only know a * subset of the request — e.g. just resolution + aspect ratio at payload-build * time — never trip a false violation for a value they did not supply). */ export interface RouteRequest { resolution?: string; durationSec?: number; aspectRatio?: string; imageRefs?: number; videoRefs?: number; audioRefs?: number; mode?: string; /** * Resolved Veo model for a `veo-useapi` request (`fast | quality | omni-flash`). * Only consulted by the veo-useapi-specific gate below. Other routes ignore it. */ veoModel?: string; /** * True when this request carries a voice-narration preset (`flow.ts --voice`). * Provider-side this is `omni-flash`-only on the veo-useapi route. */ hasVoice?: boolean; /** * True when this request carries a V2V edit video reference * (`flow.ts --ref-video`). NOTE: this is NOT the scene-chaining seed * (`inputKind: 'video'`), which the route supports on any model — it is the * dedicated omni-flash V2V edit source. omni-flash-only on the veo-useapi route. */ hasVideoRef?: boolean; /** * True when this request carries an omni-flash First-Frame (startImage / I2V) * seed — the gated build-ahead identity-lock path (see VideoExecutionTask. * firstFrame). A start image satisfies the omni-flash "voice needs a visual * anchor" precondition just like an R2V image or V2V video. Only ever true on * omni-flash once the `VCLAW_OMNI_FIRST_FRAME` gate is enabled; absent → * byte-identical legacy behavior on the veo-useapi route. */ hasStartImage?: boolean; } /** Options for {@link assertRouteRequestValid}. */ export interface AssertRouteRequestValidOptions { /** Defaults to `process.env`. Pure callers can inject a fixed map. */ env?: NodeJS.ProcessEnv; } /** Result of a capability check. `ok` is always true when no Error is thrown. */ export interface RouteRequestValidation { ok: boolean; warnings: string[]; } /** * Gate for the omni-flash First-Frame (startImage / I2V) path, shared by the * execution-runtime payload builder and the veo-useapi transport so a single env * flag controls both layers. * * As of 2026-06-06 omni-flash startImage is LIVE on useapi.net (live-verified: * the request routes to abra_i2v_8s / IMAGE_TO_VIDEO), so this is now ENABLED BY * DEFAULT. `VCLAW_OMNI_FIRST_FRAME` is a kill-switch — only 0/false/no/off * disables it (e.g. if the provider regresses). See VideoExecutionTask.firstFrame. */ export declare function isOmniFirstFrameEnabled(env?: NodeJS.ProcessEnv): boolean; /** * Validate a {@link RouteRequest} against {@link ROUTE_CAPABILITIES} for the * given route. Pure and deterministic (no fs/network); the only side input is * `env` (default `process.env`), read once for the `VCLAW_ALLOW_UNSAFE_MODELS` * escape hatch. * * Behavior: * - On a hard violation (resolution/duration/mode not supported, or refs over * budget), throws a clear {@link Error} — UNLESS `VCLAW_ALLOW_UNSAFE_MODELS` * is truthy, in which case each violation is downgraded to a `warnings[]` * entry and `{ ok: true }` is returned. * - A fully-valid (or empty) request returns `{ ok: true, warnings: [] }`. * - veo-useapi only: a `hasVoice` or `hasVideoRef` request whose `veoModel` * is not `omni-flash` is a violation (voice/V2V are omni-flash-only), * pushed through the same downgradable path. * * Only fields that are present on the request are checked, so partial requests * never produce spurious violations for fields the caller did not supply. */ export declare function assertRouteRequestValid(routeId: ProviderRouteId, req: RouteRequest, opts?: AssertRouteRequestValidOptions): RouteRequestValidation; //# sourceMappingURL=route-capabilities.d.ts.map