Skip to content

Commit 512fa96

Browse files
authored
[app-platform] add agent flow module (#524)
* [frontend] Add agent flow module * [frontend] Update frontend dependency position
1 parent d0c6f7c commit 512fa96

File tree

470 files changed

+48420
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

470 files changed

+48420
-1
lines changed

agent-flow/.eslintrc.cjs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:react/recommended',
7+
'plugin:react/jsx-runtime',
8+
'plugin:react-hooks/recommended',
9+
],
10+
ignorePatterns: ['dist', '.eslintrc.cjs'],
11+
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12+
settings: { react: { version: '18.2' } },
13+
plugins: ['react-refresh'],
14+
rules: {
15+
'react/jsx-no-target-blank': 'off',
16+
'react-refresh/only-export-components': [
17+
'warn',
18+
{ allowConstantExport: true },
19+
],
20+
},
21+
}

agent-flow/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package-lock.json
2+
node_modules/
3+
build/

agent-flow/.npmrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
strict-ssl=false
2+
package-lock=true # 启用lockfiles
3+
registry=https://registry.npmjs.org/

agent-flow/README.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# @fit-elsa/agent-flow
2+
3+
## 简介
4+
5+
@fit-elsa/agent-flow 是基于React的前端应用模块,为 @fit-elsa/elsa 核心框架提供React封装和UI组件。
6+
7+
## 功能亮点
8+
9+
### 集成React能力
10+
- 基于Context的上下文传递
11+
- 节点渲染缓存:React.memo + 自定义shouldComponentUpdate
12+
13+
### 集成Ant Design能力
14+
- 基于Form组件的实时校验提示系统
15+
- 基于Tree组件封装的节点上下文观察者机制
16+
17+
## 安装
18+
19+
```bash
20+
npm install @fit-elsa/agent-flow @fit-elsa/elsa
21+
```
22+
23+
## 快速开始
24+
25+
### 基本用法
26+
27+
```jsx
28+
import React from 'react';
29+
import { JadeFlow, createGraphOperator } from '@fit-elsa/agent-flow';
30+
31+
function MyFlowApp() {
32+
// 创建图形操作器
33+
const graphOperator = createGraphOperator();
34+
35+
// 处理图形数据变更
36+
const handleGraphChange = (graphData) => {
37+
console.log('图形数据已变更:', graphData);
38+
};
39+
40+
return (
41+
<div style={{ width: '100%', height: '100vh' }}>
42+
<JadeFlow
43+
graphOperator={graphOperator}
44+
onGraphChange={handleGraphChange}
45+
height={600}
46+
width={800}
47+
/>
48+
</div>
49+
);
50+
}
51+
52+
export default MyFlowApp;
53+
```
54+
55+
### 多会话示例
56+
57+
```jsx
58+
import React, { useState } from 'react';
59+
import { MultiConversation, MultiConversationContent } from '@fit-elsa/agent-flow';
60+
61+
function MultiConvApp() {
62+
const [selectedConversation, setSelectedConversation] = useState(null);
63+
64+
const conversations = [
65+
{ id: '1', title: '会话 1', content: '这是第一个会话的内容' },
66+
{ id: '2', title: '会话 2', content: '这是第二个会话的内容' }
67+
];
68+
69+
return (
70+
<div style={{ display: 'flex', height: '100vh' }}>
71+
<div style={{ width: '300px', borderRight: '1px solid #ccc' }}>
72+
<MultiConversation
73+
conversations={conversations}
74+
onSelectConversation={setSelectedConversation}
75+
selectedConversationId={selectedConversation?.id}
76+
/>
77+
</div>
78+
<div style={{ flex: 1, padding: '20px' }}>
79+
{selectedConversation && (
80+
<MultiConversationContent
81+
conversation={selectedConversation}
82+
/>
83+
)}
84+
</div>
85+
</div>
86+
);
87+
}
88+
89+
export default MultiConvApp;
90+
```
91+
92+
## 组件API
93+
94+
### JadeFlow
95+
96+
主要的流程图组件,用于显示和编辑流程图。
97+
98+
**属性**:
99+
- `graphOperator`: 图形操作器实例
100+
- `onGraphChange`: 图形数据变更时的回调函数
101+
- `height`: 流程图高度
102+
- `width`: 流程图宽度
103+
- `readOnly`: 是否只读模式
104+
- `locale`: 语言设置
105+
106+
### MultiConversation
107+
108+
多会话列表组件,用于显示和选择多个会话。
109+
110+
**属性**:
111+
- `conversations`: 会话列表数据
112+
- `onSelectConversation`: 选择会话时的回调函数
113+
- `selectedConversationId`: 当前选中的会话ID
114+
115+
### MultiConversationContent
116+
117+
会话内容组件,用于显示选中会话的详细内容。
118+
119+
**属性**:
120+
- `conversation`: 会话对象数据
121+
122+
### createGraphOperator
123+
124+
创建图形操作器的函数,用于管理图形数据和操作。
125+
126+
## 开发
127+
128+
### 构建命令
129+
130+
```bash
131+
# 安装依赖
132+
npm install
133+
134+
# 启动开发服务器
135+
npm run dev
136+
137+
# 构建生产版本
138+
npm run build
139+
140+
# 预览生产版本
141+
npm run preview
142+
```
143+
144+
## 许可证
145+
146+
MIT License
147+
148+
## 版权
149+
150+
/*---------------------------------------------------------------------------------------------
151+
* Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
152+
* This file is a part of the ModelEngine Project.
153+
* Licensed under the MIT License. See License.txt in the project root for license information.
154+
*--------------------------------------------------------------------------------------------*/
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# 大模型节点工具详情查看功能
2+
3+
## 功能概述
4+
5+
为大模型节点的工具卡片添加了查看详情功能,用户可以点击眼睛图标跳转到对应工具流的详情页面。
6+
7+
## 实现细节
8+
9+
### 1. 数据存储
10+
11+
在选择工具时,系统会自动提取并存储以下信息:
12+
- **appId**: 从 `selectedData.runnables.APP.appId` 提取
13+
- **tenantId**: 从 `selectedData.schema.parameters.properties.tenantId.default` 提取
14+
15+
这些信息会保存在 `tools``value` 数组中,每个工具项包含 `appId``tenantId` 字段。
16+
17+
### 2. UI 增强
18+
19+
每个工具卡片显示:
20+
- **工具图标** (左侧)
21+
- **工具名称和类型** (中间)
22+
- **版本号** (右侧)
23+
- **眼睛图标** (右侧,仅当存在 appId 和 tenantId 时显示) - 用于查看详情
24+
- **删除图标** (最右侧)
25+
26+
眼睛图标按钮特性:
27+
- **仅在工具包含 appId 和 tenantId 时显示**
28+
- 鼠标悬停时显示"工具详情"提示
29+
- 在禁用状态下不可点击
30+
- 点击时不会触发父元素的点击事件
31+
32+
### 3. 跳转逻辑
33+
34+
点击眼睛图标时:
35+
1. 从工具配置中获取 `appId``tenantId`
36+
2. 从 graph configs 中获取 `endpoint` 配置(如果未配置,使用当前域名)
37+
3. 构建跳转 URL: `{endpoint}/app-develop/{tenantId}/add-flow/${appId}?type=workFlow`
38+
4. 在新标签页中打开目标页面
39+
40+
### 4. 配置说明
41+
42+
如果需要自定义 endpoint,可以在 configs 中配置:
43+
44+
```javascript
45+
configs.push({
46+
node: 'llmNodeState',
47+
urls: {
48+
endpoint: 'https://your-domain.com'
49+
}
50+
});
51+
```
52+
53+
如果未配置 endpoint,系统会自动使用 `window.location.origin`
54+
55+
## 修改文件列表
56+
57+
1. **SkillForm.jsx**
58+
- 导入 `EyeOutlined` 图标
59+
-`onSelect` 中提取 `appId``tenantId`
60+
- 添加 `handleViewDetails` 函数实现跳转逻辑
61+
- 添加 `renderViewIcon` 函数渲染眼睛图标(包含条件判断)
62+
- 在工具卡片上显示眼睛图标
63+
64+
2. **LlmFormWrapper.jsx**
65+
-`processToolData` 函数中,从 `tool.value` 获取 `appId``tenantId`
66+
-`appId``tenantId` 添加到 `toolOptions`
67+
68+
3. **reducers/reducers.js**
69+
- 更新 `AddSkillReducer` 中的 `newSkill` 对象
70+
-`appId``tenantId` 作为新的字段存储
71+
72+
## 数据结构
73+
74+
大模型节点中的工具数据结构示例:
75+
76+
```javascript
77+
{
78+
inputParams: [
79+
{
80+
name: "tools",
81+
value: [
82+
{
83+
id: "uuid",
84+
type: "String",
85+
from: "Input",
86+
value: "tool-unique-name",
87+
appId: "app-123", // 新增
88+
tenantId: "tenant-456", // 新增
89+
name: "工具名称", // updateTools 时更新
90+
tags: ["TOOL"], // updateTools 时更新
91+
version: "1.0.0" // updateTools 时更新
92+
}
93+
]
94+
}
95+
]
96+
}
97+
```
98+
99+
## 工作流程
100+
101+
1. **用户选择工具**: 用户点击"添加技能"按钮选择工具
102+
2. **数据提取**: `onSelect` 回调从选择的数据中提取 `appId``tenantId`
103+
3. **数据存储**: `AddSkillReducer` 将工具信息(包括 `appId``tenantId`)存储到 config 中
104+
4. **获取详情**: `getSkillInfo` 函数从后端获取工具的详细信息(名称、标签、版本等)
105+
5. **构建选项**: `processToolData` 函数构建 `toolOptions`,同时保留 `appId``tenantId`
106+
6. **更新显示**: `updateTools` reducer 更新工具的显示信息
107+
7. **渲染卡片**: `SkillContent` 组件渲染工具卡片,包括眼睛图标(如果有 `appId``tenantId`
108+
109+
## 注意事项
110+
111+
1. **眼睛图标显示条件**: 只有当工具同时包含 `appId``tenantId` 信息时,才会显示眼睛图标
112+
2. **老数据兼容**: 对于不包含 `appId``tenantId` 的老数据,不显示眼睛图标,只显示工具名称、版本和删除功能
113+
3. 跳转在新标签页中打开,不影响当前编辑状态
114+
4. 即使没有配置 endpoint,系统也会使用当前域名作为默认值
115+
5. 工具信息通过 `getSkillInfo` 从后端获取,`appId``tenantId` 从本地 config 中保留
116+
117+
## 兼容性
118+
119+
- 不会影响现有功能
120+
- 对于不包含 `appId``tenantId` 的旧数据,不显示眼睛图标,工具卡片正常显示所有其他功能
121+
- 所有更改向后兼容,老数据可以正常使用
122+
- 与循环节点和并行节点的实现保持一致,使用相同的数据提取逻辑
123+
124+
## 与其他节点的对比
125+
126+
| 特性 | 循环节点 | 并行节点 | 大模型节点 |
127+
|------|---------|---------|-----------|
128+
| 数据提取 | 相同 | 相同 | 相同 |
129+
| 存储位置 | toolInfo 对象 | plugin.value 数组 | tools.value 数组 |
130+
| 显示位置 | 工具卡片右侧 | 折叠面板 header | 工具卡片右侧 |
131+
| 跳转逻辑 | 相同 | 相同 | 相同 |
132+
| 配置节点名 | loopNodeState | parallelNodeState | llmNodeState |
133+
| 额外处理 | - | - | 需要通过 getSkillInfo 获取工具详情 |
134+
135+
## 使用示例
136+
137+
```javascript
138+
// 用户选择工具时,系统会自动提取数据
139+
{
140+
uniqueName: "my-tool",
141+
name: "我的工具",
142+
tags: ["WATER_FLOW"],
143+
version: "1.0.0",
144+
runnables: {
145+
APP: {
146+
appId: "app-123"
147+
}
148+
},
149+
schema: {
150+
parameters: {
151+
properties: {
152+
tenantId: {
153+
default: "tenant-456"
154+
}
155+
}
156+
}
157+
}
158+
}
159+
160+
// 存储后的数据结构
161+
{
162+
id: "uuid",
163+
type: "String",
164+
from: "Input",
165+
value: "my-tool",
166+
appId: "app-123",
167+
tenantId: "tenant-456"
168+
}
169+
170+
// 点击眼睛图标后跳转到
171+
// https://your-domain.com/app-develop/tenant-456/add-flow/app-123?type=workFlow
172+
```
173+

0 commit comments

Comments
 (0)