import type { AgentAttachment } from "../agent/types.js"; import { type FastMossIntegration } from "../integrations/fastmoss.js"; import { downloadTikwmReference } from "./tikwm-download.js"; export declare const VIDEO_ANALYSIS_MODEL_ARGS: string[]; export declare const VIDEO_CUT_OBSERVATION_VERSION = "cut-observation-v1"; export declare const LOCAL_SPEECH_RECOGNITION_VERSION = "whisper-original-language-v1"; type LocalAsrResult = { text?: string; chunks?: Array<{ text?: string; timestamp?: [number | null, number | null]; }>; }; export type LocalVideoLearningSource = { id?: string; source?: string; platform?: string; sourceUrl?: string; source_url?: string; platformVideoId?: string; platform_video_id?: string; market?: string; category?: string; rankingDimension?: string; ranking_dimension?: string; title?: string; creatorName?: string; creator_name?: string; productTitle?: string; product_title?: string; metrics?: Record; archiveStatus?: string; archive_status?: string; archivedVideoUrl?: string; archived_video_url?: string; archivedTranscript?: string; archived_transcript?: string; cutObservationVersion?: string; speechRecognitionVersion?: string; }; type VideoArchiveUpload = { uploadUrl: string; publicUrl: string; headers?: Record; maxBytes?: number; alreadyUploaded?: boolean; downloadUrl?: string | null; }; export declare function shouldUploadVideoArchive(input: { kind: "uploaded-mp4" | "tiktok"; url: string; }, publicUrl: string, alreadyUploaded?: boolean): boolean; export declare class LocalVideoIntelligence { private readonly fastmoss; private readonly browserDownload?; constructor(fastmoss: FastMossIntegration, browserDownload?: ((sourceUrl: string) => Promise) | undefined); archive(source: LocalVideoLearningSource, upload: VideoArchiveUpload): Promise<{ archive: { publicUrl: string; sha256: string; bytes: number; contentType: string; transcript: string; mediaProbeVersion: number; hasVideo: boolean; hasAudio: boolean; durationMs: number; }; }>; analyze(source: LocalVideoLearningSource, options?: { onStage?: (stage: string) => Promise; timeoutMs?: number; }): Promise<{ analysis: Record; evidence: { cutObservationVersion?: string | undefined; durationMs: number; frameCount: number; transcriptCueCount: number; visualSource: string; transcriptSource: string; speechRecognitionVersion: string; speechLanguage: { language: string; probability: number; } | undefined; transcript: string; }; }>; } export declare function verifiedVideoLearningSource(source: LocalVideoLearningSource): { kind: "tiktok" | "uploaded-mp4"; url: string; }; export declare function localVideoAnalysisPrompt(source: LocalVideoLearningSource, durationMs: number, transcript: string, attachments: AgentAttachment[], transcriptSource?: string): string; /** Bind citations to images actually supplied, never a model-authored evidence manifest. */ export declare function bindCutObservationEvidence(analysis: Record, attachments: AgentAttachment[]): void; export declare function assertJointVisualAndSpokenEvidence(analysis: Record): void; export declare function timedTranscriptFromVtt(value: string): string; /** * Keep the dense first three seconds, then add actual shot-change frames before * uniform coverage. This follows shot-level video-understanding practice while * staying inside the existing FFmpeg-only customer runtime. */ export declare function sceneAwareVideoEvidenceTimestamps(videoFile: string, durationMs: number, workDir?: string, cutObservations?: boolean): Promise; /** Reserve dense opening and whole-film coverage before admitting complete cut pairs. */ export declare function selectSceneAwareEvidenceTimestamps(durationMs: number, sceneTimestamps: number[], cutObservations?: boolean): number[]; export declare function sceneChangeTimestampsFromMetadata(value: string, durationMs: number): number[]; export declare function isTikwmReferenceSource(sourceUrl: string): boolean; export declare function downloadVideoArchive(sourceUrl: string, workDir: string, maxBytes: number, localDirectory?: string, browserDownload?: (sourceUrl: string) => Promise, tikwmOptions?: Parameters[4], requireApi?: boolean): Promise<{ media: { durationMs: number; hasAudio: boolean; }; file: string; transcript: string; provenance: string; }>; export declare function classifyVideoArchiveDownloadFailure(error: string): Error; export declare function inspectVideoFile(videoFile: string, workDir?: string): Promise<{ durationMs: number; hasAudio: boolean; }>; type VideoProbeResult = { streams?: Array<{ codec_type?: string; width?: number; height?: number; duration?: string; }>; format?: { duration?: string; format_name?: string; }; }; export declare function assertVideoMediaProbe(parsed: VideoProbeResult): { durationMs: number; hasAudio: boolean; }; export declare function transcribeLocalMedia(videoFile: string | undefined, workDir: string): Promise; export declare function transcribeLocalMediaEvidence(videoFile: string | undefined, workDir: string): Promise<{ transcript: string; status: string; detectedLanguage?: undefined; } | { transcript: string; status: string; detectedLanguage: { language: string; probability: number; }; }>; export declare function selectWhisperLanguage(logits: ArrayLike, languageTokens: Record): { language: string; probability: number; }; export declare function formatLocalAsrEvidence(result: LocalAsrResult, durationSeconds: number): { transcript: string; status: string; }; export declare function resolveLocalCodexEntrypoint(): string; /** CLI stderr can contain the prompt and unrelated MCP logs; never return it to the website. */ export declare function localCodexAnalysisError(result: { stdout: string; error: string; }): "本机 Codex 视频理解失败:Agent 自带的 Codex 版本过旧,当前模型需要更新运行程序。原视频已保存,更新后可直接重试反推,无需重新上传。" | "本机 Codex 视频理解失败:当前账号的模型额度或请求频率受限,请待额度恢复后重试。原视频已保存,无需重新上传。" | "本机 Codex 视频理解失败:本机 Codex 登录已失效,请恢复登录后重试。原视频已保存,无需重新上传。" | "本机 Codex 视频理解超时,原视频已保存,可直接重试反推,无需重新上传。" | "本机 Codex 未完成视频理解,原视频已保存,可直接重试反推。若持续失败,请检查本机 Codex 运行状态。"; export {};