@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.
Files changed (41) hide show
  1. package/README.md +66 -0
  2. package/dist/z-agent-frontend-component.css +1 -0
  3. package/dist/z-agent-frontend-component.es.js +9956 -0
  4. package/dist/z-agent-frontend-component.umd.js +219 -0
  5. package/package.json +77 -0
  6. package/src/api/apiRouter.js +78 -0
  7. package/src/api/index.js +23 -0
  8. package/src/api/request.js +59 -0
  9. package/src/api/routes.js +140 -0
  10. package/src/dev.jsx +80 -0
  11. package/src/index.js +86 -0
  12. package/src/pages/agent/app/index.jsx +2 -0
  13. package/src/pages/agent/editor/AgentAppEditor.jsx +456 -0
  14. package/src/pages/agent/editor/WorkflowEditor.jsx +495 -0
  15. package/src/pages/agent/editor/nodes/index.ts +225 -0
  16. package/src/pages/agent/index.jsx +1379 -0
  17. package/src/pages/agent/share.jsx +512 -0
  18. package/src/pages/ak/AkUsageDrawer.jsx +208 -0
  19. package/src/pages/ak/index.jsx +496 -0
  20. package/src/pages/llm/index.jsx +736 -0
  21. package/src/pages/llm/model/index.jsx +220 -0
  22. package/src/pages/llm/provider/index.jsx +173 -0
  23. package/src/pages/mcp/index.jsx +359 -0
  24. package/src/pages/oss/BucketList.jsx +320 -0
  25. package/src/pages/oss/ObjectBrowser.jsx +409 -0
  26. package/src/pages/product/execute.jsx +608 -0
  27. package/src/pages/product/index.jsx +628 -0
  28. package/src/pages/product/scene.jsx +746 -0
  29. package/src/pages/script/ApiBridgeEditor.jsx +255 -0
  30. package/src/pages/script/CurlImportModal.jsx +263 -0
  31. package/src/pages/script/FieldMappingEditor.jsx +131 -0
  32. package/src/pages/script/OpenApiImportModal.jsx +212 -0
  33. package/src/pages/script/index.jsx +532 -0
  34. package/src/pages/skill/index.jsx +1595 -0
  35. package/src/pages/trace/DebugPlayground.jsx +357 -0
  36. package/src/pages/trace/components/MetricsDashboard.jsx +164 -0
  37. package/src/pages/trace/components/RagFragments.jsx +134 -0
  38. package/src/pages/trace/components/Timeline.jsx +142 -0
  39. package/src/pages/trace/components/ToolCallTree.jsx +116 -0
  40. package/src/pages/trace/index.jsx +13 -0
  41. 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
+ }