/** * Google Flow inline @-mention markers (useapi.net Google Flow API v1, * blog 260609). Markers anchor a reference to a position in the prompt text: * * POST /videos: @character_1..7, @referenceImage_1..7, @referenceAudio_1..5 * POST /images: @character_1..7, @reference_1..10 * * Case-INSENSITIVE and opt-in — a slot without a marker is always fine, but a * marker without a matching body slot makes the API 400. There is NO * `@referenceVideo_1` marker — V2V stays flag-only (`--ref-video`). * * Pure module: no I/O, no env, no provider calls. */ export type FlowMarkerFamily = 'character' | 'referenceImage' | 'referenceAudio' | 'reference'; export interface FlowMarker { family: FlowMarkerFamily; /** 1-based slot index as written (out-of-range values are reported by the validators, not here). */ index: number; /** The token exactly as matched in the prompt, e.g. '@Character_2'. */ raw: string; } /** * Extract every Flow @-marker occurrence in order, duplicates included. * Family is normalized to canonical camelCase regardless of input casing; * `raw` keeps the token exactly as written. */ export declare function extractFlowMarkers(prompt: string): FlowMarker[]; export interface FlowVideoMarkerSlots { characterCount: number; referenceImageCount: number; referenceAudioCount: number; } export interface FlowImageMarkerSlots { characterCount: number; referenceCount: number; } /** * Validate Flow @-markers in a VIDEO prompt (POST /videos grammar) against the * body slots the caller intends to send. Returns human-readable error strings * (empty = valid). Slots WITHOUT markers are never an error (markers are * opt-in); duplicate markers for one index are fine. */ export declare function validateFlowVideoMarkers(prompt: string, slots: FlowVideoMarkerSlots): string[]; /** * Validate Flow @-markers in an IMAGE prompt (POST /images grammar) against the * body slots the caller intends to send. Same contract as the video validator. * (The model x ref-count matrix intentionally lives with the callers, not here.) */ export declare function validateFlowImageMarkers(prompt: string, slots: FlowImageMarkerSlots): string[]; export interface FlowCharacterSlotPlan { /** Lowercased character name → 1-based slot index into `orderedRefs`. */ slotByLowerName: Map; /** The final characterRefs array — slot N is `orderedRefs[N-1]`. */ orderedRefs: string[]; /** Names (original casing, first occurrence) aligned with `orderedRefs`. */ orderedNames: string[]; /** Registered names beyond the 7-slot cap, in the order they were dropped. */ overflow: string[]; } /** * Plan the `character_1..7` body slots for one scene. The final array is the * ordered union of: * 1. `unique(sceneCharacters)` filtered/mapped via * `characterRefByName.get(name)` — EXACT-case lookup, verbatim the legacy * cast semantics, so a tagless prompt yields exactly today's * characterRefs list (byte-identical payload). A cast name that only * case-mismatches the registry ('clawbot' vs registered 'Clawbot') stays * unresolved, exactly as before this feature. * 2. registered names appearing as `@Name` tags in `rawPrompt` (tag scan * order) that are not already included. TAG matching is case-INSENSITIVE * — tags are single tokens and `@clawbot` must resolve to a registered * 'Clawbot' (the plan-mandated case-insensitivity applies to tags only). * Capped at 7; registered names beyond the cap land in `overflow`. * `orderedNames` keeps the casing of the first occurrence. Unregistered names * are never slot candidates — they keep the descriptor-substitution path in * resolveAssetTags. * * `slotByLowerName` is keyed by the lowercased FINAL ordered names: if two * case-only-distinct cast names both carry refs (e.g. 'Bob' and 'BOB' both * registered), both keep their slots in `orderedRefs`, but the lowercased * injection key first-wins — a prompt tag cannot disambiguate * case-only-distinct names (pathological; exact-case cast behavior is * preserved either way). */ export declare function planFlowCharacterSlots(rawPrompt: string, sceneCharacters: string[], characterRefByName: Map): FlowCharacterSlotPlan; /** * Replace each `@Name` tag whose lowercased name is in `slotByLowerName` with * the canonical lowercase `@character_N` marker. Duplicate mentions of one name * all resolve to the SAME marker (one slot — the API dedup rule). Every other * tag — unregistered names, `@imageN`, hand-authored Flow markers like * `@character_2` — is untouched. `injected` lists `Name->@character_N` strings * in order of first replacement. Tagless text comes back byte-identical. */ export declare function injectFlowCharacterMarkers(text: string, slotByLowerName: Map): { text: string; injected: string[]; }; /** * Remove every Flow @-marker token from `text`, collapsing the doubled * whitespace left behind and trimming the ends. `stripped` lists the removed * raw tokens in order. Text without markers comes back byte-identical. */ export declare function stripFlowMarkers(text: string): { text: string; stripped: string[]; }; //# sourceMappingURL=flow-markers.d.ts.map