76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import type { CanvasAgentContext } from "@/types/canvas/agent-protocol";
|
||
|
||
function trimText(value: unknown, maxLength: number) {
|
||
return typeof value === "string" ? value.trim().slice(0, maxLength) : "";
|
||
}
|
||
|
||
function uniqueStrings(values: Array<string | undefined | null>) {
|
||
return Array.from(
|
||
new Set(values.map((value) => trimText(value, 160)).filter(Boolean))
|
||
);
|
||
}
|
||
|
||
export function hasCanvasAgentAnnotationEditIntent(userText: string) {
|
||
const text = trimText(userText, 1000);
|
||
if (!text) return false;
|
||
const annotationKeyword = "(?:批注|标注|箭头|框选|圈选|备注|annotation|note)";
|
||
if (new RegExp(`(?:添加|新增|创建|加|写).{0,8}${annotationKeyword}`, "i").test(text)) {
|
||
return false;
|
||
}
|
||
return (
|
||
new RegExp(`(?:按|按照|根据|依据|依照|参考|基于).{0,18}${annotationKeyword}`, "i").test(
|
||
text
|
||
) ||
|
||
new RegExp(
|
||
`${annotationKeyword}.{0,24}(?:修改|编辑|修图|改图|处理|调整|去掉|移除|换|生成|出图|执行)`,
|
||
"i"
|
||
).test(text)
|
||
);
|
||
}
|
||
|
||
export function buildCanvasAgentAnnotationEditPrompt(params: {
|
||
context?: CanvasAgentContext | null;
|
||
targetNodeIds?: string[];
|
||
userText: string;
|
||
maxAnnotations?: number;
|
||
}) {
|
||
const context = params.context;
|
||
if (!context || !hasCanvasAgentAnnotationEditIntent(params.userText)) {
|
||
return "";
|
||
}
|
||
|
||
const targetNodeIds = uniqueStrings([
|
||
...(params.targetNodeIds || []),
|
||
...context.selectedNodeIds,
|
||
...context.selectedNodes.filter((node) => node.isSelected).map((node) => node.nodeId),
|
||
]);
|
||
if (targetNodeIds.length === 0) return "";
|
||
|
||
const targetSet = new Set(targetNodeIds);
|
||
const annotations = context.annotations
|
||
.filter((annotation) => targetSet.has(annotation.sourceNodeId))
|
||
.slice(0, Math.max(1, params.maxAnnotations || 8));
|
||
if (annotations.length === 0) return "";
|
||
|
||
const lines = annotations.map((annotation, index) => {
|
||
const parts = [
|
||
`${index + 1}. 节点 ${annotation.sourceNodeId}`,
|
||
`类型 ${annotation.type}`,
|
||
annotation.text ? `说明:${annotation.text}` : "",
|
||
annotation.bounds
|
||
? `框选区域:x=${annotation.bounds.x}, y=${annotation.bounds.y}, width=${annotation.bounds.width}, height=${annotation.bounds.height}`
|
||
: "",
|
||
annotation.targetPoint
|
||
? `目标点:x=${annotation.targetPoint.x}, y=${annotation.targetPoint.y}`
|
||
: "",
|
||
].filter(Boolean);
|
||
return parts.join(";");
|
||
});
|
||
|
||
return [
|
||
"【画布批注编辑要求】用户要求按画布批注/标注执行编辑。请把以下批注作为本轮编辑的主要约束:",
|
||
...lines,
|
||
"执行要求:优先修改批注指向或框选的区域;未被批注要求修改的主体、背景、构图与文字尽量保持不变;如果批注文字与用户当前文字冲突,以用户当前文字为准。",
|
||
].join("\n");
|
||
}
|