import { createEmptyAgentModeWorkspaceState, normalizeAgentModeWorkspaceState, } from "@/lib/agents/mode-workspace-state"; import { createEmptyAgentWorkflowMaterialSelections, normalizeAgentWorkflowMaterialSelections, } from "@/lib/agents/workflow-material-config"; import type { AgentGenerationProjectPersistedState, AgentGenerationProjectWorkspaceState, AgentWorkflowPersistedState, } from "@/types/agent"; export function createEmptyAgentGenerationProjectWorkspaceState(): AgentGenerationProjectWorkspaceState { return { input: "", attachments: [], selectedModelId: "auto", imageParams: { aspectRatio: "auto", imageSize: "2K", imageCount: 1, }, }; } export function createEmptyAgentWorkflowPersistedState(): AgentWorkflowPersistedState { return { inputs: { primarySku: "", secondarySku: "", brand: "", store: "", }, materials: createEmptyAgentWorkflowMaterialSelections(), selections: {}, selectedBrandModel: null, selectedAgentPresetId: null, currentStage: "workflow", agentModeState: createEmptyAgentModeWorkspaceState(), }; } export function createEmptyAgentGenerationProjectPersistedState(): AgentGenerationProjectPersistedState { return { workflowState: createEmptyAgentWorkflowPersistedState(), workspaceState: createEmptyAgentGenerationProjectWorkspaceState(), resultImageUrls: [], }; } function normalizeWorkspaceState(value: unknown): AgentGenerationProjectWorkspaceState { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; const attachments = Array.isArray(raw.attachments) ? raw.attachments .map((item) => { if (!item || typeof item !== "object" || Array.isArray(item)) { return null; } const record = item as Record; const url = String(record.url || "").trim(); if (!url) return null; return { url, name: String(record.name || "").trim() || null, contentType: String(record.contentType || "").trim() || null, assetId: String(record.assetId || "").trim() || null, }; }) .slice(0, 16) : []; const rawImageParams = raw.imageParams && typeof raw.imageParams === "object" && !Array.isArray(raw.imageParams) ? (raw.imageParams as Record) : {}; const imageCount = Number(rawImageParams.imageCount); return { input: String(raw.input || "").trim(), attachments, selectedModelId: String(raw.selectedModelId || "").trim() || "auto", imageParams: { aspectRatio: String(rawImageParams.aspectRatio || "").trim() || "auto", imageSize: String(rawImageParams.imageSize || "").trim() || "2K", imageCount: Number.isFinite(imageCount) ? Math.max(1, Math.min(8, Math.round(imageCount))) : 1, }, }; } function normalizeWorkflowState(value: unknown): AgentWorkflowPersistedState { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; return { inputs: { primarySku: String(raw.inputs && typeof raw.inputs === "object" ? (raw.inputs as Record).primarySku || "" : "").trim(), secondarySku: String(raw.inputs && typeof raw.inputs === "object" ? (raw.inputs as Record).secondarySku || "" : "").trim(), brand: String(raw.inputs && typeof raw.inputs === "object" ? (raw.inputs as Record).brand || "" : "").trim(), store: String(raw.inputs && typeof raw.inputs === "object" ? (raw.inputs as Record).store || "" : "").trim(), }, materials: normalizeAgentWorkflowMaterialSelections(raw.materials), selections: raw.selections && typeof raw.selections === "object" && !Array.isArray(raw.selections) ? (raw.selections as Record) : {}, selectedBrandModel: raw.selectedBrandModel && typeof raw.selectedBrandModel === "object" && !Array.isArray(raw.selectedBrandModel) ? { ...(raw.selectedBrandModel as Record), brandName: String((raw.selectedBrandModel as Record).brandName || "").trim(), id: String((raw.selectedBrandModel as Record).id || "").trim(), imageUrl: String((raw.selectedBrandModel as Record).imageUrl || "").trim(), assetId: String((raw.selectedBrandModel as Record).assetId || "").trim() || null, displayName: String((raw.selectedBrandModel as Record).displayName || "").trim() || null, mimeType: String((raw.selectedBrandModel as Record).mimeType || "").trim() || null, sortOrder: Number.isFinite(Number((raw.selectedBrandModel as Record).sortOrder)) ? Math.max(0, Math.min(999, Math.round(Number((raw.selectedBrandModel as Record).sortOrder)))) : 0, } : null, selectedAgentPresetId: String(raw.selectedAgentPresetId || "").trim() || null, currentStage: raw.currentStage === "mode" ? "mode" : "workflow", agentModeState: normalizeAgentModeWorkspaceState(raw.agentModeState), }; } export function normalizeAgentGenerationProjectPersistedState( value: unknown ): AgentGenerationProjectPersistedState { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; const resultImageUrls = Array.isArray(raw.resultImageUrls) ? Array.from( new Set( raw.resultImageUrls .map((item) => String(item || "").trim()) .filter((item) => /^https?:\/\//i.test(item)) ) ).slice(0, 64) : []; return { workflowState: normalizeWorkflowState(raw.workflowState), workspaceState: normalizeWorkspaceState(raw.workspaceState), resultImageUrls, }; }