fix: trace annotation edits in canvas writeback metadata
This commit is contained in:
parent
ef0f9bc93d
commit
763696e8d0
@ -3,7 +3,9 @@ import {
|
||||
getSelectedMediaNodes,
|
||||
getSelectedSlots,
|
||||
} from "@/lib/canvas/agent-context";
|
||||
import { hasCanvasAgentAnnotationEditIntent } from "@/lib/canvas/agent-annotation-prompt";
|
||||
import type {
|
||||
CanvasAgentAnnotationRef,
|
||||
CanvasAgentContext,
|
||||
CanvasAgentNodeRef,
|
||||
CanvasMediaItem,
|
||||
@ -69,6 +71,43 @@ function resolveTargetMediaNodes(params: {
|
||||
);
|
||||
}
|
||||
|
||||
function formatAnnotationBrief(annotation: CanvasAgentAnnotationRef) {
|
||||
const parts = [
|
||||
annotation.id,
|
||||
annotation.type,
|
||||
annotation.text ? `text=${annotation.text}` : "",
|
||||
annotation.bounds
|
||||
? `bounds=${annotation.bounds.x},${annotation.bounds.y},${annotation.bounds.width},${annotation.bounds.height}`
|
||||
: "",
|
||||
annotation.targetPoint
|
||||
? `target=${annotation.targetPoint.x},${annotation.targetPoint.y}`
|
||||
: "",
|
||||
].filter(Boolean);
|
||||
return parts.join(";");
|
||||
}
|
||||
|
||||
function buildAnnotationTraceMetadata(params: {
|
||||
context: CanvasAgentContext;
|
||||
sourceNodeIds: string[];
|
||||
userText?: string | null;
|
||||
}) {
|
||||
if (!hasCanvasAgentAnnotationEditIntent(params.userText || "")) return {};
|
||||
const sourceNodeIdSet = new Set(params.sourceNodeIds);
|
||||
const annotations = params.context.annotations
|
||||
.filter((annotation) => sourceNodeIdSet.has(annotation.sourceNodeId))
|
||||
.slice(0, 8);
|
||||
if (annotations.length === 0) return {};
|
||||
|
||||
return {
|
||||
canvasAgentAnnotationIds: annotations.map((annotation) => annotation.id),
|
||||
canvasAgentAnnotationCount: annotations.length,
|
||||
canvasAgentAnnotationBrief: annotations
|
||||
.map(formatAnnotationBrief)
|
||||
.join("\n")
|
||||
.slice(0, 2000),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildCanvasAgentDirectWritebackPlan(
|
||||
params: BuildCanvasAgentDirectWritebackPlanParams
|
||||
): CanvasAgentDirectWritebackPlanResult | null {
|
||||
@ -131,6 +170,9 @@ export function buildCanvasAgentDirectWritebackPlan(
|
||||
: "insert_beside";
|
||||
const mediaItems: CanvasMediaItem[] = resultUrls.map((url, index) => {
|
||||
const mediaItemId = `${params.assistantMessageId}:${params.operationLabel}:${index + 1}`;
|
||||
const itemSourceNodeIds = perResultSourceNodeIds[index]
|
||||
? [perResultSourceNodeIds[index]]
|
||||
: sourceNodeIds;
|
||||
return {
|
||||
mediaItemId,
|
||||
type: params.resultType,
|
||||
@ -139,14 +181,17 @@ export function buildCanvasAgentDirectWritebackPlan(
|
||||
title:
|
||||
params.resultType === "video" ? "Agent 视频结果" : "Agent 图片结果",
|
||||
prompt: params.prompt,
|
||||
sourceNodeIds: perResultSourceNodeIds[index]
|
||||
? [perResultSourceNodeIds[index]]
|
||||
: sourceNodeIds,
|
||||
sourceNodeIds: itemSourceNodeIds,
|
||||
metadata: {
|
||||
messageId: params.assistantMessageId,
|
||||
chatId: params.chatId,
|
||||
model: params.model || undefined,
|
||||
sourceImageUrls: params.sourceImageUrls || [],
|
||||
...buildAnnotationTraceMetadata({
|
||||
context: params.context,
|
||||
sourceNodeIds: itemSourceNodeIds,
|
||||
userText: params.requestTextContent || params.prompt,
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@ -570,6 +570,52 @@ test.describe("canvas chat pure helpers", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("records annotation trace metadata for direct annotation edits", () => {
|
||||
const context: CanvasAgentContext = {
|
||||
...plannerContext,
|
||||
annotations: [
|
||||
{
|
||||
id: "annotation-keep-bg",
|
||||
sourceNodeId: "image-1",
|
||||
type: "text-note",
|
||||
text: "背景换成浅灰",
|
||||
bounds: { x: 0.1, y: 0.2, width: 0.3, height: 0.4 },
|
||||
},
|
||||
{
|
||||
id: "annotation-other",
|
||||
sourceNodeId: "image-other",
|
||||
type: "text-note",
|
||||
text: "不应进入 image-1 的结果 metadata",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = buildCanvasAgentDirectWritebackPlan({
|
||||
projectId: plannerContext.projectId || "",
|
||||
chatId: "chat-1",
|
||||
assistantMessageId: "assistant-annotation-edit",
|
||||
operationLabel: "agent-edit-image",
|
||||
resultType: "image",
|
||||
resultUrls: ["https://cdn.example.com/annotation-edit.png"],
|
||||
prompt: "按批注修改这张图",
|
||||
requestTextContent: "按批注修改这张图",
|
||||
mode: "edit",
|
||||
context,
|
||||
targetRefs: [{ nodeId: "image-1" }],
|
||||
});
|
||||
|
||||
expect(result?.mediaItems[0]?.metadata).toMatchObject({
|
||||
canvasAgentAnnotationIds: ["annotation-keep-bg"],
|
||||
canvasAgentAnnotationCount: 1,
|
||||
});
|
||||
expect(
|
||||
String(result?.mediaItems[0]?.metadata?.canvasAgentAnnotationBrief || "")
|
||||
).toContain("背景换成浅灰");
|
||||
expect(
|
||||
String(result?.mediaItems[0]?.metadata?.canvasAgentAnnotationBrief || "")
|
||||
).not.toContain("annotation-other");
|
||||
});
|
||||
|
||||
test("plans direct batch generations beside each matched source", () => {
|
||||
const context: CanvasAgentContext = {
|
||||
...plannerContext,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user