import { uploadGeminiFile } from './gemini-files.js'; import type { VideoAnalyzeOutput } from './types.js'; /** * Pure sampling-math seam: given a clip duration in seconds, produce the ffmpeg * `-vf` value and frame cap that spread {@link count} frames EVENLY across the * whole clip (one frame every `duration / count` seconds via the `fps` filter), * not clustered at the head. Returns `null` when the duration is unusable * (missing/non-finite/≤0) so the caller can fall back to head-clustered * `thumbnail` sampling without breaking the local-file path. * * The `fps` filter can emit `count` or `count ± 1` frames at clip boundaries, so * the caller MUST also pass `-frames:v frames` and tolerate fewer than `count` * outputs (the caller already slices/handles the resulting array). */ export declare function analyzeFrameSampling(durationSeconds: number | undefined, count?: number): { vf: string; frames: number; } | null; /** * The one prompt both modes send. `frameCount` > 0 appends the sentence that * tells the model the attached images are evenly sampled frames (static path); * 0 yields the bare prompt (URL-only static path AND the agentic path, which * attaches the whole video instead of frames). */ export declare function buildAnalyzePromptText(input: { source: string; title?: string; durationSeconds?: number; frameCount: number; }): string; export type AnalyzeProcessing = 'static' | 'agentic'; /** Flag > env > 'static'. Throws on an unrecognised value from either source. */ export declare function resolveAnalyzeProcessing(input: { flag?: string; env?: string; }): AnalyzeProcessing; /** Flag > env > DEFAULT_AGENTIC_MODEL. Validation against the allowlist is the caller's job. */ export declare function resolveAgenticModel(input: { flag?: string; env?: string; }): string; export declare function generateAnalyzeOutputWithGemini(input: { source: string; title?: string; durationSeconds?: number; endpoint?: string; fetcher?: typeof fetch; /** * `'agentic'` sends the whole video by reference to the Interactions API * (see `gemini-interactions.ts`) instead of sampling frames; absent or * `'static'` is the unchanged legacy path below. */ processing?: AnalyzeProcessing; /** Agentic model (default `gemini-3.8-flash`); ignored on the static path. */ agenticModel?: string; /** Base URL for the Interactions/Files APIs (default from VCLAW_GEMINI_API_BASE). */ apiBase?: string; /** Injectable sleep for the Files API ACTIVE poll (tests). */ sleep?: (ms: number) => Promise; /** Injectable Files API uploader (tests). */ uploadFile?: typeof uploadGeminiFile; /** * Injectable frame-extraction seam (returns base64-encoded JPEG frames). * Defaults to the real ffmpeg helper; tests inject fakes so the suite never * shells out to ffmpeg. Only invoked when `source` is a readable local file. * The optional `durationSeconds` lets the extractor spread frames evenly * across the clip; injected fakes may ignore it. */ extractFrames?: (videoPath: string, durationSeconds?: number) => Promise; }): Promise; export declare function generateMultiShotWithGemini(input: { preset: import('./multi-shot-prompt.js').MultiShotPreset; imagePath: string; character?: string; action?: string; location: string; timeOfDay: string; repairInstructions?: string; /** Injectable fetch for tests; falls back to the global Gemini key pool. */ fetcher?: typeof fetch; }): Promise; //# sourceMappingURL=gemini-analyze.d.ts.map