feat(agent): 创作能力 - 接通专业节点发现与插件执行基础

This commit is contained in:
王志伟 committed 2026-09-09 13:01:30 +08:00
1 parent 88f4b9ccdf
commit f69535c93f
29 files changed
+617 -88

No files matched your search

+12 -9
View File
@@ -1,12 +1,14 @@
import { nanoid } from "nanoid";
import { getNodeSpec } from "@/constant/canvas";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type CanvasNodeMetadata, type ViewportTransform } from "@/types/canvas";
import { getNodeDefinition } from "./node-registry";
import { isPluginEffectivelyEnabled } from "@/stores/use-plugin-store";
import { CanvasNodeType, type CanvasNodeTypeId, type CanvasConnection, type CanvasNodeData, type CanvasNodeMetadata, type ViewportTransform } from "@/types/canvas";
export type CanvasAgentOp =
| { type: "add_node"; id?: string; nodeType?: CanvasNodeType; title?: string; position?: { x: number; y: number }; x?: number; y?: number; width?: number; height?: number; metadata?: CanvasNodeMetadata }
| { type: "add_node"; id?: string; nodeType?: CanvasNodeTypeId; title?: string; position?: { x: number; y: number }; x?: number; y?: number; width?: number; height?: number; metadata?: CanvasNodeMetadata }
| { type: "update_node"; id: string; patch?: Partial<CanvasNodeData>; metadata?: CanvasNodeMetadata }
| { type: "delete_node"; id?: string; ids?: string[]; nodeType?: CanvasNodeType }
| { type: "delete_node"; id?: string; ids?: string[]; nodeType?: CanvasNodeTypeId }
| { type: "delete_connections"; id?: string; ids?: string[]; all?: boolean }
| { type: "connect_nodes"; id?: string; fromNodeId: string; toNodeId: string; fromHandleId?: string; toHandleId?: string }
| { type: "set_viewport"; viewport: ViewportTransform }
@@ -320,8 +322,10 @@ export function applyCanvasAgentOps(snapshot: CanvasAgentSnapshot, ops?: CanvasA
(Array.isArray(ops) ? ops : []).forEach((op, index) => {
if (!op?.type) return;
if (op.type === "add_node") {
const nodeType = Object.values(CanvasNodeType).includes(op.nodeType as CanvasNodeType) ? op.nodeType! : CanvasNodeType.Text;
const spec = getNodeSpec(nodeType);
const nodeType = op.nodeType || CanvasNodeType.Text;
const definition = getNodeDefinition(nodeType);
if (!definition || (definition.plugin && !isPluginEffectivelyEnabled(definition.plugin.pluginId))) throw new Error(`节点类型未注册或插件不可用:${nodeType}`);
const spec = getNodeSpec(nodeType as CanvasNodeType) || { title: definition.defaultTitle, ...definition.defaultSize, metadata: definition.defaultMetadata };
const node: CanvasNodeData = {
id: op.id || `${nodeType}-${Date.now()}-${index}`,
type: nodeType,
@@ -329,7 +333,7 @@ export function applyCanvasAgentOps(snapshot: CanvasAgentSnapshot, ops?: CanvasA
position: op.position || { x: op.x ?? index * 36, y: op.y ?? index * 36 },
width: op.width || spec.width,
height: op.height || spec.height,
metadata: { ...spec.metadata, ...op.metadata },
metadata: { ...spec.metadata, ...op.metadata, ...(definition.plugin ? { pluginId: definition.plugin.pluginId, pluginNodeId: nodeType } : {}) },
};
nodes = [...nodes, node];
selectedNodeIds = [node.id];
@@ -390,7 +394,7 @@ function opLabel(type: string) {
return type;
}
function canvasNodeTypeLabel(type?: CanvasNodeType) {
function canvasNodeTypeLabel(type?: CanvasNodeTypeId) {
if (type === CanvasNodeType.Image) return "图片节点";
if (type === CanvasNodeType.Video) return "视频节点";
if (type === CanvasNodeType.Audio) return "音频节点";
@@ -399,8 +403,7 @@ function canvasNodeTypeLabel(type?: CanvasNodeType) {
if (type === CanvasNodeType.Frame) return "背板";
if (type === CanvasNodeType.Drawing) return "绘图节点";
if (type === CanvasNodeType.Skill) return "技能节点";
if (type === CanvasNodeType.MediaConversion) return "转换节点";
return "文本节点";
return type ? `${getNodeDefinition(type)?.label || type}节点` : "文本节点";
}
function generationModeLabel(mode?: "text" | "image" | "video" | "audio") {