feat: label image notes as canvas annotations

This commit is contained in:
134 2026-06-22 22:17:25 +08:00
parent bcea56c0d9
commit 3c7c122b2f
3 changed files with 22 additions and 9 deletions

View File

@ -5737,7 +5737,7 @@ export function ImageNode({
}); });
setDraftNote(nextNote); setDraftNote(nextNote);
setNotePanelOpen(false); setNotePanelOpen(false);
toast.success(nextNote ? "备注已保存" : "备注已清除"); toast.success(nextNote ? "批注已保存" : "批注已清除");
}, [data, draftNote, node.id, updateNode]); }, [data, draftNote, node.id, updateNode]);
const detectTextItems = useCallback( const detectTextItems = useCallback(
@ -6136,7 +6136,7 @@ export function ImageNode({
"scene-fusion": "批量处理", "scene-fusion": "批量处理",
annotate: "标注", annotate: "标注",
"text-edit": "改字", "text-edit": "改字",
note: "备注", note: "添加批注",
"prompt-regenerate": "重绘", "prompt-regenerate": "重绘",
"box-cutout": "框选抠图", "box-cutout": "框选抠图",
"local-edit": "局部编辑", "local-edit": "局部编辑",
@ -10677,7 +10677,7 @@ export function ImageNode({
document.body document.body
)} )}
{/* 图片备注对话框 */} {/* 图片批注对话框 */}
<Dialog onOpenChange={setNotePanelOpen} open={notePanelOpen}> <Dialog onOpenChange={setNotePanelOpen} open={notePanelOpen}>
<DialogContent <DialogContent
className="max-h-[85vh] overflow-y-auto border-slate-200 bg-white opacity-100 shadow-2xl backdrop-blur-none sm:max-w-[560px] dark:border-slate-700 dark:bg-slate-950" className="max-h-[85vh] overflow-y-auto border-slate-200 bg-white opacity-100 shadow-2xl backdrop-blur-none sm:max-w-[560px] dark:border-slate-700 dark:bg-slate-950"
@ -10686,26 +10686,26 @@ export function ImageNode({
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center gap-2"> <DialogTitle className="flex items-center gap-2">
<StickyNote className="h-5 w-5" /> <StickyNote className="h-5 w-5" />
图片备注 图片批注
</DialogTitle> </DialogTitle>
</DialogHeader> </DialogHeader>
<div className="space-y-3 py-1"> <div className="space-y-3 py-1">
<Textarea <Textarea
className="min-h-[180px] resize-y border-slate-300 bg-white opacity-100 dark:border-slate-700 dark:bg-slate-950" className="min-h-[180px] resize-y border-slate-300 bg-white opacity-100 dark:border-slate-700 dark:bg-slate-950"
onChange={(e) => setDraftNote(e.target.value)} onChange={(e) => setDraftNote(e.target.value)}
placeholder="记录这张图的想法、待办或交付要求..." placeholder="记录这张图的修改要求、局部说明或交付批注..."
rows={8} rows={8}
value={draftNote} value={draftNote}
/> />
<p className="text-muted-foreground text-xs"> <p className="text-muted-foreground text-xs">
备注仅在你点开时显示,不会直接覆盖在画面上。 批注会作为 Agent 修改图片时的上下文,不会直接覆盖在画面上。
</p> </p>
</div> </div>
<DialogFooter> <DialogFooter>
<Button onClick={() => setNotePanelOpen(false)} variant="outline"> <Button onClick={() => setNotePanelOpen(false)} variant="outline">
取消 取消
</Button> </Button>
<Button onClick={handleSaveNote}>保存备注</Button> <Button onClick={handleSaveNote}>保存批注</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>

View File

@ -295,8 +295,8 @@ export const DEFAULT_CANVAS_TOOLBAR_ITEMS = [
{ {
key: "imageNote", key: "imageNote",
group: "节点工具栏", group: "节点工具栏",
label: "备注", label: "添加批注",
description: "打开或显示图片备注", description: "打开图片批注并作为 Agent 编辑上下文",
}, },
{ {
key: "imageRename", key: "imageRename",

View File

@ -20,6 +20,10 @@ import {
buildCanvasAgentAnnotationEditPrompt, buildCanvasAgentAnnotationEditPrompt,
hasCanvasAgentAnnotationEditIntent, hasCanvasAgentAnnotationEditIntent,
} from "@/lib/canvas/agent-annotation-prompt"; } from "@/lib/canvas/agent-annotation-prompt";
import {
defaultCanvasToolbarConfig,
getCanvasToolbarItem,
} from "@/lib/canvas-toolbar-config";
import { shouldBypassCanvasAgentMissingTargetClarification } from "@/lib/ai/runtime/canvas-agent-clarification"; import { shouldBypassCanvasAgentMissingTargetClarification } from "@/lib/ai/runtime/canvas-agent-clarification";
import { import {
CANVAS_LOCAL_EDIT_REGION_ANNOTATION_SOURCE, CANVAS_LOCAL_EDIT_REGION_ANNOTATION_SOURCE,
@ -1809,6 +1813,15 @@ test.describe("canvas chat pure helpers", () => {
).toBe(""); ).toBe("");
}); });
test("labels image note action as an agent annotation entry", () => {
expect(
getCanvasToolbarItem(defaultCanvasToolbarConfig, "imageNote")
).toMatchObject({
label: "添加批注",
enabled: true,
});
});
test("syncs image notes into structured canvas annotations", () => { test("syncs image notes into structured canvas annotations", () => {
const first = syncCanvasNodeNoteAnnotationMetadata({ const first = syncCanvasNodeNoteAnnotationMetadata({
metadata: { metadata: {