134 lines
5.7 KiB
TypeScript
134 lines
5.7 KiB
TypeScript
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<typeof buildAgentThreadStateFromStoryboardTask>[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,
|
||
},
|
||
};
|
||
}
|