import type { AgentEmit } from "../agent/types.js"; import { type CanvasAgentConfig } from "../config.js"; import { type FlowCProductExecutionProfile } from "./product-profile.js"; import { type ReferenceTopicPlanInput, type ReferenceTopicBinding, type SavedReferenceTopicPlan } from "./reference-topics.js"; import { type CommerceRequestDiagnostic } from "./commerce-http.js"; import { type FlowCContentAdvisory, type FlowCContentStrategy, type FlowCContentSummary } from "./content-method.js"; export declare const FLOW_C_CODEX_TURN_TIMEOUT_MS: number; export declare const FLOW_C_SELECTED_BLUEPRINT_PROMPT_MAX_CHARS = 45000; export declare const FLOW_C_REFERENCE_TOPIC_PROMPT_MAX_CHARS = 30000; export declare const FLOW_C_SCRIPT_REWRITE_MAX_ATTEMPTS = 2; export declare const FLOW_C_CANDIDATE_REVISION_MAX_ATTEMPTS = 2; export declare const FLOW_C_VOICE_PACING_REPAIR_MAX_ATTEMPTS = 1; export declare const FLOW_C_VOICE_PACING_REVIEW_REQUIRED = "FLOW_C_VOICE_PACING_REVIEW_REQUIRED"; export declare const FLOW_C_LEGACY_DIRECT_CONTRACT_VERSION = "flow-c-template-direct-v2"; export declare const FLOW_C_PRODUCT_PROFILE_DIRECT_CONTRACT_VERSION = "flow-c-product-profile-direct-v1"; export declare const FLOW_C_CREATIVE_SOURCE_DIRECT_CONTRACT_VERSION = "flow-c-creative-source-direct-v1"; type ScriptStatus = "queued" | "running" | "complete" | "review" | "error" | "expired"; type DownloadStatus = "waiting" | "running" | "complete" | "error" | "expired"; type ScriptRecord = { id: string; apiBase: string; accessToken: string; status: ScriptStatus; requestedCount: number; receivedOrdinals: number[]; threadId?: string; message?: string; expiresAt?: string; attempts: number; chunkSize?: number; activeChunks?: number; productProfiles?: FlowCProductExecutionProfile[]; pendingReferenceTopicPlans?: ReferenceTopicPlanInput[]; pendingScriptJobs?: DraftJob[]; /** Locally recoverable originals; unlike pendingScriptJobs these must never be replayed to the center. */ voicePacingReviewJobs?: DraftJob[]; voicePacingRepairAttempts?: Array<{ ordinal: number; candidateRevision: string; attempts: number; }>; /** Only these failed revisions are excluded from automatic waves; clean siblings keep running. */ voicePacingReviewHolds?: Array<{ ordinal: number; candidateRevision: string; reason: string; }>; contentStrategy?: FlowCContentStrategy; contentSummaries?: FlowCContentSummary[]; contentAdvisories?: FlowCContentAdvisory[]; lastFailure?: CommerceRequestDiagnostic; retryRequested?: boolean; priorityAt?: string; updatedAt: string; }; type ReferenceStyleCard = { id?: unknown; templateKind?: unknown; templateProfile?: unknown; modelFamily?: unknown; sourceDurationSeconds?: unknown; visualPremisePattern?: unknown; mutationAxes?: unknown; culturePattern?: unknown; spectaclePattern?: unknown; productIntegrationPattern?: unknown; openingPattern?: unknown; proofPattern?: unknown; rhythmPattern?: unknown; capturePattern?: unknown; voiceTone?: unknown; targetDurationPolicy?: unknown; retimingRule?: unknown; segmentRule?: unknown; omniAdaptation?: unknown; sourceEvidenceTier?: unknown; truthBoundaries?: unknown; applicability?: { markets?: unknown; categories?: unknown; }; }; type StoryboardLayoutVersion = "director-table-scripted-v1" | "visual-storyboard-landscape-v2" | "visual-storyboard-adaptive-v1" | "hybrid-three-anchor-v1" | "legacy-five-row-v1"; type FlowCProductionMode = "storyboard" | "visual-storyboard" | "first-frame-chain"; type FlowCScriptSource = "learned-viral" | "selling-form-library" | "generated-montage"; type FlowCSelectedScriptSource = FlowCScriptSource | "user-framework"; type ProductInput = { productIndex: number; title: string; category?: string; quantity: number; sellingForm?: string; creativeBrief?: string; scriptSourceOverride?: "inherit" | FlowCScriptSource; sellingFormSelection?: { mode?: "smart" | "controlled-random" | "explicit"; cardId?: string | null; }; productImageUrlsInExactOrder?: string[]; }; type SelectedCandidate = { ordinal: number; productIndex: number; referenceTopic?: ReferenceTopicBinding; candidateRevision?: string; contentDirection?: unknown; contentStyle?: unknown; contentStyleVersion?: unknown; scriptSource?: FlowCSelectedScriptSource; creativeSource?: FlowCSelectedScriptSource; sellingFormCardId?: string | null; sellingFormName?: string | null; sellingFormSelectionReason?: string | null; sellingFormSelection?: Record; learnedTemplateId?: string | null; learnedTemplateSource?: Record | null; productIdentityProfile?: Record; productExecutionProfileRef?: string; executionBlueprint?: string; templateMatch?: Record; sourceDurationSeconds?: number | null; targetDurationSeconds?: number | null; retimingMode?: "compress" | "expand" | "same" | null; retimingInstruction?: string; visualPremise: string; mutationAxes: string[]; culturalAnchors: Array>; spectacleEscalation: string; productProofAction: string; purchaseReason: string; truthBoundary: string; riskFlags: string[]; firstFrame: string; firstFrameFocus: string; visualContrast: string; sensoryTexture: string; motionPeak: string; compositionLighting: string; localNativeDetail: string; antiFlatness: string; creativeFingerprint: Record; fingerprintKey?: string; selectionScore?: number; selectionBreakdown?: Record; selectionMode?: string; }; type ScriptTask = { reference_topic_plans?: SavedReferenceTopicPlan[]; id: string; workflow: "flow-c"; market: string; target_language?: string | null; localization?: Record; creative_strategy?: unknown; content_recent_scripts?: FlowCContentSummary[]; script_source_default?: FlowCScriptSource; duration_seconds?: 10 | 15 | 20 | 30; video_model_key?: "veo-omni-flash" | "seedance-2.0-mini-15s" | "seedance-2.0-fast-15s"; script_output_contract_version?: string; storyboard_layout_version?: StoryboardLayoutVersion; storyboardLayoutVersion?: StoryboardLayoutVersion; production_mode?: FlowCProductionMode; productionMode?: FlowCProductionMode; reference_style_card?: ReferenceStyleCard; referenceStyleCard?: ReferenceStyleCard; product_inputs?: ProductInput[]; product_execution_profiles?: FlowCProductExecutionProfile[]; product_profile_stage?: { completed?: number; requested?: number; }; reference_style_cards?: ReferenceStyleCard[]; selected_candidates?: SelectedCandidate[]; creative_fingerprint_ledger?: Array>; candidate_stage?: { selected?: number; requested?: number; }; requested_count: number; product_quantities: number[]; instructions: string; status: "pending" | "writing" | "ready"; received_ordinals: number[]; expires_at: string; }; type DraftJob = { ordinal: number; productIndex: number; sellingFormId: string; script: string; expectedCandidateRevision?: string; masterScript?: string; creativePlan?: Record; executionBindings?: Record; creativeTags?: Record; voiceProfile?: Record; qualityGate?: Record; segmentVoiceovers?: string[][]; segment?: { script: string; continuityMode: "continue" | "reset"; }; segments?: Array<{ script: string; continuityMode: "continue" | "reset"; }>; }; type ScriptChunkResult = { error?: string; terminal: boolean; terminalKind?: "contract" | "transport" | "timeout" | "turn" | "delivery" | "review" | "isolation"; affectedOrdinals?: number[]; replanOrdinals?: number[]; }; export declare class WorkflowDownloadDirectoryBusyError extends Error { readonly code = "WORKFLOW_DOWNLOAD_DIRECTORY_BUSY"; constructor(); } /** 本机持久化的 Flow C 控制器:脚本交给本机 Codex,视频直接落盘。 */ export declare class WorkflowManager { private config; private emit; private state; private runningScripts; private scriptQueueRunning; private syncingDownloads; private pendingDownloadBatchIds; private directorySelection?; constructor(config: CanvasAgentConfig, emit: AgentEmit); /** 接收网站创建的短期交接能力并立即启动本机 Codex。 */ enqueueScript(input: { id?: unknown; apiBase?: unknown; accessToken?: unknown; expiresAt?: unknown; }): { contentReview?: { blocking: boolean; semanticAcceptance: string; advisories: FlowCContentAdvisory[]; } | undefined; id: string; status: ScriptStatus; requestedCount: number; received: number; reviewOrdinals: number[]; reviewCount: number; threadId: string | undefined; chunkSize: number | null; activeChunks: number; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }; retryScript(idValue: unknown): { contentReview?: { blocking: boolean; semanticAcceptance: string; advisories: FlowCContentAdvisory[]; } | undefined; id: string; status: ScriptStatus; requestedCount: number; received: number; reviewOrdinals: number[]; reviewCount: number; threadId: string | undefined; chunkSize: number | null; activeChunks: number; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }; scriptStatus(idValue: unknown): { contentReview?: { blocking: boolean; semanticAcceptance: string; advisories: FlowCContentAdvisory[]; } | undefined; id: string; status: ScriptStatus; requestedCount: number; received: number; reviewOrdinals: number[]; reviewCount: number; threadId: string | undefined; chunkSize: number | null; activeChunks: number; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }; /** MCP 读取服务端持久化的完整任务,不向模型暴露令牌。 */ scriptTask(idValue: unknown): Promise; /** MCP 分段回传脚本,中心接口再次执行数量、产品索引和脚本完整性校验。 */ submitScriptChunk(idValue: unknown, jobsValue: unknown): Promise<{ accepted: number; received: number; receivedOrdinals?: number[]; requestedCount: number; status: string; }>; submitCandidateChunk(idValue: unknown, groupsValue: unknown): Promise<{ accepted: number; selected: number; requestedCount: number; selectedCandidates: SelectedCandidate[]; }>; submitProductProfileChunk(idValue: unknown, profilesValue: unknown[], contractVersion?: string): Promise<{ accepted: number; profiled: number; requestedProducts: number; selected: number; requestedCount: number; status: string; }>; private scriptRequestOptions; downloadState(): { configured: boolean; directoryName: string | undefined; subscriptions: { batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }[]; }; health(): { contentStrategyVersion: string; referenceWritingVersion: string; referenceTopicPlanVersion: string; generatedMontageVersion: string; activeScriptHandoffIds: string[]; activeScripts: number; scriptConcurrencyLimit: number; queuedScripts: number; blockedScripts: number; }; startDownloadDirectorySelection(): { id: string; status: "selecting" | "selected" | "cancelled" | "error"; directoryName?: string; error?: string; } | { id: `${string}-${string}-${string}-${string}-${string}`; status: "selecting"; }; downloadDirectorySelection(idValue: unknown): { id: string; status: "selecting" | "selected" | "cancelled" | "error"; directoryName?: string; error?: string; }; clearDownloadDirectory(): { configured: boolean; directoryName: string | undefined; subscriptions: { batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }[]; }; subscribeDownload(input: { batchId?: unknown; apiBase?: unknown; accessToken?: unknown; expiresAt?: unknown; }): { batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }; syncDownload(batchIdValue?: unknown): Promise<{ batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; } | { configured: boolean; directoryName: string | undefined; subscriptions: { batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }[]; }>; setDownloadDirectory(directoryValue: unknown): Promise<{ configured: boolean; directoryName: string | undefined; subscriptions: { batchId: string; status: DownloadStatus; downloaded: number; market: string | undefined; message: string | undefined; expiresAt: string | undefined; updatedAt: string; }[]; }>; private assertDownloadDirectoryIdle; private scheduleScript; /** 同一台电脑串行处理脚本交接,避免多个大批次争用一个 Codex app-server。 */ private pumpScriptQueue; private finishDownloadDirectorySelection; private runScript; /** A finished lane refills immediately; a fatal result closes admission but drains every admitted lane. */ private runScriptChunksRolling; /** Analyze each product once; image 1 owns identity and later images may only corroborate visible evidence. */ private ensureProductExecutionProfiles; private ensureReferenceTopicPlans; private submitReferenceTopicPlan; private runReferenceTopicPlan; private runProductExecutionProfile; private runCandidateChunk; /** 一个 chunk 使用独立线程;解析与中心持久化失败不会影响并行 lane。 */ private runScriptChunk; private submitScriptJobsWithVoicePacingRepair; /** * One correction turn only. Originals live outside pendingScriptJobs, so a * restart or response loss can never replay an overcrowded draft as accepted. */ private repairVoicePacingJobs; private holdVoicePacingReview; private runVoicePacingRepairTurn; /** Nonblocking, text-free diagnostics for newly generated policy scripts only. */ private noteScriptContentAdvisories; /** 只记录阶段、ordinal 和毫秒数;禁止记录 prompt、令牌或中心能力。 */ private emitScriptStage; /** * 中心批量校验失败时逐条补交,避免一条格式异常拖累同轮其他有效脚本。 * 已接纳 ordinal 由中心持久化,下一轮只会继续缺失项。 */ private submitGeneratedScriptJobs; private syncDownloads; private syncDownloadRecord; private saveDelivery; private scriptRecord; private downloadRecord; private save; } export declare function compareScriptQueueRecords(left: Pick, right: Pick): number; export declare function flowCVoicePacingRepairTurnOptions(): { readonly maxProcessAttempts: 1; }; export declare function voicePacingRepairAttemptCount(record: Pick, job: Pick): number; /** * Accept only repaired per-shot speech. Every visual/timeline/state/selection * field comes from the locally validated original and rendered projections are * rebuilt from that one final voice source. */ export declare function applyFlowCVoicePacingRepair(originalValue: unknown, candidateValue: unknown, preserveExactTranscript?: boolean, segmentSeconds?: 10 | 15): DraftJob; /** A deterministic response-format failure stops fallback isolation immediately. */ export declare function terminalScriptChunkError(results: Array<{ error?: string; terminal?: boolean; }>): string; export declare function terminalScriptChunkFailure(results: T[], receivedOrdinals?: number[]): T; export declare function scriptCreativeReplanOrdinals(results: unknown[]): number[]; /** Keep a mixed reset signal after an exact-duplicate rewrite finishes. */ export declare function preserveScriptRecoveryReplans(result: ScriptChunkResult, error: unknown): ScriptChunkResult; export declare function creativeReplanOrdinals(error: unknown): number[]; export declare function scriptDeliveryOrdinals(error: unknown): number[]; export declare function candidateRevisionChangedOrdinals(error: unknown): number[]; export declare function scriptRewriteOrdinals(error: unknown): number[]; export declare function terminalScriptValidationError(error: unknown): boolean; export declare function aggregateScriptRecoveryErrors(errors: unknown[]): Error; export declare function recordCreativeReplanAttempts(attempts: Map, ordinals: number[], limit?: number): void; export declare function isFlowCPromptPayloadTooLarge(error: unknown): error is Error & { code: "FLOW_C_PROMPT_PAYLOAD_TOO_LARGE"; }; /** Preflight the real immutable prompt; only a size error permits subdividing it. */ export declare function promptSafeScriptChunks(id: string, task: ScriptTask, ordinals: number[]): number[][]; export declare function productExecutionProfilePrompt(product: ProductInput, contractVersion?: string): string; export declare function referenceTopicPlanningPrompt(task: ScriptTask, productIndex: number): string; export declare function scriptChunkPrompt(id: string, task: ScriptTask, ordinals: number[], rewriteAttempt?: number): string; export declare function creativeCandidatePrompt(id: string, task: ScriptTask, ordinals: number[]): string; export declare function selectedBlueprintPromptPayload(values: SelectedCandidate[], fallbackTargetDurationSeconds?: number, contentStrategy?: FlowCContentStrategy | null): { referenceTopics?: Record[] | undefined; executionBlueprints: { blueprintRef: string; executionBlueprint: string; sourceDurationSeconds: number | null; targetDurationSeconds: number | null; retimingMode: "compress" | "expand" | "same" | null; }[]; productAdaptations: Record[]; ordinalBindings: { referenceTopic?: Record | undefined; contentDirection?: import("./content-method.js").FlowCContentDirection | undefined; ordinal: number; productIndex: number; blueprintRef: string | null; adaptationRef: string; variationSeed: string; }[]; }; /** Avoid encoding a complete JSON blueprint as an escaped JSON string again. */ export declare function unescapeBlueprintPromptPayload(payload: ReturnType): { executionBlueprints: ({ blueprintRef: string; executionBlueprint: string; sourceDurationSeconds: number | null; targetDurationSeconds: number | null; retimingMode: "compress" | "expand" | "same" | null; } | { executionBlueprint: object; blueprintRef: string; sourceDurationSeconds: number | null; targetDurationSeconds: number | null; retimingMode: "compress" | "expand" | "same" | null; })[]; referenceTopics?: Record[] | undefined; productAdaptations: Record[]; ordinalBindings: { referenceTopic?: Record | undefined; contentDirection?: import("./content-method.js").FlowCContentDirection | undefined; ordinal: number; productIndex: number; blueprintRef: string | null; adaptationRef: string; variationSeed: string; }[]; }; export declare function selectedCandidatePlan(value: SelectedCandidate | undefined, contentStrategy?: FlowCContentStrategy | null): { referenceTopic?: ReferenceTopicBinding | undefined; contentDirection?: import("./content-method.js").FlowCContentDirection | undefined; sellingFormCardId: string | null; sellingFormName: string | null; sellingFormSelectionReason: string | null; sellingFormLibraryVersion: string | null; sellingFormSelectionVersion: string | null; productIdentityProfile: Record; productExecutionProfileRef: string; mutationAxes: string[]; culturalAnchors: Record[]; spectacleEscalation: string; productProofAction: string; purchaseReason: string; truthBoundary: string; riskFlags: string[]; firstFrame: string; visualHook: string; conflict: string; escalation: string; turn: string; productIntervention: string; visibleProof: string; callbackMotivation: string; differentiationKey: string | undefined; firstFrameFocus: string; visualContrast: string; sensoryTexture: string; motionPeak: string; compositionLighting: string; localNativeDetail: string; antiFlatness: string; creativeFingerprint: Record; fingerprintKey: string | undefined; selectionScore: number | undefined; selectionBreakdown: Record | undefined; selectionMode: string | undefined; visualExecutionVersion: string; contentStyle?: string | undefined; contentStyleVersion?: string | undefined; visualPremise: string; learnedTemplateId: string | null; learnedTemplateSource: Record | null; scriptSource: FlowCSelectedScriptSource | null; }; /** * 已选创意永远优先进入脚本扩写;只有当前没有可写脚本时才生成下一小波候选。 * 每次最多占用受控 worker 数量的子批,避免把整批候选提前塞满 worker 队列。 */ export declare function nextScriptPipelineWave(task: Pick, receivedOrdinals: number[], durationSeconds: 10 | 15 | 20 | 30, scriptChunkSize: number, candidateChunkSize?: number, concurrency?: number): { stage: "script"; chunks: number[][]; } | { stage: "candidate"; chunks: number[][]; }; export declare function immediateScriptOrdinals(task: Pick, receivedOrdinals: number[], candidateOrdinals: number[]): number[]; export declare function missingOrdinals(total: number, received: number[]): number[]; export declare function mergeProductProfiles(local?: FlowCProductExecutionProfile[], confirmed?: FlowCProductExecutionProfile[]): FlowCProductExecutionProfile[]; export {};