@axiom-lattice/gateway 4.3.3 → 4.4.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/dist/{a2a-standard-ALXWP7V6.mjs → a2a-standard-RWR5JTMH.mjs} +64 -36
- package/dist/a2a-standard-RWR5JTMH.mjs.map +1 -0
- package/dist/{registerExposedPlugins-ZBOEHJYH.mjs → chunk-3XIIQ6EK.mjs} +61 -19
- package/dist/chunk-3XIIQ6EK.mjs.map +1 -0
- package/dist/chunk-526UYVNQ.mjs +157 -0
- package/dist/chunk-526UYVNQ.mjs.map +1 -0
- package/dist/chunk-73QZQQOT.mjs +43 -0
- package/dist/chunk-73QZQQOT.mjs.map +1 -0
- package/dist/{chunk-GF4GGTWJ.mjs → chunk-HVIKCUOF.mjs} +10 -7
- package/dist/chunk-HVIKCUOF.mjs.map +1 -0
- package/dist/embed/embed-page-AgentDetailSideApp-2BDEWFQ6.js +1 -0
- package/dist/embed/embed-page-AgentGovernanceWorkbench-WG7E3G5T.js +5 -0
- package/dist/embed/embed-page-MessageGraph-5SWPEQ4V.js +6 -0
- package/dist/embed/{embed-page-TasksSideApp-F4XUHPTG.css → embed-page-MessageGraph-UT2TCPSO.css} +1 -1
- package/dist/embed/embed-page-ReactChart-MXGF35OQ.css +1 -0
- package/dist/embed/{embed-page-ReactChart-XS7D26VP.js → embed-page-ReactChart-ZYWRXIMC.js} +1 -1
- package/dist/embed/embed-page-SkillFlow-TKBMB5VV.js +1 -0
- package/dist/embed/{embed-page-TopologyRuntimeView-2NQ3OOYI.css → embed-page-TasksSideApp-HV6DKQ26.css} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-MQTUCJO4.js → embed-page-TasksSideApp-X6255GEF.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-7T2HRXLG.js → embed-page-TeamWorkspace-XNZM7AV7.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-DXKGNQ3C.css → embed-page-TeamWorkspace-YQFWXDLI.css} +1 -1
- package/dist/embed/{embed-page-MessageGraph-TYOOATYV.css → embed-page-TopologyRuntimeView-CWOXLVFW.css} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-PU2D7VZ7.js → embed-page-TopologyRuntimeView-DGSHSTIU.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-ST76M33F.js → embed-page-WorkflowAutomationView-BHIRIWV3.js} +1 -1
- package/dist/embed/embed-page-WorkflowAutomationView-YQFB3CTV.css +1 -0
- package/dist/embed/embed-page-chunk-DEDTYRZE.js +245 -0
- package/dist/embed/{embed-page-chunk-LE6OFJ7R.js → embed-page-chunk-HEO7X7LH.js} +1 -1
- package/dist/embed/{embed-page-chunk-T25T2YE6.js → embed-page-chunk-HMTKPZ5B.js} +7 -5
- package/dist/embed/embed-page-chunk-JMZ7OODN.js +2 -0
- package/dist/embed/embed-page-chunk-SPC4BYNU.js +6974 -0
- package/dist/embed/{embed-page-chunk-ZKJ7Z7P3.js → embed-page-chunk-XUXEGF3S.js} +1 -1
- package/dist/embed/{embed-page-chunk-Z4S4OYA4.js → embed-page-chunk-YCX5YZRP.js} +1 -1
- package/dist/embed/embed-page.js +1 -1
- package/dist/index.js +5188 -4089
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1574 -433
- package/dist/index.mjs.map +1 -1
- package/dist/{open-HH7RKGML.mjs → open-AMEMJOFJ.mjs} +99 -14
- package/dist/open-AMEMJOFJ.mjs.map +1 -0
- package/dist/{open-catalog-WYS2AENM.mjs → open-catalog-SZQ435AY.mjs} +34 -3
- package/dist/open-catalog-SZQ435AY.mjs.map +1 -0
- package/dist/{open-exposure-FK4G6O6L.mjs → open-exposure-I44Q4M3T.mjs} +37 -7
- package/dist/open-exposure-I44Q4M3T.mjs.map +1 -0
- package/dist/{open-files-GVRMK5PL.mjs → open-files-EJ6O2SGX.mjs} +4 -4
- package/dist/{open-session-3VN65PRR.mjs → open-session-LBTCU3AE.mjs} +4 -4
- package/dist/{openLattice-GAAGQJST.mjs → openLattice-Q6M5S6CY.mjs} +4 -2
- package/dist/registerExposedPlugins-6GCOE64C.mjs +11 -0
- package/dist/{resources-JFKAPS45.mjs → resources-DXPXAXEZ.mjs} +16 -9
- package/dist/{resources-JFKAPS45.mjs.map → resources-DXPXAXEZ.mjs.map} +1 -1
- package/package.json +11 -8
- package/dist/a2a-standard-ALXWP7V6.mjs.map +0 -1
- package/dist/chunk-GF4GGTWJ.mjs.map +0 -1
- package/dist/chunk-QKPZWWHH.mjs +0 -433
- package/dist/chunk-QKPZWWHH.mjs.map +0 -1
- package/dist/embed/embed-page-AgentDetailSideApp-7PQ2JKG6.js +0 -1
- package/dist/embed/embed-page-AgentGovernanceWorkbench-ZNW72EEJ.js +0 -5
- package/dist/embed/embed-page-MessageGraph-P7DBTZCL.js +0 -6
- package/dist/embed/embed-page-ReactChart-VBM467ER.css +0 -1
- package/dist/embed/embed-page-SkillFlow-HPH37PZH.js +0 -1
- package/dist/embed/embed-page-WorkflowAutomationView-MAYS27YJ.css +0 -1
- package/dist/embed/embed-page-chunk-4ZSGPIBZ.js +0 -1
- package/dist/embed/embed-page-chunk-BRETUPSG.js +0 -4094
- package/dist/embed/embed-page-chunk-I42T7B7V.js +0 -2415
- package/dist/embed/embed-page-chunk-RLP3BC7G.js +0 -245
- package/dist/embed/embed-page-chunk-VRV57DFE.js +0 -466
- package/dist/embed/embed-page-chunk-ZXFZANZM.js +0 -1
- package/dist/mcp-configs-WCY5EXCW.mjs +0 -30
- package/dist/open-HH7RKGML.mjs.map +0 -1
- package/dist/open-catalog-WYS2AENM.mjs.map +0 -1
- package/dist/open-exposure-FK4G6O6L.mjs.map +0 -1
- package/dist/registerExposedPlugins-ZBOEHJYH.mjs.map +0 -1
- /package/dist/{open-files-GVRMK5PL.mjs.map → open-files-EJ6O2SGX.mjs.map} +0 -0
- /package/dist/{open-session-3VN65PRR.mjs.map → open-session-LBTCU3AE.mjs.map} +0 -0
- /package/dist/{mcp-configs-WCY5EXCW.mjs.map → openLattice-Q6M5S6CY.mjs.map} +0 -0
- /package/dist/{openLattice-GAAGQJST.mjs.map → registerExposedPlugins-6GCOE64C.mjs.map} +0 -0
package/dist/chunk-QKPZWWHH.mjs
DELETED
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
// src/controllers/mcp-configs.ts
|
|
2
|
-
import {
|
|
3
|
-
getStoreLattice,
|
|
4
|
-
mcpManager,
|
|
5
|
-
McpLatticeManager
|
|
6
|
-
} from "@axiom-lattice/core";
|
|
7
|
-
import { randomUUID } from "crypto";
|
|
8
|
-
function getTenantId(request) {
|
|
9
|
-
const userTenantId = request.user?.tenantId;
|
|
10
|
-
if (userTenantId) {
|
|
11
|
-
return userTenantId;
|
|
12
|
-
}
|
|
13
|
-
return request.headers["x-tenant-id"] || "default";
|
|
14
|
-
}
|
|
15
|
-
async function getMcpServerConfigList(request, reply) {
|
|
16
|
-
const tenantId = getTenantId(request);
|
|
17
|
-
try {
|
|
18
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
19
|
-
const store = storeLattice.store;
|
|
20
|
-
const configs = await store.getAllConfigs(tenantId);
|
|
21
|
-
return {
|
|
22
|
-
success: true,
|
|
23
|
-
message: "MCP server configurations retrieved successfully",
|
|
24
|
-
data: {
|
|
25
|
-
records: configs,
|
|
26
|
-
total: configs.length
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error("Failed to get MCP server configs:", error);
|
|
31
|
-
return {
|
|
32
|
-
success: false,
|
|
33
|
-
message: "Failed to retrieve MCP server configurations",
|
|
34
|
-
data: {
|
|
35
|
-
records: [],
|
|
36
|
-
total: 0
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async function getMcpServerConfig(request, reply) {
|
|
42
|
-
const tenantId = getTenantId(request);
|
|
43
|
-
const { key } = request.params;
|
|
44
|
-
try {
|
|
45
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
46
|
-
const store = storeLattice.store;
|
|
47
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
48
|
-
if (!config) {
|
|
49
|
-
return {
|
|
50
|
-
success: false,
|
|
51
|
-
message: "MCP server configuration not found"
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
success: true,
|
|
56
|
-
message: "MCP server configuration retrieved successfully",
|
|
57
|
-
data: config
|
|
58
|
-
};
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.error("Failed to get MCP server config:", error);
|
|
61
|
-
return {
|
|
62
|
-
success: false,
|
|
63
|
-
message: "Failed to retrieve MCP server configuration"
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
async function createMcpServerConfig(request, reply) {
|
|
68
|
-
const tenantId = getTenantId(request);
|
|
69
|
-
const body = request.body;
|
|
70
|
-
try {
|
|
71
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
72
|
-
const store = storeLattice.store;
|
|
73
|
-
const existing = await store.getConfigByKey(tenantId, body.key);
|
|
74
|
-
if (existing) {
|
|
75
|
-
reply.code(409);
|
|
76
|
-
return {
|
|
77
|
-
success: false,
|
|
78
|
-
message: "MCP server configuration with this key already exists"
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
const id = body.id || randomUUID();
|
|
82
|
-
const config = await store.createConfig(tenantId, id, body);
|
|
83
|
-
try {
|
|
84
|
-
await connectAndRegisterTools(config);
|
|
85
|
-
await store.updateConfig(tenantId, id, { status: "connected" });
|
|
86
|
-
config.status = "connected";
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.warn("Failed to auto-connect MCP server:", error);
|
|
89
|
-
await store.updateConfig(tenantId, id, { status: "error" });
|
|
90
|
-
config.status = "error";
|
|
91
|
-
}
|
|
92
|
-
reply.code(201);
|
|
93
|
-
return {
|
|
94
|
-
success: true,
|
|
95
|
-
message: "MCP server configuration created successfully",
|
|
96
|
-
data: config
|
|
97
|
-
};
|
|
98
|
-
} catch (error) {
|
|
99
|
-
console.error("Failed to create MCP server config:", error);
|
|
100
|
-
return {
|
|
101
|
-
success: false,
|
|
102
|
-
message: "Failed to create MCP server configuration"
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
async function updateMcpServerConfig(request, reply) {
|
|
107
|
-
const tenantId = getTenantId(request);
|
|
108
|
-
const { key } = request.params;
|
|
109
|
-
const updates = request.body;
|
|
110
|
-
try {
|
|
111
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
112
|
-
const store = storeLattice.store;
|
|
113
|
-
const existing = await store.getConfigByKey(tenantId, key);
|
|
114
|
-
if (!existing) {
|
|
115
|
-
reply.code(404);
|
|
116
|
-
return {
|
|
117
|
-
success: false,
|
|
118
|
-
message: "MCP server configuration not found"
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const shouldReconnect = updates.config !== void 0;
|
|
122
|
-
const updated = await store.updateConfig(tenantId, existing.id, updates);
|
|
123
|
-
if (!updated) {
|
|
124
|
-
return {
|
|
125
|
-
success: false,
|
|
126
|
-
message: "Failed to update MCP server configuration"
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
if (shouldReconnect) {
|
|
130
|
-
try {
|
|
131
|
-
await mcpManager.reconnectServer(key);
|
|
132
|
-
await mcpManager.registerToolsToToolLattice(key, updated.selectedTools);
|
|
133
|
-
await store.updateConfig(tenantId, existing.id, { status: "connected" });
|
|
134
|
-
updated.status = "connected";
|
|
135
|
-
} catch (error) {
|
|
136
|
-
console.warn("Failed to reconnect MCP server:", error);
|
|
137
|
-
await store.updateConfig(tenantId, existing.id, { status: "error" });
|
|
138
|
-
updated.status = "error";
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
success: true,
|
|
143
|
-
message: "MCP server configuration updated successfully",
|
|
144
|
-
data: updated
|
|
145
|
-
};
|
|
146
|
-
} catch (error) {
|
|
147
|
-
console.error("Failed to update MCP server config:", error);
|
|
148
|
-
return {
|
|
149
|
-
success: false,
|
|
150
|
-
message: "Failed to update MCP server configuration"
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async function deleteMcpServerConfig(request, reply) {
|
|
155
|
-
const tenantId = getTenantId(request);
|
|
156
|
-
const { keyOrId } = request.params;
|
|
157
|
-
try {
|
|
158
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
159
|
-
const store = storeLattice.store;
|
|
160
|
-
let config = await store.getConfigByKey(tenantId, keyOrId);
|
|
161
|
-
let configKey = keyOrId;
|
|
162
|
-
if (!config) {
|
|
163
|
-
config = await store.getConfigById(tenantId, keyOrId);
|
|
164
|
-
if (config) {
|
|
165
|
-
configKey = config.key;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (!config) {
|
|
169
|
-
reply.code(404);
|
|
170
|
-
return {
|
|
171
|
-
success: false,
|
|
172
|
-
message: "MCP server configuration not found"
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
try {
|
|
176
|
-
if (mcpManager.hasServer(configKey)) {
|
|
177
|
-
await mcpManager.removeServer(configKey);
|
|
178
|
-
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
console.warn("Failed to remove from MCP manager:", error);
|
|
181
|
-
}
|
|
182
|
-
const deleted = await store.deleteConfig(tenantId, config.id);
|
|
183
|
-
if (!deleted) {
|
|
184
|
-
return {
|
|
185
|
-
success: false,
|
|
186
|
-
message: "Failed to delete MCP server configuration"
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
success: true,
|
|
191
|
-
message: "MCP server configuration deleted successfully"
|
|
192
|
-
};
|
|
193
|
-
} catch (error) {
|
|
194
|
-
console.error("Failed to delete MCP server config:", error);
|
|
195
|
-
return {
|
|
196
|
-
success: false,
|
|
197
|
-
message: "Failed to delete MCP server configuration"
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
async function testMcpServerConnection(request, reply) {
|
|
202
|
-
const tenantId = getTenantId(request);
|
|
203
|
-
const { key } = request.params;
|
|
204
|
-
try {
|
|
205
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
206
|
-
const store = storeLattice.store;
|
|
207
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
208
|
-
if (!config) {
|
|
209
|
-
reply.code(404);
|
|
210
|
-
return {
|
|
211
|
-
success: false,
|
|
212
|
-
message: "MCP server configuration not found"
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
const testKey = `__test_${key}_${Date.now()}`;
|
|
217
|
-
const connection = convertToConnection(config.config);
|
|
218
|
-
const { latency } = await McpLatticeManager.testConnection(testKey, connection);
|
|
219
|
-
return {
|
|
220
|
-
success: true,
|
|
221
|
-
message: "Connection test successful",
|
|
222
|
-
data: {
|
|
223
|
-
connected: true,
|
|
224
|
-
latency
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
} catch (error) {
|
|
228
|
-
return {
|
|
229
|
-
success: true,
|
|
230
|
-
message: "Connection test failed",
|
|
231
|
-
data: {
|
|
232
|
-
connected: false,
|
|
233
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.error("Failed to test MCP server connection:", error);
|
|
239
|
-
return {
|
|
240
|
-
success: false,
|
|
241
|
-
message: "Failed to test MCP server connection",
|
|
242
|
-
data: {
|
|
243
|
-
connected: false,
|
|
244
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
async function listMcpServerTools(request, reply) {
|
|
250
|
-
const tenantId = getTenantId(request);
|
|
251
|
-
const { key } = request.params;
|
|
252
|
-
try {
|
|
253
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
254
|
-
const store = storeLattice.store;
|
|
255
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
256
|
-
if (!config) {
|
|
257
|
-
reply.code(404);
|
|
258
|
-
return {
|
|
259
|
-
success: false,
|
|
260
|
-
message: "MCP server configuration not found"
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
if (!mcpManager.hasServer(key)) {
|
|
264
|
-
await connectAndRegisterTools(config);
|
|
265
|
-
}
|
|
266
|
-
const tools = await mcpManager.getServerTools(key);
|
|
267
|
-
return {
|
|
268
|
-
success: true,
|
|
269
|
-
message: "Tools retrieved successfully",
|
|
270
|
-
data: {
|
|
271
|
-
tools
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
} catch (error) {
|
|
275
|
-
console.error("Failed to list MCP tools:", error);
|
|
276
|
-
return {
|
|
277
|
-
success: false,
|
|
278
|
-
message: "Failed to retrieve tools"
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
async function connectMcpServer(request, reply) {
|
|
283
|
-
const tenantId = getTenantId(request);
|
|
284
|
-
const { key } = request.params;
|
|
285
|
-
try {
|
|
286
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
287
|
-
const store = storeLattice.store;
|
|
288
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
289
|
-
if (!config) {
|
|
290
|
-
reply.code(404);
|
|
291
|
-
return {
|
|
292
|
-
success: false,
|
|
293
|
-
message: "MCP server configuration not found"
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
await connectAndRegisterTools(config);
|
|
297
|
-
const updated = await store.updateConfig(tenantId, config.id, {
|
|
298
|
-
status: "connected"
|
|
299
|
-
});
|
|
300
|
-
return {
|
|
301
|
-
success: true,
|
|
302
|
-
message: "MCP server connected successfully",
|
|
303
|
-
data: updated || config
|
|
304
|
-
};
|
|
305
|
-
} catch (error) {
|
|
306
|
-
console.error("Failed to connect MCP server:", error);
|
|
307
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
308
|
-
const store = storeLattice.store;
|
|
309
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
310
|
-
if (config) {
|
|
311
|
-
await store.updateConfig(tenantId, config.id, { status: "error" });
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
success: false,
|
|
315
|
-
message: `Failed to connect MCP server: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
async function disconnectMcpServer(request, reply) {
|
|
320
|
-
const tenantId = getTenantId(request);
|
|
321
|
-
const { key } = request.params;
|
|
322
|
-
try {
|
|
323
|
-
const storeLattice = getStoreLattice("default", "mcp");
|
|
324
|
-
const store = storeLattice.store;
|
|
325
|
-
const config = await store.getConfigByKey(tenantId, key);
|
|
326
|
-
if (!config) {
|
|
327
|
-
reply.code(404);
|
|
328
|
-
return {
|
|
329
|
-
success: false,
|
|
330
|
-
message: "MCP server configuration not found"
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
if (mcpManager.hasServer(key)) {
|
|
334
|
-
await mcpManager.removeServer(key);
|
|
335
|
-
}
|
|
336
|
-
const updated = await store.updateConfig(tenantId, config.id, {
|
|
337
|
-
status: "disconnected"
|
|
338
|
-
});
|
|
339
|
-
return {
|
|
340
|
-
success: true,
|
|
341
|
-
message: "MCP server disconnected successfully",
|
|
342
|
-
data: updated || config
|
|
343
|
-
};
|
|
344
|
-
} catch (error) {
|
|
345
|
-
console.error("Failed to disconnect MCP server:", error);
|
|
346
|
-
return {
|
|
347
|
-
success: false,
|
|
348
|
-
message: "Failed to disconnect MCP server"
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
async function testMcpServerTools(request, reply) {
|
|
353
|
-
const body = request.body;
|
|
354
|
-
try {
|
|
355
|
-
if (!body.config) {
|
|
356
|
-
reply.code(400);
|
|
357
|
-
return {
|
|
358
|
-
success: false,
|
|
359
|
-
message: "config is required"
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
const testKey = `__test_${Date.now()}`;
|
|
363
|
-
const connection = convertToConnection(body.config);
|
|
364
|
-
const { tools } = await McpLatticeManager.testConnection(testKey, connection);
|
|
365
|
-
return {
|
|
366
|
-
success: true,
|
|
367
|
-
message: "Tools retrieved successfully",
|
|
368
|
-
data: {
|
|
369
|
-
tools
|
|
370
|
-
}
|
|
371
|
-
};
|
|
372
|
-
} catch (error) {
|
|
373
|
-
console.error("Failed to test MCP server tools:", error);
|
|
374
|
-
return {
|
|
375
|
-
success: false,
|
|
376
|
-
message: `Failed to retrieve tools: ${error instanceof Error ? error.message : String(error)}`
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
function convertToConnection(config) {
|
|
381
|
-
const baseConfig = {
|
|
382
|
-
env: config.env
|
|
383
|
-
};
|
|
384
|
-
if (config.transport === "stdio") {
|
|
385
|
-
return {
|
|
386
|
-
...baseConfig,
|
|
387
|
-
transport: "stdio",
|
|
388
|
-
command: config.command,
|
|
389
|
-
args: config.args || []
|
|
390
|
-
};
|
|
391
|
-
} else {
|
|
392
|
-
return {
|
|
393
|
-
...baseConfig,
|
|
394
|
-
transport: config.transport === "streamable_http" ? "http" : config.transport,
|
|
395
|
-
url: config.url,
|
|
396
|
-
headers: config.headers
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
async function connectAndRegisterTools(config) {
|
|
401
|
-
const connection = convertToConnection(config.config);
|
|
402
|
-
mcpManager.addServer(config.key, connection);
|
|
403
|
-
await mcpManager.connect();
|
|
404
|
-
await mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
|
|
405
|
-
}
|
|
406
|
-
function registerMcpServerConfigRoutes(app) {
|
|
407
|
-
app.get("/api/mcp-servers", getMcpServerConfigList);
|
|
408
|
-
app.get("/api/mcp-servers/:key", getMcpServerConfig);
|
|
409
|
-
app.post("/api/mcp-servers", createMcpServerConfig);
|
|
410
|
-
app.put("/api/mcp-servers/:key", updateMcpServerConfig);
|
|
411
|
-
app.delete("/api/mcp-servers/:keyOrId", deleteMcpServerConfig);
|
|
412
|
-
app.post("/api/mcp-servers/:key/test", testMcpServerConnection);
|
|
413
|
-
app.get("/api/mcp-servers/:key/tools", listMcpServerTools);
|
|
414
|
-
app.post("/api/mcp-servers/:key/connect", connectMcpServer);
|
|
415
|
-
app.post("/api/mcp-servers/:key/disconnect", disconnectMcpServer);
|
|
416
|
-
app.post("/api/mcp-servers/test-tools", testMcpServerTools);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
export {
|
|
420
|
-
getMcpServerConfigList,
|
|
421
|
-
getMcpServerConfig,
|
|
422
|
-
createMcpServerConfig,
|
|
423
|
-
updateMcpServerConfig,
|
|
424
|
-
deleteMcpServerConfig,
|
|
425
|
-
testMcpServerConnection,
|
|
426
|
-
listMcpServerTools,
|
|
427
|
-
connectMcpServer,
|
|
428
|
-
disconnectMcpServer,
|
|
429
|
-
testMcpServerTools,
|
|
430
|
-
convertToConnection,
|
|
431
|
-
registerMcpServerConfigRoutes
|
|
432
|
-
};
|
|
433
|
-
//# sourceMappingURL=chunk-QKPZWWHH.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/controllers/mcp-configs.ts"],"sourcesContent":["/**\n * MCP Server Config Controller\n * Handles MCP server configuration CRUD operations with automatic tool registration\n */\n\nimport { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n mcpManager,\n McpLatticeManager,\n} from \"@axiom-lattice/core\";\nimport type {\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n McpServerConfig,\n McpTool,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * MCP server config list response\n */\ninterface McpServerConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: McpServerConfigEntry[];\n total: number;\n };\n}\n\n/**\n * MCP server config response\n */\ninterface McpServerConfigResponse {\n success: boolean;\n message: string;\n data?: McpServerConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * List tools response\n */\ninterface ListToolsResponse {\n success: boolean;\n message: string;\n data?: {\n tools: McpTool[];\n };\n}\n\n/**\n * Get all MCP server configs for a tenant\n */\nexport async function getMcpServerConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n\n return {\n success: true,\n message: \"MCP server configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get MCP server configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get MCP server config by key\n */\nexport async function getMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configuration\",\n };\n }\n}\n\n/**\n * Create new MCP server config\n */\nexport async function createMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateMcpServerConfigRequest & {\n id?: string;\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"MCP server configuration with this key already exists\",\n };\n }\n\n const id = body.id || randomUUID();\n const config = await store.createConfig(tenantId, id, body);\n\n // Auto-connect and register tools\n try {\n await connectAndRegisterTools(config);\n // Update status to connected\n await store.updateConfig(tenantId, id, { status: \"connected\" });\n config.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to auto-connect MCP server:\", error);\n // Update status to error but don't fail the creation\n await store.updateConfig(tenantId, id, { status: \"error\" });\n config.status = \"error\";\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"MCP server configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to create MCP server configuration\",\n };\n }\n}\n\n/**\n * Update MCP server config\n */\nexport async function updateMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateMcpServerConfigRequest>;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // If config is being updated, we need to reconnect\n const shouldReconnect = updates.config !== undefined;\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n\n // Reconnect and re-register tools if config changed\n if (shouldReconnect) {\n try {\n // Reconnect single server without affecting others\n await mcpManager.reconnectServer(key);\n\n // Re-register tools with new config\n await mcpManager.registerToolsToToolLattice(key, updated.selectedTools);\n\n await store.updateConfig(tenantId, existing.id, { status: \"connected\" });\n updated.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to reconnect MCP server:\", error);\n await store.updateConfig(tenantId, existing.id, { status: \"error\" });\n updated.status = \"error\";\n }\n }\n\n return {\n success: true,\n message: \"MCP server configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n}\n\n/**\n * Delete MCP server config by key or id\n */\nexport async function deleteMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect and remove from MCP manager\n try {\n if (mcpManager.hasServer(configKey)) {\n await mcpManager.removeServer(configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from MCP manager:\", error);\n }\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n}\n\n/**\n * Test MCP server connection\n */\nexport async function testMcpServerConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Test connection by creating a standalone client\n try {\n const testKey = `__test_${key}_${Date.now()}`;\n const connection = convertToConnection(config.config);\n const { latency } = await McpLatticeManager.testConnection(testKey, connection);\n\n return {\n success: true,\n message: \"Connection test successful\",\n data: {\n connected: true,\n latency,\n },\n };\n } catch (error) {\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test MCP server connection:\", error);\n return {\n success: false,\n message: \"Failed to test MCP server connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * List available tools from an MCP server\n */\nexport async function listMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Ensure server is connected\n if (!mcpManager.hasServer(key)) {\n await connectAndRegisterTools(config);\n }\n\n const tools = await mcpManager.getServerTools(key);\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to list MCP tools:\", error);\n return {\n success: false,\n message: \"Failed to retrieve tools\",\n };\n }\n}\n\n/**\n * Connect to MCP server and register tools\n */\nexport async function connectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n await connectAndRegisterTools(config);\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"connected\",\n });\n\n return {\n success: true,\n message: \"MCP server connected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to connect MCP server:\", error);\n\n // Update status to error\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n const config = await store.getConfigByKey(tenantId, key);\n if (config) {\n await store.updateConfig(tenantId, config.id, { status: \"error\" });\n }\n\n return {\n success: false,\n message: `Failed to connect MCP server: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n}\n\n/**\n * Disconnect from MCP server\n */\nexport async function disconnectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect from MCP manager\n if (mcpManager.hasServer(key)) {\n await mcpManager.removeServer(key);\n }\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"disconnected\",\n });\n\n return {\n success: true,\n message: \"MCP server disconnected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to disconnect MCP server:\", error);\n return {\n success: false,\n message: \"Failed to disconnect MCP server\",\n };\n }\n}\n\n/**\n * Test MCP server connection and list tools without saving config\n * Used for multi-step configuration flow\n */\nexport async function testMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const body = request.body as {\n config: McpServerConfig;\n };\n\n try {\n if (!body.config) {\n reply.code(400);\n return {\n success: false,\n message: \"config is required\",\n };\n }\n\n const testKey = `__test_${Date.now()}`;\n\n // Create standalone client for testing — does not affect global mcpManager\n const connection = convertToConnection(body.config);\n const { tools } = await McpLatticeManager.testConnection(testKey, connection);\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to test MCP server tools:\", error);\n return {\n success: false,\n message: `Failed to retrieve tools: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n}\n\n/**\n * Convert McpServerConfig to Connection format compatible with @langchain/mcp-adapters\n */\nexport function convertToConnection(config: McpServerConfig): any {\n const baseConfig = {\n env: config.env,\n };\n\n if (config.transport === \"stdio\") {\n return {\n ...baseConfig,\n transport: \"stdio\" as const,\n command: config.command!,\n args: config.args || [],\n };\n } else {\n // For HTTP/SSE transports\n return {\n ...baseConfig,\n transport: config.transport === \"streamable_http\" ? \"http\" : config.transport,\n url: config.url!,\n headers: config.headers,\n };\n }\n}\n\n/**\n * Helper function to connect to MCP server and register selected tools\n */\nasync function connectAndRegisterTools(\n config: McpServerConfigEntry\n): Promise<void> {\n // Add server to MCP manager\n const connection = convertToConnection(config.config);\n mcpManager.addServer(config.key, connection);\n\n // Connect only unconnected servers (new server gets connected)\n await mcpManager.connect();\n\n // Register tools for this server (handles unregister + filter + prefix)\n await mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);\n}\n\n/**\n * Register MCP server config routes\n */\nexport function registerMcpServerConfigRoutes(app: any): void {\n // Get all configs\n app.get(\"/api/mcp-servers\", getMcpServerConfigList);\n\n // Get config by key\n app.get(\"/api/mcp-servers/:key\", getMcpServerConfig);\n\n // Create config\n app.post(\"/api/mcp-servers\", createMcpServerConfig);\n\n // Update config\n app.put(\"/api/mcp-servers/:key\", updateMcpServerConfig);\n\n // Delete config by key or id\n app.delete(\"/api/mcp-servers/:keyOrId\", deleteMcpServerConfig);\n\n // Test connection\n app.post(\"/api/mcp-servers/:key/test\", testMcpServerConnection);\n\n // List available tools\n app.get(\"/api/mcp-servers/:key/tools\", listMcpServerTools);\n\n // Connect to server\n app.post(\"/api/mcp-servers/:key/connect\", connectMcpServer);\n\n // Disconnect from server\n app.post(\"/api/mcp-servers/:key/disconnect\", disconnectMcpServer);\n\n // Test tools without saving config (for multi-step config flow)\n app.post(\"/api/mcp-servers/test-tools\", testMcpServerTools);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as C}from"./embed-page-chunk-RLP3BC7G.js";import"./embed-page-chunk-LE6OFJ7R.js";import"./embed-page-chunk-Z4S4OYA4.js";import"./embed-page-chunk-ZKJ7Z7P3.js";import"./embed-page-chunk-KEL6XU6R.js";import"./embed-page-chunk-AC6X2XRH.js";import"./embed-page-chunk-S4XZPBRM.js";import"./embed-page-chunk-I42T7B7V.js";import"./embed-page-chunk-VRV57DFE.js";import"./embed-page-chunk-4ZSGPIBZ.js";import{b as B}from"./embed-page-chunk-ZXFZANZM.js";import{Ya as T}from"./embed-page-chunk-BRETUPSG.js";import{r as P}from"./embed-page-chunk-T25T2YE6.js";import{a as I}from"./embed-page-chunk-MB65DZAX.js";import"./embed-page-chunk-VW3NF5NT.js";import"./embed-page-chunk-5JDQ456X.js";import"./embed-page-chunk-Z7USDLHI.js";import{U as c,W as p,oa as D,va as b,xa as l}from"./embed-page-chunk-O4QK5LWZ.js";import{a as U}from"./embed-page-chunk-4BKXE5ON.js";import"./embed-page-chunk-IX4WLWCY.js";import"./embed-page-chunk-EUOOO2LS.js";import{e as u}from"./embed-page-chunk-6Y3UYJ6Z.js";var e=u(U());var t=u(I()),G={component_key:"workspace_assistants",data:{},message:"Assistants"},N=r=>{let i=r;if(typeof r=="string")try{i=JSON.parse(r)}catch{return{}}return i!==null&&typeof i=="object"&&!Array.isArray(i)?i:{}},H=({data:r})=>{let{assistantId:i,initialTab:F}=r??{},{get:m,put:f,del:A}=P(),y=T(),[g,w]=(0,e.useState)(null),[R,h]=(0,e.useState)([]),[E,v]=(0,e.useState)(!1),[L,S]=(0,e.useState)(null),d=(0,e.useCallback)(()=>{y(G)},[y]),a=(0,e.useCallback)(async()=>{v(!0),S(null);try{let s=(await m("/api/assistants")).data?.records??[];h(s),w(s.find(o=>o.id===i)??null)}catch{S("Failed to load agent")}finally{v(!1)}},[m,i]);(0,e.useEffect)(()=>{i&&a()},[a,i]);let _=(0,e.useCallback)(async(n,s)=>{let o=N(n.graphDefinition),k;try{k=await f(`/api/assistants/${n.id}`,{name:s.name!==void 0?s.name:n.name,description:s.description!==void 0?s.description:n.description,graphDefinition:{...o,...s}})}catch(z){throw l.error("Failed to save agent"),z}if(!k.success)throw l.error("Failed to save agent"),new Error("Failed to save agent");l.success("Saved"),await a()},[f,a]),j=(0,e.useCallback)(n=>{w(s=>s&&s.id===n.id?n:s),h(s=>s.map(o=>o.id===n.id?n:o))},[]),x=(0,e.useCallback)(async n=>{if(!(await A(`/api/assistants/${n}`)).success)throw new Error("Failed to delete agent");l.success("Agent deleted"),d()},[A,d]);return i?g?(0,t.jsx)("div",{style:{height:"100%",overflow:"auto"},children:(0,t.jsx)(B,{children:(0,t.jsx)(C,{assistant:g,allAssistants:R,onBack:d,onDeleted:x,onSave:_,onAssistantUpdated:j,onAgentListInvalidated:()=>void a(),initialTab:F})},g.id)}):E?(0,t.jsx)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"},children:(0,t.jsx)(b,{})}):L?(0,t.jsx)("div",{style:{padding:24},children:(0,t.jsx)(c,{type:"error",showIcon:!0,message:"Failed to load agent","data-testid":"detail-error",action:(0,t.jsxs)(D,{children:[(0,t.jsx)(p,{size:"small",onClick:()=>void a(),children:"Retry"}),(0,t.jsx)(p,{size:"small",type:"primary",onClick:d,children:"Back to list"})]})})}):(0,t.jsx)("div",{style:{padding:24},children:(0,t.jsx)(c,{type:"warning",showIcon:!0,message:"Agent not found","data-testid":"detail-not-found",action:(0,t.jsx)(p,{size:"small",type:"primary",onClick:d,children:"Back to list"})})}):(0,t.jsx)("div",{style:{padding:24},children:(0,t.jsx)(c,{type:"warning",showIcon:!0,message:"Missing agent id","data-testid":"detail-missing-id"})})};export{H as AgentDetailSideApp};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{a as Re,b as Me,c as Tt,d as It,e as Dt,f as Rt,g as Pt,h as Ft,i as Et,j as Mt,k as Nt,l as Lt}from"./embed-page-chunk-RLP3BC7G.js";import"./embed-page-chunk-LE6OFJ7R.js";import{a as Ge}from"./embed-page-chunk-Z4S4OYA4.js";import"./embed-page-chunk-ZKJ7Z7P3.js";import"./embed-page-chunk-KEL6XU6R.js";import{b as _e,e as Ve,f as At,g as Ct,h as xt,i as wt,l as vt,m as kt}from"./embed-page-chunk-AC6X2XRH.js";import{a as mt,b as gt,c as ut,d as ft,e as yt}from"./embed-page-chunk-SV2BM3WO.js";import"./embed-page-chunk-S4XZPBRM.js";import"./embed-page-chunk-I42T7B7V.js";import"./embed-page-chunk-VRV57DFE.js";import"./embed-page-chunk-4ZSGPIBZ.js";import{b as St}from"./embed-page-chunk-ZXFZANZM.js";import{C as at,Da as dt,M as ot,Ma as ct,Oa as pt,P as rt,X as st,Ya as ht,gb as bt,hb as Ke,ja as it,o as De,pa as lt}from"./embed-page-chunk-BRETUPSG.js";import{m as Qe,r as fe}from"./embed-page-chunk-T25T2YE6.js";import{a as E}from"./embed-page-chunk-MB65DZAX.js";import"./embed-page-chunk-VW3NF5NT.js";import"./embed-page-chunk-5JDQ456X.js";import"./embed-page-chunk-Z7USDLHI.js";import{Db as et,Fa as Je,Ia as Ie,Ja as Ye,La as Y,Ua as Xe,W as Z,_ as Se,aa as Te,ac as Ee,ea as Fe,ka as Oe,la as We,ma as qe,mc as tt,oa as Ze,ra as P,ta as V,wa as $e,xa as v,ya as ue,yc as nt}from"./embed-page-chunk-O4QK5LWZ.js";import{a as ge}from"./embed-page-chunk-4BKXE5ON.js";import"./embed-page-chunk-IX4WLWCY.js";import"./embed-page-chunk-EUOOO2LS.js";import{e as x}from"./embed-page-chunk-6Y3UYJ6Z.js";var u=x(ge());var X=x(ge());var J=x(ge());var Bt=x(ge());var se=x(E()),Ot=60,$t=72,ze=(0,Bt.memo)(({data:n})=>{let r=Re(n.type),p=Math.min(12+Math.sqrt(n.subAgentCount)*10,48);return(0,se.jsxs)("div",{style:{display:"flex",flexDirection:"column",alignItems:"center"},children:[(0,se.jsx)(Ve,{type:"target",position:_e.Top,style:{left:"50%",top:"50%",transform:"translate(-50%, -50%)",background:"transparent",border:"none",width:0,height:0},isConnectable:!1}),(0,se.jsx)("div",{title:n.label,style:{width:p,height:p,borderRadius:"50%",background:Me(r.color),display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:Math.max(10,p*.4),fontWeight:600,cursor:"pointer",boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},children:n.label.charAt(0).toUpperCase()}),(0,se.jsx)("div",{style:{fontSize:11,maxWidth:120,textAlign:"center",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",marginTop:4},children:n.label}),(0,se.jsx)(Ve,{type:"source",position:_e.Top,style:{left:"50%",top:"50%",transform:"translate(-50%, -50%)",background:"transparent",border:"none",width:0,height:0},isConnectable:!1})]})});ze.displayName="AgentGraphNode";var Q=x(E()),sn=({assistants:n,onNodeClick:r})=>{let[p,d,g]=xt([]),[o,f,k]=wt([]),[c,S]=(0,J.useState)(null),H=(0,J.useMemo)(()=>({agent:ze}),[]),m=(0,J.useMemo)(()=>Dt(n),[n]);(0,J.useEffect)(()=>{let w=m.nodes.map(i=>({id:i.id})),F=m.edges.map(i=>({source:i.source,target:i.target})),N=new Map(m.nodes.map(i=>[i.id,i])),_=ft(w).force("link",ut(F).id(i=>i.id).distance(80)).force("charge",yt().strength(-220)).force("center",mt(0,0)).force("collide",gt(45)).stop();for(let i=0;i<300;i++)_.tick();let R=w.map(i=>({id:i.id,type:"agent",data:N.get(i.id),position:{x:i.x-Ot/2,y:i.y-$t/2}})),s=m.edges.map(i=>({id:`e${i.source}-${i.target}`,source:i.source,target:i.target,style:{stroke:"#1677ff",strokeWidth:2},type:"straight"}));d(R),f(s)},[m,d,f]);let I=(0,J.useMemo)(()=>c===null?p:p.map(w=>{let F=w.id===c||o.some(N=>N.source===c&&N.target===w.id||N.target===c&&N.source===w.id);return{...w,style:{opacity:F?1:.2,transition:"opacity 0.2s ease"}}}),[p,o,c]),K=(0,J.useMemo)(()=>c===null?o.map(w=>({...w,style:{stroke:"#1677ff",strokeWidth:1.5,opacity:.25,transition:"opacity 0.2s ease"}})):o.map(w=>{let F=w.source===c||w.target===c;return{...w,style:{stroke:"#1677ff",strokeWidth:F?2.5:1,opacity:F?1:.04,transition:"opacity 0.2s ease"}}}),[o,c]);return(0,Q.jsx)("div",{style:{width:"100%",height:"100%",background:"#fafafa",position:"relative"},children:(0,Q.jsxs)(Ct,{nodes:I,edges:K,onNodesChange:g,onEdgesChange:k,onNodeMouseEnter:(w,F)=>S(F.id),onNodeMouseLeave:()=>S(null),onNodeClick:(w,F)=>r?.(String(F.id)),nodeTypes:H,fitView:!0,fitViewOptions:{padding:.25},children:[(0,Q.jsx)(vt,{color:"#eee",gap:20}),(0,Q.jsx)(kt,{})]})})},Kt=n=>(0,Q.jsx)(At,{children:(0,Q.jsx)(sn,{...n})});var M=x(E()),ln=n=>{if(!n)return"\u2014";let r=Date.now()-new Date(n).getTime(),p=Math.floor(r/6e4);if(p<1)return"just now";if(p<60)return`${p}m ago`;let d=Math.floor(p/60);return d<24?`${d}h ago`:`${Math.floor(d/24)}d ago`},dn=n=>n===null?"#d9d9d9":n>=80?"#22c55e":n>=50?"#f59e0b":"#ef4444",cn=ct(({css:n})=>({row:n`
|
|
2
|
-
display: flex;
|
|
3
|
-
justify-content: space-between;
|
|
4
|
-
align-items: flex-end;
|
|
5
|
-
`})),_t={fontSize:16,fontWeight:700,lineHeight:1.2,cursor:"help"},Ue={fontSize:10,color:"rgba(0, 0, 0, 0.45)",whiteSpace:"nowrap",marginTop:1},je={display:"flex",flexDirection:"column",alignItems:"center"},Vt=({stats:n})=>{let{styles:r}=cn();if(!n)return(0,M.jsxs)("div",{style:{display:"flex",fontSize:11,color:"#d9d9d9"},children:[(0,M.jsx)("span",{style:{flex:1},children:"score \u2014"}),(0,M.jsx)("span",{style:{flex:1},children:"threads \u2014"})]});let p=n.evalScore!==null?Number(n.evalScore).toFixed(1):"\u2014",d=n.threadCount>0?n.threadCount:"\u2014",g=dn(n.evalScore),o=n.evalPassRate!==null?`${n.evalPassRate}%`:"\u2014";return(0,M.jsxs)("div",{className:r.row,children:[(0,M.jsxs)("div",{style:{display:"flex",gap:16,alignItems:"flex-end"},children:[(0,M.jsx)(Te,{title:`Eval score: ${p} \xB7 pass rate ${o} \xB7 ${n.evalRuns} runs`,children:(0,M.jsxs)("div",{style:je,children:[(0,M.jsx)("span",{style:{..._t,color:g},children:p}),(0,M.jsx)("span",{className:"lattice-stat-label",style:Ue,children:"eval score"})]})}),(0,M.jsx)(Te,{title:`Conversations: ${n.threadCount} total \xB7 ${n.last7d} in 7d \xB7 ${n.last30d} in 30d${n.lastActive?` \xB7 last active ${ln(n.lastActive)}`:""}`,children:(0,M.jsxs)("div",{style:je,children:[(0,M.jsx)("span",{style:{..._t,color:d==="\u2014"?"#d9d9d9":"#595959"},children:d}),(0,M.jsx)("span",{className:"lattice-stat-label",style:Ue,children:"threads"})]})})]}),n.daily7d.length>0&&(0,M.jsxs)("div",{style:je,children:[(0,M.jsx)(Rt,{values:n.daily7d,width:40,height:24,color:"#8c8c8c"}),(0,M.jsx)("span",{className:"lattice-stat-label",style:Ue,children:"7d threads"})]})]})};var C=x(E()),pn=[{key:"all",label:"All"},{key:"capability",label:"Capability"},{key:"orchestrator",label:"Orchestrator"},{key:"team",label:"Team"},{key:"workflow",label:"Workflow"}],Gt=({items:n,assistants:r=[],stats:p,loading:d,onItemClick:g,onOpenPlayground:o,onOpenEval:f,onCreate:k,onDelete:c})=>{let[S,H]=(0,X.useState)("all"),[m,I]=(0,X.useState)(null),[K,w]=(0,X.useState)(null),F=(0,X.useMemo)(()=>{let s=new Set;return n.forEach(i=>i.tags.forEach(te=>s.add(te))),Array.from(s).map(i=>({value:i,label:i}))},[n]),N=(0,X.useMemo)(()=>n.filter(s=>!(S!=="all"&&s.type!==S||m&&!s.tags.includes(m)||K&&s.status!==K)),[n,S,m,K]),_=[{key:"edit",icon:lt,label:"Edit",onClick:s=>g(s.id)},{key:"playground",icon:at,label:"Playground",onClick:s=>o(s.id)},{key:"eval",icon:rt,label:"Eval",onClick:s=>f(s.id)}];c&&_.push({key:"delete",icon:dt,label:"Delete",danger:!0,onClick:s=>c(s.id)});let R=(0,X.useMemo)(()=>[{mode:"graph",icon:it,label:"Graph",render:()=>(0,C.jsx)(Kt,{assistants:r,onNodeClick:g})}],[r,g]);return(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("span",{"data-testid":"agent-list-state","data-loading":String(d),"data-count":N.length,hidden:!0,"aria-hidden":"true"}),(0,C.jsx)(bt,{title:"Agents",itemName:"agent",items:N,loading:d,keyExtractor:s=>s.id,tabs:pn,activeTab:S,onTabChange:s=>H(s),headerLeft:(0,C.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,C.jsx)(Ke,{value:m,onChange:I,options:F,placeholder:"Domain",allLabel:"All domains"}),(0,C.jsx)(Ke,{value:K,onChange:w,options:[{value:"enabled",label:"Enabled"},{value:"draft",label:"Draft"},{value:"disabled",label:"Disabled"}],placeholder:"Status",allLabel:"All statuses"})]}),renderIcon:s=>{let i=Me(Re(s.type).color);return(0,C.jsx)("div",{title:`${s.type} agent`,style:{width:32,height:32,borderRadius:8,background:`${i}1A`,color:i,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0},children:(0,C.jsx)(De,{size:18})})},renderPrimary:s=>(0,C.jsx)("span",{"data-testid":"agent-name","data-agent-id":s.id,children:s.name}),renderSecondary:s=>s.description||void 0,renderDetails:s=>(0,C.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",gap:8,flexWrap:"wrap"},children:[(0,C.jsxs)("div",{style:{display:"flex",gap:4,flexWrap:"wrap",alignItems:"center"},children:[s.tags.map(i=>(0,C.jsx)(Ie,{color:"magenta",style:{margin:0,borderRadius:10,border:"none"},children:i},i)),(0,C.jsx)(Ie,{color:Re(s.type).color,style:{margin:0,borderRadius:10,border:"none"},children:s.type})]}),(0,C.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8,flexShrink:0},children:[(0,C.jsx)(Te,{title:`Status: ${s.status}`,children:(0,C.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:Tt(s.status),display:"inline-block",cursor:"help"}})}),(0,C.jsx)("span",{style:{fontSize:12,color:"#8c8c8c"},children:s.version})]})]}),renderFooter:s=>(0,C.jsx)("div",{style:{borderTop:"1px dashed #f0f0f0",paddingTop:10},children:(0,C.jsx)(Vt,{stats:p?.[s.id]})}),itemActions:_,actionsStyle:"icon",actionsPosition:"hover",onItemClick:s=>g(s.id),createLabel:"New Agent",onCreateClick:k,viewModeExtensions:R,emptyIcon:(0,C.jsx)(De,{size:48,style:{opacity:.5}}),emptyTitle:"No agents yet",emptyDescription:'Click "New Agent" to create one'})]})};var b=x(ge());var ie=x(ge());var ye=x(E()),{Text:mn}=Y,zt=({onSelect:n,value:r,placeholder:p="Select a parent agent to extend..."})=>{let[d,g]=(0,ie.useState)([]),[o,f]=(0,ie.useState)(!1),{get:k}=fe(),c=(0,ie.useCallback)(async()=>{f(!0);try{let m=await k("/api/assistants");m.success&&g(m.data?.records||[])}catch(m){console.error("Failed to fetch assistants:",m)}finally{f(!1)}},[k]);return(0,ie.useEffect)(()=>{c()},[c]),(0,ye.jsx)(Se,{showSearch:!0,allowClear:!0,value:r,placeholder:p,loading:o,onChange:m=>{if(!m){n(null);return}let I=d.find(K=>K.id===m);n(I||null)},onDropdownVisibleChange:m=>{m&&c()},optionFilterProp:"label",style:{width:"100%"},options:d.map(m=>({value:m.id,label:m.name||m.id,description:m.description})),optionRender:m=>(0,ye.jsxs)("div",{children:[(0,ye.jsx)("div",{children:m.label}),m.data.description&&(0,ye.jsx)(mn,{type:"secondary",style:{fontSize:12},children:m.data.description})]})})};var O=x(E()),{Text:Ut}=Y,jt=({subAgentKeys:n,decisions:r,onChange:p})=>{let{token:d}=Ye.useToken(),g=(f,k)=>{let c=r.map(S=>S.originalKey===f?{...S,clone:k,cloneKey:k?`${f}_clone`:void 0}:S);p(c)},o=(f,k)=>{let c=r.map(S=>S.originalKey===f?{...S,cloneKey:k}:S);p(c)};return n.length===0?null:(0,O.jsxs)("div",{children:[(0,O.jsx)(Ut,{type:"secondary",style:{display:"block",marginBottom:8},children:"Choose how to handle each sub-agent from the parent:"}),(0,O.jsx)($e,{size:"small",bordered:!0,dataSource:r,style:{borderRadius:d.borderRadius},renderItem:f=>(0,O.jsxs)($e.Item,{style:{display:"flex",flexDirection:"column",alignItems:"stretch",gap:8,padding:"8px 16px"},children:[(0,O.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,O.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[f.clone?(0,O.jsx)(Ee,{style:{color:d.colorPrimary}}):(0,O.jsx)(tt,{style:{color:d.colorTextSecondary}}),(0,O.jsx)(Ut,{style:{fontFamily:"monospace"},children:f.originalKey})]}),(0,O.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,O.jsx)(Ie,{color:f.clone?"blue":"default",children:f.clone?"Clone as new":"Reuse"}),(0,O.jsx)(Je,{size:"small",checked:f.clone,onChange:k=>g(f.originalKey,k)})]})]}),f.clone&&(0,O.jsx)(V,{size:"small",placeholder:"Enter key for the cloned agent",value:f.cloneKey,onChange:k=>o(f.originalKey,k.target.value),style:{fontFamily:"monospace",fontSize:12},addonBefore:"Key"})]})})]})};function Ht(n){return n.mode!=="local"||n.templateKey||typeof n.executable=="string"&&n.executable.trim().length>0?null:"Choose a template or enter a custom executable"}var t=x(E()),{TextArea:Wt}=V,{Text:ee}=Y,qt="/.well-known/agent-card.json",gn=[{value:"http://",label:"http://"},{value:"https://",label:"https://"}],Zt={react:"Executor: Directly executes tasks using tools. Best for single-step operations like search, code execution, and data retrieval.",deep_agent:"Orchestrator: Manages a sequential todo list to plan and assign todo items to sub-agents. Best for structured multi-step workflows.",team:"Team: Creates tasks with dependencies and dynamically spawns teammates. Like a swarm, teammates communicate via mailbox. Best for tasks requiring exploration and divergent thinking.",processing:"Workflow: Enforces a fixed workflow topology by delegating to sub-agents in a predefined order. Best for deterministic multi-step processes with validated delegation paths.",a2a_remote:"A2A Remote: Delegates to an external A2A-compatible agent server. Use for local CLI tools (Claude Code, Codex, OpenCode) or remote agents."};function Jt(n,r,p="https://"){let d=String(n??"").trim();if(!d)return"";let g=r==="http://"||r==="https://"?r:p,f=(/^https?:\/\//i.test(d)?d:`${g}${d.replace(/^\/+/,"")}`).replace(/\/+$/,"");return f.endsWith(qt)?f:`${f}${qt}`}function un(n){try{return new URL(n).port||void 0}catch{return}}function fn(n){return n.some(r=>r==="--port"||r==="-p"||/^--port=/.test(r)||/^-p=/.test(r))}function Yt(n,r){let p=[...n.args],d=un(r);return d&&!fn(p)&&p.push("--port",d),{...n,args:p,...n.env?{env:{...n.env}}:{}}}var Qt=({open:n,onCancel:r,onSuccess:p,initialMode:d,initialValues:g})=>{let[o]=P.useForm(),[f,k]=(0,b.useState)(!1),[c,S]=(0,b.useState)("learn"),[H,m]=(0,b.useState)(""),[I,K]=(0,b.useState)(null),[w,F]=(0,b.useState)([]),N=P.useWatch("type",o)||"react",_=N==="a2a_remote",[R,s]=(0,b.useState)("remote"),[i,te]=(0,b.useState)(void 0),[le,he]=(0,b.useState)([]),[de,ce]=(0,b.useState)(!1),ne=(0,b.useRef)(0),[Ne,be]=(0,b.useState)(!1),[ae,W]=(0,b.useState)(!1),{get:Ae,post:q,put:z}=fe(),Le=Qe("agent-architect"),{workspaceId:pe,trainingProjects:me,loading:oe}=pt(),[Ce,xe]=(0,b.useState)(null),Be=JSON.stringify(g??null),L=me.find(e=>e.id===Ce)??me[0]??null,[we,ve]=(0,b.useState)([]),Pe=(0,b.useCallback)(()=>{K(null),F([])},[]),re=(0,b.useCallback)(()=>{o.resetFields(),Pe(),S("learn"),m(""),ve([]),xe(null),s("remote"),te(void 0),he([]),W(!1),be(!1)},[o,Pe]);(0,b.useEffect)(()=>{if(n){re(),S(d??"learn");let e=g?.a2aMode;(e==="remote"||e==="local")&&s(e),o.setFieldsValue({type:"react",agentCardProtocol:"https://",a2aMode:"remote",timeout:3e5,...g})}},[n,o,d,Be,re]),(0,b.useEffect)(()=>{let e=++ne.current,a=!0;return n&&_?(o.setFieldValue("prompt",""),R==="local"?(ce(!0),Ae("/api/local-a2a/templates").then(A=>{a&&e===ne.current&&A?.data?.records&&he(A.data.records)}).catch(()=>{a&&e===ne.current&&he([])}).finally(()=>{a&&e===ne.current&&ce(!1)})):ce(!1)):ce(!1),()=>{a=!1,ne.current+=1}},[o,_,R,Ae,n]);let l=le.find(e=>e.key===i),h=(0,b.useCallback)(()=>{let e=Ht({mode:R,templateKey:i,executable:o.getFieldValue("commandExecutable")});return e?(W(!0),o.setFields([{name:"commandExecutable",errors:[e]}]),v.warning(e),!1):!0},[R,i,o]);(0,b.useEffect)(()=>{l&&o.setFieldsValue({agentCardProtocol:"http://"})},[o,l]);let T=(0,b.useCallback)(async()=>{if(!h())return;let e=Jt(o.getFieldValue("agentCardUrl"),o.getFieldValue("agentCardProtocol"),R==="local"?"http://":"https://");if(!e){v.warning("Please enter an A2A server URL first");return}be(!0);try{let a={agentCardUrl:e,apiKey:o.getFieldValue("apiKey")};if(R==="local"){let y=l;if(y)a.localRuntime={label:o.getFieldValue("name")||void 0,agentCardUrl:e,command:Yt(y.command,e)};else{let B=o.getFieldValue("commandArgs")||"",j=B?B.split(/\s+/).filter(Boolean):[],D=String(o.getFieldValue(["command","cwd"])||"").trim();a.localRuntime={label:o.getFieldValue("name")||void 0,agentCardUrl:e,command:{executable:String(o.getFieldValue("commandExecutable")||"").trim(),args:j,...D?{cwd:D}:{}}}}}let A=await q("/api/a2a/test-connection",a);if(A.data?.reachable){let y=A.data.agentCard;v.success(`Connected to "${A.data.agentName||e}"`)}else v.error(A.data?.error||"Connection failed")}catch{v.error("Connection test failed")}finally{be(!1)}},[o,q,R,l,h]),U=(0,b.useCallback)(e=>{if(K(e),!e){o.resetFields(["key","name","description","type","prompt"]),F([]);return}let a=typeof e.graphDefinition=="object"&&e.graphDefinition!==null?e.graphDefinition:{},A=a.key||e.id,y=e.name||a.name||"";o.setFieldsValue({key:`${A}_ext`,name:y?`${y} (Extended)`:"",description:e.description||a.description||"",type:a.type||"react",prompt:a.prompt||""});let B=a.subAgents||[];F(B.map(j=>({originalKey:j,clone:!1})))},[o]),ke=async(e,a)=>{let A=await Ae(`/api/assistants/${e}`);if(!A.success)throw new Error(`Failed to fetch sub-agent "${e}" for cloning`);let y=A.data,B=typeof y.graphDefinition=="object"?y.graphDefinition:{},j={id:a,name:`${y.name} (Clone)`,description:y.description||"",graphDefinition:{...B,key:a,name:`${y.name} (Clone)`}},D=await q("/api/assistants",j);if(!D.success)throw new Error(D.message||`Failed to clone sub-agent "${e}"`);return D.data},tn=e=>{let a={id:e.key,name:e.name,description:e.description||"",graphDefinition:{key:e.key,name:e.name,description:e.description||"",type:e.type,prompt:e.prompt||"",tools:[],skills:[],subAgents:e.type==="deep_agent"||e.type==="processing"?[]:void 0,middleware:[]}};if(e.type==="a2a_remote"&&(a.graphDefinition.agentCardUrl=Jt(e.agentCardUrl,e.agentCardProtocol,(e.a2aMode||R)==="local"?"http://":"https://"),e.apiKey&&(a.graphDefinition.apiKey=e.apiKey),e.timeout&&(a.graphDefinition.timeout=e.timeout),(e.a2aMode||R)==="local")){let A=l;if(A)a.graphDefinition.localRuntime={label:e.name||void 0,agentCardUrl:a.graphDefinition.agentCardUrl,command:Yt(A.command,a.graphDefinition.agentCardUrl)};else{let y=e.commandArgs||"",B=y?y.split(/\s+/).filter(Boolean):[],j=String(e.command?.cwd||"").trim();a.graphDefinition.localRuntime={label:e.name||void 0,agentCardUrl:a.graphDefinition.agentCardUrl,command:{executable:String(e.commandExecutable||"").trim(),args:B,...j?{cwd:j}:{}}}}}return a},nn=async(e,a)=>{if(!I)throw new Error("No parent agent selected");let A=w.filter(D=>D.clone);for(let D of A){if(!D.cloneKey||!D.cloneKey.trim())throw new Error(`Please provide a key for the cloned sub-agent "${D.originalKey}"`);if(!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(D.cloneKey))throw new Error(`Invalid key "${D.cloneKey}" for cloned sub-agent "${D.originalKey}". Key must start with a letter and contain only letters, numbers, underscores, or hyphens.`)}let y=[];for(let D of w)if(D.clone){let rn=await ke(D.originalKey,D.cloneKey);a.push(rn),y.push(D.cloneKey)}else y.push(D.originalKey);let B=typeof I.graphDefinition=="object"?I.graphDefinition:{},j={key:e.key,name:e.name,description:e.description||"",extendsAgent:I.id,type:e.type||B.type};return e.prompt&&e.prompt!==B.prompt&&(j.prompt=e.prompt),(y.length>0||B.subAgents&&B.subAgents.length>0)&&(j.subAgents=y),{id:e.key,name:e.name,description:e.description||"",graphDefinition:j}},an=async()=>{if(c==="learn"){let e=H.trim();if(!e){v.error("Please describe the training goal");return}if(!L){v.error("No shared training project available");return}k(!0);try{let a=`agent-${Ft(e+Date.now())}`,A=await q("/api/assistants",{id:a,name:a,graphDefinition:{key:a,name:a,description:"",type:"react",prompt:"To be trained",metadata:{trainingProjectId:L.id,learningPlaceholder:"true",architectureStatus:"undecided"}}});if(!A.data)throw new Error("Failed to create agent");let{roundTaskId:y}=await Mt({goal:e,targetAgentId:a,workspaceId:pe??void 0,projectId:L.id,existingThreadId:Et(Le.tenantId,a),files:we,post:q,put:z});v.success("Agent created \u2014 architect started building"),m(""),ve([]),S("learn"),p?.(A.data,{initialMessage:Nt({goal:e,roundTaskId:y,targetAgentId:a,targetMode:"placeholder",files:we,projectId:L.id,workspaceId:L.workspaceId??pe??void 0}),projectId:L.id}),r()}catch(a){v.error(a instanceof Error?a.message:"Failed to create agent")}finally{k(!1)}return}try{if(c==="scratch"&&_&&!h())return;let e=await o.validateFields();k(!0);let a=[],A=c==="scratch"?tn(e):await nn(e,a),y=await q("/api/assistants",A);if(y.success){v.success(c==="extend"?`Assistant created by extending "${I?.name}"`:"Assistant created successfully"),re();for(let B of a)p?.(B);p?.(y.data),r()}else v.error(y.message||"Failed to create assistant")}catch(e){if(e?.errorFields){let a={key:"Key (ID)",name:"Name",description:"Description",prompt:"System Prompt"},A=e.errorFields.map(y=>a[String((y.name??[])[0])]??String((y.name??[])[0])).filter(Boolean);v.warning(A.length>0?`Please complete the required fields: ${[...new Set(A)].join(", ")}`:"Please complete the required fields");return}v.error(e.message||"An error occurred while creating the assistant")}finally{k(!1)}},He=I?.graphDefinition?.subAgents||[],on=c==="extend"&&I&&He.length>0;return(0,t.jsxs)(ue,{title:"Create New Assistant",open:n,onCancel:()=>{re(),r()},footer:[(0,t.jsx)(Z,{onClick:()=>{re(),r()},children:"Cancel"},"cancel"),(0,t.jsx)(Z,{type:"primary",icon:c==="extend"?(0,t.jsx)(Ee,{}):c==="learn"?(0,t.jsx)(et,{}):(0,t.jsx)(nt,{}),loading:f,disabled:c==="learn"&&(oe||!L),onClick:an,children:c==="extend"?"Create (Extend)":c==="learn"?"Start Learning":"Create"},"submit")],width:760,children:[c==="extend"&&(0,t.jsxs)("div",{style:{marginBottom:20},children:[(0,t.jsx)(ee,{type:"secondary",style:{display:"block",marginBottom:8},children:"Parent Agent"}),(0,t.jsx)(zt,{value:I?.id,onSelect:U}),I&&(0,t.jsx)(ee,{type:"secondary",style:{display:"block",marginTop:4,fontSize:12},children:"Fields left unchanged will be inherited from the parent agent."})]}),c==="extend"&&I&&(0,t.jsx)(Oe,{style:{margin:"12px 0"}}),c==="learn"&&(0,t.jsxs)("div",{children:[(0,t.jsx)(ee,{style:{display:"block",marginBottom:8},children:"Describe what the agent should do."}),(0,t.jsx)(V.TextArea,{rows:3,value:H,onChange:e=>m(e.target.value),placeholder:"e.g. Handle price disputes using the price protection policy"}),L&&(0,t.jsxs)("div",{style:{marginTop:12},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,marginBottom:8},children:[(0,t.jsx)(ee,{type:"secondary",children:"Reference Files"}),(0,t.jsx)(Ge,{project:L,projects:me,value:L?.id??null,onChange:xe,loading:oe})]}),(0,t.jsx)(Pt,{projectId:L.id,value:we,onChange:ve}),(0,t.jsx)(ee,{type:"secondary",style:{display:"block",marginTop:6,fontSize:12},children:"Optional \u2014 uploaded to the shared training workspace and attached to the learning round; the architect reads them as round material."})]}),!L&&!oe&&(0,t.jsx)("div",{style:{marginTop:12},children:(0,t.jsx)(Ge,{project:L,projects:me,value:null,onChange:xe,loading:oe})})]}),c!=="learn"&&(0,t.jsxs)(P,{form:o,layout:"vertical",autoComplete:"off",initialValues:{type:"react",agentCardProtocol:"https://",a2aMode:"remote"},children:[(0,t.jsx)(P.Item,{name:"key",label:"Key (ID)",rules:[{required:!0,message:"Please enter a unique key"},{pattern:/^[a-zA-Z][a-zA-Z0-9_-]*$/,message:"Key must start with a letter and contain only letters, numbers, underscores, or hyphens"}],style:{marginBottom:16},children:(0,t.jsx)(V,{placeholder:"e.g., my_assistant"})}),(0,t.jsx)(P.Item,{name:"name",label:"Name",rules:[{required:!0,message:"Please enter a name"}],style:{marginBottom:16},children:(0,t.jsx)(V,{placeholder:"e.g., My Assistant"})}),(0,t.jsx)(P.Item,{name:"description",label:"Description",rules:[{required:!0,message:"Please enter a description"}],style:{marginBottom:16},children:(0,t.jsx)(Wt,{placeholder:"Enter a description for this assistant...",autoSize:{minRows:2,maxRows:4}})}),(0,t.jsx)(P.Item,{name:"type",label:"Agent Type",rules:[{required:!0}],style:{marginBottom:16},children:(0,t.jsx)(We,{options:[{value:"react",label:"Executor"},{value:"deep_agent",label:"Orchestrator"},{value:"team",label:"Team"},{value:"processing",label:"Workflow"},{value:"a2a_remote",label:"A2A Remote"}],block:!0})}),(0,t.jsx)(ee,{type:"secondary",style:{fontSize:12,display:"block",marginTop:-12,marginBottom:16,lineHeight:1.5},children:Zt[N]||Zt.react}),_&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(P.Item,{label:"Connection Mode",style:{marginBottom:16},children:(0,t.jsxs)(Fe.Group,{value:R,onChange:e=>{let a=e.target.value;s(a),o.setFieldValue("a2aMode",a),a==="local"&&o.setFieldValue("agentCardProtocol","http://"),te(void 0)},optionType:"button",buttonStyle:"solid",children:[(0,t.jsx)(Fe.Button,{value:"remote",children:"Remote URL"}),(0,t.jsx)(Fe.Button,{value:"local",children:"Local Managed"})]})}),(0,t.jsx)(P.Item,{name:"a2aMode",noStyle:!0,hidden:!0,children:(0,t.jsx)(V,{})}),R==="local"&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(P.Item,{label:"Template",style:{marginBottom:16},children:(0,t.jsx)(Se,{placeholder:"Choose a template...",allowClear:!0,loading:de,value:i,onChange:e=>{te(e),e&&W(!1)},options:le.map(e=>({value:e.key,label:e.name||e.key})),notFoundContent:de?void 0:(0,t.jsx)(ee,{type:"secondary",style:{padding:8,display:"block"},children:'No templates. Use "Custom Command" below.'})})}),!i&&(0,t.jsx)(t.Fragment,{children:ae?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(P.Item,{name:"commandExecutable",label:"Executable",rules:[{required:!0,whitespace:!0,message:"Executable is required"}],style:{marginBottom:16},children:(0,t.jsx)(V,{placeholder:"e.g. node, opencode, /usr/local/bin/my-server"})}),(0,t.jsx)(P.Item,{name:"commandArgs",label:"Arguments",style:{marginBottom:16},children:(0,t.jsx)(V,{placeholder:"e.g. --serve --port 4301"})}),(0,t.jsx)(P.Item,{name:["command","cwd"],label:"Working directory",style:{marginBottom:16},children:(0,t.jsx)(V,{placeholder:"e.g. /Users/me/project"})}),(0,t.jsx)(Z,{type:"link",onClick:()=>{W(!1),o.setFieldsValue({commandExecutable:"",commandArgs:"",command:{cwd:void 0}})},style:{padding:0,marginBottom:16,display:"block"},children:"- Hide Custom Command"})]}):(0,t.jsx)(Z,{type:"link",onClick:()=>W(!0),style:{padding:0,marginBottom:16,display:"block"},children:"+ Custom Command"})})]}),(0,t.jsx)(P.Item,{label:"Agent Card URL",required:!0,style:{marginBottom:16},children:(0,t.jsxs)(Ze.Compact,{style:{width:"100%"},children:[(0,t.jsx)(P.Item,{name:"agentCardProtocol",noStyle:!0,children:(0,t.jsx)(Se,{style:{width:100},options:gn})}),(0,t.jsx)(P.Item,{name:"agentCardUrl",noStyle:!0,rules:[{required:!0,message:"Please enter the A2A server URL"}],children:(0,t.jsx)(V,{placeholder:R==="local"?"localhost:4301":"host:port or full URL"})}),(0,t.jsx)(Z,{icon:(0,t.jsx)(Xe,{}),onClick:T,loading:Ne,children:"Test"})]})}),R==="remote"&&(0,t.jsx)(P.Item,{name:"apiKey",label:"API Key (optional)",style:{marginBottom:16},children:(0,t.jsx)(V.Password,{placeholder:"API key for authentication"})}),(0,t.jsx)(P.Item,{name:"timeout",label:"Timeout (ms)",style:{marginBottom:16},initialValue:3e5,children:(0,t.jsx)(qe,{min:1e3,max:36e5,style:{width:"100%"},placeholder:"300000"})})]}),!_&&(0,t.jsx)(P.Item,{name:"prompt",label:c==="extend"&&I?"System Prompt (leave unchanged to inherit from parent)":"System Prompt",rules:c==="scratch"?[{required:!0,message:"Please enter a system prompt"}]:[],children:(0,t.jsx)(Wt,{placeholder:c==="extend"&&I?"Leave empty to inherit parent's prompt, or enter a new prompt to override...":"Enter the system prompt for this agent...",autoSize:{minRows:4,maxRows:8},style:{fontFamily:"monospace",fontSize:13,lineHeight:1.6}})})]}),on&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(Oe,{style:{margin:"12px 0"}}),(0,t.jsx)(ee,{strong:!0,style:{display:"block",marginBottom:8},children:"Sub-Agents"}),(0,t.jsx)(jt,{subAgentKeys:He,decisions:w,onChange:F})]})]})};var $=x(E()),{Paragraph:yn,Text:Xt}=Y,hn=[{key:"manual",icon:De,title:"Manual Configuration",description:"Define the agent's identity, type, tools, and system prompt yourself."},{key:"external",icon:ot,title:"External Agent",description:"Connect an existing A2A-compatible agent by URL or manage a local runtime."},{key:"learn",icon:st,title:"Learn with Agent Architect",description:"Describe the goal and let Agent Architect build and evaluate the agent with training context."}],en=({open:n,onCancel:r,onSelectMethod:p,focusTriggerAfterClose:d=!0})=>(0,$.jsx)(ue,{title:"Choose how to create your agent",open:n,onCancel:r,footer:null,width:560,centered:!0,destroyOnHidden:!0,focusTriggerAfterClose:d,children:(0,$.jsxs)("div",{style:{padding:"8px 4px 4px"},children:[(0,$.jsx)(yn,{style:{color:"#595959",fontSize:15,margin:"8px 0 24px"},children:"Choose the path that best fits the agent you want to build."}),(0,$.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:12},children:hn.map(g=>{let o=g.icon;return(0,$.jsxs)(Z,{type:"default",onClick:()=>p(g.key),"aria-label":g.title,style:{display:"flex",flexDirection:"row",alignItems:"center",gap:16,width:"100%",minHeight:88,height:"auto",padding:16,borderRadius:16,textAlign:"left",whiteSpace:"normal"},children:[(0,$.jsx)("div",{style:{width:40,height:40,borderRadius:12,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,color:"#6366f1",background:"#eeeeff"},children:(0,$.jsx)(o,{size:19})}),(0,$.jsxs)("div",{style:{minWidth:0},children:[(0,$.jsx)(Xt,{strong:!0,style:{display:"block",fontSize:15,marginBottom:3},children:g.title}),(0,$.jsx)(Xt,{style:{color:"#737373",lineHeight:1.5},children:g.description})]})]},g.key)})}),(0,$.jsx)("div",{style:{display:"flex",justifyContent:"flex-end",gap:8,flexWrap:"wrap",marginTop:24},children:(0,$.jsx)(Z,{onClick:r,children:"Not now"})})]})});var G=x(E()),bn=n=>{let r=n;if(typeof n=="string")try{r=JSON.parse(n)}catch{return{}}return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:{}},Da=()=>{let{get:n,del:r,put:p}=fe(),[d,g]=(0,u.useState)([]),[o,f]=(0,u.useState)({}),[k,c]=(0,u.useState)(null),[S,H]=(0,u.useState)(!1),[m,I]=(0,u.useState)(null),[K,w]=(0,u.useState)("graph"),[F,N]=(0,u.useState)(null),[_,R]=(0,u.useState)(null),[s,i]=(0,u.useState)(!1),[te,le]=(0,u.useState)(!0),[he,de]=(0,u.useState)(!1),[ce,ne]=(0,u.useState)("learn"),[Ne,be]=(0,u.useState)({}),[ae,W]=(0,u.useState)(null),[Ae,q]=(0,u.useState)(!1),z=(0,u.useCallback)(async()=>{H(!0);try{let[l,h]=await Promise.all([n("/api/assistants"),n("/api/assistants/stats").catch(()=>null)]);if(l.success&&l.data?.records&&g(l.data.records),h?.success&&h.data?.records){let T={};for(let U of h.data.records)T[U.id]=U;f(T),c(h.cache?.expiresAt??null)}}catch{v.error("Failed to load agents")}finally{H(!1)}},[n]);(0,u.useEffect)(()=>{z()},[z]);let Le=u.default.useMemo(()=>It(d),[d]),pe=d.find(l=>l.id===m)??null,me=(0,u.useCallback)((l,h="graph")=>{I(l),w(h),N(null),R(null)},[]),oe=ht(),Ce=(0,u.useCallback)((l,h)=>{let T=d.find(U=>U.id===l)?.name??"Agent";oe({component_key:"agent_detail_side_app",data:{assistantId:l,initialTab:h},message:T})},[d,oe]),xe=(0,u.useCallback)(()=>{le(!0),i(!0)},[]),Be=(0,u.useCallback)(l=>{let T={manual:{mode:"scratch",values:{}},external:{mode:"scratch",values:{type:"a2a_remote"}},learn:{mode:"learn",values:{}}}[l];ne(T.mode),be(T.values),le(!1),i(!1),de(!0)},[]),L=(0,u.useCallback)(async(l,h)=>{let T=bn(l.graphDefinition),U;try{U=await p(`/api/assistants/${l.id}`,{name:h.name!==void 0?h.name:l.name,description:h.description!==void 0?h.description:l.description,graphDefinition:{...T,...h}})}catch(ke){throw v.error("Failed to save agent"),ke}if(!U.success)throw v.error("Failed to save agent"),new Error("Failed to save agent");v.success("Saved"),z()},[p,z]),we=(0,u.useCallback)(l=>{g(h=>h.map(T=>T.id===l.id?l:T))},[]),ve=(0,u.useCallback)(l=>{W(l)},[]),Pe=(0,u.useCallback)(async()=>{if(ae){q(!0);try{(await r(`/api/assistants/${ae}`)).success?(v.success("Agent deleted"),g(h=>h.filter(T=>T.id!==ae)),z(),W(null)):v.error("Failed to delete agent")}catch{v.error("Failed to delete agent")}finally{q(!1)}}},[ae,r,z]),re=(0,u.useCallback)(async l=>{if(!(await r(`/api/assistants/${l}`)).success)throw new Error("Failed to delete agent");v.success("Agent deleted"),g(T=>T.filter(U=>U.id!==l)),z()},[r,z]);return(0,G.jsxs)("div",{style:{height:"100%",background:"#fafafa",overflow:"hidden"},children:[pe?(0,G.jsx)(St,{defaultProjectId:_??void 0,children:(0,G.jsx)(Lt,{assistant:pe,allAssistants:d,onBack:()=>I(null),onDeleted:re,onSave:L,onAssistantUpdated:we,onAgentListInvalidated:z,initialTab:K,initialMessage:F,initialProjectId:_})},pe.id):(0,G.jsx)(G.Fragment,{children:(0,G.jsx)(Gt,{items:Le,assistants:d,stats:o,statsExpiresAt:k,loading:S,onItemClick:l=>Ce(l,"graph"),onOpenPlayground:l=>Ce(l,"playground"),onOpenEval:l=>Ce(l,"eval"),onCreate:xe,onDelete:ve})}),(0,G.jsx)(en,{open:s,onCancel:()=>{le(!0),i(!1)},onSelectMethod:Be,focusTriggerAfterClose:te}),(0,G.jsx)(Qt,{open:he,initialMode:ce,initialValues:Ne,onCancel:()=>de(!1),onSuccess:(l,h)=>{de(!1),g(T=>T.some(ke=>ke.id===l.id)?T:[l,...T]),me(l.id,"graph"),N(h?.initialMessage??null),R(h?.projectId??null),z()}}),(0,G.jsx)(ue,{title:"Delete Agent",open:ae!==null,onCancel:()=>W(null),onOk:Pe,okText:"Delete",okButtonProps:{danger:!0,loading:Ae},cancelText:"Cancel",children:(0,G.jsx)("p",{children:"This action cannot be undone."})})]})};export{Da as AgentGovernanceWorkbench};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{c as L,d as U}from"./embed-page-chunk-KEL6XU6R.js";import{b,d as H,e as N}from"./embed-page-chunk-AC6X2XRH.js";import"./embed-page-chunk-S4XZPBRM.js";import{_a as w,ab as z,bb as F,ob as k,pb as W,qb as V}from"./embed-page-chunk-BRETUPSG.js";import"./embed-page-chunk-T25T2YE6.js";import{a as g}from"./embed-page-chunk-MB65DZAX.js";import"./embed-page-chunk-VW3NF5NT.js";import"./embed-page-chunk-5JDQ456X.js";import"./embed-page-chunk-Z7USDLHI.js";import{Dc as D,Ia as O,Rc as G,Sc as C,Vc as _,W as h,aa as M,gb as P,lb as B,nc as E}from"./embed-page-chunk-O4QK5LWZ.js";import{a as x}from"./embed-page-chunk-4BKXE5ON.js";import"./embed-page-chunk-IX4WLWCY.js";import"./embed-page-chunk-EUOOO2LS.js";import{e as p}from"./embed-page-chunk-6Y3UYJ6Z.js";var s=p(x());var R=p(x());var o=p(g());var ne="tracePulse 1.4s ease-in-out infinite",re={running:(0,o.jsx)(E,{style:{color:"#1890ff"}}),success:(0,o.jsx)(P,{style:{color:"#52c41a"}}),error:(0,o.jsx)(B,{style:{color:"#ff4d4f"}})};function se({kind:e}){switch(e){case"human":return(0,o.jsx)(_,{});case"agent":return(0,o.jsx)(G,{});case"tool":return(0,o.jsx)(C,{});case"ai":return(0,o.jsx)(D,{});default:return(0,o.jsx)(C,{})}}var S=R.default.createContext({}),ie=()=>R.default.useContext(S),ae=({data:e,selected:i})=>{let{onJumpToMessage:a}=ie(),t=e.isAnswer===!0,r=e.status==="running",d=(e.parallelCount??1)>1,m=!!(a&&e.messageId&&!e.messageId.startsWith("summary:")),f=e.toolCall?F(e.toolCall.name):e.label,y=()=>(e.kind==="tool"||e.kind==="agent")&&e.toolCall?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(z,{data:{name:e.toolCall.name,parameters:e.toolCall.args,type:"tool_call"},component_key:`${e.toolCall.id}-params`,interactive:!1}),e.toolCall.response&&(0,o.jsx)("div",{style:{marginTop:8},children:(0,o.jsx)(w,{content:e.toolCall.response})})]}):e.content?(0,o.jsx)(w,{content:e.content}):(0,o.jsx)("span",{style:{color:"#8c8c8c"},children:e.label});return(0,o.jsxs)("div",{"data-testid":"trace-card",style:{height:"100%",display:"flex",flexDirection:"column",border:`1px solid ${t||i?"#6366f1":r?"#91caff":"#e5e7eb"}`,borderRadius:12,background:t?"#eef2ff":"#fff",boxShadow:r?"0 0 0 2px rgba(24,144,255,0.18)":i?"0 0 0 2px rgba(99,102,241,0.2)":"none",animation:r?ne:void 0,overflow:"hidden",fontSize:13},children:[(0,o.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 12px",borderBottom:"1px solid #f0f0f0",background:"rgba(0,0,0,0.02)"},children:[(0,o.jsx)(se,{kind:e.kind}),(0,o.jsx)("span",{style:{fontWeight:t?700:600,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:f}),d&&(0,o.jsxs)(O,{color:"purple",style:{marginInlineEnd:0,fontSize:10},children:["\u5E76\u53D1 \xD7",e.parallelCount]}),re[e.status],m&&(0,o.jsx)(h,{type:"text",size:"small",onClick:()=>a?.(e.messageId),children:"\u5BF9\u8BDD"})]}),(0,o.jsx)("div",{style:{flex:1,minHeight:0,overflow:"auto",padding:12},children:y()})]})},le=({data:e,selected:i})=>(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(N,{type:"target",position:b.Top}),(0,o.jsx)(ae,{data:e,selected:i}),(0,o.jsx)(N,{type:"source",position:b.Bottom})]}),$={trace:le};var J=p(x());var u=p(g()),de={running:"#1890ff",success:"#52c41a",error:"#ff4d4f"},K=({graph:e,activeNodeId:i,onSelectNode:a})=>{let t=J.default.useMemo(()=>new Map(e.nodes.map(r=>[r.id,r])),[e.nodes]);return(0,u.jsx)("div",{"data-testid":"trace-overview-rail",style:{display:"flex",flexDirection:"column",gap:10,width:160,padding:8,overflowY:"auto",borderRight:"1px solid #f0f0f0"},children:e.phases.map(r=>(0,u.jsxs)("div",{"data-testid":"trace-rail-phase",children:[(0,u.jsx)("div",{style:{fontSize:12,color:"#8c8c8c",marginBottom:4},children:r.title}),(0,u.jsx)("div",{style:{display:"flex",flexWrap:"wrap",gap:4},children:r.nodeIds.map(d=>{let m=t.get(d);if(!m)return null;let f=d===i;return(0,u.jsx)(M,{title:m.data.label,children:(0,u.jsx)("button",{type:"button","data-testid":"trace-rail-tick",onClick:()=>a?.(d),style:{width:f?12:8,height:f?12:8,borderRadius:"50%",border:"none",padding:0,cursor:"pointer",background:de[m.data.status],outline:f?"2px solid #6366f1":"none"}})},d)})})]},r.id))})};var l=p(g()),Y=3,Z=()=>{},ce=`
|
|
2
|
-
@keyframes tracePulse {
|
|
3
|
-
0%, 100% { box-shadow: 0 0 0 2px rgba(24,144,255,0.18); }
|
|
4
|
-
50% { box-shadow: 0 0 0 6px rgba(24,144,255,0.05); }
|
|
5
|
-
}
|
|
6
|
-
`;function pe(e){let i=e.nodes.map(t=>({id:t.id,...k[t.data.kind]})),a=e.edges.map(t=>({from:t.from,to:t.to}));return L(i,a,{nodesep:48,ranksep:80,rankdir:"TB"})}function fe({focusNodeId:e,follow:i}){let a=H();return(0,s.useEffect)(()=>{if(!i||!e)return;let t=a.getNode(e);if(!t)return;let r=t.style?.width??0,d=t.style?.height??0;a.setCenter(t.position.x+r/2,t.position.y+d/2,{zoom:1,duration:300})},[e,i,a]),null}var Ae=({messages:e,isLoading:i,onJumpToMessage:a})=>{let[t,r]=(0,s.useState)(),[d,m]=(0,s.useState)(!1),[f,y]=(0,s.useState)(!0),I=(0,s.useDeferredValue)(e),v=(0,s.useMemo)(()=>W(I,{isLoading:i}),[I,i]),c=(0,s.useMemo)(()=>d?v:V(v,Y),[v,d]),j=(0,s.useMemo)(()=>`${c.nodes.map(n=>n.id).join(",")}|${c.edges.map(n=>n.id).join(",")}`,[c]),A=(0,s.useMemo)(()=>pe(c),[j]),q=(0,s.useMemo)(()=>c.nodes.map(n=>{let T=k[n.data.kind];return{id:n.id,type:"trace",position:A.get(n.id)??{x:0,y:0},data:n.data,draggable:!1,style:{width:T.width,height:T.height}}}),[c,A]),Q=(0,s.useMemo)(()=>c.edges.map(n=>({id:n.id,source:n.from,target:n.to,animated:n.kind==="invoke",style:{stroke:n.kind==="invoke"?"#6366f1":n.kind==="result"?"#a5b4fc":"#d9d9d9"}})),[c]),X=c.nodes[c.nodes.length-1]?.id,ee=t??X,oe=v.phases.length>Y,te=(0,s.useMemo)(()=>({onJumpToMessage:a}),[a]);return(0,l.jsxs)(S.Provider,{value:te,children:[(0,l.jsx)("style",{children:ce}),(0,l.jsxs)("div",{style:{display:"flex",height:"100%",minHeight:0,width:"100%"},children:[(0,l.jsx)(K,{graph:c,activeNodeId:t,onSelectNode:r}),(0,l.jsxs)("div",{style:{flex:1,minWidth:0,minHeight:0,display:"flex",flexDirection:"column"},children:[(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",alignItems:"center",gap:4,padding:"4px 8px"},children:[!f&&(0,l.jsx)(h,{size:"small",type:"text",onClick:()=>{r(void 0),y(!0)},children:"\u56DE\u5230\u5F53\u524D"}),oe&&(0,l.jsx)(h,{size:"small",type:"text",onClick:()=>m(n=>!n),children:d?"\u6536\u8D77\u66F4\u65E9":"\u5C55\u5F00\u5168\u90E8"})]}),(0,l.jsx)("div",{style:{flex:1,minHeight:0},children:(0,l.jsx)(U,{nodes:q,edges:Q,nodeTypes:$,onNodesChange:Z,onEdgesChange:Z,nodesDraggable:!1,nodesConnectable:!1,fitView:!0,miniMap:{pannable:!0,zoomable:!0},onMoveStart:()=>y(!1),onNodeClick:(n,T)=>{r(T.id),y(!0)},children:(0,l.jsx)(fe,{focusNodeId:ee,follow:f})})})]})]})]})};export{Ae as MessageGraph};
|