feat(canvas): auto-name generated images via auto-title model
This commit is contained in:
parent
c43f6a95fc
commit
d137e0ba26
@ -2676,13 +2676,14 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
const x = 100 + (existingNodes % 3) * (dimensions.width + spacing);
|
||||
const y = 100 + Math.floor(existingNodes / 3) * (dimensions.height + spacing);
|
||||
|
||||
addNode({
|
||||
const nodeId = addNode({
|
||||
type: 'image',
|
||||
position: { x, y },
|
||||
size: { width: dimensions.width, height: dimensions.height },
|
||||
data: {
|
||||
src: url,
|
||||
status: 'completed',
|
||||
title: '图片',
|
||||
prompt: generationPrompt || '对话生成',
|
||||
metadata: {
|
||||
originalWidth: dimensions.originalWidth,
|
||||
@ -2693,6 +2694,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
},
|
||||
connections: [],
|
||||
});
|
||||
void autoNameGeneratedImageNode(nodeId, url);
|
||||
addedImageCount += 1;
|
||||
}
|
||||
}
|
||||
@ -2736,7 +2738,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [messages, addNode, nodes]);
|
||||
}, [messages, addNode, nodes, autoNameGeneratedImageNode]);
|
||||
|
||||
// 为历史节点补全可编辑的原始提示词(旧数据里可能只有“对话生成”占位文案)
|
||||
useEffect(() => {
|
||||
@ -2789,6 +2791,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
|
||||
// 标记是否已经为当前画布设置过标题(避免重复调用)
|
||||
const hasSetCanvasTitle = useRef(false);
|
||||
const imageAutoTitleCacheRef = useRef<Map<string, string>>(new Map());
|
||||
|
||||
// 🆕 Agent模式上下文(画布图片布局)
|
||||
const buildAutoContext = useCallback(() => {
|
||||
@ -4437,6 +4440,60 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
}
|
||||
}, [chatId]);
|
||||
|
||||
const autoNameGeneratedImageNode = useCallback(
|
||||
async (nodeId: string, imageUrl: string) => {
|
||||
if (!nodeId || !imageUrl) return;
|
||||
|
||||
const normalizeAutoTitle = (rawTitle: string) => {
|
||||
const compact = String(rawTitle || "").replace(/\s+/g, "").trim();
|
||||
if (!compact || compact === "新画布" || compact === "未命名画布" || compact.includes("画布")) {
|
||||
return "图片";
|
||||
}
|
||||
return compact.slice(0, 12);
|
||||
};
|
||||
|
||||
const applyNodeTitle = (title: string) => {
|
||||
const storeState = useCanvasStore.getState();
|
||||
const currentNode = storeState.getNode(nodeId);
|
||||
if (!currentNode) return;
|
||||
const currentData = ((currentNode.data as any) || {}) as Record<string, any>;
|
||||
storeState.updateNode(nodeId, {
|
||||
data: {
|
||||
...currentData,
|
||||
title,
|
||||
metadata: {
|
||||
...(currentData.metadata || {}),
|
||||
autoTitle: title,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const cachedTitle = imageAutoTitleCacheRef.current.get(imageUrl);
|
||||
if (cachedTitle) {
|
||||
applyNodeTitle(cachedTitle);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/canvas/auto-title', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ imageUrl }),
|
||||
});
|
||||
|
||||
const data = await response.json().catch(() => ({}));
|
||||
const title = normalizeAutoTitle(String(data?.title || ""));
|
||||
imageAutoTitleCacheRef.current.set(imageUrl, title);
|
||||
applyNodeTitle(title);
|
||||
} catch (error) {
|
||||
console.warn('[CanvasChat] 自动命名图片失败:', error);
|
||||
applyNodeTitle("图片");
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const uploadImageFileAndAddToCanvas = useCallback(async (
|
||||
file: File,
|
||||
nodeIndex: number
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user