/** * Long-form → multi-shorts orchestrator. * * The "1 hour podcast → 10 shorts" pipeline. Slides a window across a * transcript, asks the LLM to nominate up to 3 candidate clips inside * each window, then `score_clip`'s every nominee, dedups overlaps, and * returns the top-N. * * Pure helpers + the LLM proposal step live here so the tool wrapper * can stay thin. The ranking + dedup pass is plain TS — easy to unit * test without the network. */ import type { Transcript } from "./whisper.js"; export interface ViralCandidate { startSec: number; endSec: number; hookLine: string; suggestedTitle: string; suggestedCaption: string; why: string; } export interface ScoredCandidate extends ViralCandidate { score: number; hook: number; flow: number; engagement: number; trend: number; durationSec: number; } export interface WindowSpec { startSec: number; endSec: number; /** Transcript text within this window, already extracted. */ text: string; } /** * Slice the transcript into overlapping windows. Each window covers * `windowSec` seconds with `overlapSec` spillover into the next so a * clip straddling a boundary can still be proposed by at least one * window. The dedup step later collapses duplicates. * * Pure — exported for unit testing. */ export declare function buildSlidingWindows(t: Transcript, windowSec: number, overlapSec: number): WindowSpec[]; /** * Dedup overlapping candidates: when two candidates overlap > 50% (of * the smaller), keep the higher-scoring one. Stable / sort-agnostic — * the function sorts internally before walking. * * Pure — exported for testing. */ export declare function dedupCandidates(cands: ScoredCandidate[]): ScoredCandidate[]; /** * Clamp candidate ranges to [0, totalSec] and to the requested duration * range. Drops candidates that fall outside or are degenerate. */ export declare function normalizeCandidates(cands: ViralCandidate[], totalSec: number, minSec: number, maxSec: number): ViralCandidate[]; export interface ProposeOptions { apiKey?: string; model?: string; durationRange: [number, number]; signal?: AbortSignal; } export declare function proposeCandidates(window: WindowSpec, opts: ProposeOptions): Promise; /** * Tolerant parser. Drops malformed entries silently (we'd rather skip a * bad candidate than blow up the whole window). */ export declare function parseProposalResponse(content: string): ViralCandidate[]; //# sourceMappingURL=viral-moments.d.ts.map