@yuku123/z-agent-frontend-component 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/z-agent-frontend-component.css +1 -0
- package/dist/z-agent-frontend-component.es.js +9956 -0
- package/dist/z-agent-frontend-component.umd.js +219 -0
- package/package.json +77 -0
- package/src/api/apiRouter.js +78 -0
- package/src/api/index.js +23 -0
- package/src/api/request.js +59 -0
- package/src/api/routes.js +140 -0
- package/src/dev.jsx +80 -0
- package/src/index.js +86 -0
- package/src/pages/agent/app/index.jsx +2 -0
- package/src/pages/agent/editor/AgentAppEditor.jsx +456 -0
- package/src/pages/agent/editor/WorkflowEditor.jsx +495 -0
- package/src/pages/agent/editor/nodes/index.ts +225 -0
- package/src/pages/agent/index.jsx +1379 -0
- package/src/pages/agent/share.jsx +512 -0
- package/src/pages/ak/AkUsageDrawer.jsx +208 -0
- package/src/pages/ak/index.jsx +496 -0
- package/src/pages/llm/index.jsx +736 -0
- package/src/pages/llm/model/index.jsx +220 -0
- package/src/pages/llm/provider/index.jsx +173 -0
- package/src/pages/mcp/index.jsx +359 -0
- package/src/pages/oss/BucketList.jsx +320 -0
- package/src/pages/oss/ObjectBrowser.jsx +409 -0
- package/src/pages/product/execute.jsx +608 -0
- package/src/pages/product/index.jsx +628 -0
- package/src/pages/product/scene.jsx +746 -0
- package/src/pages/script/ApiBridgeEditor.jsx +255 -0
- package/src/pages/script/CurlImportModal.jsx +263 -0
- package/src/pages/script/FieldMappingEditor.jsx +131 -0
- package/src/pages/script/OpenApiImportModal.jsx +212 -0
- package/src/pages/script/index.jsx +532 -0
- package/src/pages/skill/index.jsx +1595 -0
- package/src/pages/trace/DebugPlayground.jsx +357 -0
- package/src/pages/trace/components/MetricsDashboard.jsx +164 -0
- package/src/pages/trace/components/RagFragments.jsx +134 -0
- package/src/pages/trace/components/Timeline.jsx +142 -0
- package/src/pages/trace/components/ToolCallTree.jsx +116 -0
- package/src/pages/trace/index.jsx +13 -0
- package/src/pages/usage/index.jsx +352 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import {useState} from 'react'
|
|
2
|
+
import {Alert, Button, Card, Input, message, Modal, Progress, Space, Table, Tag} from 'antd'
|
|
3
|
+
import {ApiOutlined, FileTextOutlined, UploadOutlined} from '@ant-design/icons'
|
|
4
|
+
import {scriptApi} from '../../api'
|
|
5
|
+
|
|
6
|
+
const {TextArea} = Input
|
|
7
|
+
|
|
8
|
+
export default function OpenApiImportModal({open, onClose, onSuccess}) {
|
|
9
|
+
const [jsonContent, setJsonContent] = useState('')
|
|
10
|
+
const [parsedItems, setParsedItems] = useState(null) // 前端预览
|
|
11
|
+
const [importResult, setImportResult] = useState(null) // 后端返回
|
|
12
|
+
const [loading, setLoading] = useState(false)
|
|
13
|
+
|
|
14
|
+
const reset = () => {
|
|
15
|
+
setJsonContent('')
|
|
16
|
+
setParsedItems(null)
|
|
17
|
+
setImportResult(null)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const handleClose = () => {
|
|
21
|
+
reset()
|
|
22
|
+
onClose()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 前端预解析展示预览
|
|
26
|
+
const handlePreview = () => {
|
|
27
|
+
if (!jsonContent.trim()) {
|
|
28
|
+
message.warning('请粘贴 OpenAPI JSON')
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const spec = JSON.parse(jsonContent)
|
|
33
|
+
const paths = spec.paths
|
|
34
|
+
if (!paths) {
|
|
35
|
+
message.warning('OpenAPI 中没有 paths 段')
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
const items = []
|
|
39
|
+
for (const path of Object.keys(paths)) {
|
|
40
|
+
const methods = paths[path]
|
|
41
|
+
for (const method of ['get', 'post', 'put', 'delete', 'patch']) {
|
|
42
|
+
const op = methods[method]
|
|
43
|
+
if (!op) continue
|
|
44
|
+
items.push({
|
|
45
|
+
key: `${method}_${path}`,
|
|
46
|
+
method: method.toUpperCase(),
|
|
47
|
+
path,
|
|
48
|
+
summary: op.summary || op.operationId || '',
|
|
49
|
+
operationId: op.operationId || '-',
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
setParsedItems(items)
|
|
54
|
+
if (items.length === 0) {
|
|
55
|
+
message.info('未找到可解析的接口')
|
|
56
|
+
} else {
|
|
57
|
+
message.success(`解析到 ${items.length} 个接口`)
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
message.error('JSON 解析失败: ' + e.message)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 导入到后端
|
|
65
|
+
const handleImport = async () => {
|
|
66
|
+
if (!jsonContent.trim()) return
|
|
67
|
+
setLoading(true)
|
|
68
|
+
try {
|
|
69
|
+
const res = await scriptApi.importOpenApi({openApiJson: jsonContent})
|
|
70
|
+
if (res?.success) {
|
|
71
|
+
setImportResult(res)
|
|
72
|
+
message.success(`成功导入 ${res.count} 个脚本`)
|
|
73
|
+
} else {
|
|
74
|
+
message.error(res?.message || '导入失败')
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
message.error('导入失败: ' + (e?.message || '网络错误'))
|
|
78
|
+
} finally {
|
|
79
|
+
setLoading(false)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const columns = [
|
|
84
|
+
{
|
|
85
|
+
title: '方法', dataIndex: 'method', key: 'method', width: 80,
|
|
86
|
+
render: (v) => {
|
|
87
|
+
const colorMap = {GET: 'green', POST: 'blue', PUT: 'orange', DELETE: 'red', PATCH: 'purple'}
|
|
88
|
+
return <Tag color={colorMap[v] || 'default'}>{v}</Tag>
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
title: '路径', dataIndex: 'path', key: 'path', width: 280,
|
|
93
|
+
render: (v) => <code style={{fontSize: 12}}>{v}</code>,
|
|
94
|
+
},
|
|
95
|
+
{title: '描述', dataIndex: 'summary', key: 'summary', ellipsis: true},
|
|
96
|
+
{
|
|
97
|
+
title: 'OperationId', dataIndex: 'operationId', key: 'operationId', width: 160,
|
|
98
|
+
render: (v) => <Tag style={{fontFamily: 'monospace'}}>{v}</Tag>,
|
|
99
|
+
},
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
const resultColumns = [
|
|
103
|
+
{
|
|
104
|
+
title: '方法', dataIndex: 'method', key: 'method', width: 80,
|
|
105
|
+
render: (v) => {
|
|
106
|
+
const colorMap = {GET: 'green', POST: 'blue', PUT: 'orange', DELETE: 'red', PATCH: 'purple'}
|
|
107
|
+
return <Tag color={colorMap[v] || 'default'}>{v}</Tag>
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
title: '路径', dataIndex: 'path', key: 'path', width: 280,
|
|
112
|
+
render: (v) => <code style={{fontSize: 12}}>{v}</code>,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
title: '脚本编码', dataIndex: 'scriptCode', key: 'scriptCode', width: 200,
|
|
116
|
+
render: (v) => <Tag color="blue" style={{fontFamily: 'monospace'}}>{v}</Tag>,
|
|
117
|
+
},
|
|
118
|
+
{title: '脚本名称', dataIndex: 'scriptName', key: 'scriptName', ellipsis: true},
|
|
119
|
+
{
|
|
120
|
+
title: '结果', dataIndex: 'created', key: 'created', width: 80,
|
|
121
|
+
render: (v) => v ? <Tag color="green">成功</Tag> : <Tag color="red">跳过</Tag>,
|
|
122
|
+
},
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<Modal
|
|
127
|
+
title={<Space><ApiOutlined/>从 OpenAPI 批量导入脚本</Space>}
|
|
128
|
+
open={open}
|
|
129
|
+
onCancel={handleClose}
|
|
130
|
+
width={960}
|
|
131
|
+
footer={null}
|
|
132
|
+
destroyOnClose
|
|
133
|
+
>
|
|
134
|
+
{/* 上传区域 */}
|
|
135
|
+
{!parsedItems && !importResult && (
|
|
136
|
+
<div>
|
|
137
|
+
<p style={{color: '#666', marginBottom: 8}}>
|
|
138
|
+
粘贴 OpenAPI 3.0 / Swagger 2.0 规范的 JSON 内容,系统将自动为每个端点生成 API_BRIDGE 脚本。
|
|
139
|
+
</p>
|
|
140
|
+
<TextArea
|
|
141
|
+
rows={12}
|
|
142
|
+
value={jsonContent}
|
|
143
|
+
onChange={e => setJsonContent(e.target.value)}
|
|
144
|
+
placeholder={`{\n "openapi": "3.0.0",\n "info": {...},\n "paths": {\n "/users": {\n "get": {\n "operationId": "listUsers",\n "summary": "获取用户列表",\n ...\n }\n }\n }\n}`}
|
|
145
|
+
style={{fontFamily: 'monospace', fontSize: 13, marginBottom: 12}}
|
|
146
|
+
/>
|
|
147
|
+
<Button type="primary" icon={<FileTextOutlined/>} onClick={handlePreview} block>
|
|
148
|
+
解析预览
|
|
149
|
+
</Button>
|
|
150
|
+
</div>
|
|
151
|
+
)}
|
|
152
|
+
|
|
153
|
+
{/* 预览列表 */}
|
|
154
|
+
{parsedItems && !importResult && (
|
|
155
|
+
<div>
|
|
156
|
+
<Alert
|
|
157
|
+
type="info"
|
|
158
|
+
message={`共解析到 ${parsedItems.length} 个接口,确认后将批量导入为 API_BRIDGE 脚本`}
|
|
159
|
+
style={{marginBottom: 12}}
|
|
160
|
+
showIcon
|
|
161
|
+
/>
|
|
162
|
+
<Table
|
|
163
|
+
dataSource={parsedItems}
|
|
164
|
+
columns={columns}
|
|
165
|
+
pagination={{pageSize: 10}}
|
|
166
|
+
size="small"
|
|
167
|
+
bordered
|
|
168
|
+
rowKey="key"
|
|
169
|
+
/>
|
|
170
|
+
<div style={{marginTop: 16, textAlign: 'right'}}>
|
|
171
|
+
<Space>
|
|
172
|
+
<Button onClick={() => {
|
|
173
|
+
setParsedItems(null);
|
|
174
|
+
setJsonContent('')
|
|
175
|
+
}}>返回修改</Button>
|
|
176
|
+
<Button type="primary" icon={<UploadOutlined/>} onClick={handleImport} loading={loading}>
|
|
177
|
+
导入 {parsedItems.length} 个脚本
|
|
178
|
+
</Button>
|
|
179
|
+
</Space>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
|
|
184
|
+
{/* 导入结果 */}
|
|
185
|
+
{importResult && (
|
|
186
|
+
<div>
|
|
187
|
+
<Card style={{marginBottom: 12, textAlign: 'center'}}>
|
|
188
|
+
<Progress type="circle" percent={100} format={() => `${importResult.count}`} width={80}/>
|
|
189
|
+
<div style={{marginTop: 8, fontWeight: 500}}>成功导入 {importResult.count} 个脚本</div>
|
|
190
|
+
</Card>
|
|
191
|
+
<Table
|
|
192
|
+
dataSource={importResult.items || []}
|
|
193
|
+
columns={resultColumns}
|
|
194
|
+
pagination={{pageSize: 10}}
|
|
195
|
+
size="small"
|
|
196
|
+
bordered
|
|
197
|
+
rowKey="scriptCode"
|
|
198
|
+
/>
|
|
199
|
+
<div style={{marginTop: 16, textAlign: 'right'}}>
|
|
200
|
+
<Space>
|
|
201
|
+
<Button onClick={() => {
|
|
202
|
+
reset();
|
|
203
|
+
onSuccess?.();
|
|
204
|
+
onClose()
|
|
205
|
+
}}>完成</Button>
|
|
206
|
+
</Space>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
)}
|
|
210
|
+
</Modal>
|
|
211
|
+
)
|
|
212
|
+
}
|