Bladeren bron

feat: 新增边线添加节点

jiaxing.liao 1 maand geleden
bovenliggende
commit
4bbe1e3db6

+ 1 - 1
apps/web/src/nodes/src/condition/index.ts

@@ -37,7 +37,7 @@ export const conditionNode: INodeType = {
 		})
 
 		ports.push({
-			id: data?.id ? `${data.id}-else` : 'source',
+			id: data?.id ? `${data.id}-source` : 'source',
 			label: 'ELSE',
 			type: 'port'
 		})

+ 50 - 8
apps/web/src/views/Editor.vue

@@ -67,6 +67,7 @@
 						@dragover="onDragOver"
 						@dragleave="onDragLeave"
 						@create:connection:cancelled="onConnectionOpenNodeLibary"
+						@click:connection:add="handleClickConectionAdd"
 						class="bg-#f5f5f5"
 					>
 						<Toolbar
@@ -146,10 +147,12 @@ const workflowWrapperRef = ref<HTMLElement>()
 const showNodeLibary = ref(false)
 const libaryRefferenceRef = ref<HTMLElement>()
 const peddingHandlePayload = ref<{
-	handle: ConnectStartEvent
+	by?: 'node' | 'edge'
+	handle?: ConnectStartEvent
 	position: XYPosition
 	event?: MouseEvent
 	parentId?: string
+	connection?: Connection
 }>()
 
 const projectMap = JSON.parse(localStorage.getItem(`workflow-map`) || '{}') as Record<
