ai-chatbot/lib/ai/conversation-thread-state-builder.ts
Your Name e7812060b8
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
Update conversation memory and canvas persistence
2026-03-13 12:31:13 +08:00

134 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
},
};
}