export type AgentWorkflowType = | "storyboard_video" | "image_generation_followup" | "image_edit_followup" | "high_cost_video" | "image_batch" | "custom"; export type AgentWorkflowStatus = | "draft" | "awaiting_user_confirmation" | "confirmed" | "rejected" | "running" | "completed" | "failed" | "cancelled"; export interface AgentWorkflowPendingItem { id?: string; index?: number; title?: string; summary?: string; status?: string; } export interface AgentWorkflowState { workflowId: string; type: AgentWorkflowType; status: AgentWorkflowStatus; title?: string; summary?: string; confirmPhrases: string[]; revisionHints: string[]; pendingItems: AgentWorkflowPendingItem[]; metadata?: Record; } function normalizeText(value: unknown, max = 200): string | undefined { const normalized = String(value || "").trim(); if (!normalized) return undefined; return normalized.slice(0, max); } function normalizeList(value: unknown, fallback: string[]): string[] { const raw = Array.isArray(value) ? value : fallback; const normalized = raw .map((item) => String(item || "").trim()) .filter(Boolean); return normalized.length > 0 ? Array.from(new Set(normalized)) : fallback; } function normalizePendingItems(value: unknown): AgentWorkflowPendingItem[] { if (!Array.isArray(value)) return []; return value .map((item) => { if (!item || typeof item !== "object") return null; const record = item as Record; const normalized: AgentWorkflowPendingItem = { id: normalizeText(record.id, 80), title: normalizeText(record.title, 80), summary: normalizeText(record.summary, 160), status: normalizeText(record.status, 32), }; const rawIndex = Number(record.index); if (Number.isFinite(rawIndex) && rawIndex > 0) { normalized.index = Math.round(rawIndex); } return normalized; }) .filter((item): item is AgentWorkflowPendingItem => Boolean(item)); } export function normalizeAgentWorkflowState( value?: Partial | null, ): AgentWorkflowState | null { if (!value || typeof value !== "object") return null; const workflowId = normalizeText(value.workflowId, 120); const type = normalizeText(value.type, 32) as AgentWorkflowType | undefined; const status = normalizeText(value.status, 40) as AgentWorkflowStatus | undefined; if (!workflowId || !type || !status) { return null; } return { workflowId, type, status, title: normalizeText(value.title, 120), summary: normalizeText(value.summary, 240), confirmPhrases: normalizeList(value.confirmPhrases, [ "确认开始生成视频", "开始生成", "按这个分镜生成", ]), revisionHints: normalizeList(value.revisionHints, [ "修改第3镜头", "调整第5镜头动作", "重生第2张高清图", ]), pendingItems: normalizePendingItems(value.pendingItems), metadata: value.metadata && typeof value.metadata === "object" && !Array.isArray(value.metadata) ? (value.metadata as Record) : undefined, }; } export function isAwaitingUserConfirmationWorkflow( workflowState?: AgentWorkflowState | null, ): boolean { return workflowState?.status === "awaiting_user_confirmation"; }