From c4d2976df3f596fb36ea4ec9dc3b9cff58bc39a1 Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Wed, 19 Aug 2026 19:28:58 +0800 Subject: [PATCH] fix: delete folder --- ui/src/mk-workflow/core/CustomLine.vue | 39 - ui/src/mk-workflow/core/NodeCascader.vue | 131 -- ui/src/mk-workflow/core/NodeContainer.vue | 257 ---- ui/src/mk-workflow/core/NodeControl.vue | 30 - ui/src/mk-workflow/core/NodeSearch.vue | 93 -- ui/src/mk-workflow/core/app-node.ts | 247 ---- ui/src/mk-workflow/core/data.ts | 187 --- ui/src/mk-workflow/core/edge.ts | 210 --- ui/src/mk-workflow/core/shortcut.ts | 325 ----- ui/src/mk-workflow/core/teleport.ts | 77 -- ui/src/mk-workflow/core/template.ts | 1140 ----------------- ui/src/mk-workflow/core/validate.ts | 101 -- .../extension/WorkflowNodeMenu.vue | 107 -- .../mk-workflow/icons/ai-chat-node-icon.vue | 6 - ui/src/mk-workflow/icons/base-node-icon.vue | 6 - ui/src/mk-workflow/icons/reply-node-icon.vue | 6 - ui/src/mk-workflow/icons/start-node-icon.vue | 6 - ui/src/mk-workflow/icons/utils.ts | 7 - ui/src/mk-workflow/index.vue | 225 ---- .../mk-workflow/nodes/ai-chat-node/index.ts | 15 - .../mk-workflow/nodes/ai-chat-node/index.vue | 119 -- ui/src/mk-workflow/nodes/base-node/index.ts | 22 - ui/src/mk-workflow/nodes/base-node/index.vue | 74 -- ui/src/mk-workflow/nodes/reply-node/index.ts | 15 - ui/src/mk-workflow/nodes/reply-node/index.vue | 84 -- ui/src/mk-workflow/nodes/start-node/index.ts | 15 - ui/src/mk-workflow/nodes/start-node/index.vue | 111 -- ui/src/mk-workflow/plugins/dagre.ts | 66 - ui/src/mk-workflow/types.ts | 61 - 29 files changed, 3782 deletions(-) delete mode 100644 ui/src/mk-workflow/core/CustomLine.vue delete mode 100644 ui/src/mk-workflow/core/NodeCascader.vue delete mode 100644 ui/src/mk-workflow/core/NodeContainer.vue delete mode 100644 ui/src/mk-workflow/core/NodeControl.vue delete mode 100644 ui/src/mk-workflow/core/NodeSearch.vue delete mode 100644 ui/src/mk-workflow/core/app-node.ts delete mode 100644 ui/src/mk-workflow/core/data.ts delete mode 100644 ui/src/mk-workflow/core/edge.ts delete mode 100644 ui/src/mk-workflow/core/shortcut.ts delete mode 100644 ui/src/mk-workflow/core/teleport.ts delete mode 100644 ui/src/mk-workflow/core/template.ts delete mode 100644 ui/src/mk-workflow/core/validate.ts delete mode 100644 ui/src/mk-workflow/extension/WorkflowNodeMenu.vue delete mode 100644 ui/src/mk-workflow/icons/ai-chat-node-icon.vue delete mode 100644 ui/src/mk-workflow/icons/base-node-icon.vue delete mode 100644 ui/src/mk-workflow/icons/reply-node-icon.vue delete mode 100644 ui/src/mk-workflow/icons/start-node-icon.vue delete mode 100644 ui/src/mk-workflow/icons/utils.ts delete mode 100644 ui/src/mk-workflow/index.vue delete mode 100644 ui/src/mk-workflow/nodes/ai-chat-node/index.ts delete mode 100644 ui/src/mk-workflow/nodes/ai-chat-node/index.vue delete mode 100644 ui/src/mk-workflow/nodes/base-node/index.ts delete mode 100644 ui/src/mk-workflow/nodes/base-node/index.vue delete mode 100644 ui/src/mk-workflow/nodes/reply-node/index.ts delete mode 100644 ui/src/mk-workflow/nodes/reply-node/index.vue delete mode 100644 ui/src/mk-workflow/nodes/start-node/index.ts delete mode 100644 ui/src/mk-workflow/nodes/start-node/index.vue delete mode 100644 ui/src/mk-workflow/plugins/dagre.ts delete mode 100644 ui/src/mk-workflow/types.ts diff --git a/ui/src/mk-workflow/core/CustomLine.vue b/ui/src/mk-workflow/core/CustomLine.vue deleted file mode 100644 index b96df251608..00000000000 --- a/ui/src/mk-workflow/core/CustomLine.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - - diff --git a/ui/src/mk-workflow/core/NodeCascader.vue b/ui/src/mk-workflow/core/NodeCascader.vue deleted file mode 100644 index 673ab6505d0..00000000000 --- a/ui/src/mk-workflow/core/NodeCascader.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/core/NodeContainer.vue b/ui/src/mk-workflow/core/NodeContainer.vue deleted file mode 100644 index 513ddd0575e..00000000000 --- a/ui/src/mk-workflow/core/NodeContainer.vue +++ /dev/null @@ -1,257 +0,0 @@ - - - - diff --git a/ui/src/mk-workflow/core/NodeControl.vue b/ui/src/mk-workflow/core/NodeControl.vue deleted file mode 100644 index 25395e47baa..00000000000 --- a/ui/src/mk-workflow/core/NodeControl.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/core/NodeSearch.vue b/ui/src/mk-workflow/core/NodeSearch.vue deleted file mode 100644 index 0dcb74141e1..00000000000 --- a/ui/src/mk-workflow/core/NodeSearch.vue +++ /dev/null @@ -1,93 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/core/app-node.ts b/ui/src/mk-workflow/core/app-node.ts deleted file mode 100644 index 23ca50327df..00000000000 --- a/ui/src/mk-workflow/core/app-node.ts +++ /dev/null @@ -1,247 +0,0 @@ -import type { Component } from 'vue' -import { createApp, h as createVNode } from 'vue' -import ElementPlus from 'element-plus' -import zhCn from 'element-plus/es/locale/lang/zh-cn' -import { - h as createLogicFlowElement, - HtmlNode, - HtmlNodeModel, - type GraphModel, - type IHtmlNodeProperties, - type Model, -} from '@logicflow/core' -import { BasicComponentsNode } from '@/mk-workflow/core/data' -import { WorkflowNodeType } from '@/mk-workflow/types' - -type NodeViewProps = ConstructorParameters[0] -type NodeFieldGroup = Record>> -export type WorkflowNodeConfig = { - chatFields?: Array> - fields?: Array> - globalFields?: Array> -} - -export interface WorkflowNodeProperties extends IHtmlNodeProperties { - api_input_field_list?: unknown[] - chat_input_field_list?: unknown[] - config?: WorkflowNodeConfig - node_data?: unknown - showNode?: boolean - status?: number - stepName?: string - user_input_field_list?: unknown[] -} - -export class AppNode extends HtmlNode { - private nodeApp?: ReturnType - private readonly vueComponent: Component - - constructor(props: NodeViewProps, vueComponent: Component) { - super(props) - this.vueComponent = vueComponent - - const nodeModel = props.model as unknown as AppNodeModel - nodeModel.clear_next_node_field = this.clearNextNodeField.bind(this) - nodeModel.get_node_field_list = this.getNodeFieldList.bind(this) - nodeModel.get_up_node_field_dict = this.getUpNodeFieldDict.bind(this) - nodeModel.get_up_node_field_list = this.getUpNodeFieldList.bind(this) - - const definition = BasicComponentsNode[nodeModel.type as WorkflowNodeType] - if (definition && !nodeModel.properties.config) { - nodeModel.properties.config = structuredClone(definition.properties.config ?? {}) - } - nodeModel.properties.stepName = this.getUniqueNodeName( - props.graphModel, - String(nodeModel.properties.stepName ?? definition?.label ?? nodeModel.type), - nodeModel.id, - ) - } - - private getUniqueNodeName(graphModel: GraphModel, baseName: string, nodeId: string) { - const names = new Set( - graphModel.nodes - .filter((node) => node.id !== nodeId) - .map((node) => String(node.properties.stepName ?? '')), - ) - let index = 0 - let nodeName = baseName - while (names.has(nodeName.trim())) nodeName = `${baseName}${++index}` - return nodeName - } - - private getNodeFieldList() { - const nodeModel = this.props.model as unknown as AppNodeModel - const config = nodeModel.properties.config ?? {} - const fields = [...(config.fields ?? [])] - const result: Array> = [] - - if (String(nodeModel.type) === WorkflowNodeType.Start) { - result.push({ - value: 'global', - label: '全局变量', - type: 'global', - children: config.globalFields ?? [], - }) - result.push({ - value: 'chat', - label: '会话变量', - type: 'chat', - children: config.chatFields ?? [], - }) - } - - result.push({ - value: nodeModel.id, - label: nodeModel.properties.stepName, - type: nodeModel.type, - children: fields, - }) - return result - } - - private getUpNodeFieldDict(containSelf: boolean, useCache: boolean): NodeFieldGroup { - const nodeModel = this.props.model as unknown as AppNodeModel - if (!nodeModel.upNodeFieldDict || !useCache) { - nodeModel.upNodeFieldDict = nodeModel.graphModel - .getNodeIncomingNode(nodeModel.id) - .filter((node) => node.id !== WorkflowNodeType.Start) - .reduce((fieldGroups, node) => { - const upstreamModel = node as unknown as AppNodeModel - return { - ...fieldGroups, - ...upstreamModel.get_up_node_field_dict?.(true, useCache), - } - }, {}) - } - - if (!containSelf) return nodeModel.upNodeFieldDict - return { - ...nodeModel.upNodeFieldDict, - [nodeModel.id]: this.getNodeFieldList(), - } - } - - private getUpNodeFieldList(containSelf: boolean, useCache: boolean) { - const nodeModel = this.props.model as unknown as AppNodeModel - const upstreamFields = Object.values(this.getUpNodeFieldDict(containSelf, useCache)).flat() - const startFields = ( - nodeModel.graphModel.getNodeModelById(WorkflowNodeType.Start) as unknown as - | AppNodeModel - | undefined - )?.get_node_field_list?.() - return [...(startFields ?? []), ...upstreamFields] - } - - private clearNextNodeField(containSelf: boolean) { - const nodeModel = this.props.model as unknown as AppNodeModel - nodeModel.graphModel.getNodeOutgoingNode(nodeModel.id).forEach((node) => { - ;(node as unknown as AppNodeModel).clear_next_node_field?.(true) - }) - if (containSelf) nodeModel.upNodeFieldDict = undefined - } - - getAnchorShape(anchorData?: Model.AnchorConfig) { - if (!anchorData) return null - const { x, y, type } = anchorData - const connected = this.props.graphModel.edges.some((edge) => - type === 'left' - ? edge.targetAnchorId === anchorData.id - : edge.sourceAnchorId === anchorData.id, - ) - - return createLogicFlowElement( - 'foreignObject', - { ...anchorData, x: x - 10, y: y - 10, width: 20, height: 20 }, - [ - createLogicFlowElement('div', { - className: 'h-5 w-5 cursor-pointer rounded-full border-2 border-primary bg-white', - style: connected ? { background: 'var(--mk-primary)' } : {}, - onClick: () => { - if (type === 'right') { - ;(this.props.model as unknown as AppNodeModel).openNodeMenu?.(anchorData) - } - }, - }), - ], - ) - } - - setHtml(rootElement: SVGForeignObjectElement) { - if (this.nodeApp) return - const mountElement = document.createElement('div') - rootElement.replaceChildren(mountElement) - const nodeModel = this.props.model - - this.nodeApp = createApp({ - render: () => createVNode(this.vueComponent, { nodeModel }), - }) - this.nodeApp.use(ElementPlus, { locale: zhCn }) - this.nodeApp.mount(mountElement) - } - - componentWillUnmount() { - super.componentWillUnmount() - this.nodeApp?.unmount() - this.nodeApp = undefined - } -} - -export class AppNodeModel extends HtmlNodeModel { - upNodeFieldDict?: NodeFieldGroup - clear_next_node_field?: (containSelf: boolean) => void - get_node_field_list?: () => Array> - get_up_node_field_dict?: (containSelf: boolean, useCache: boolean) => NodeFieldGroup - get_up_node_field_list?: ( - containSelf: boolean, - useCache: boolean, - ) => Array> - openNodeMenu?: (anchorData: Model.AnchorConfig) => void - validate?: () => Promise - - setAttributes() { - this.width = Number( - this.properties.width ?? (String(this.type) === WorkflowNodeType.Base ? 600 : 340), - ) - this.height = Number(this.properties.height ?? 300) - this.text.editable = false - } - - setHeight(contentHeight: number) { - const targetHeight = Math.max(contentHeight + 32, 120) - if (targetHeight === this.height) return - const offset = (targetHeight - this.height) / 2 - this.height = targetHeight - this.properties.height = targetHeight - this.move(0, offset) - } - - getDefaultAnchor(): Model.AnchorConfig[] { - if (String(this.type) === WorkflowNodeType.Base) return [] - - const anchors: Model.AnchorConfig[] = [] - if (String(this.type) !== WorkflowNodeType.Start) { - anchors.push({ - x: this.x - this.width / 2, - y: this.y, - id: `${this.id}_left`, - type: 'left', - edgeAddable: false, - }) - } - anchors.push({ - x: this.x + this.width / 2, - y: this.y, - id: `${this.id}_right`, - type: 'right', - }) - return anchors - } - - getNodeStyle() { - return { ...super.getNodeStyle(), stroke: 'transparent' } - } - - getOutlineStyle() { - return { ...super.getOutlineStyle(), stroke: 'transparent' } - } -} diff --git a/ui/src/mk-workflow/core/data.ts b/ui/src/mk-workflow/core/data.ts deleted file mode 100644 index 7b0f844737a..00000000000 --- a/ui/src/mk-workflow/core/data.ts +++ /dev/null @@ -1,187 +0,0 @@ -import type LogicFlow from '@logicflow/core' -import { WorkflowNodeType, WorkflowMode } from '@/mk-workflow/types' - -export interface WorkflowField { - label: string - value: string -} - -export interface WorkflowNodeDefinition { - height: number - label: string - properties: LogicFlow.PropertiesType - text: string - type: WorkflowNodeType -} - -export const baseNode: LogicFlow.NodeConfig = { - id: WorkflowNodeType.Base, - type: WorkflowNodeType.Base, - x: 260, - y: 300, - properties: { - height: 728.375, - stepName: '基本信息', - config: {}, - node_data: { - name: '', - desc: '', - prologue: '您好,我是您的智能助手,请问有什么可以帮助您?', - }, - api_input_field_list: [], - chat_input_field_list: [], - user_input_field_list: [], - showNode: true, - }, -} - -export const startNode: LogicFlow.NodeConfig = { - id: WorkflowNodeType.Start, - type: WorkflowNodeType.Start, - x: 680, - y: 300, - properties: { - height: 364, - stepName: '开始', - config: { - fields: [{ label: '用户问题', value: 'question' }], - globalFields: [ - { label: '当前时间', value: 'time' }, - { label: '历史聊天记录', value: 'history_context' }, - { label: '对话 ID', value: 'chat_id' }, - ], - }, - fields: [{ label: '用户问题', value: 'question' }], - showNode: true, - }, -} - -export const aiChatNode: WorkflowNodeDefinition = { - type: WorkflowNodeType.AiChat, - text: '与 AI 大模型进行对话', - label: 'AI 对话', - height: 500, - properties: { - stepName: 'AI 对话', - config: { - fields: [ - { label: 'AI 回答内容', value: 'answer' }, - { label: '思考过程', value: 'reasoning_content' }, - { label: '历史聊天记录', value: 'history_message' }, - ], - }, - node_data: { - model_id: '', - model_id_reference: [], - model_id_type: 'custom', - model_setting: { reasoning_content_enable: false }, - prompt: '{{开始.question}}', - system: '', - is_result: true, - }, - showNode: true, - }, -} - -export const replyNode: WorkflowNodeDefinition = { - type: WorkflowNodeType.Reply, - text: '指定回复内容,引用变量会转换为字符串进行输出', - label: '指定回复', - height: 320, - properties: { - stepName: '指定回复', - config: { - fields: [{ label: '内容', value: 'answer' }], - }, - node_data: { - content: '', - fields: [], - is_result: true, - reply_type: 'content', - }, - showNode: true, - }, -} - -export const BasicComponentsNode: Partial> = { - [WorkflowNodeType.AiChat]: aiChatNode, - [WorkflowNodeType.Reply]: replyNode, -} - -export const defaultNodes: LogicFlow.NodeConfig[] = [baseNode, startNode] - -export const menuNodes = [ - { - label: 'AI 能力', - list: [aiChatNode], - }, -] - -export const getMenuNodes = (workflowMode: WorkflowMode) => { - if (workflowMode == WorkflowMode.Application) { - return menuNodes - } - // if (workflowMode == WorkflowMode.ApplicationLoop) { - // return applicationLoopMenuNodes - // } - // if (workflowMode == WorkflowMode.Knowledge) { - // return knowledgeMenuNodes - // } - // if (workflowMode == WorkflowMode.KnowledgeLoop) { - // return knowledgeLoopMenuNodes - // } - // if (workflowMode == WorkflowMode.Tool) { - // return toolMenuNodes - // } - // if (workflowMode == WorkflowMode.ToolLoop) { - // return toolLoopMenuNodes - // } -} -export const workflowModelDict: any = { - [WorkflowMode.Application]: (node: any) => { - return ( - ['application-node', 'tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) && - node?.properties?.node_data?.tool_type !== 'DATA_SOURCE' - ) - }, - [WorkflowMode.ApplicationLoop]: (node: any) => { - return ( - ['application-node', 'tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) && - node?.properties?.node_data?.tool_type !== 'DATA_SOURCE' - ) - }, - [WorkflowMode.Knowledge]: (node: any) => { - console.log(['tool-workflow-lib-node', 'tool-lib-node'].includes(node)) - return ['tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) - }, - [WorkflowMode.KnowledgeLoop]: (node: any) => { - return ( - ['tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) && - node?.properties?.node_data?.tool_type !== 'DATA_SOURCE' - ) - }, - [WorkflowMode.Tool]: (node: any) => { - return ( - ['tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) && - node?.properties?.node_data?.tool_type !== 'DATA_SOURCE' - ) - }, - [WorkflowMode.ToolLoop]: (node: any) => { - return ( - ['tool-workflow-lib-node', 'tool-lib-node'].includes(node.type) && - node?.properties?.node_data?.tool_type !== 'DATA_SOURCE' - ) - }, -} - -export function isLastNode(nodeModel: { - graphModel: { - getNodeIncomingNode: (nodeId: string) => unknown[] - getNodeOutgoingNode: (nodeId: string) => unknown[] - } - id: string -}) { - const incomingNodes = nodeModel.graphModel.getNodeIncomingNode(nodeModel.id) - const outgoingNodes = nodeModel.graphModel.getNodeOutgoingNode(nodeModel.id) - return incomingNodes.length > 0 && outgoingNodes.length === 0 -} diff --git a/ui/src/mk-workflow/core/edge.ts b/ui/src/mk-workflow/core/edge.ts deleted file mode 100644 index e2f0f9db98c..00000000000 --- a/ui/src/mk-workflow/core/edge.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { BezierEdge, BezierEdgeModel, h } from '@logicflow/core' -import { createApp, h as vh } from 'vue' -import CustomLine from './CustomLine.vue' -const DEFAULT_WIDTH = 32 -const DEFAULT_HEIGHT = 32 -class CustomEdge2 extends BezierEdge { - isMounted - customLineApp?: any - root?: any - constructor() { - super() - this.isMounted = false - } - /** - * 渲染vue组件 - * @param root - */ - protected renderVueComponent(root: any) { - this.unmountVueComponent() - this.root = root - const { graphModel } = this.props - if (root) { - this.customLineApp = createApp({ - render: () => vh(CustomLine, { model: this.props.model, graphModel }), - }) - this.customLineApp.mount(root) - } - } - protected targetId() { - return `${this.props.graphModel.flowId}:${this.props.model.id}` - } - /** - * 组件即将卸载勾子 - */ - componentWillUnmount() { - if (super.componentWillUnmount) { - super.componentWillUnmount() - } - this.unmountVueComponent() - } - /** - * 卸载vue - * @returns - */ - protected unmountVueComponent() { - if (this.customLineApp) { - this.customLineApp.unmount() - this.customLineApp = null - } - if (this.root) { - this.root.innerHTML = '' - } - return this.root - } - - getEdge() { - const { model } = this.props - const id = model.id - const { customWidth = DEFAULT_WIDTH, customHeight = DEFAULT_HEIGHT } = model.getProperties() - const { startPoint, endPoint, path, isAnimation, arrowConfig } = model - const animationStyle = model.getEdgeAnimationStyle() - const { - strokeDasharray, - stroke, - strokeDashoffset, - animationName, - animationDuration, - animationIterationCount, - animationTimingFunction, - animationDirection, - } = animationStyle - const positionData = { - x: (startPoint.x + endPoint.x - customWidth) / 2, - y: (startPoint.y + endPoint.y - customHeight) / 2, - width: customWidth, - height: customHeight, - } - const style = model.getEdgeStyle() - const wrapperStyle = { - width: customWidth, - height: customHeight, - } - - setTimeout(() => { - const s = document.getElementById(id) - if (s && !this.isMounted) { - this.isMounted = true - this.renderVueComponent(s) - } - }, 0) - - delete style.stroke - - return h('g', {}, [ - h( - 'style' as any, - { type: 'text/css' }, - '.lf-edge{stroke:#afafaf}.lf-edge:hover{stroke: #3370FF;}', - ), - h('path', { - d: path, - ...style, - ...arrowConfig, - ...(isAnimation - ? { - strokeDasharray, - stroke, - style: { - strokeDashoffset, - animationName, - animationDuration, - animationIterationCount, - animationTimingFunction, - animationDirection, - }, - } - : {}), - }), - h( - 'foreignObject', - { - ...positionData, - y: positionData.y + 5, - x: positionData.x + 5, - style: {}, - }, - [ - h('div', { - id, - style: { ...wrapperStyle }, - className: 'lf-custom-edge-wrapper', - }), - ], - ), - ]) - } -} - -class CustomEdgeModel2 extends BezierEdgeModel { - getArrowStyle() { - const arrowStyle = super.getArrowStyle() - arrowStyle.offset = 1 - arrowStyle.verticalLength = 0 - return arrowStyle - } - - getEdgeStyle() { - const style = super.getEdgeStyle() - // svg属性 - style.strokeWidth = 2 - style.stroke = '#BBBFC4' - style.offset = 0 - return style - } - /** - * 重写此方法,使保存数据是能带上锚点数据。 - */ - getData() { - const data: any = super.getData() - if (data) { - data.sourceAnchorId = this.sourceAnchorId - data.targetAnchorId = this.targetAnchorId - } - return data - } - /** - * 给边自定义方案,使其支持基于锚点的位置更新边的路径 - */ - updatePathByAnchor() { - const sourceNodeModel = this.graphModel.getNodeModelById(this.sourceNodeId) - if (!sourceNodeModel) return - const sourceAnchor = sourceNodeModel - .getDefaultAnchor() - .find((anchor: any) => anchor.id === this.sourceAnchorId) - - const targetNodeModel = this.graphModel.getNodeModelById(this.targetNodeId) - if (!targetNodeModel) return - const targetAnchor = targetNodeModel - .getDefaultAnchor() - .find((anchor: any) => anchor.id === this.targetAnchorId) - if (sourceAnchor && targetAnchor) { - const startPoint = { - x: sourceAnchor.x, - y: sourceAnchor.y, - } - this.updateStartPoint(startPoint) - const endPoint = { - x: targetAnchor.x, - y: targetAnchor.y, - } - - this.updateEndPoint(endPoint) - } - - // 这里需要将原有的pointsList设置为空,才能触发bezier的自动计算control点。 - this.pointsList = [] - this.initPoints() - } - setAttributes(): void { - super.setAttributes() - this.isHitable = true - this.zIndex = 0 - } -} - -export default { - type: 'app-edge', - view: CustomEdge2, - model: CustomEdgeModel2, -} diff --git a/ui/src/mk-workflow/core/shortcut.ts b/ui/src/mk-workflow/core/shortcut.ts deleted file mode 100644 index 050ac3c9e5a..00000000000 --- a/ui/src/mk-workflow/core/shortcut.ts +++ /dev/null @@ -1,325 +0,0 @@ -import type LogicFlow from '@logicflow/core' -import type { GraphModel } from '@logicflow/core' -import { cloneDeep } from 'lodash' -import { getMenuNodes, workflowModelDict, defaultNodes } from '@/mk-workflow/core/data' -import { WorkflowMode, WorkflowNodeType } from '@/mk-workflow/types' -import { copyText } from '@/utils/clipboard' -import { MsgConfirm, MsgError } from '@/utils/message' - -type WorkflowGraphModel = GraphModel & { - get_provide: ( - node: LogicFlow.NodeData | null, - graph: GraphModel | null, - ) => { workflowMode: WorkflowMode } -} - -const TRANSLATION_DISTANCE = 40 -const fixedNodeTypes = new Set([ - WorkflowNodeType.Start, - WorkflowNodeType.ToolStartNode, - WorkflowNodeType.ToolBaseNode, - WorkflowNodeType.Base, - WorkflowNodeType.LoopBodyNode, - WorkflowNodeType.LoopStartNode, - WorkflowNodeType.KnowledgeBase, -]) - -let activeCanvasId: string | null = null -let childrenTranslationDistance = TRANSLATION_DISTANCE -let selectedGraphData: LogicFlow.GraphData | null = null - -const lastMousePosition = { - x: 0, - y: 0, - hasValue: false, -} - -function bindMousePosition(logicFlow: LogicFlow) { - const updateMousePosition = (event: MouseEvent) => { - lastMousePosition.x = event.clientX - lastMousePosition.y = event.clientY - lastMousePosition.hasValue = true - } - - logicFlow.container.addEventListener('mousemove', updateMousePosition) - return () => logicFlow.container.removeEventListener('mousemove', updateMousePosition) -} - -function bindCanvasActive(logicFlow: LogicFlow) { - const { container } = logicFlow - container.tabIndex = 0 - - const activateCanvas = () => { - activeCanvasId = logicFlow.graphModel.flowId ?? null - container.focus() - } - - container.addEventListener('mousedown', activateCanvas) - container.addEventListener('focus', activateCanvas) - return () => { - container.removeEventListener('mousedown', activateCanvas) - container.removeEventListener('focus', activateCanvas) - } -} - -function translateNodeData(nodeData: LogicFlow.NodeData, distance: number) { - nodeData.x += distance - nodeData.y += distance - if (nodeData.text) { - nodeData.text.x += distance - nodeData.text.y += distance - } -} - -function translateEdgeData(edgeData: LogicFlow.EdgeData, distance: number) { - edgeData.startPoint.x += distance - edgeData.startPoint.y += distance - edgeData.endPoint.x += distance - edgeData.endPoint.y += distance - edgeData.pointsList?.forEach((point) => { - point.x += distance - point.y += distance - }) - if (edgeData.text) { - edgeData.text.x += distance - edgeData.text.y += distance - } -} - -function translateGraphData(graphData: LogicFlow.GraphData, offsetX: number, offsetY: number) { - graphData.nodes.forEach((node) => { - node.x += offsetX - node.y += offsetY - }) - graphData.edges.forEach((edge) => { - edge.startPoint.x += offsetX - edge.startPoint.y += offsetY - edge.endPoint.x += offsetX - edge.endPoint.y += offsetY - if (edge.text) { - edge.text.x += offsetX - edge.text.y += offsetY - } - edge.pointsList = edge.pointsList?.map((point) => ({ - ...point, - x: point.x + offsetX, - y: point.y + offsetY, - })) - }) -} - -function getNodeBounds(nodes: LogicFlow.NodeData[]) { - const firstNode = nodes[0] - if (!firstNode) return { minX: 0, maxX: 0, minY: 0, maxY: 0 } - - return nodes.reduce( - (bounds, node) => ({ - minX: Math.min(bounds.minX, node.x), - maxX: Math.max(bounds.maxX, node.x), - minY: Math.min(bounds.minY, node.y), - maxY: Math.max(bounds.maxY, node.y), - }), - { minX: firstNode.x, maxX: firstNode.x, minY: firstNode.y, maxY: firstNode.y }, - ) -} - -function createGraphElementId() { - return crypto.randomUUID() -} - -function resetGraphDataIds(graphData: LogicFlow.GraphData) { - const idMap = new Map() - const replaceId = (oldId: string) => { - const existingId = idMap.get(oldId) - if (existingId) return existingId - const newId = createGraphElementId() - idMap.set(oldId, newId) - return newId - } - - graphData.nodes.forEach((node) => { - node.id = replaceId(node.id) - }) - graphData.edges.forEach((edge) => { - const oldSourceNodeId = edge.sourceNodeId - const oldTargetNodeId = edge.targetNodeId - edge.id = replaceId(edge.id) - edge.sourceNodeId = replaceId(oldSourceNodeId) - edge.targetNodeId = replaceId(oldTargetNodeId) - if (edge.sourceAnchorId) { - edge.sourceAnchorId = edge.sourceAnchorId.replace(oldSourceNodeId, edge.sourceNodeId) - } - if (edge.targetAnchorId) { - edge.targetAnchorId = edge.targetAnchorId.replace(oldTargetNodeId, edge.targetNodeId) - } - }) - return graphData -} - -function isRecord(value: unknown): value is Record { - return typeof value === 'object' && value !== null && !Array.isArray(value) -} - -function parseGraphData(text: string): LogicFlow.GraphData { - let parsedData: unknown - try { - parsedData = JSON.parse(text) - } catch { - throw new Error('数据不是合法的 JSON') - } - - if (!isRecord(parsedData)) throw new Error('数据必须是对象') - if (!Array.isArray(parsedData.nodes)) throw new Error('nodes 必须是数组') - if (!Array.isArray(parsedData.edges)) throw new Error('edges 必须是数组') - - parsedData.nodes.forEach((node, index) => { - if (!isRecord(node)) throw new Error(`nodes[${index}] 必须是对象`) - if (typeof node.id !== 'string' || !node.id) throw new Error(`nodes[${index}] 缺少 id`) - }) - parsedData.edges.forEach((edge, index) => { - if (!isRecord(edge)) throw new Error(`edges[${index}] 必须是对象`) - if (typeof edge.id !== 'string' || !edge.id) throw new Error(`edges[${index}] 缺少 id`) - }) - - return parsedData as unknown as LogicFlow.GraphData -} - -export function initDefaultShortcut(logicFlow: LogicFlow, graphModel: GraphModel) { - const unbindMousePosition = bindMousePosition(logicFlow) - const unbindCanvasActive = bindCanvasActive(logicFlow) - const { keyboard } = logicFlow - const keyboardEnabled = () => keyboard.options.keyboard?.enabled === true - - const copyNode = () => { - childrenTranslationDistance = TRANSLATION_DISTANCE - if (!keyboardEnabled() || graphModel.textEditElement) return true - - const selectedElements = graphModel.getSelectElements(false) - const cloneAllowed = logicFlow.options.guards?.beforeClone?.(selectedElements) ?? true - if ( - !cloneAllowed || - (selectedElements.nodes.length === 0 && selectedElements.edges.length === 0) - ) { - selectedGraphData = null - return true - } - - const fixedNode = selectedElements.nodes.find((node) => fixedNodeTypes.has(node.type)) - if (fixedNode) { - MsgError(`${String(fixedNode.properties?.stepName ?? fixedNode.type)}不能被复制`) - return true - } - - selectedGraphData = cloneDeep(selectedElements) - selectedGraphData.nodes.forEach((node) => translateNodeData(node, TRANSLATION_DISTANCE)) - selectedGraphData.edges.forEach((edge) => translateEdgeData(edge, TRANSLATION_DISTANCE)) - void copyText(JSON.stringify(selectedGraphData)) - return false - } - - const pasteNode = (event: ClipboardEvent) => { - if (logicFlow.graphModel.flowId !== activeCanvasId) return true - if (!keyboardEnabled() || graphModel.textEditElement) return true - - const clipboardText = event.clipboardData?.getData('text/plain') ?? '' - const graphData = resetGraphDataIds(parseGraphData(clipboardText)) - selectedGraphData = graphData - - const workflowMode = (logicFlow.graphModel as WorkflowGraphModel).get_provide( - null, - null, - ).workflowMode - const menuNodeTypes = getMenuNodes(workflowMode) - ?.flatMap((menuGroup) => menuGroup.list) - .map((node) => node.type) - - if (!lastMousePosition.hasValue) { - translateGraphData(graphData, TRANSLATION_DISTANCE, TRANSLATION_DISTANCE) - } else { - const { canvasOverlayPosition } = logicFlow.graphModel.getPointByClient({ - x: lastMousePosition.x, - y: lastMousePosition.y, - }) - const { minX, maxX, minY, maxY } = getNodeBounds(graphData.nodes) - translateGraphData( - graphData, - canvasOverlayPosition.x - (minX + maxX) / 2, - canvasOverlayPosition.y - (minY + maxY) / 2, - ) - } - - const workflowNodeMatcher = workflowModelDict[workflowMode] - graphData.nodes = graphData.nodes.filter( - (node) => menuNodeTypes?.includes(node.type as WorkflowNodeType) || workflowNodeMatcher(node), - ) - - logicFlow.clearSelectElements() - const addedElements = logicFlow.addElements(graphData, childrenTranslationDistance) - addedElements.nodes.forEach((node) => logicFlow.selectElementById(node.id, true)) - addedElements.edges.forEach((edge) => logicFlow.selectElementById(edge.id, true)) - selectedGraphData.nodes.forEach((node) => translateNodeData(node, TRANSLATION_DISTANCE)) - selectedGraphData.edges.forEach((edge) => translateEdgeData(edge, TRANSLATION_DISTANCE)) - childrenTranslationDistance += TRANSLATION_DISTANCE - selectedGraphData = null - return false - } - - const deleteNode = () => { - const selectedElements = graphModel.getSelectElements(true) - logicFlow.clearSelectElements() - if (!selectedElements.nodes.length && !selectedElements.edges.length) return true - - if (selectedElements.edges.length && !selectedElements.nodes.length) { - selectedElements.edges - .filter((edge) => edge.type !== 'loop-edge') - .forEach((edge) => logicFlow.deleteEdge(edge.id)) - return false - } - - const fixedNode = selectedElements.nodes.find((node) => fixedNodeTypes.has(node.type)) - if (fixedNode) { - MsgError(`${String(fixedNode.properties?.stepName ?? fixedNode.type)}节点不允许删除`) - return true - } - - void MsgConfirm('提示', '确定要删除吗?', { - confirmButtonText: '确认', - confirmButtonClass: 'danger', - }).then(() => { - if (!keyboardEnabled() || graphModel.textEditElement) return - selectedElements.edges.forEach((edge) => logicFlow.deleteEdge(edge.id)) - selectedElements.nodes.forEach((node) => { - if (node.type === WorkflowNodeType.LoopNode) { - logicFlow - .getNodeOutgoingNode(node.id) - .filter((nextNode) => String(nextNode.type) === WorkflowNodeType.LoopBodyNode) - .forEach((nextNode) => logicFlow.deleteNode(nextNode.id)) - } - logicFlow.deleteNode(node.id) - }) - }) - return false - } - - graphModel.eventCenter.on('copy_node', copyNode) - keyboard.on(['cmd + c', 'ctrl + c'], copyNode) - keyboard.on(['cmd + v', 'ctrl + v'], () => undefined) - keyboard.on(['cmd + z', 'ctrl + z'], () => undefined) - keyboard.on(['cmd + y', 'ctrl + y'], () => { - if (keyboardEnabled() && !graphModel.textEditElement) logicFlow.redo() - }) - keyboard.on('backspace', deleteNode) - document.addEventListener('paste', pasteNode) - - return () => { - unbindMousePosition() - unbindCanvasActive() - document.removeEventListener('paste', pasteNode) - graphModel.eventCenter.off('copy_node', copyNode) - keyboard.off(['cmd + c', 'ctrl + c']) - keyboard.off(['cmd + v', 'ctrl + v']) - keyboard.off(['cmd + z', 'ctrl + z']) - keyboard.off(['cmd + y', 'ctrl + y']) - keyboard.off('backspace') - } -} diff --git a/ui/src/mk-workflow/core/teleport.ts b/ui/src/mk-workflow/core/teleport.ts deleted file mode 100644 index a763edad309..00000000000 --- a/ui/src/mk-workflow/core/teleport.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { BaseEdgeModel, BaseNodeModel, GraphModel } from '@logicflow/core' -import type { Component } from 'vue' -import { defineComponent, Fragment, h, markRaw, reactive, Teleport } from 'vue' - -type TeleportModel = BaseNodeModel | BaseEdgeModel -type ComponentProps = Record -type ProvideValues = Record -type GetComponentProps = (node: TeleportModel, graph: GraphModel) => ComponentProps -type GetProvideValues = (node: TeleportModel, graph: GraphModel) => ProvideValues - -let active = false -const teleportItems = reactive>({}) - -export function connect( - id: string, - component: Component, - container: HTMLDivElement, - node: TeleportModel, - graph: GraphModel, - getComponentProps: GetComponentProps = (currentNode, currentGraph) => ({ - nodeModel: currentNode, - graph: currentGraph, - }), - getProvideValues: GetProvideValues = (currentNode, currentGraph) => ({ - getNode: () => currentNode, - getGraph: () => currentGraph, - }), -) { - if (!active) return - - teleportItems[id] = markRaw( - defineComponent({ - name: 'WorkflowTeleportItem', - provide: () => getProvideValues(node, graph), - render: () => h(Teleport, { to: container }, [h(component, getComponentProps(node, graph))]), - }), - ) -} - -export function disconnect(id: string) { - if (active) delete teleportItems[id] -} - -export function disconnectByFlow(flowId: string) { - Object.keys(teleportItems).forEach((id) => { - if (id.startsWith(flowId)) delete teleportItems[id] - }) -} - -export function disconnectAll() { - Object.keys(teleportItems).forEach((id) => delete teleportItems[id]) -} - -export function isActive() { - return active -} - -export function getTeleport() { - active = true - return defineComponent({ - name: 'WorkflowTeleportContainer', - props: { - flowId: { - type: String, - required: true, - }, - }, - setup() { - return () => - h( - Fragment, - {}, - Object.values(teleportItems).map((component) => h(component)), - ) - }, - }) -} diff --git a/ui/src/mk-workflow/core/template.ts b/ui/src/mk-workflow/core/template.ts deleted file mode 100644 index ea618d1eb0d..00000000000 --- a/ui/src/mk-workflow/core/template.ts +++ /dev/null @@ -1,1140 +0,0 @@ -import type LogicFlow from '@logicflow/core' -import { defaultNodes } from '@/mk-workflow/core/data' - -export const applicationTemplate = { - blank: { - edges: [], - nodes: defaultNodes, - }, - assistant: { - nodes: [ - { - id: 'base-node', - type: 'base-node', - x: 120, - y: 260.30849999999987, - properties: { - config: {}, - height: 734.766, - showNode: true, - stepName: '基本信息', - node_data: { - desc: '模板', - name: '知识库问答助手', - prologue: - '您好,我是 XXX 小助手,您可以向我提出 XXX 使用问题。\n- XXX 主要功能有什么?\n- XXX 如何收费?\n- 需要转人工服务', - tts_type: 'BROWSER', - }, - input_field_list: [], - user_input_config: { - title: '用户输入', - }, - api_input_field_list: [], - user_input_field_list: [], - }, - }, - { - id: 'start-node', - type: 'start-node', - x: 120, - y: 929.6914999999999, - properties: { - config: { - fields: [ - { - label: '用户问题', - value: 'question', - }, - ], - globalFields: [ - { - label: '当前时间', - value: 'time', - }, - { - label: '历史聊天记录', - value: 'history_context', - }, - { - label: '对话 ID', - value: 'chat_id', - }, - ], - }, - fields: [ - { - label: '用户问题', - value: 'question', - }, - ], - height: 364, - showNode: true, - stepName: '开始', - globalFields: [ - { - label: '当前时间', - value: 'time', - }, - ], - }, - }, - { - id: 'fd0324fc-f5e4-4fa6-a2d9-cb251b467605', - type: 'search-knowledge-node', - x: 710, - y: 929.6914999999999, - properties: { - config: { - fields: [ - { - label: '检索结果的分段列表', - value: 'paragraph_list', - }, - { - label: '满足直接回答的分段列表', - value: 'is_hit_handling_method_list', - }, - { - label: '检索结果', - value: 'data', - }, - { - label: '满足直接回答的分段内容', - value: 'directly_return', - }, - ], - }, - height: 794, - showNode: true, - stepName: '知识库检索', - condition: 'AND', - node_data: { - knowledge_id_list: [], - knowledge_setting: { - top_n: 3, - similarity: 0.6, - search_mode: 'embedding', - max_paragraph_char_number: 5000, - }, - question_reference_address: ['start-node', 'question'], - all_knowledge_id_list: [], - knowledge_list: [], - }, - }, - }, - { - id: '420a6e4f-44ff-4847-bb81-0923630846b5', - type: 'condition-node', - x: 1300, - y: 929.6914999999999, - properties: { - width: 600, - config: { - fields: [ - { - label: '分支名称', - value: 'branch_name', - }, - ], - }, - height: 544.148, - showNode: true, - stepName: '判断器', - condition: 'AND', - node_data: { - branch: [ - { - id: '7887', - type: 'IF', - condition: 'and', - conditions: [ - { - field: ['fd0324fc-f5e4-4fa6-a2d9-cb251b467605', 'is_hit_handling_method_list'], - value: 1, - compare: 'is_not_null', - }, - ], - }, - { - id: '6847', - type: 'ELSE IF 1', - condition: 'and', - conditions: [ - { - field: ['fd0324fc-f5e4-4fa6-a2d9-cb251b467605', 'paragraph_list'], - value: 1, - compare: 'is_not_null', - }, - ], - }, - { - id: '2794', - type: 'ELSE', - condition: 'and', - conditions: [], - }, - ], - }, - branch_condition_list: [ - { - index: 0, - height: 121.383, - id: '7887', - }, - { - index: 1, - height: 121.383, - id: '6847', - }, - { - index: 2, - height: 44, - id: '2794', - }, - ], - }, - }, - { - id: '36a440a9-5b00-4d82-b13a-8e7819112918', - type: 'reply-node', - x: 1890, - y: 120, - properties: { - config: { - fields: [ - { - label: '内容', - value: 'answer', - }, - ], - }, - height: 386, - showNode: true, - stepName: '指定回复', - condition: 'AND', - node_data: { - fields: ['fd0324fc-f5e4-4fa6-a2d9-cb251b467605', 'directly_return'], - content: '', - is_result: true, - reply_type: 'referencing', - }, - }, - }, - { - id: 'f7c3b4a2-cb80-4e47-b050-7fef0315daaf', - type: 'ai-chat-node', - x: 1890, - y: 929.6914999999999, - properties: { - config: { - fields: [ - { - label: 'AI 回答内容', - value: 'answer', - }, - { - label: '思考过程', - value: 'reasoning_content', - }, - ], - }, - height: 993.383, - showNode: true, - stepName: 'AI 对话', - condition: 'AND', - node_data: { - prompt: '已知信息:\n{{知识库检索.data}}\n问题:\n{{开始.question}}', - system: '', - model_id: '', - is_result: true, - max_tokens: null, - temperature: null, - dialogue_type: 'WORKFLOW', - model_setting: { - reasoning_content_end: '', - reasoning_content_start: '', - reasoning_content_enable: false, - }, - dialogue_number: 1, - }, - }, - }, - { - id: '04dd6c1e-95f9-4757-bb3e-134d503fce54', - type: 'reply-node', - x: 1890, - y: 1798.383, - properties: { - config: { - fields: [ - { - label: '内容', - value: 'answer', - }, - ], - }, - height: 504, - showNode: true, - stepName: '指定回复1', - condition: 'AND', - node_data: { - fields: [], - content: '抱歉,没有在知识库查询到相关内容,请提供更详细的信息。', - is_result: true, - reply_type: 'content', - }, - }, - }, - ], - edges: [ - { - id: '73f8992c-65ef-409a-a151-378d0927f2aa', - type: 'app-edge', - sourceNodeId: 'start-node', - targetNodeId: 'fd0324fc-f5e4-4fa6-a2d9-cb251b467605', - startPoint: { - x: 280, - y: 929.6914999999999, - }, - endPoint: { - x: 550, - y: 929.6914999999999, - }, - properties: {}, - pointsList: [ - { - x: 280, - y: 929.6914999999999, - }, - { - x: 390, - y: 929.6914999999999, - }, - { - x: 440, - y: 929.6914999999999, - }, - { - x: 550, - y: 929.6914999999999, - }, - ], - sourceAnchorId: 'start-node_right', - targetAnchorId: 'fd0324fc-f5e4-4fa6-a2d9-cb251b467605_left', - }, - { - id: '6a8d23d9-5179-424e-80c2-f08d37cdb8d4', - type: 'app-edge', - sourceNodeId: 'fd0324fc-f5e4-4fa6-a2d9-cb251b467605', - targetNodeId: '420a6e4f-44ff-4847-bb81-0923630846b5', - startPoint: { - x: 870, - y: 929.6914999999999, - }, - endPoint: { - x: 1010, - y: 929.6914999999999, - }, - properties: {}, - pointsList: [ - { - x: 870, - y: 929.6914999999999, - }, - { - x: 980, - y: 929.6914999999999, - }, - { - x: 900, - y: 929.6914999999999, - }, - { - x: 1010, - y: 929.6914999999999, - }, - ], - sourceAnchorId: 'fd0324fc-f5e4-4fa6-a2d9-cb251b467605_right', - targetAnchorId: '420a6e4f-44ff-4847-bb81-0923630846b5_left', - }, - { - id: '56006748-d9fe-491b-a14b-04fd568cac08', - type: 'app-edge', - sourceNodeId: '420a6e4f-44ff-4847-bb81-0923630846b5', - targetNodeId: '36a440a9-5b00-4d82-b13a-8e7819112918', - startPoint: { - x: 1590, - y: 793.3089999999999, - }, - endPoint: { - x: 1730, - y: 120, - }, - properties: {}, - pointsList: [ - { - x: 1590, - y: 793.3089999999999, - }, - { - x: 1700, - y: 793.3089999999999, - }, - { - x: 1620, - y: 120, - }, - { - x: 1730, - y: 120, - }, - ], - sourceAnchorId: '420a6e4f-44ff-4847-bb81-0923630846b5_7887_right', - targetAnchorId: '36a440a9-5b00-4d82-b13a-8e7819112918_left', - }, - { - id: '9bc8721b-07aa-4730-9347-910ed64e26b9', - type: 'app-edge', - sourceNodeId: '420a6e4f-44ff-4847-bb81-0923630846b5', - targetNodeId: 'f7c3b4a2-cb80-4e47-b050-7fef0315daaf', - startPoint: { - x: 1590, - y: 922.6919999999999, - }, - endPoint: { - x: 1730, - y: 929.6914999999999, - }, - properties: {}, - pointsList: [ - { - x: 1590, - y: 922.6919999999999, - }, - { - x: 1700, - y: 922.6919999999999, - }, - { - x: 1620, - y: 929.6914999999999, - }, - { - x: 1730, - y: 929.6914999999999, - }, - ], - sourceAnchorId: '420a6e4f-44ff-4847-bb81-0923630846b5_6847_right', - targetAnchorId: 'f7c3b4a2-cb80-4e47-b050-7fef0315daaf_left', - }, - { - id: 'c276a5b6-ec29-4ab9-b911-a0a929ff193f', - type: 'app-edge', - sourceNodeId: '420a6e4f-44ff-4847-bb81-0923630846b5', - targetNodeId: '04dd6c1e-95f9-4757-bb3e-134d503fce54', - startPoint: { - x: 1590, - y: 1013.3834999999998, - }, - endPoint: { - x: 1730, - y: 1798.383, - }, - properties: {}, - pointsList: [ - { - x: 1590, - y: 1013.3834999999998, - }, - { - x: 1700, - y: 1013.3834999999998, - }, - { - x: 1620, - y: 1798.383, - }, - { - x: 1730, - y: 1798.383, - }, - ], - sourceAnchorId: '420a6e4f-44ff-4847-bb81-0923630846b5_2794_right', - targetAnchorId: '04dd6c1e-95f9-4757-bb3e-134d503fce54_left', - }, - ], - }, -} satisfies Record - -export const knowledgeTemplate = { - default: { - edges: [ - { - id: '846dd161-450e-4d2f-8119-78557d88421c', - type: 'app-edge', - endPoint: { - x: 550, - y: 720, - }, - pointsList: [ - { - x: 280, - y: 720, - }, - { - x: 390, - y: 720, - }, - { - x: 440, - y: 720, - }, - { - x: 550, - y: 720, - }, - ], - properties: {}, - startPoint: { - x: 280, - y: 720, - }, - sourceNodeId: '768aed24-8139-4689-870f-2065ef05473c', - targetNodeId: '1bed736e-711f-4afd-8454-2c8502444af7', - sourceAnchorId: '768aed24-8139-4689-870f-2065ef05473c_right', - targetAnchorId: '1bed736e-711f-4afd-8454-2c8502444af7_left', - }, - { - id: '79cf563e-0b4d-4d41-ad6f-4ee0c6042af6', - type: 'app-edge', - endPoint: { - x: 1010, - y: 720, - }, - pointsList: [ - { - x: 870, - y: 720, - }, - { - x: 980, - y: 720, - }, - { - x: 900, - y: 720, - }, - { - x: 1010, - y: 720, - }, - ], - properties: {}, - startPoint: { - x: 870, - y: 720, - }, - sourceNodeId: '1bed736e-711f-4afd-8454-2c8502444af7', - targetNodeId: '9018d6b6-be6e-420b-9a0d-7226fd789398', - sourceAnchorId: '1bed736e-711f-4afd-8454-2c8502444af7_right', - targetAnchorId: '9018d6b6-be6e-420b-9a0d-7226fd789398_left', - }, - { - id: '38111bbe-f2ff-428e-acf8-c2f49e45fb08', - type: 'app-edge', - endPoint: { - x: 550, - y: 1460, - }, - pointsList: [ - { - x: 280, - y: 1460, - }, - { - x: 390, - y: 1460, - }, - { - x: 440, - y: 1460, - }, - { - x: 550, - y: 1460, - }, - ], - properties: {}, - startPoint: { - x: 280, - y: 1460, - }, - sourceNodeId: 'affa7bad-1898-4bdb-967b-9e12a72492c6', - targetNodeId: 'd81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d', - sourceAnchorId: 'affa7bad-1898-4bdb-967b-9e12a72492c6_right', - targetAnchorId: 'd81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d_left', - }, - { - id: '632ed493-fd99-461b-9510-f4e3d02120d0', - type: 'app-edge', - endPoint: { - x: 1010, - y: 1460, - }, - pointsList: [ - { - x: 870, - y: 1460, - }, - { - x: 980, - y: 1460, - }, - { - x: 900, - y: 1460, - }, - { - x: 1010, - y: 1460, - }, - ], - properties: {}, - startPoint: { - x: 870, - y: 1460, - }, - sourceNodeId: 'd81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d', - targetNodeId: 'a1d0fa5d-4779-4364-8b54-7eff69bd1ec4', - sourceAnchorId: 'd81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d_right', - targetAnchorId: 'a1d0fa5d-4779-4364-8b54-7eff69bd1ec4_left', - }, - { - id: '5888e8cc-75fc-4df7-a627-1dc6feedea17', - type: 'app-edge', - endPoint: { - x: 1790, - y: 1440, - }, - pointsList: [ - { - x: 1490, - y: 720, - }, - { - x: 1600, - y: 720, - }, - { - x: 1680, - y: 1440, - }, - { - x: 1790, - y: 1440, - }, - ], - properties: {}, - startPoint: { - x: 1490, - y: 720, - }, - sourceNodeId: '9018d6b6-be6e-420b-9a0d-7226fd789398', - targetNodeId: 'ade860cd-db62-4538-9943-c8f42c1b927e', - sourceAnchorId: '9018d6b6-be6e-420b-9a0d-7226fd789398_right', - targetAnchorId: 'ade860cd-db62-4538-9943-c8f42c1b927e_left', - }, - { - id: '3f294d6b-6f4f-4a5c-9d49-f118033eec70', - type: 'app-edge', - endPoint: { - x: 1790, - y: 1440, - }, - pointsList: [ - { - x: 1490, - y: 1460, - }, - { - x: 1600, - y: 1460, - }, - { - x: 1680, - y: 1440, - }, - { - x: 1790, - y: 1440, - }, - ], - properties: {}, - startPoint: { - x: 1490, - y: 1460, - }, - sourceNodeId: 'a1d0fa5d-4779-4364-8b54-7eff69bd1ec4', - targetNodeId: 'ade860cd-db62-4538-9943-c8f42c1b927e', - sourceAnchorId: 'a1d0fa5d-4779-4364-8b54-7eff69bd1ec4_right', - targetAnchorId: 'ade860cd-db62-4538-9943-c8f42c1b927e_left', - }, - { - id: 'd04c1570-6572-4505-bf84-f29d81c30e57', - type: 'app-edge', - endPoint: { - x: 1790, - y: 1440, - }, - pointsList: [ - { - x: 1490, - y: 2190, - }, - { - x: 1600, - y: 2190, - }, - { - x: 1680, - y: 1440, - }, - { - x: 1790, - y: 1440, - }, - ], - properties: {}, - startPoint: { - x: 1490, - y: 2190, - }, - sourceNodeId: 'dddebd93-ea1a-4880-8a52-ea8112f7e769', - targetNodeId: 'ade860cd-db62-4538-9943-c8f42c1b927e', - sourceAnchorId: 'dddebd93-ea1a-4880-8a52-ea8112f7e769_right', - targetAnchorId: 'ade860cd-db62-4538-9943-c8f42c1b927e_left', - }, - { - id: '536d7d47-9ad8-4144-a6df-35e3e2398327', - type: 'app-edge', - endPoint: { - x: 2430, - y: 1430, - }, - pointsList: [ - { - x: 2110, - y: 1440, - }, - { - x: 2220, - y: 1440, - }, - { - x: 2320, - y: 1430, - }, - { - x: 2430, - y: 1430, - }, - ], - properties: {}, - startPoint: { - x: 2110, - y: 1440, - }, - sourceNodeId: 'ade860cd-db62-4538-9943-c8f42c1b927e', - targetNodeId: '1c5abed5-e181-41f7-96f5-b5175cc37f3c', - sourceAnchorId: 'ade860cd-db62-4538-9943-c8f42c1b927e_right', - targetAnchorId: '1c5abed5-e181-41f7-96f5-b5175cc37f3c_left', - }, - { - id: '8b5bb2b5-5baa-4e54-b848-fa87231d9585', - type: 'app-edge', - endPoint: { - x: 1010, - y: 2190, - }, - pointsList: [ - { - x: 870, - y: 2190, - }, - { - x: 980, - y: 2190, - }, - { - x: 900, - y: 2190, - }, - { - x: 1010, - y: 2190, - }, - ], - properties: {}, - startPoint: { - x: 870, - y: 2190, - }, - sourceNodeId: '08503db8-f2e3-4eb3-96f7-957f30a6da6e', - targetNodeId: 'dddebd93-ea1a-4880-8a52-ea8112f7e769', - sourceAnchorId: '08503db8-f2e3-4eb3-96f7-957f30a6da6e_right', - targetAnchorId: 'dddebd93-ea1a-4880-8a52-ea8112f7e769_left', - }, - ], - nodes: [ - { - x: 120, - y: 115.05849999999998, - id: 'knowledge-base-node', - type: 'knowledge-base-node', - properties: { - config: { - fields: [], - globalFields: [], - }, - height: 394.383, - showNode: true, - stepName: '\u57fa\u672c\u4fe1\u606f', - node_data: { - desc: '', - name: '', - prologue: - '\u60a8\u597d\uff0c\u6211\u662f XXX \u5c0f\u52a9\u624b\uff0c\u60a8\u53ef\u4ee5\u5411\u6211\u63d0\u51fa XXX \u4f7f\u7528\u95ee\u9898\u3002\n- XXX \u4e3b\u8981\u529f\u80fd\u6709\u4ec0\u4e48\uff1f\n- XXX \u5982\u4f55\u6536\u8d39\uff1f\n- \u9700\u8981\u8f6c\u4eba\u5de5\u670d\u52a1', - tts_type: 'BROWSER', - }, - input_field_list: [], - user_input_config: { - title: '\u6587\u6863\u5904\u7406\u8bbe\u7f6e', - }, - user_input_field_list: [], - }, - }, - { - x: 120, - y: 720, - id: '768aed24-8139-4689-870f-2065ef05473c', - type: 'data-source-local-node', - properties: { - kind: 'data-source', - config: { - fields: [ - { - label: '\u6587\u4ef6\u5217\u8868', - value: 'file_list', - }, - ], - }, - height: 566, - showNode: true, - stepName: '\u6587\u672c\u6587\u4ef6', - node_data: { - file_type_list: ['TXT', 'DOCX', 'PDF', 'HTML', 'XLS', 'XLSX', 'CSV'], - file_size_limit: 100, - file_count_limit: 50, - }, - input_field_list: [], - user_input_config: {}, - user_input_field_list: [], - }, - }, - { - x: 710, - y: 720, - id: '1bed736e-711f-4afd-8454-2c8502444af7', - type: 'document-extract-node', - properties: { - config: { - fields: [ - { - label: '\u6587\u6863\u5185\u5bb9', - value: 'content', - }, - { - label: '\u6587\u6863\u5217\u8868', - value: 'document_list', - }, - ], - }, - height: 394, - showNode: true, - stepName: '\u6587\u6863\u5185\u5bb9\u63d0\u53d6', - condition: 'OR', - node_data: { - document_list: ['768aed24-8139-4689-870f-2065ef05473c', 'file_list'], - }, - }, - }, - { - x: 1250, - y: 2190, - id: 'dddebd93-ea1a-4880-8a52-ea8112f7e769', - type: 'document-split-node', - properties: { - width: 500, - config: { - fields: [ - { - label: '\u5206\u6bb5\u5217\u8868', - value: 'paragraph_list', - }, - ], - }, - height: 652, - showNode: true, - stepName: 'Web\u667a\u80fd\u5206\u6bb5', - condition: 'AND', - node_data: { - limit: 4096, - patterns: [], - chunk_size: 256, - limit_type: 'custom', - with_filter: false, - document_list: ['08503db8-f2e3-4eb3-96f7-957f30a6da6e', 'document_list'], - patterns_type: 'custom', - split_strategy: 'auto', - chunk_size_type: 'custom', - limit_reference: [], - with_filter_type: 'custom', - patterns_reference: [], - chunk_size_reference: [], - with_filter_reference: [], - document_name_relate_problem: false, - paragraph_title_relate_problem: true, - document_name_relate_problem_type: 'custom', - paragraph_title_relate_problem_type: 'custom', - document_name_relate_problem_reference: [], - paragraph_title_relate_problem_reference: [], - }, - }, - }, - { - x: 2590, - y: 1430, - id: '1c5abed5-e181-41f7-96f5-b5175cc37f3c', - type: 'knowledge-write-node', - properties: { - config: { - fields: [], - }, - height: 278, - showNode: true, - stepName: '\u77e5\u8bc6\u5e93\u5199\u5165', - condition: 'AND', - node_data: { - document_list: ['ade860cd-db62-4538-9943-c8f42c1b927e', 'Segmented_List'], - }, - }, - }, - { - x: 1250, - y: 720, - id: '9018d6b6-be6e-420b-9a0d-7226fd789398', - type: 'document-split-node', - properties: { - width: 500, - config: { - fields: [ - { - label: '\u5206\u6bb5\u5217\u8868', - value: 'paragraph_list', - }, - ], - }, - height: 652, - showNode: true, - stepName: '\u667a\u80fd\u5206\u6bb5', - condition: 'AND', - node_data: { - limit: 4096, - patterns: [], - chunk_size: 256, - limit_type: 'custom', - with_filter: false, - document_list: ['1bed736e-711f-4afd-8454-2c8502444af7', 'document_list'], - patterns_type: 'custom', - split_strategy: 'auto', - chunk_size_type: 'custom', - limit_reference: [], - with_filter_type: 'custom', - patterns_reference: [], - chunk_size_reference: [], - with_filter_reference: [], - document_name_relate_problem: true, - paragraph_title_relate_problem: true, - document_name_relate_problem_type: 'custom', - paragraph_title_relate_problem_type: 'custom', - document_name_relate_problem_reference: [], - paragraph_title_relate_problem_reference: [], - }, - }, - }, - { - x: 120, - y: 1460, - id: 'affa7bad-1898-4bdb-967b-9e12a72492c6', - type: 'data-source-local-node', - properties: { - kind: 'data-source', - config: { - fields: [ - { - label: '\u6587\u4ef6\u5217\u8868', - value: 'file_list', - }, - ], - }, - height: 536, - showNode: true, - stepName: 'QA\u95ee\u7b54\u5bf9', - node_data: { - file_type_list: ['XLS', 'XLSX', 'CSV', 'ZIP'], - file_size_limit: 100, - file_count_limit: 50, - }, - input_field_list: [], - user_input_config: {}, - user_input_field_list: [], - }, - }, - { - x: 710, - y: 1460, - id: 'd81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d', - type: 'document-extract-node', - properties: { - config: { - fields: [ - { - label: '\u6587\u6863\u5185\u5bb9', - value: 'content', - }, - { - label: '\u6587\u6863\u5217\u8868', - value: 'document_list', - }, - ], - }, - height: 394, - showNode: true, - stepName: '\u6587\u6863\u5185\u5bb9\u63d0\u53d61', - condition: 'AND', - node_data: { - document_list: ['affa7bad-1898-4bdb-967b-9e12a72492c6', 'file_list'], - }, - }, - }, - { - x: 1250, - y: 1460, - id: 'a1d0fa5d-4779-4364-8b54-7eff69bd1ec4', - type: 'document-split-node', - properties: { - width: 500, - config: { - fields: [ - { - label: '\u5206\u6bb5\u5217\u8868', - value: 'paragraph_list', - }, - ], - }, - height: 580, - showNode: true, - stepName: 'QA\u95ee\u7b54\u5bf9\u5206\u6bb5', - condition: 'AND', - node_data: { - limit: 4096, - patterns: [], - chunk_size: 256, - limit_type: 'custom', - with_filter: false, - document_list: ['d81adcf1-bfd4-4a1c-b62c-e9ae0eb9488d', 'document_list'], - patterns_type: 'custom', - split_strategy: 'qa', - chunk_size_type: 'custom', - limit_reference: [], - with_filter_type: 'custom', - patterns_reference: [], - chunk_size_reference: [], - with_filter_reference: [], - document_name_relate_problem: true, - paragraph_title_relate_problem: false, - document_name_relate_problem_type: 'custom', - paragraph_title_relate_problem_type: 'custom', - document_name_relate_problem_reference: [], - paragraph_title_relate_problem_reference: [], - }, - }, - }, - { - x: 1950, - y: 1440, - id: 'ade860cd-db62-4538-9943-c8f42c1b927e', - type: 'variable-aggregation-node', - properties: { - config: { - fields: [ - { - label: '\u6587\u6863\u5206\u6bb5\u5217\u8868', - value: 'Segmented_List', - }, - ], - }, - height: 570.7660000000001, - showNode: true, - stepName: '\u805a\u5408\u6587\u6863\u5206\u6bb5\u5217\u8868', - condition: 'OR', - node_data: { - strategy: 'first_non_null', - is_result: true, - group_list: [ - { - id: 'kU2zR8yRzNIt3RXKHmJtL', - field: 'Segmented_List', - label: '\u6587\u6863\u5206\u6bb5\u5217\u8868', - variable_list: [ - { - v_id: 'N59Lo_VyRKuYASHaKN6g0', - variable: ['9018d6b6-be6e-420b-9a0d-7226fd789398', 'paragraph_list'], - }, - { - v_id: 'IRQkWPB7THGXlkSBCWmkY', - variable: ['a1d0fa5d-4779-4364-8b54-7eff69bd1ec4', 'paragraph_list'], - }, - { - v_id: 'jGrIINd-6O6UEzNmZvFap', - variable: ['dddebd93-ea1a-4880-8a52-ea8112f7e769', 'paragraph_list'], - }, - ], - }, - ], - }, - }, - }, - { - x: 710, - y: 2190, - id: '08503db8-f2e3-4eb3-96f7-957f30a6da6e', - type: 'data-source-web-node', - properties: { - kind: 'data-source', - config: { - fields: [ - { - label: '\u6587\u6863\u5217\u8868', - value: 'document_list', - }, - ], - }, - height: 292, - showNode: true, - stepName: 'Web\u7ad9\u70b9', - }, - }, - ], - }, -} satisfies Record diff --git a/ui/src/mk-workflow/core/validate.ts b/ui/src/mk-workflow/core/validate.ts deleted file mode 100644 index 3ca6c975939..00000000000 --- a/ui/src/mk-workflow/core/validate.ts +++ /dev/null @@ -1,101 +0,0 @@ -import type LogicFlow from '@logicflow/core' -import { WorkflowNodeType } from '@/mk-workflow/types' - -type WorkflowGraph = { - edges: LogicFlow.EdgeData[] - nodes: LogicFlow.NodeData[] -} - -/** 校验当前已迁入的智能体工作流节点及其连线关系。 */ -export class WorkFlowInstance { - readonly edges: LogicFlow.EdgeData[] - readonly nodes: LogicFlow.NodeData[] - private workflowNodeIds = new Set() - - constructor(workflow: WorkflowGraph) { - this.nodes = workflow.nodes - this.edges = workflow.edges - } - - is_valid_start_node() { - const startNodes = this.nodes.filter((node) => node.type === WorkflowNodeType.Start) - if (!startNodes.length) throw new Error('开始节点必填') - if (startNodes.length > 1) throw new Error('开始节点只能有一个') - } - - is_valid_base_node() { - const baseNodes = this.nodes.filter((node) => node.type === WorkflowNodeType.Base) - if (!baseNodes.length) throw new Error('基本信息节点必填') - if (baseNodes.length > 1) throw new Error('基本信息节点只能有一个') - } - - is_valid() { - this.is_valid_start_node() - this.is_valid_base_node() - this.is_valid_work_flow() - this.is_valid_nodes() - } - - get_start_node() { - return this.nodes.find((node) => node.type === WorkflowNodeType.Start) - } - - get_base_node() { - return this.nodes.find((node) => node.type === WorkflowNodeType.Base) - } - - get_next_nodes(node: LogicFlow.NodeData) { - const targetIds = this.edges - .filter((edge) => edge.sourceNodeId === node.id) - .map((edge) => edge.targetNodeId) - return this.nodes.filter((candidate) => targetIds.includes(candidate.id)) - } - - is_valid_work_flow() { - const startNode = this.get_start_node() - if (!startNode) return - - this.workflowNodeIds = new Set() - const visit = (node: LogicFlow.NodeData) => { - if (this.workflowNodeIds.has(node.id)) return - this.workflowNodeIds.add(node.id) - this.is_valid_node(node) - this.get_next_nodes(node).forEach(visit) - } - visit(startNode) - - const detachedNodes = this.nodes.filter( - (node) => - node.type !== WorkflowNodeType.Base && - node.type !== WorkflowNodeType.Start && - !this.workflowNodeIds.has(node.id), - ) - if (detachedNodes.length) { - throw new Error( - `未在流程中的节点:${detachedNodes.map((node) => node.properties?.stepName).join(',')}`, - ) - } - } - - is_valid_nodes() { - const detachedNode = this.nodes.find( - (node) => - node.type !== WorkflowNodeType.Base && - node.type !== WorkflowNodeType.Start && - !this.edges.some((edge) => edge.targetNodeId === node.id), - ) - if (detachedNode) throw new Error(`未在流程中的节点:${detachedNode.properties?.stepName}`) - } - - is_valid_node(node: LogicFlow.NodeData) { - if (node.properties?.status && node.properties.status !== 200) { - throw new Error(`${node.properties.stepName} 节点不可用`) - } - const isTerminalNode = [WorkflowNodeType.AiChat, WorkflowNodeType.Reply].includes( - node.type as WorkflowNodeType, - ) - if (!isTerminalNode && !this.edges.some((edge) => edge.sourceNodeId === node.id)) { - throw new Error(`${node.properties?.stepName} 节点不能当做结束节点`) - } - } -} diff --git a/ui/src/mk-workflow/extension/WorkflowNodeMenu.vue b/ui/src/mk-workflow/extension/WorkflowNodeMenu.vue deleted file mode 100644 index f8d1c9aa292..00000000000 --- a/ui/src/mk-workflow/extension/WorkflowNodeMenu.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/icons/ai-chat-node-icon.vue b/ui/src/mk-workflow/icons/ai-chat-node-icon.vue deleted file mode 100644 index 7a220814144..00000000000 --- a/ui/src/mk-workflow/icons/ai-chat-node-icon.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/ui/src/mk-workflow/icons/base-node-icon.vue b/ui/src/mk-workflow/icons/base-node-icon.vue deleted file mode 100644 index fc526666e04..00000000000 --- a/ui/src/mk-workflow/icons/base-node-icon.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/ui/src/mk-workflow/icons/reply-node-icon.vue b/ui/src/mk-workflow/icons/reply-node-icon.vue deleted file mode 100644 index c30ebc85929..00000000000 --- a/ui/src/mk-workflow/icons/reply-node-icon.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/ui/src/mk-workflow/icons/start-node-icon.vue b/ui/src/mk-workflow/icons/start-node-icon.vue deleted file mode 100644 index 3f0eee973ed..00000000000 --- a/ui/src/mk-workflow/icons/start-node-icon.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/ui/src/mk-workflow/icons/utils.ts b/ui/src/mk-workflow/icons/utils.ts deleted file mode 100644 index e1644c4d4a4..00000000000 --- a/ui/src/mk-workflow/icons/utils.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Component } from 'vue' - -const icons = import.meta.glob<{ default: Component }>('./**.vue', { eager: true }) -export function iconComponent(name: string) { - const url = `./${name}.vue` - return icons[url]?.default || null -} diff --git a/ui/src/mk-workflow/index.vue b/ui/src/mk-workflow/index.vue deleted file mode 100644 index cefa27d45e7..00000000000 --- a/ui/src/mk-workflow/index.vue +++ /dev/null @@ -1,225 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/nodes/ai-chat-node/index.ts b/ui/src/mk-workflow/nodes/ai-chat-node/index.ts deleted file mode 100644 index 691d038ea3f..00000000000 --- a/ui/src/mk-workflow/nodes/ai-chat-node/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import AiChatNode from './index.vue' -import { AppNode, AppNodeModel } from '@/mk-workflow/core/app-node' -import { WorkflowNodeType } from '@/mk-workflow/types' - -class AiChatNodeView extends AppNode { - constructor(props: ConstructorParameters[0]) { - super(props, AiChatNode) - } -} - -export default { - type: WorkflowNodeType.AiChat, - model: AppNodeModel, - view: AiChatNodeView, -} diff --git a/ui/src/mk-workflow/nodes/ai-chat-node/index.vue b/ui/src/mk-workflow/nodes/ai-chat-node/index.vue deleted file mode 100644 index d486127a8d2..00000000000 --- a/ui/src/mk-workflow/nodes/ai-chat-node/index.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/nodes/base-node/index.ts b/ui/src/mk-workflow/nodes/base-node/index.ts deleted file mode 100644 index 33636e27b7b..00000000000 --- a/ui/src/mk-workflow/nodes/base-node/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import BaseNode from './index.vue' -import { AppNode, AppNodeModel } from '@/mk-workflow/core/app-node' -import { WorkflowNodeType } from '@/mk-workflow/types' - -class BaseNodeView extends AppNode { - constructor(props: ConstructorParameters[0]) { - super(props, BaseNode) - } -} - -class BaseNodeModel extends AppNodeModel { - setAttributes() { - super.setAttributes() - this.width = 600 - } -} - -export default { - type: WorkflowNodeType.Base, - model: BaseNodeModel, - view: BaseNodeView, -} diff --git a/ui/src/mk-workflow/nodes/base-node/index.vue b/ui/src/mk-workflow/nodes/base-node/index.vue deleted file mode 100644 index cb7829efd80..00000000000 --- a/ui/src/mk-workflow/nodes/base-node/index.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/nodes/reply-node/index.ts b/ui/src/mk-workflow/nodes/reply-node/index.ts deleted file mode 100644 index 26916a797a2..00000000000 --- a/ui/src/mk-workflow/nodes/reply-node/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import ReplyNode from './index.vue' -import { AppNode, AppNodeModel } from '@/mk-workflow/core/app-node' -import { WorkflowNodeType } from '@/mk-workflow/types' - -class ReplyNodeView extends AppNode { - constructor(props: ConstructorParameters[0]) { - super(props, ReplyNode) - } -} - -export default { - type: WorkflowNodeType.Reply, - model: AppNodeModel, - view: ReplyNodeView, -} diff --git a/ui/src/mk-workflow/nodes/reply-node/index.vue b/ui/src/mk-workflow/nodes/reply-node/index.vue deleted file mode 100644 index 81d73a9cbe4..00000000000 --- a/ui/src/mk-workflow/nodes/reply-node/index.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/nodes/start-node/index.ts b/ui/src/mk-workflow/nodes/start-node/index.ts deleted file mode 100644 index 1b396b697d8..00000000000 --- a/ui/src/mk-workflow/nodes/start-node/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import StartNode from './index.vue' -import { AppNode, AppNodeModel } from '@/mk-workflow/core/app-node' -import { WorkflowNodeType } from '@/mk-workflow/types' - -class StartNodeView extends AppNode { - constructor(props: ConstructorParameters[0]) { - super(props, StartNode) - } -} - -export default { - type: WorkflowNodeType.Start, - model: AppNodeModel, - view: StartNodeView, -} diff --git a/ui/src/mk-workflow/nodes/start-node/index.vue b/ui/src/mk-workflow/nodes/start-node/index.vue deleted file mode 100644 index 9eb8a2e511c..00000000000 --- a/ui/src/mk-workflow/nodes/start-node/index.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - diff --git a/ui/src/mk-workflow/plugins/dagre.ts b/ui/src/mk-workflow/plugins/dagre.ts deleted file mode 100644 index f2bbea1ff1f..00000000000 --- a/ui/src/mk-workflow/plugins/dagre.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type LogicFlow from '@logicflow/core' -import type { BaseNodeModel } from '@logicflow/core' -import { DagreLayout, type DagreLayoutOptions } from '@antv/layout' - -type LayoutNode = { - id: string - model: BaseNodeModel -} - -type LayoutEdge = { - id: string - source: string - target: string -} - -export default class Dagre { - static pluginName = 'dagre' - - private logicFlow?: LogicFlow - - render(logicFlow: LogicFlow) { - this.logicFlow = logicFlow - } - - async layout(options: Partial = {}) { - const logicFlow = this.logicFlow - if (!logicFlow) return - - const { edges, gridSize, nodes } = logicFlow.graphModel - const defaultSpacing = gridSize > 20 ? gridSize * 2 : 40 - const layoutOptions: Partial = { - rankdir: 'LR', - align: 'DR', - nodesep: defaultSpacing, - ranksep: defaultSpacing, - nodeSize: (node) => { - const { model } = node as LayoutNode - return [model.width, model.height] - }, - node: (node) => ({ id: (node as LayoutNode).id }), - edge: (edge) => { - const layoutEdge = edge as LayoutEdge - return { - id: layoutEdge.id, - source: layoutEdge.source, - target: layoutEdge.target, - } - }, - ...options, - } - const layoutInstance = new DagreLayout(layoutOptions) - await layoutInstance.execute({ - nodes: nodes.map((node) => ({ id: node.id, model: node })), - edges: edges.map((edge) => ({ - id: edge.id, - source: edge.sourceNodeId, - target: edge.targetNodeId, - })), - }) - layoutInstance.forEachNode((node) => { - const { model } = node._original as LayoutNode - model.moveTo(node.x, node.y) - }) - logicFlow.fitView() - } -} diff --git a/ui/src/mk-workflow/types.ts b/ui/src/mk-workflow/types.ts deleted file mode 100644 index f386be7844e..00000000000 --- a/ui/src/mk-workflow/types.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** LogicFlow 节点类型,作为工作流图数据中的稳定协议值。 */ -export enum WorkflowNodeType { - Base = 'base-node', - KnowledgeBase = 'knowledge-base-node', - Start = 'start-node', - AiChat = 'ai-chat-node', - SearchKnowledge = 'search-knowledge-node', - SearchDocument = 'search-document-node', - Question = 'question-node', - Condition = 'condition-node', - Reply = 'reply-node', - ToolLib = 'tool-lib-node', - ToolWorkflowLib = 'tool-workflow-lib-node', - ToolLibCustom = 'tool-node', - RerankerNode = 'reranker-node', - Application = 'application-node', - DocumentExtractNode = 'document-extract-node', - DocumentSplitNode = 'document-split-node', - ImageUnderstandNode = 'image-understand-node', - VariableAssignNode = 'variable-assign-node', - FormNode = 'form-node', - TextToSpeechNode = 'text-to-speech-node', - SpeechToTextNode = 'speech-to-text-node', - ImageGenerateNode = 'image-generate-node', - McpNode = 'mcp-node', - IntentNode = 'intent-node', - TextToVideoGenerateNode = 'text-to-video-node', - ImageToVideoGenerateNode = 'image-to-video-node', - LoopNode = 'loop-node', - LoopBodyNode = 'loop-body-node', - LoopStartNode = 'loop-start-node', - LoopContinueNode = 'loop-continue-node', - LoopBreakNode = 'loop-break-node', - VariableSplittingNode = 'variable-splitting-node', - VariableAggregationNode = 'variable-aggregation-node', - VideoUnderstandNode = 'video-understand-node', - ParameterExtractionNode = 'parameter-extraction-node', - DataSourceLocalNode = 'data-source-local-node', - DataSourceWebNode = 'data-source-web-node', - KnowledgeWriteNode = 'knowledge-write-node', - ToolStartNode = 'tool-start-node', - ToolBaseNode = 'tool-base-node', -} - -export enum WorkflowKind { - DataSource = 'data-source', -} -export enum WorkflowMode { - // 应用工作流 - Application = 'application', - // 应用工作流循环 - ApplicationLoop = 'application-loop', - // 知识库工作流 - Knowledge = 'knowledge', - // 工具 - Tool = 'tool', - // 工具循环体 - ToolLoop = 'tool-loop', - // 知识库工作流循环体 - KnowledgeLoop = 'knowledge-loop', -}