import "server-only"; import type { AgentThreadState } from "@/lib/ai/runtime/agent-thread-state"; import type { PromptMemoryEntry } from "@/lib/ai/prompt-memory"; import type { ImageWorkflowMemory } from "@/lib/ai/image-workflow-memory"; import type { StoryboardPreferenceMemory } from "@/lib/video-agent/storyboard-preference-memory"; import { buildAgentThreadStateFromStoryboardTask } from "@/lib/video-agent/agent-thread-state"; type StoryboardTaskDetail = Parameters[0]; function normalizeText(value: unknown, max = 240): string | undefined { const normalized = String(value || "").trim(); if (!normalized) return undefined; return normalized.slice(0, max); } export function buildConversationThreadState(params: { activeStoryboardTask?: StoryboardTaskDetail | null; storyboardPreferenceMemory?: StoryboardPreferenceMemory | null; promptMemory?: PromptMemoryEntry | null; imageWorkflowMemory?: ImageWorkflowMemory | null; }): AgentThreadState | null { const storyboardState = buildAgentThreadStateFromStoryboardTask( params.activeStoryboardTask, { storyboardPreferenceMemory: params.storyboardPreferenceMemory, promptMemory: params.promptMemory, }, ); if (params.activeStoryboardTask?.task?.id) { return { workflowState: storyboardState?.workflowState || null, memoryHints: [ ...(storyboardState?.memoryHints || []), params.imageWorkflowMemory?.lastOptimizedPrompt ? "当前会话里也保留了最近一次图片工作流记忆,可辅助理解用户是在继续哪一轮生图。" : "", ].filter(Boolean), contextSummary: storyboardState?.contextSummary || normalizeText(params.imageWorkflowMemory?.lastUserPrompt, 320), metadata: { ...(storyboardState?.metadata || {}), imageWorkflowMemory: params.imageWorkflowMemory || undefined, }, }; } const hasImageFollowup = Boolean(params.promptMemory?.optimizedPrompt) || Boolean(params.imageWorkflowMemory?.lastOptimizedPrompt) || Boolean(params.imageWorkflowMemory?.lastResultImageUrls?.length) || Boolean(params.imageWorkflowMemory?.lastSourceImageUrls?.length); if (!hasImageFollowup && !params.storyboardPreferenceMemory) { return null; } const preferredCount = params.imageWorkflowMemory?.lastRequestedImageCount; const preferredRatio = params.imageWorkflowMemory?.lastAspectRatio; const preferredSize = params.imageWorkflowMemory?.lastImageSize; const sourceCount = params.imageWorkflowMemory?.lastSourceImageUrls?.length || 0; const resultCount = params.imageWorkflowMemory?.lastResultImageUrls?.length || 0; const imageFollowupType = params.imageWorkflowMemory?.lastIntent === "image_edit" ? "image_edit_followup" : "image_generation_followup"; const imageFollowupTitle = imageFollowupType === "image_edit_followup" ? "连续修图工作流" : "连续生图工作流"; return { workflowState: hasImageFollowup ? { workflowId: "image-generation-followup", type: imageFollowupType, status: "draft", title: imageFollowupTitle, summary: [ params.promptMemory?.optimizedPrompt || params.imageWorkflowMemory?.lastOptimizedPrompt ? "当前会话中存在上一轮可复用提示词。" : "", preferredCount ? `上一轮目标出图数:${preferredCount} 张。` : "", preferredRatio ? `上一轮画幅:${preferredRatio}。` : "", preferredSize ? `上一轮清晰度:${preferredSize}。` : "", sourceCount > 0 ? `上一轮参考图数:${sourceCount}。` : "", resultCount > 0 ? `上一轮结果图数:${resultCount}。` : "", ] .filter(Boolean) .join(" "), confirmPhrases: ["按上一个提示词生成", "继续生成", "就按这个来"], revisionHints: ["换一版", "保持提示词不变再来一组", "沿用上一个提示词"], pendingItems: [], metadata: { promptMemory: params.promptMemory || undefined, imageWorkflowMemory: params.imageWorkflowMemory || undefined, storyboardPreferenceMemory: params.storyboardPreferenceMemory || undefined, }, } : null, memoryHints: [ params.promptMemory?.optimizedPrompt ? "当前会话存在上一轮可复用提示词;如果用户明确要求沿用它继续生成,应优先复用。" : "", params.imageWorkflowMemory?.lastResultImageUrls?.length ? "当前会话保留了上一轮生成结果图,可用于理解“继续做这张/沿用上一版”的指代。" : "", params.imageWorkflowMemory?.lastSourceImageUrls?.length ? "当前会话保留了上一轮参考图/目标图,可用于连续图生图理解。" : "", params.storyboardPreferenceMemory ? "当前会话也存在 storyboard 偏好记忆,后续如果转入分镜任务可继续复用。" : "", ].filter(Boolean), contextSummary: [ params.promptMemory?.optimizedPrompt ? `上一轮提示词摘要:${normalizeText(params.promptMemory.optimizedPrompt, 180)}` : "", params.imageWorkflowMemory?.lastUserPrompt ? `上一轮用户原始需求:${normalizeText(params.imageWorkflowMemory.lastUserPrompt, 180)}` : "", ] .filter(Boolean) .join("\n"), metadata: { promptMemory: params.promptMemory || undefined, imageWorkflowMemory: params.imageWorkflowMemory || undefined, storyboardPreferenceMemory: params.storyboardPreferenceMemory || undefined, }, }; }