308 lines
18 KiB
Markdown
308 lines
18 KiB
Markdown
|
|
# Agent Hooks GUI 学习与复现指南
|
|||
|
|
|
|||
|
|
本指南逐一梳理 `src/pages/agent/hooks` 目录下的所有 Agent 相关 Hooks,帮助你理解画布、抽屉、运行与日志的全链路逻辑,并可据此复现功能。文档涵盖职责、导出、参数与返回、关键逻辑、典型用法及注意事项。
|
|||
|
|
|
|||
|
|
> 约定:`useGraphStore` 为画布状态中心(维护 `nodes`/`edges` 及更新方法);`@xyflow/react` 用于节点/边渲染与交互;`Operator`、`NodeHandleId`、`NodeMap` 定义节点类型、句柄及渲染映射。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 图数据获取与构建
|
|||
|
|
|
|||
|
|
### use-fetch-data.ts
|
|||
|
|
- 作用:页面挂载时获取 Agent 详情并注入画布。
|
|||
|
|
- 导出:`useFetchDataOnMount()` → `{ loading, flowDetail }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 读取 `useFetchAgent()` 的 `data.dsl.graph`,通过 `useSetGraphInfo()` 写入 `nodes/edges`。
|
|||
|
|
- 首次挂载 `refetch()` 刷新详情。
|
|||
|
|
- 用法:在页面 `useEffect` 中调用以初始化画布。
|
|||
|
|
- 注意:`data.dsl.graph` 可能为空,已做空处理。
|
|||
|
|
|
|||
|
|
### use-set-graph.ts
|
|||
|
|
- 作用:将后端返回的 `IGraph` 写入画布。
|
|||
|
|
- 导出:`useSetGraphInfo()` → `setGraphInfo({ nodes = [], edges = [] }: IGraph)`
|
|||
|
|
- 关键逻辑:有数据才更新,避免清空现有状态。
|
|||
|
|
- 关联:与 `useFetchDataOnMount` 搭配使用。
|
|||
|
|
|
|||
|
|
### use-build-dsl.ts
|
|||
|
|
- 作用:根据当前 `nodes/edges` 构建可保存的 DSL 数据对象,并过滤占位符节点(`Operator.Placeholder`)。
|
|||
|
|
- 导出:`useBuildDslData()` → `{ buildDslData(currentNodes?) }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 过滤占位符节点与相关边。
|
|||
|
|
- `buildDslComponentsByGraph(filteredNodes, filteredEdges, data.dsl.components)` 生成组件列表。
|
|||
|
|
- 返回 `{ ...data.dsl, graph, components }`。
|
|||
|
|
- 用法:保存前构建 DSL;导出 JSON 时使用。
|
|||
|
|
|
|||
|
|
### use-export-json.ts
|
|||
|
|
- 作用:导出当前画布图为 JSON 文件。
|
|||
|
|
- 导出:`useHandleExportJsonFile()` → `{ handleExportJson }`
|
|||
|
|
- 关键逻辑:`downloadJsonFile(buildDslData().graph, \
|
|||
|
|
\`\${data.title}.json\`)`
|
|||
|
|
|
|||
|
|
### use-save-graph.ts
|
|||
|
|
- 作用:保存画布到后端;在打开调试时确保最新 DSL。
|
|||
|
|
- 导出:
|
|||
|
|
- `useSaveGraph(showMessage?: boolean)` → `{ saveGraph(currentNodes?), loading }`
|
|||
|
|
- `useSaveGraphBeforeOpeningDebugDrawer(show)` → `{ handleRun(nextNodes?), loading }`
|
|||
|
|
- `useWatchAgentChange(chatDrawerVisible)` → 自动 debounce 保存,并回显更新时间字符串。
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 基于路由 `id` + `data.title` + `buildDslData` 组装 `dsl` 调用 `useSetAgent`。
|
|||
|
|
- 打开调试前先 `saveGraph()`,再 `resetAgent()` 清空旧消息。
|
|||
|
|
- `useDebounceEffect`:每 20 秒在节点/边变化时自动保存(聊天抽屉打开时不保存)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 节点创建与拖拽
|
|||
|
|
|
|||
|
|
### use-add-node.ts
|
|||
|
|
- 作用:核心节点添加逻辑,含初始参数、坐标计算、特殊类型处理(Agent/Tool/Iteration/Note)。
|
|||
|
|
- 导出:
|
|||
|
|
- `useInitializeOperatorParams()` → `{ initializeOperatorParams, initialFormValuesMap }`
|
|||
|
|
- `useGetNodeName()` → 根据 `Operator` 返回国际化默认名称。
|
|||
|
|
- `useCalculateNewlyChildPosition()` → 计算新增子节点位置避免覆盖。
|
|||
|
|
- `useAddNode(reactFlowInstance?)` → `{ addCanvasNode, addNoteNode }`
|
|||
|
|
- 内部逻辑:`useAddChildEdge()`、`useAddToolNode()`、`useResizeIterationNode()`。
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 初始化各 `Operator` 的 `form` 默认值;Agent/Extractor 等会注入 `llm_id`、默认 prompts。
|
|||
|
|
- 迭代节点 `Operator.Iteration` 自动创建 `Operator.IterationStart` 子节点并设为 `extent='parent'`。
|
|||
|
|
- Agent 底部子 Agent 的水平分布通过已有子节点 `x` 轴最大值计算,避免重叠;Tool 节点仅允许一个(检查是否已有 `NodeHandleId.Tool` 连接)。
|
|||
|
|
- 通过 `reactFlowInstance.screenToFlowPosition` 将点击位置转换为画布坐标;右侧新增子节点时自动用 `NodeHandleId` 连线。
|
|||
|
|
- 容器内新增子节点时可能触发父容器宽度调整以容纳子节点。
|
|||
|
|
- 典型用法:
|
|||
|
|
```ts
|
|||
|
|
const { addCanvasNode } = useAddNode(reactFlowInstance);
|
|||
|
|
// 在菜单点击或连接拖拽结束时:
|
|||
|
|
addCanvasNode(Operator.Agent, { nodeId, position: Position.Right, id: NodeHandleId.Start })(event);
|
|||
|
|
```
|
|||
|
|
- 注意:
|
|||
|
|
- `Operator.Placeholder` 节点 `draggable=false`。
|
|||
|
|
- Tool 节点唯一性;容器内节点可能触发 resize。
|
|||
|
|
|
|||
|
|
### use-connection-drag.ts
|
|||
|
|
- 作用:连接拖拽起止处理;在拖拽终止位置弹出节点选择下拉,创建占位符节点并连线。
|
|||
|
|
- 导出:`useConnectionDrag(reactFlowInstance, onConnect, showModal, hideModal, setDropdownPosition, setCreatedPlaceholderRef, calculateDropdownPosition, removePlaceholderNode, clearActiveDropdown, checkAndRemoveExistingPlaceholder)` → `{ nodeId, onConnectStart, onConnectEnd, handleConnect, getConnectionStartContext, shouldPreventClose, onMove }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- `onConnectStart` 记录起点节点/句柄及鼠标起始位置,区分点击/拖拽(<5px 移动视为点击)。
|
|||
|
|
- `onConnectEnd` 计算下拉面板位置;点击则清理状态并关闭下拉;拖拽时先移除旧占位符,再创建新占位符并连线。
|
|||
|
|
- `onMove` 在画布滚动/缩放时隐藏下拉并清理占位符。
|
|||
|
|
|
|||
|
|
### use-dropdown-position.ts
|
|||
|
|
- 作用:屏幕与 Flow 坐标互转,计算下拉菜单位置使其对齐占位节点。
|
|||
|
|
- 导出:`useDropdownPosition(reactFlowInstance)` → `{ calculateDropdownPosition, getPlaceholderNodePosition, flowToScreenPosition, screenToFlowPosition }`
|
|||
|
|
- 关键逻辑:按常量 `HALF_PLACEHOLDER_NODE_WIDTH`、`DROPDOWN_HORIZONTAL_OFFSET`、`DROPDOWN_VERTICAL_OFFSET` 计算偏移。
|
|||
|
|
|
|||
|
|
### use-placeholder-manager.ts
|
|||
|
|
- 作用:占位符节点的创建、删除与状态追踪;替换为真实节点后自动建立连接并同步位置。
|
|||
|
|
- 导出:`usePlaceholderManager(reactFlowInstance)` → `{ removePlaceholderNode, onNodeCreated, setCreatedPlaceholderRef, resetUserSelectedFlag, checkAndRemoveExistingPlaceholder, createdPlaceholderRef, userSelectedNodeRef }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 保证面板上仅有一个占位符。
|
|||
|
|
- `onNodeCreated(newNodeId)`:真实节点位置与占位符对齐;按占位符的起点连线;删除占位符及相关边。
|
|||
|
|
- 使用 `reactFlowInstance.deleteElements` 执行批量删除。
|
|||
|
|
|
|||
|
|
### use-before-delete.tsx
|
|||
|
|
- 作用:拦截删除操作,保护 `Operator.Begin`、容器首节点(`Operator.IterationStart` 非成对删除时阻止)及下游 Agent/Tool 的联动删除。
|
|||
|
|
- 导出:`useBeforeDelete()` → `{ handleBeforeDelete }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- `UndeletableNodes`:Begin 与 IterationStart 的特殊保护。
|
|||
|
|
- 当包含 Agent 节点时,额外删除其下游 Agent/Tool(节点与边)。
|
|||
|
|
- 用法:作为 React Flow 的 `onBeforeDelete` 回调。
|
|||
|
|
|
|||
|
|
### use-change-node-name.ts
|
|||
|
|
- 作用:处理节点名称与 Tool 名称变更,避免重复命名并同步到画布。
|
|||
|
|
- 导出:`useHandleNodeNameChange({ id, data })` → `{ name, handleNameBlur, handleNameChange }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- Tool 名称变更写入父 Agent 的 `tools` 字段,通过 `updateNodeForm(agentId, nextTools, ['tools'])`。
|
|||
|
|
- 普通节点名通过 `updateNodeName(id, name)` 更新;同一画布内不可重名,重复则提示 `message.error('The name cannot be repeated')`。
|
|||
|
|
|
|||
|
|
### use-agent-tool-initial-values.ts
|
|||
|
|
- 作用:为 Agent Tool(非画布节点)生成初始参数(裁剪/重组)以适配对话调用。
|
|||
|
|
- 导出:`useAgentToolInitialValues()` → `{ initializeAgentToolValues(operatorName) }`
|
|||
|
|
- 关键逻辑:对不同 `Operator` 精简参数,如去除 `query/sql/stock_code`,或仅保留 `smtp_*` 邮件字段等。
|
|||
|
|
|
|||
|
|
### use-form-values.ts
|
|||
|
|
- 作用:表单初始值合并,优先使用节点已有 `data.form`,否则回退为 `defaultValues`。
|
|||
|
|
- 导出:`useFormValues(defaultValues, node?)`
|
|||
|
|
|
|||
|
|
### use-watch-form-change.ts
|
|||
|
|
- 作用:监听 `react-hook-form` 表单变化并同步到画布节点 `form`。
|
|||
|
|
- 导出:`useWatchFormChange(id?, form?)`
|
|||
|
|
- 关键逻辑:手动获取 `form.getValues()`,再 `updateNodeForm(id, values)`。
|
|||
|
|
|
|||
|
|
### use-move-note.ts
|
|||
|
|
- 作用:便签(Note)悬浮预览位置跟随鼠标。
|
|||
|
|
- 导出:`useMoveNote()` → `{ ref, showImage, hideImage, mouse, imgVisible }`
|
|||
|
|
- 关键逻辑:使用 `useMouse()` 监听坐标,更新 `ref.current.style.top/left`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 运行与日志
|
|||
|
|
|
|||
|
|
### use-run-dataflow.ts
|
|||
|
|
- 作用:保存画布后触发数据流运行(SSE),打开日志抽屉并设置当前 `messageId`。
|
|||
|
|
- 导出:`useRunDataflow({ showLogSheet, setMessageId })` → `{ run(fileResponseData), loading, uploadedFileData }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 先 `saveGraph()`,再 `send({ id, query: '', session_id: null, files: [file] })` 到 `api.runCanvas`。
|
|||
|
|
- 校验响应成功后设置 `uploadedFileData/file` 与 `messageId`。
|
|||
|
|
|
|||
|
|
### use-cancel-dataflow.ts
|
|||
|
|
- 作用:取消当前数据流,并停止日志拉取。
|
|||
|
|
- 导出:`useCancelCurrentDataflow({ messageId, stopFetchTrace })` → `{ handleCancel }`
|
|||
|
|
- 关键逻辑:`cancelDataflow(messageId)` 返回 `code===0` 时调用 `stopFetchTrace()`。
|
|||
|
|
|
|||
|
|
### use-fetch-pipeline-log.ts
|
|||
|
|
- 作用:拉取运行日志(trace),判断是否完成与是否为空,控制轮询。
|
|||
|
|
- 导出:`useFetchPipelineLog(logSheetVisible)` → `{ logs, isLogEmpty, isCompleted, loading, isParsing, messageId, setMessageId, stopFetchTrace }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- `END` 且 `trace[0].message` 非空视为完成,随后 `stopFetchTrace()`;抽屉打开时重置 `isStopFetchTrace=false` 继续拉取。
|
|||
|
|
|
|||
|
|
### use-download-output.ts
|
|||
|
|
- 作用:从日志中提取 `END` 节点输出并下载 JSON。
|
|||
|
|
- 导出:`findEndOutput(list)`, `isEndOutputEmpty(list)`, `useDownloadOutput(data?)` → `{ handleDownloadJson }`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 抽屉与面板显示
|
|||
|
|
|
|||
|
|
### use-show-drawer.tsx
|
|||
|
|
- 作用:统一管理“运行/聊天抽屉”、“单节点调试抽屉”、“表单抽屉”、“日志抽屉”的显示逻辑。
|
|||
|
|
- 导出:
|
|||
|
|
- `useShowFormDrawer()` → `{ formDrawerVisible, hideFormDrawer, showFormDrawer(e, nodeId), clickedNode }`
|
|||
|
|
- `useShowSingleDebugDrawer()` → `{ singleDebugDrawerVisible, hideSingleDebugDrawer, showSingleDebugDrawer }`
|
|||
|
|
- `useShowDrawer({ drawerVisible, hideDrawer })` → `{ chatVisible, runVisible, onPaneClick, singleDebugDrawerVisible, showSingleDebugDrawer, hideSingleDebugDrawer, formDrawerVisible, showFormDrawer, clickedNode, onNodeClick, hideFormDrawer, hideRunOrChatDrawer, showChatModal }`
|
|||
|
|
- `useShowLogSheet({ setCurrentMessageId })` → `{ logSheetVisible, hideLogSheet, showLogSheet(messageId) }`
|
|||
|
|
- `useHideFormSheetOnNodeDeletion({ hideFormDrawer })` → 在节点被删除时自动关闭表单抽屉。
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- 当 `drawerVisible=true`:若 Begin 有输入则显示“运行”抽屉;否则显示“聊天”抽屉。
|
|||
|
|
- 点击节点打开表单抽屉(排除 Note/Placeholder/File);点击节点上的“播放”图标打开单节点调试抽屉。
|
|||
|
|
- `hideRunOrChatDrawer` 同时关闭运行/聊天抽屉与外层抽屉。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Begin 相关选项与变量
|
|||
|
|
|
|||
|
|
### use-get-begin-query.tsx
|
|||
|
|
- 作用:围绕 Begin 节点数据构建输入、输出、变量与组件引用选项。
|
|||
|
|
- 导出:
|
|||
|
|
- `useSelectBeginNodeDataInputs()` → Begin 的输入 `BeginQuery[]`
|
|||
|
|
- `useIsTaskMode(isTask?)` → 返回是否任务模式(从 Begin 的 `form.mode` 或传入)。
|
|||
|
|
- `useGetBeginNodeDataQuery()` → 读取 Begin 的 `inputs` 并转换为列表。
|
|||
|
|
- `useBuildNodeOutputOptions(nodeId?)` → 输出引用选项(带 `OperatorIcon`)。
|
|||
|
|
- `useBuildVariableOptions(nodeId?, parentId?)` → Begin 变量与节点输出选项合并。
|
|||
|
|
- `useBuildComponentIdOptions(nodeId?, parentId?)` → 组件引用(排除某些节点,容器内仅引用同层或外部节点)。
|
|||
|
|
- `useBuildComponentIdAndBeginOptions(nodeId?, parentId?)` → Begin + 组件引用。
|
|||
|
|
- `useGetComponentLabelByValue(nodeId)` / `useGetVariableLabelByValue(nodeId)` → 根据值反查标签。
|
|||
|
|
- 注意:容器内节点引用受限:子节点只能引用同容器同层节点或外部节点,不能引用父节点。
|
|||
|
|
|
|||
|
|
### use-build-options.tsx
|
|||
|
|
- 作用:轻量版,仅构建节点输出选项。
|
|||
|
|
- 导出:`useBuildNodeOutputOptions(nodeId?)`
|
|||
|
|
|
|||
|
|
### use-is-pipeline.ts
|
|||
|
|
- 作用:读取路由查询判断是否显示数据流画布(`AgentQuery.Category === DataflowCanvas`)。
|
|||
|
|
- 导出:`useIsPipeline()`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 聊天与共享
|
|||
|
|
|
|||
|
|
### use-chat-logic.ts
|
|||
|
|
- 作用:对话中处理“等待用户填写”的表单组件逻辑,组装提交时的 `beginInputs`。
|
|||
|
|
- 导出:`useAwaitCompentData({ derivedMessages, sendFormMessage, canvasId })` → `{ getInputs, buildInputList, handleOk, isWaitting }`
|
|||
|
|
- 关键逻辑:将消息中的 `data.inputs` 与用户填写值合并后发送。
|
|||
|
|
|
|||
|
|
### use-cache-chat-log.ts
|
|||
|
|
- 作用:聊天事件按 `message_id` 分片缓存,支持过滤与清空。
|
|||
|
|
- 导出:`useCacheChatLog()` → `{ eventList, currentEventListWithoutMessage, currentEventListWithoutMessageById, setEventList, clearEventList, addEventList, filterEventListByEventType, filterEventListByMessageId, setCurrentMessageId, currentMessageId }`
|
|||
|
|
- 关键逻辑:排除 `Message/MessageEnd` 事件,保留节点事件日志用于“运行日志”展示。
|
|||
|
|
|
|||
|
|
### use-send-shared-message.ts
|
|||
|
|
- 作用:分享页的消息发送逻辑(可任务模式),包含参数弹窗与自动触发任务。
|
|||
|
|
- 导出:
|
|||
|
|
- `useSendButtonDisabled(value)` → 空字符串时禁用。
|
|||
|
|
- `useGetSharedChatSearchParams()` → 从 URL 解析 `from/shared_id/locale` 等。
|
|||
|
|
- `useSendNextSharedMessage(addEventList)` → `{ sendMessage, hasError, parameterDialogVisible, inputsData, isTaskMode, hideParameterDialog, showParameterDialog, ok }`
|
|||
|
|
- 关键逻辑:
|
|||
|
|
- `url` 动态拼接:`agentbots` 或 `chatbots`。
|
|||
|
|
- 任务模式且 `inputs` 为空时自动触发一次空参数运行。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 外部资源与工具
|
|||
|
|
|
|||
|
|
### use-find-mcp-by-id.ts
|
|||
|
|
- 作用:在 MCP 服务列表中按 ID 查找服务器对象。
|
|||
|
|
- 导出:`useFindMcpById()` → `{ findMcpById(id) }`
|
|||
|
|
|
|||
|
|
### use-open-document.ts
|
|||
|
|
- 作用:打开在线文档(Agent 组件说明)。
|
|||
|
|
- 导出:`useOpenDocument()` → `openDocument()`(`window.open` 到 `https://ragflow.io/docs/dev/category/agent-components`)。
|
|||
|
|
|
|||
|
|
### use-show-dialog.ts
|
|||
|
|
- 作用:系统 API Key 管理与分享预览。
|
|||
|
|
- 导出:
|
|||
|
|
- `useOperateApiKey(idKey, dialogId?)` → `{ removeToken, createToken, tokenList, creatingLoading, listLoading }`
|
|||
|
|
- `usePreviewChat(idKey)` → `{ handlePreview }`
|
|||
|
|
- `useSelectChartStatsList()` → 将统计数据转换为图表用的 `{ xAxis, yAxis }[]`。
|
|||
|
|
- 关键逻辑:创建/删除系统 token;打开分享页预览 URL(根据 `idKey` 判断 Agent 或 Chat)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 布局与其他
|
|||
|
|
|
|||
|
|
### use-calculate-sheet-right.ts
|
|||
|
|
- 作用:根据 `body` 宽度返回抽屉的右侧定位类名。
|
|||
|
|
- 导出:`useCalculateSheetRight()` → `'right-[620px]' | 'right-1/3'`
|
|||
|
|
|
|||
|
|
### use-iteration.ts
|
|||
|
|
- 作用:当前文件为空,预留迭代相关的后续逻辑。
|
|||
|
|
- 导出:暂无(空文件)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 复现建议与流程
|
|||
|
|
|
|||
|
|
- 画布初始化:
|
|||
|
|
- 页面挂载时调用 `useFetchDataOnMount()`,保证 `nodes/edges` 与后端一致。
|
|||
|
|
- 如需区分是否数据流画布,调用 `useIsPipeline()` 控制界面模式。
|
|||
|
|
|
|||
|
|
- 节点与连接交互:
|
|||
|
|
- 连接拖拽中,使用 `useConnectionDrag` 的 `onConnectStart/onConnectEnd/onMove` 管理占位符与下拉。
|
|||
|
|
- 选择节点类型后,配合 `usePlaceholderManager.onNodeCreated(newNodeId)` 落地真实节点并连线。
|
|||
|
|
- 添加节点通过 `useAddNode.addCanvasNode(type,{ nodeId, position, id })(event)`,自动计算位置与连线。
|
|||
|
|
|
|||
|
|
- 表单与抽屉:
|
|||
|
|
- 点击节点打开 `useShowFormDrawer.showFormDrawer(e, nodeId)`;点击“播放”打开 `useShowSingleDebugDrawer`。
|
|||
|
|
- 外层抽屉控制 `useShowDrawer`;运行/聊天抽屉根据 Begin 输入状态切换。
|
|||
|
|
- 表单变更用 `useWatchFormChange(id, form)` 将 `react-hook-form` 值同步到 `data.form`。
|
|||
|
|
|
|||
|
|
- 运行与日志:
|
|||
|
|
- 上传文件后,调用 `useRunDataflow.run(fileResponseData)`;在日志抽屉中用 `useFetchPipelineLog(logSheetVisible)` 拉取状态。
|
|||
|
|
- 取消运行用 `useCancelCurrentDataflow.handleCancel()`;下载输出用 `useDownloadOutput.handleDownloadJson()`。
|
|||
|
|
|
|||
|
|
- 保存与导出:
|
|||
|
|
- 使用 `useSaveGraphBeforeOpeningDebugDrawer` 在每次调试前保存并重置状态。
|
|||
|
|
- 自动保存:`useWatchAgentChange(chatDrawerVisible)` 在无聊天抽屉时 debounce 落库。
|
|||
|
|
- 导出 JSON:`useHandleExportJsonFile.handleExportJson()`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 易踩坑与注意事项
|
|||
|
|
|
|||
|
|
- 占位符节点必须在保存 DSL 时过滤,否则会污染组件图(`useBuildDslData` 已处理)。
|
|||
|
|
- Tool 节点只允许有一个;`useAddNode` 中对 Tool 的添加有唯一性校验。
|
|||
|
|
- 容器类(Iteration)中的引用受限:子节点只能引用同容器同层节点或外部节点,不能引用父节点(`useBuildComponentIdOptions`)。
|
|||
|
|
- 名称唯一性:画布内节点与 Agent 下的 Tool name 均需唯一(`useChangeNodeName`)。
|
|||
|
|
- 聊天日志拉取需在 END 且 trace 有 message 时停止,否则会持续轮询(`useFetchPipelineLog`)。
|
|||
|
|
- 运行/聊天抽屉切换逻辑依赖 Begin 输入是否存在(`useShowDrawer`)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 关联常量与工具(理解 hooks 需要)
|
|||
|
|
|
|||
|
|
- `Operator`、`NodeHandleId`、`NodeMap`:定义节点类型和画布渲染类型。
|
|||
|
|
- `generateNodeNamesWithIncreasingIndex`:为新增节点生成不重复的默认名称。
|
|||
|
|
- `getNodeDragHandle(type)`:为不同节点类型定义可拖拽句柄范围。
|
|||
|
|
- `buildNodeOutputOptions`、`buildBeginInputListFromObject`、`buildBeginQueryWithObject`:构建下拉选项与输入/变量结构。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
如需按模块拆分为多页或增加“最小复现代码片段”,可进一步细化。也可以优先从“连接拖拽 + 占位符 + 节点添加”链路开始,逐步验证 UI 与数据正确性。
|