@@ -630,6 +633,7 @@ const handleRunNode = async (id: string) => {
 	}
 }
 const handleNodeCreate = (value: { type: string; position?: XYPosition } | string) => {
+	// TODO: 处理注释节点
 	if (typeof value === 'string') {
 		if (value === 'stickyNote') {
 			workflow.value?.nodes.push({
@@ -663,7 +667,7 @@ const handleNodeCreate = (value: { type: string; position?: XYPosition } | strin
 
 	// 如果存在对应节点则添加
 	if (nodeToAdd) {
-		const newNodeParam = {
+		const newNodeParam: any = {
 			...nodeToAdd,
 			appAgentId: workflow.value?.id || '',
 			position: value.position
@@ -683,20 +687,34 @@ const handleNodeCreate = (value: { type: string; position?: XYPosition } | strin
 			const { position, handle, parentId } = peddingHandlePayload.value
 
 			newNodeParam.position = position
-			newNodeParam.prevNodeId = handle.nodeId
+			newNodeParam.prevNodeId = handle?.nodeId
 			newNodeParam.parentId = parentId
-			if (handle.handleId?.includes('_')) {
-				newNodeParam.nodeHandleId = handle.handleId
+			// 条件句柄
+			if (handle?.handleId?.includes('_')) {
+				newNodeParam.nodeHandleId = handle?.handleId
 			}
-			// if (handle.handleId?.endsWith('-else')) {
-			// 	newNodeParam.nodeHandleId = handle.nodeId
-			// }
 		}
 
 		if (!newNodeParam.position) {
 			newNodeParam.position = nodeToAdd.position
 		}
 
+		// 根据连线添加节点
+		if (peddingHandlePayload.value?.by === 'edge' && peddingHandlePayload.value?.connection) {
+			const { connection } = peddingHandlePayload.value
+			const params = {
+				edgeId: connection.id,
+				newNode: newNodeParam
+			}
+			agent.postAgentDoNewAgentNodeWithEdge(params).then(async (response) => {
+				if (handleApiResult(response, '节点已添加', '新增节点失败')) {
+					await loadAgentWorkflow(workflow.value.id)
+				}
+			})
+			onHideNodeLibary()
+			return
+		}
+
 		onHideNodeLibary()
 
 		agent
@@ -963,6 +981,30 @@ const onHideNodeLibary = () => {
 	showNodeLibary.value = false
 }
 
+/**
+ * 连线添加按钮触发
+ */
+const handleClickConectionAdd = (connection: Connection) => {
+	const el = document.querySelector(`[edge-add-btn="${connection.id}"]`) as HTMLElement
+	const screenToFlowCoordinate = workflowRef.value?.getVueFlow()?.screenToFlowCoordinate
+
+	if (el && screenToFlowCoordinate) {
+		const rect = el.getBoundingClientRect()
+		const position = screenToFlowCoordinate({
+			x: rect.left,
+			y: rect.top
+		})
+
+		libaryRefferenceRef.value = el
+		showNodeLibary.value = true
+		peddingHandlePayload.value = {
+			by: 'edge',
+			position,
+			connection
+		}
+	}
+}
+
 onBeforeUnmount(() => {
 	if (saveAgentTimer.value) window.clearTimeout(saveAgentTimer.value)
 	if (saveVarsTimer.value) window.clearTimeout(saveVarsTimer.value)

File diff suppressed because it is too large
+ 663 - 57
packages/api-service/agent.openapi.json


+ 80 - 2
packages/api-service/servers/api/agent.ts

@@ -59,6 +59,7 @@ export async function postAgentDoExecute(
     appAgentId: string
     start_node_id: string
     is_debugger: boolean
+    responseType: string
     params: Record<string, any>
   },
   options?: { [key: string]: any }
@@ -80,19 +81,19 @@ export async function postAgentDoExecute(
 export async function postAgentDoNewAgentNode(
   body: {
     appAgentId: string
+    parentId?: string
     position: { x: number; y: number }
     width: number
     height: number
     selected: boolean
     nodeType: string
     zIndex: number
-    parentId?: string
     prevNodeId?: string
     nodeHandleId?: string
   },
   options?: { [key: string]: any }
 ) {
-  return request<{ isSuccess: boolean; code: number; isAuthorized: boolean }>(
+  return request<{ isSuccess: boolean; code: number; result: string; isAuthorized: boolean }>(
     '/api/agent/doNewAgentNode',
     {
       method: 'POST',
@@ -105,6 +106,38 @@ export async function postAgentDoNewAgentNode(
   )
 }
 
+/** 根据边缘线,创建新的智能体节点 POST /api/agent/doNewAgentNodeWithEdge */
+export async function postAgentDoNewAgentNodeWithEdge(
+  body: {
+    edgeId: string
+    newNode: {
+      appAgentId: string
+      parentId: string
+      position: { x: number; y: number }
+      width: number
+      height: number
+      selected: boolean
+      nodeType: string
+      zIndex: number
+      prevNodeId: string
+      nodeHandleId: string
+    }
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{ isSuccess: boolean; code: number; result: string; isAuthorized: boolean }>(
+    '/api/agent/doNewAgentNodeWithEdge',
+    {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json'
+      },
+      data: body,
+      ...(options || {})
+    }
+  )
+}
+
 /** 新增智能体边缘信息 POST /api/agent/doNewEdge */
 export async function postAgentDoNewEdge(
   body: {
@@ -352,6 +385,51 @@ export async function postAgentGetAgentList(
   })
 }
 
+/** 获取智能体节点的最后一次运行日志 POST /api/agent/getAgentNodeLastRunnerLogs */
+export async function postAgentGetAgentNodeLastRunnerLogs(
+  body: {
+    node_id: string
+  },
+  options?: { [key: string]: any }
+) {
+  return request<{
+    isSuccess: boolean
+    code: number
+    result: {
+      appAgentId: string
+      appAgentNodeId: string
+      appAgentRunnerId: string
+      creationTime: string
+      errorMsg: string
+      id: string
+      isDeleted: boolean
+      raw: {
+        agent_node_id: string
+        children: string[]
+        end_time: number
+        input_variable: { str: string }
+        is_success: boolean
+        node_name: string
+        node_type: string
+        output_variable: { result: string[] }
+        start_time: number
+        use_time: number
+      }
+      status: string
+      updateTime: string
+      useTime: number
+    }
+    isAuthorized: boolean
+  }>('/api/agent/getAgentNodeLastRunnerLogs', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
 /** 根据节点id,获取节点之前的所有变量列表 POST /api/agent/getPrevNodeOutVariableList */
 export async function postAgentGetPrevNodeOutVariableList(
   body: {

+ 4 - 0
packages/workflow/src/components/Canvas.vue

@@ -76,6 +76,9 @@ const emit = defineEmits<{
 			parentId?: string
 		}
 	]
+	/**
+	 * 连线节点添加
+	 */
 	'click:connection:add': [connection: Connection]
 }>()
 
@@ -446,6 +449,7 @@ defineExpose({
 					@delete="onDeleteNode"
 					@run="onRunNode"
 					@update:nodes:position="onUpdateNodesPosition"
+					@edge:add:click="onClickConnectionAdd"
 				/>
 			</slot>
 		</template>

+ 1 - 1
packages/workflow/src/components/elements/edges/CanvasEdge.vue

@@ -94,7 +94,7 @@ const onDelete = () => {
 			class="nodrag nopan"
 		>
 			<div v-if="renderToolbar" class="flex">
-				<IconButton icon="lucide:plus" size="small" square @click="onAdd" />
+				<IconButton :edge-add-btn="id" icon="lucide:plus" size="small" square @click="onAdd" />
 				<IconButton icon="lucide:brush-cleaning" size="small" square @click="onDelete" />
 			</div>
 		</div>

+ 2 - 0
packages/workflow/src/components/elements/nodes/render-types/NodeLoop.vue

@@ -44,6 +44,7 @@ const emit = defineEmits<{
 	'create:connection:cancelled': [
 		payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }
 	]
+	'edge:add:click': [connection: Connection]
 }>()
 
 const nodeData = computed(() => node.props.value.node?.data ?? node.props.value.data)
@@ -148,6 +149,7 @@ function onAddEdge(connection: Connection) {
 					@create:connection:cancelled="emit('create:connection:cancelled', $event)"
 					@update:node:attrs="(id, attrs) => emit('update', id, attrs)"
 					@update:nodes:position="emit('update:nodes:position', $event)"
+					@click:connection:add="emit('edge:add:click', $event)"
 				/>
 			</div>
 		</div>