fix: route explicit canvas annotations
This commit is contained in:
parent
cf879c63b6
commit
e0dc5a3d77
@ -8,6 +8,7 @@ import {
|
|||||||
} from "@/lib/canvas/agent-model-planner";
|
} from "@/lib/canvas/agent-model-planner";
|
||||||
|
|
||||||
type ExplicitOperationKind =
|
type ExplicitOperationKind =
|
||||||
|
| "add_annotation"
|
||||||
| "create_agent_slot"
|
| "create_agent_slot"
|
||||||
| "create_text_node"
|
| "create_text_node"
|
||||||
| "rename_node"
|
| "rename_node"
|
||||||
@ -332,6 +333,59 @@ function buildUpdateNoteOperation(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildAddAnnotationOperation(params: {
|
||||||
|
context: CanvasAgentContext;
|
||||||
|
projectId: string;
|
||||||
|
messageId: string;
|
||||||
|
chatId: string;
|
||||||
|
userText: string;
|
||||||
|
requestedNodeIds?: string[];
|
||||||
|
}): CanvasAgentExplicitOperationPlan | null {
|
||||||
|
const text = params.userText.trim();
|
||||||
|
if (!/批注|标注|箭头|框选/i.test(text)) return null;
|
||||||
|
if (/按.*(?:批注|标注|箭头|框选).*(?:修改|编辑|改图|改主图|生成|出图|修图)/i.test(text)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (hasMediaMutationIntent(text)) return null;
|
||||||
|
|
||||||
|
const annotationText = extractContentFromPatterns(
|
||||||
|
text,
|
||||||
|
[
|
||||||
|
/(?:添加批注|加批注|写批注|批注为|批注成|批注|添加标注|加标注|写标注|标注为|标注成|标注|箭头说明|框选说明)\s*[::]?\s*([\s\S]+)$/i,
|
||||||
|
/[::]\s*([\s\S]+)$/i,
|
||||||
|
],
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
if (!annotationText) return null;
|
||||||
|
|
||||||
|
const targetNodeIds = getTargetNodeIds({
|
||||||
|
context: params.context,
|
||||||
|
requestedNodeIds: params.requestedNodeIds,
|
||||||
|
allowedTypes: ["image", "video"],
|
||||||
|
}).slice(0, 10);
|
||||||
|
if (targetNodeIds.length === 0) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
operationPlan: {
|
||||||
|
...buildPlanBase({ ...params, operation: "add_annotation" }),
|
||||||
|
targetNodeIds,
|
||||||
|
textContent: annotationText,
|
||||||
|
annotations: [
|
||||||
|
{
|
||||||
|
type: "text-note",
|
||||||
|
text: annotationText,
|
||||||
|
color: "#f59e0b",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
reply: "已给选中图片添加批注。",
|
||||||
|
progressTitle: "正在添加画布批注",
|
||||||
|
progressMessage: "我会把批注保存到选中的图片或视频节点。",
|
||||||
|
completedTitle: "画布批注已添加",
|
||||||
|
failedTitle: "画布批注添加失败",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function buildCanvasAgentExplicitOperationPlan(params: {
|
export function buildCanvasAgentExplicitOperationPlan(params: {
|
||||||
context: CanvasAgentContext;
|
context: CanvasAgentContext;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
@ -354,6 +408,7 @@ export function buildCanvasAgentExplicitOperationPlan(params: {
|
|||||||
buildCreateAgentSlotOperation(commonParams) ||
|
buildCreateAgentSlotOperation(commonParams) ||
|
||||||
buildCreateTextOperation(commonParams) ||
|
buildCreateTextOperation(commonParams) ||
|
||||||
buildRenameOperation(commonParams) ||
|
buildRenameOperation(commonParams) ||
|
||||||
buildUpdateNoteOperation(commonParams)
|
buildUpdateNoteOperation(commonParams) ||
|
||||||
|
buildAddAnnotationOperation(commonParams)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1020,6 +1020,34 @@ test.describe("canvas chat pure helpers", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("builds deterministic annotation additions for selected media nodes only", () => {
|
||||||
|
const outcome = buildCanvasAgentExplicitOperationPlan({
|
||||||
|
context: plannerContext,
|
||||||
|
projectId: plannerContext.projectId || "",
|
||||||
|
messageId: "message-1",
|
||||||
|
chatId: "chat-1",
|
||||||
|
userText: "给选中图片加批注:这里需要重点保留产品轮廓",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(outcome?.operationPlan).toMatchObject({
|
||||||
|
operation: "add_annotation",
|
||||||
|
targetNodeIds: ["image-1"],
|
||||||
|
textContent: "这里需要重点保留产品轮廓",
|
||||||
|
annotations: [
|
||||||
|
{
|
||||||
|
type: "text-note",
|
||||||
|
text: "这里需要重点保留产品轮廓",
|
||||||
|
color: "#f59e0b",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
messageId: "message-1",
|
||||||
|
chatId: "chat-1",
|
||||||
|
planner: "deterministic",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("does not route media generation or note-driven image edits as explicit canvas operations", () => {
|
test("does not route media generation or note-driven image edits as explicit canvas operations", () => {
|
||||||
expect(
|
expect(
|
||||||
buildCanvasAgentExplicitOperationPlan({
|
buildCanvasAgentExplicitOperationPlan({
|
||||||
@ -1050,6 +1078,16 @@ test.describe("canvas chat pure helpers", () => {
|
|||||||
userText: "新建一个视频槽位并生成片头",
|
userText: "新建一个视频槽位并生成片头",
|
||||||
})
|
})
|
||||||
).toBeNull();
|
).toBeNull();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
buildCanvasAgentExplicitOperationPlan({
|
||||||
|
context: plannerContext,
|
||||||
|
projectId: plannerContext.projectId || "",
|
||||||
|
messageId: "message-1",
|
||||||
|
chatId: "chat-1",
|
||||||
|
userText: "按这张图上的批注修改",
|
||||||
|
})
|
||||||
|
).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("normalizes model-planned annotations to selected media nodes", () => {
|
test("normalizes model-planned annotations to selected media nodes", () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user