@yuku123/z-team-component 0.2.103 → 0.2.104

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 (58) hide show
  1. package/dist/ChangeLogView-DG-ogBff.js +542 -0
  2. package/dist/ComponentDoc-BW1SyDxk.js +8035 -0
  3. package/dist/InvitationManagementPage-hYvoPEcm.js +495 -0
  4. package/dist/OnboardingPage-KDp-DrzY.js +393 -0
  5. package/dist/ScheduledTasks-CErSDgyW.js +12127 -0
  6. package/dist/SystemShell-DvrY4Bl7.js +688 -0
  7. package/dist/_commonjsHelpers-B52_cu2H.js +26 -0
  8. package/dist/admin-logs-uPnnclwN.js +198 -0
  9. package/dist/api-B__qdRIf.js +20 -0
  10. package/dist/browser-jb_PFvU3.js +1538 -0
  11. package/dist/createWorkspaceWsHandler-BXbn5-Ft.js +13142 -0
  12. package/dist/ctc-sso-DtJHC-2M.js +117 -0
  13. package/dist/echarts-B1OU1xr4.js +16 -0
  14. package/dist/history-BlrA1eaW.js +41 -0
  15. package/dist/index-0smeCTnr.js +42049 -0
  16. package/dist/index-2isWwv1X.js +10169 -0
  17. package/dist/index-BC8f-JP9.js +242 -0
  18. package/dist/index-BK3YDeXH.js +2217 -0
  19. package/dist/index-BOJm25by.js +999 -0
  20. package/dist/index-B_LJRFsK.js +339 -0
  21. package/dist/index-BnJ8UEeZ.js +5892 -0
  22. package/dist/index-BohoJQPr.js +7631 -0
  23. package/dist/index-BwJPAN8f.js +112 -0
  24. package/dist/index-ByhCWenF.js +434 -0
  25. package/dist/index-C2_tfpEj.js +118 -0
  26. package/dist/index-C815hPWS.js +430 -0
  27. package/dist/index-C9fGup9t.js +189 -0
  28. package/dist/index-Cb88Xdh4.js +169 -0
  29. package/dist/index-Cih0yoxc.js +178 -0
  30. package/dist/index-CkWKJORv.js +1645 -0
  31. package/dist/index-CsaGecGX.js +132 -0
  32. package/dist/index-D-xPVrY3.js +316 -0
  33. package/dist/index-DAGa9v8r.js +142 -0
  34. package/dist/index-DBnH-lRh.js +956 -0
  35. package/dist/index-DIFIvVWE.js +93 -0
  36. package/dist/index-DOgCfVB2.js +574 -0
  37. package/dist/index-DWsfQMp8.js +208 -0
  38. package/dist/index-DcurzowX.js +2699 -0
  39. package/dist/index-DhDdFRHC.js +279 -0
  40. package/dist/index-Dpii3P5J.js +1302 -0
  41. package/dist/index-DtHoMz1H.js +8 -0
  42. package/dist/index-YVtm1SRy.js +913 -0
  43. package/dist/index-aI2EXKED.js +479 -0
  44. package/dist/index-q_TPea69.js +315 -0
  45. package/dist/index.js +10 -0
  46. package/dist/index.module-CAa-2T7m.js +72 -0
  47. package/dist/index.module-UI0iz8K0.js +42 -0
  48. package/dist/instance-pdQ_wAhB.js +216 -0
  49. package/dist/menuPermission-CCQjJVXg.js +60 -0
  50. package/dist/mobile-client-O3yr9h6t.js +24 -0
  51. package/dist/pages.js +21 -0
  52. package/dist/send-default-agent-team-message-BzeR4ahf.js +35 -0
  53. package/dist/spark-md5-Dld54a-T.js +178 -0
  54. package/dist/sso-user-DI7oiDdc.js +43 -0
  55. package/dist/training-Bz7Sr5yC.js +450 -0
  56. package/dist/webide-NcHLDiSn.js +5233 -0
  57. package/dist/z-team-component.css +1 -0
  58. package/package.json +1 -1
@@ -0,0 +1,1645 @@
1
+ import { jsxs as s, jsx as e } from "react/jsx-runtime";
2
+ import { CopyOutlined as oe, ReloadOutlined as Te, PlusOutlined as Se, DeleteOutlined as Ue, ClearOutlined as Re, CloseOutlined as De, SendOutlined as He, RobotOutlined as we, CloudServerOutlined as ze, MessageOutlined as Fe, KeyOutlined as je, ApiOutlined as qe, ToolOutlined as Ge, BarChartOutlined as Je } from "@ant-design/icons";
3
+ import { useState as N, useEffect as X, useCallback as j, useRef as ue, useMemo as Ae, Suspense as We, lazy as Qe } from "react";
4
+ import { Tooltip as Y, Tabs as Be, Input as ke, Button as H, Modal as he, Drawer as xe, Spin as Z, Statistic as E, Table as Me, message as J, Tag as W, Select as Ve, Checkbox as Ye } from "antd";
5
+ import { d as be } from "./ComponentDoc-BW1SyDxk.js";
6
+ import { AgentAppList as Xe, McpPage as Ze, SkillMarket as et } from "@yuku123/z-agent-component";
7
+ const re = "ft_gateway_default_ak", Ie = "system-default", ee = "", ge = "";
8
+ function te(a = {}) {
9
+ const n = { Accept: "application/json", ...a };
10
+ try {
11
+ const l = localStorage.getItem("token");
12
+ l && (n.Authorization = `Bearer ${l}`);
13
+ } catch {
14
+ }
15
+ return n;
16
+ }
17
+ function tt(a) {
18
+ return {
19
+ modelName: String(a.modelName ?? a.model_name ?? a.service ?? ""),
20
+ service: String(a.service ?? a.modelName ?? ""),
21
+ endpoint: String(a.endpoint ?? ""),
22
+ modelProvider: a.modelProvider ?? a.model_provider ?? null,
23
+ apiType: String(a.apiType ?? a.api_type ?? "OpenAPI")
24
+ };
25
+ }
26
+ async function fe() {
27
+ let a;
28
+ try {
29
+ a = await fetch(`${ee}/api/scenario-instances/0/models`, {
30
+ credentials: "include",
31
+ headers: te({
32
+ Accept: "application/json",
33
+ "project-env": window.ENV_TYPE ?? "local"
34
+ })
35
+ });
36
+ } catch {
37
+ throw new Error("模型列表不可达:模型配置接口请求失败");
38
+ }
39
+ if (!a.ok)
40
+ throw new Error(`模型列表获取失败(HTTP ${a.status})`);
41
+ let n;
42
+ try {
43
+ n = await a.json();
44
+ } catch {
45
+ throw new Error("模型列表返回格式异常(非 JSON)");
46
+ }
47
+ const l = n != null && n.success ? n.data : (n == null ? void 0 : n.data) ?? n;
48
+ if (!Array.isArray(l))
49
+ throw new Error("模型列表返回格式异常(非数组)");
50
+ return l.map(tt);
51
+ }
52
+ async function at(a, n, l, c) {
53
+ var M, U, A;
54
+ const u = await fetch(`${ge}/v1/chat/completions`, {
55
+ method: "POST",
56
+ headers: {
57
+ "Content-Type": "application/json",
58
+ Authorization: `Bearer ${a}`,
59
+ Accept: "text/event-stream"
60
+ },
61
+ body: JSON.stringify({
62
+ model: n,
63
+ messages: l,
64
+ stream: !0
65
+ }),
66
+ signal: c.signal
67
+ });
68
+ if (!u.ok || !u.body) {
69
+ const C = await u.text().catch(() => "");
70
+ if (/<!doctype html/i.test(C.slice(0, 200)))
71
+ throw new Error("模型网关未接入(/v1/chat/completions 落到主壳 SPA,无网关响应)");
72
+ let T = `HTTP ${u.status}`;
73
+ try {
74
+ const p = JSON.parse(C);
75
+ T = ((M = p == null ? void 0 : p.error) == null ? void 0 : M.message) ?? T;
76
+ } catch {
77
+ C && (T = C);
78
+ }
79
+ throw new Error(T);
80
+ }
81
+ const f = u.body.getReader(), y = new TextDecoder();
82
+ let _ = "", k;
83
+ try {
84
+ for (; ; ) {
85
+ const { done: C, value: T } = await f.read();
86
+ if (C) break;
87
+ _ += y.decode(T, { stream: !0 });
88
+ const p = _.split(`
89
+
90
+ `);
91
+ _ = p.pop() ?? "";
92
+ for (const i of p) {
93
+ let g = "";
94
+ for (const m of i.split(`
95
+ `))
96
+ m.startsWith("data:") && (g += m.slice(5).trim());
97
+ if (!g || g === "[DONE]") {
98
+ if (g === "[DONE]") {
99
+ c.onDone(k);
100
+ return;
101
+ }
102
+ continue;
103
+ }
104
+ try {
105
+ const m = JSON.parse(g), B = m == null ? void 0 : m.choices;
106
+ if (m != null && m.usage) {
107
+ const I = {
108
+ promptTokens: m.usage.prompt_tokens ?? 0,
109
+ completionTokens: m.usage.completion_tokens ?? 0,
110
+ totalTokens: m.usage.total_tokens ?? 0
111
+ };
112
+ (!k || I.totalTokens > 0) && (k = I);
113
+ }
114
+ if (Array.isArray(B) && B.length > 0) {
115
+ const I = (U = B[0]) == null ? void 0 : U.delta;
116
+ I != null && I.content && c.onDelta(I.content);
117
+ continue;
118
+ }
119
+ c.onDone(k);
120
+ return;
121
+ } catch {
122
+ }
123
+ }
124
+ }
125
+ c.onDone(k);
126
+ } catch (C) {
127
+ if ((A = c.signal) != null && A.aborted) return;
128
+ throw c.onError(C instanceof Error ? C : new Error(String(C))), C;
129
+ }
130
+ }
131
+ async function ne(a, n) {
132
+ const l = await a.text();
133
+ if (!a.ok)
134
+ throw new Error(`${n}失败 HTTP ${a.status}${l ? `: ${l.slice(0, 120)}` : ""}`);
135
+ if (/<!doctype html/i.test(l.slice(0, 200)))
136
+ throw new Error("AK 接口落到主壳 SPA(无后端响应)");
137
+ try {
138
+ return JSON.parse(l);
139
+ } catch {
140
+ throw new Error(`${n}返回非 JSON:${l.slice(0, 120)}`);
141
+ }
142
+ }
143
+ function nt(a) {
144
+ const n = a.status === 1;
145
+ return {
146
+ id: Number(a.id),
147
+ akPrefix: a.access_key ?? "",
148
+ userId: a.owner_user_id ?? "",
149
+ userName: a.owner_user_name ?? "",
150
+ description: a.description || a.ak_name || "",
151
+ status: n ? "active" : "disabled",
152
+ active: n,
153
+ isDeleted: a.is_deleted ?? 0,
154
+ totalRequests: 0,
155
+ totalTokens: Number(a.total_tokens ?? 0),
156
+ tokenQuota: 0,
157
+ rateLimitRpm: 0,
158
+ defaultModel: null,
159
+ lastUsedAt: a.last_used_time ?? null,
160
+ createTime: (a.created_time ?? "").replace("T", " ").slice(0, 19),
161
+ updateTime: (a.updated_time ?? "").replace("T", " ").slice(0, 19),
162
+ secret: a.secret_key
163
+ };
164
+ }
165
+ async function Pe(a, n, l) {
166
+ const c = await fetch(`${ee}/api/ak/create`, {
167
+ method: "POST",
168
+ headers: te({ Accept: "application/json", "Content-Type": "application/json" }),
169
+ credentials: "include",
170
+ body: JSON.stringify({
171
+ akName: l || `AK-${n || a}`,
172
+ description: l,
173
+ akType: "PERSONAL",
174
+ ownerUserId: a,
175
+ ownerUserName: n
176
+ })
177
+ }), u = await ne(c, "创建 AK"), f = (u == null ? void 0 : u.data) ?? {}, y = f.accessKey ?? "", _ = f.secretKey ?? "";
178
+ return y && _ && ye(y, _), { apiKey: _, akPrefix: y, message: "AK 已创建,secretKey 仅创建时可见" };
179
+ }
180
+ async function ce(a) {
181
+ const n = await fetch(
182
+ `${ee}/api/ak/list`,
183
+ { headers: te({ Accept: "application/json" }), credentials: "include" }
184
+ ), l = await ne(n, "获取 AK 列表"), c = Array.isArray(l == null ? void 0 : l.data) ? l.data : [];
185
+ return (a ? c.filter((f) => (f.owner_user_id == null || f.owner_user_id === "" ? Ie : String(f.owner_user_id)) === String(a)) : c).filter((f) => (f.is_deleted ?? 0) === 0).map(nt);
186
+ }
187
+ async function st(a) {
188
+ const n = await fetch(`${ee}/api/ak/delete?id=${encodeURIComponent(String(a))}`, {
189
+ method: "POST",
190
+ headers: te({ Accept: "application/json" }),
191
+ credentials: "include"
192
+ });
193
+ await ne(n, "吊销 AK");
194
+ }
195
+ async function Ke(a) {
196
+ var C, T;
197
+ const n = await fetch(
198
+ `${ee}/api/admin/llm-call-monitor/stats?hours=168`,
199
+ { headers: te({ Accept: "application/json" }), credentials: "include" }
200
+ ), l = await ne(n, "获取调用统计"), u = ((l == null ? void 0 : l.data) ?? {}).summary ?? {};
201
+ let f = [];
202
+ try {
203
+ const p = await fetch(
204
+ `${ee}/api/admin/llm-call-monitor/recent?page=1&size=20`,
205
+ { headers: te({ Accept: "application/json" }), credentials: "include" }
206
+ ), i = await ne(p, "获取调用明细");
207
+ f = (Array.isArray((C = i == null ? void 0 : i.data) == null ? void 0 : C.records) ? i.data.records : []).map((m, B) => {
208
+ const I = Number(m.promptTokens ?? 0), G = Number(m.completionTokens ?? 0);
209
+ return {
210
+ id: Number(m.id ?? B),
211
+ apiKeyId: a,
212
+ protocol: "chat/completions",
213
+ model: String(m.model ?? ""),
214
+ stream: Number(m.stream ?? 0),
215
+ promptTokens: I,
216
+ completionTokens: G,
217
+ totalTokens: Number(m.totalTokens ?? I + G),
218
+ latencyMs: Number(m.durationMs ?? 0),
219
+ statusCode: m.success === !1 || m.success === 0 ? 500 : 200,
220
+ errorMsg: m.errorType ?? null,
221
+ createTime: String(m.createTime ?? "").replace("T", " ").slice(0, 19)
222
+ };
223
+ });
224
+ } catch {
225
+ }
226
+ const y = {}, _ = {};
227
+ for (const p of f) {
228
+ const i = y[T = p.model] || (y[T] = [0, 0, 0]);
229
+ i[0] += 1, i[1] += p.promptTokens, i[2] += p.completionTokens;
230
+ const g = (p.createTime || "").slice(0, 10);
231
+ if (g) {
232
+ const m = _[g] || (_[g] = [0, 0, 0]);
233
+ m[0] += 1, m[1] += p.promptTokens, m[2] += p.completionTokens;
234
+ }
235
+ }
236
+ const k = Number(u.totalTokens ?? 0), M = f.reduce((p, i) => p + i.totalTokens, 0), U = f.reduce((p, i) => p + i.promptTokens, 0), A = f.reduce((p, i) => p + i.completionTokens, 0);
237
+ return {
238
+ totalRequests: Number(u.totalCount ?? 0),
239
+ // 汇总口径优先用后端整窗合计(后端 selectStats 才有 token 合计),
240
+ // 明细只有最近一页 ⇒ 只在汇总缺失时用明细兜底。
241
+ totalPromptTokens: Number(u.totalPromptTokens ?? 0) || U,
242
+ totalCompletionTokens: Number(u.totalCompletionTokens ?? 0) || A,
243
+ totalTokens: k || M,
244
+ avgLatencyMs: Number(u.avgDurationMs ?? 0),
245
+ errorCount: Number(u.failCount ?? 0),
246
+ daily: _,
247
+ models: y,
248
+ recent: f
249
+ };
250
+ }
251
+ function ot() {
252
+ return typeof window < "u" ? `${window.location.origin}${ge}` : ge;
253
+ }
254
+ const _e = "ft_gateway_ak_cache";
255
+ function ye(a, n) {
256
+ try {
257
+ const l = JSON.parse(localStorage.getItem(_e) || "{}");
258
+ l[a] = n, localStorage.setItem(_e, JSON.stringify(l));
259
+ } catch {
260
+ }
261
+ }
262
+ function lt(a) {
263
+ try {
264
+ return JSON.parse(localStorage.getItem(_e) || "{}")[a] || null;
265
+ } catch {
266
+ return null;
267
+ }
268
+ }
269
+ async function rt() {
270
+ try {
271
+ const c = localStorage.getItem(re);
272
+ if (c) return c;
273
+ } catch {
274
+ }
275
+ const n = (await ce("").catch(() => [])).find((c) => c.active && c.secret);
276
+ if (n != null && n.secret) {
277
+ try {
278
+ localStorage.setItem(re, n.secret);
279
+ } catch {
280
+ }
281
+ return n.akPrefix && ye(n.akPrefix, n.secret), n.secret;
282
+ }
283
+ const l = await Pe(
284
+ "system-default",
285
+ "系统默认",
286
+ "智能工作台默认AK(自动创建)"
287
+ );
288
+ if (!l.apiKey)
289
+ throw new Error("AK 创建成功但未返回 secretKey");
290
+ try {
291
+ localStorage.setItem(re, l.apiKey);
292
+ } catch {
293
+ }
294
+ return l.apiKey;
295
+ }
296
+ function Ee() {
297
+ try {
298
+ localStorage.removeItem(re);
299
+ } catch {
300
+ }
301
+ }
302
+ const ct = "_container_18ocl_7", it = "_sidebar_18ocl_16", dt = "_menuList_18ocl_26", mt = "_menuItem_18ocl_35", ut = "_menuItemActive_18ocl_53", ht = "_menuIcon_18ocl_59", pt = "_menuLabel_18ocl_64", kt = "_panelArea_18ocl_70", gt = "_modelMgmtHeader_18ocl_82", _t = "_modelMgmtTitle_18ocl_86", ft = "_modelMgmtSubtitle_18ocl_93", yt = "_modelGrid_18ocl_99", Ct = "_modelCard_18ocl_105", Nt = "_modelCardSelected_18ocl_134", vt = "_modelCardHeader_18ocl_139", Tt = "_modelIconWrap_18ocl_146", St = "_modelCardInfo_18ocl_159", wt = "_modelName_18ocl_164", At = "_modelTags_18ocl_173", Bt = "_modelEndpoint_18ocl_189", xt = "_modelCardFooter_18ocl_198", Mt = "_modelCheckbox_18ocl_206", bt = "_modelActionBar_18ocl_213", It = "_modelSelectionCount_18ocl_227", Pt = "_chatContainer_18ocl_236", Kt = "_chatHeader_18ocl_243", Et = "_chatTitle_18ocl_251", $t = "_chatPanels_18ocl_258", Lt = "_chatPanel_18ocl_258", Ot = "_chatPanelHeader_18ocl_285", Ut = "_chatPanelClose_18ocl_295", Rt = "_chatPanelBody_18ocl_307", Dt = "_chatMsgUser_18ocl_316", Ht = "_chatMsgAI_18ocl_328", zt = "_chatMsgError_18ocl_341", Ft = "_chatStreamingCursor_18ocl_351", jt = "_chatUsageBar_18ocl_370", qt = "_chatThinkBlock_18ocl_380", Gt = "_chatInputBar_18ocl_429", Jt = "_chatInput_18ocl_429", Wt = "_addPanelBtn_18ocl_442", Qt = "_akContainer_18ocl_471", Vt = "_akIntegrationPanel_18ocl_477", Yt = "_akIntegrationTitle_18ocl_484", Xt = "_akIntegrationGrid_18ocl_491", Zt = "_akCodeBlock_18ocl_497", ea = "_akCodeLabel_18ocl_509", ta = "_akCard_18ocl_516", aa = "_akCardRow_18ocl_534", na = "_akTitle_18ocl_541", sa = "_akPrefixSmall_18ocl_551", oa = "_akStatus_18ocl_557", la = "_akStatusActive_18ocl_563", ra = "_akStatusRevoked_18ocl_569", ca = "_akCardActions_18ocl_575", ia = "_akCardRow2_18ocl_582", da = "_akMiniBar_18ocl_588", ma = "_akMiniBarFill_18ocl_597", ua = "_akUsageText_18ocl_604", ha = "_akMetaText_18ocl_611", pa = "_akEmpty_18ocl_617", ka = "_akBaseUrlRow_18ocl_625", ga = "_akBaseUrlItem_18ocl_631", _a = "_akBaseUrlLabel_18ocl_641", fa = "_akBaseUrlValue_18ocl_647", ya = "_akCopyIcon_18ocl_657", Ca = "_usageDrawerContent_18ocl_671", Na = "_usageStatsGrid_18ocl_677", va = "_usageSection_18ocl_683", Ta = "_usageSectionTitle_18ocl_687", Sa = "_usageBarChart_18ocl_697", wa = "_usageBarCol_18ocl_706", Aa = "_usageBar_18ocl_697", Ba = "_usageBarLabel_18ocl_729", xa = "_modelBreakdown_18ocl_737", Ma = "_modelBreakdownRow_18ocl_743", ba = "_modelBreakdownName_18ocl_749", Ia = "_modelBreakdownBar_18ocl_759", Pa = "_modelBreakdownFill_18ocl_767", Ka = "_modelBreakdownCount_18ocl_774", Ea = "_usageEmpty_18ocl_781", t = {
303
+ container: ct,
304
+ sidebar: it,
305
+ menuList: dt,
306
+ menuItem: mt,
307
+ menuItemActive: ut,
308
+ menuIcon: ht,
309
+ menuLabel: pt,
310
+ panelArea: kt,
311
+ modelMgmtHeader: gt,
312
+ modelMgmtTitle: _t,
313
+ modelMgmtSubtitle: ft,
314
+ modelGrid: yt,
315
+ modelCard: Ct,
316
+ modelCardSelected: Nt,
317
+ modelCardHeader: vt,
318
+ modelIconWrap: Tt,
319
+ modelCardInfo: St,
320
+ modelName: wt,
321
+ modelTags: At,
322
+ modelEndpoint: Bt,
323
+ modelCardFooter: xt,
324
+ modelCheckbox: Mt,
325
+ modelActionBar: bt,
326
+ modelSelectionCount: It,
327
+ chatContainer: Pt,
328
+ chatHeader: Kt,
329
+ chatTitle: Et,
330
+ chatPanels: $t,
331
+ chatPanel: Lt,
332
+ chatPanelHeader: Ot,
333
+ chatPanelClose: Ut,
334
+ chatPanelBody: Rt,
335
+ chatMsgUser: Dt,
336
+ chatMsgAI: Ht,
337
+ chatMsgError: zt,
338
+ chatStreamingCursor: Ft,
339
+ chatUsageBar: jt,
340
+ chatThinkBlock: qt,
341
+ chatInputBar: Gt,
342
+ chatInput: Jt,
343
+ addPanelBtn: Wt,
344
+ akContainer: Qt,
345
+ akIntegrationPanel: Vt,
346
+ akIntegrationTitle: Yt,
347
+ akIntegrationGrid: Xt,
348
+ akCodeBlock: Zt,
349
+ akCodeLabel: ea,
350
+ akCard: ta,
351
+ akCardRow: aa,
352
+ akTitle: na,
353
+ akPrefixSmall: sa,
354
+ akStatus: oa,
355
+ akStatusActive: la,
356
+ akStatusRevoked: ra,
357
+ akCardActions: ca,
358
+ akCardRow2: ia,
359
+ akMiniBar: da,
360
+ akMiniBarFill: ma,
361
+ akUsageText: ua,
362
+ akMetaText: ha,
363
+ akEmpty: pa,
364
+ akBaseUrlRow: ka,
365
+ akBaseUrlItem: ga,
366
+ akBaseUrlLabel: _a,
367
+ akBaseUrlValue: fa,
368
+ akCopyIcon: ya,
369
+ usageDrawerContent: Ca,
370
+ usageStatsGrid: Na,
371
+ usageSection: va,
372
+ usageSectionTitle: Ta,
373
+ usageBarChart: Sa,
374
+ usageBarCol: wa,
375
+ usageBar: Aa,
376
+ usageBarLabel: Ba,
377
+ modelBreakdown: xa,
378
+ modelBreakdownRow: Ma,
379
+ modelBreakdownName: ba,
380
+ modelBreakdownBar: Ia,
381
+ modelBreakdownFill: Pa,
382
+ modelBreakdownCount: Ka,
383
+ usageEmpty: Ea
384
+ };
385
+ function Ne(a) {
386
+ return a >= 1e6 ? `${(a / 1e6).toFixed(1)}M` : a >= 1e3 ? `${(a / 1e3).toFixed(1)}K` : `${a}`;
387
+ }
388
+ function $a(a, n) {
389
+ return `# OpenAI 兼容
390
+ curl -X POST ${a}/v1/chat/completions \\
391
+ -H "Content-Type: application/json" \\
392
+ -H "Authorization: Bearer ft-xxx" \\
393
+ -d '{
394
+ "model": "${n}",
395
+ "messages": [{"role":"user","content":"你好"}],
396
+ "stream": true
397
+ }'`;
398
+ }
399
+ function La(a, n) {
400
+ return `# Anthropic 兼容
401
+ curl -X POST ${a}/v1/messages \\
402
+ -H "Content-Type: application/json" \\
403
+ -H "x-api-key: ft-xxx" \\
404
+ -d '{
405
+ "model": "${n}",
406
+ "messages": [{"role":"user","content":"你好"}]
407
+ }'`;
408
+ }
409
+ function Oa() {
410
+ const [a, n] = N("personal"), [l, c] = N([]), [u, f] = N([]), [y, _] = N(!0), [k, M] = N(!1), [U, A] = N(!1), [C, T] = N(""), [p, i] = N({ open: !1 }), [g, m] = N(null), [B, I] = N(null), [G, Q] = N(!1), z = be((d) => d.currentUser), r = String((z == null ? void 0 : z.id) ?? ""), P = (z == null ? void 0 : z.username) ?? "", [R, o] = N(""), h = ot(), [w, K] = N("<model-name>");
411
+ X(() => {
412
+ let d = !1;
413
+ return fe().then((S) => {
414
+ !d && S.length > 0 && K(S[0].modelName);
415
+ }).catch(() => {
416
+ }), () => {
417
+ d = !0;
418
+ };
419
+ }, []);
420
+ const x = j(async () => {
421
+ _(!0);
422
+ try {
423
+ const d = r ? await ce(r).catch(() => []) : [], [S] = await Promise.all([
424
+ ce("system-default").catch(() => [])
425
+ ]);
426
+ c(S), f(d);
427
+ } finally {
428
+ _(!1);
429
+ }
430
+ }, [r]);
431
+ X(() => {
432
+ x();
433
+ }, [x]);
434
+ const b = () => {
435
+ T(""), A(!0);
436
+ }, q = async () => {
437
+ if (!C.trim()) {
438
+ J.warning("请输入 AK 名称");
439
+ return;
440
+ }
441
+ if (!r) {
442
+ J.warning("登录态不可用,无法生成 AK");
443
+ return;
444
+ }
445
+ M(!0);
446
+ try {
447
+ const d = await Pe(r, P, C.trim());
448
+ ye(d.akPrefix, d.apiKey), A(!1), i({
449
+ open: !0,
450
+ apiKey: d.apiKey,
451
+ akPrefix: d.akPrefix
452
+ }), x();
453
+ } catch (d) {
454
+ J.error(d instanceof Error ? d.message : "创建 AK 失败");
455
+ } finally {
456
+ M(!1);
457
+ }
458
+ }, ie = (d) => {
459
+ he.confirm({
460
+ title: "确认吊销此 AK?",
461
+ content: "吊销后此 AK 将立即失效,无法恢复。",
462
+ okText: "确认吊销",
463
+ okType: "danger",
464
+ cancelText: "取消",
465
+ onOk: async () => {
466
+ try {
467
+ await st(d), J.success("AK 已吊销"), x(), Ee();
468
+ } catch (S) {
469
+ J.error(S instanceof Error ? S.message : "吊销失败");
470
+ }
471
+ }
472
+ });
473
+ }, $ = (d) => {
474
+ navigator.clipboard.writeText(d).then(() => J.success("已复制到剪贴板")).catch(() => J.warning("复制失败,请手动复制"));
475
+ }, F = (d) => {
476
+ const S = lt(d.akPrefix);
477
+ S ? $(S) : ($(d.akPrefix), J.info("完整 AK 未在本地缓存(可能在本设备外创建),已复制前缀"));
478
+ }, se = async (d) => {
479
+ m(d), Q(!0), I(null);
480
+ try {
481
+ const S = await Ke(d.id);
482
+ I(S);
483
+ } catch (S) {
484
+ J.error(S instanceof Error ? S.message : "获取用量失败");
485
+ } finally {
486
+ Q(!1);
487
+ }
488
+ }, de = () => {
489
+ m(null), I(null);
490
+ }, $e = (d) => {
491
+ const S = Object.entries(d);
492
+ if (S.length === 0)
493
+ return /* @__PURE__ */ e("span", { className: t.usageEmpty, children: "暂无数据" });
494
+ const V = Math.max(...S.map(([, L]) => L[1] + L[2]), 1);
495
+ return /* @__PURE__ */ e("div", { className: t.usageBarChart, children: S.map(([L, D]) => {
496
+ const v = D[1] + D[2], me = v / V * 100;
497
+ return /* @__PURE__ */ s("div", { className: t.usageBarCol, children: [
498
+ /* @__PURE__ */ e(Y, { title: `${L}: ${D[0]}次 / ${v} tokens`, children: /* @__PURE__ */ e(
499
+ "div",
500
+ {
501
+ className: t.usageBar,
502
+ style: { height: `${Math.max(me, 2)}%` }
503
+ }
504
+ ) }),
505
+ /* @__PURE__ */ e("span", { className: t.usageBarLabel, children: L })
506
+ ] }, L);
507
+ }) });
508
+ }, Le = (d) => {
509
+ const S = Object.entries(d);
510
+ if (S.length === 0)
511
+ return /* @__PURE__ */ e("span", { className: t.usageEmpty, children: "暂无数据" });
512
+ const V = Math.max(...S.map(([, L]) => L[0]), 1);
513
+ return /* @__PURE__ */ e("div", { className: t.modelBreakdown, children: S.sort((L, D) => D[1][0] - L[1][0]).map(([L, D]) => /* @__PURE__ */ s("div", { className: t.modelBreakdownRow, children: [
514
+ /* @__PURE__ */ e("span", { className: t.modelBreakdownName, children: L }),
515
+ /* @__PURE__ */ e("div", { className: t.modelBreakdownBar, children: /* @__PURE__ */ e(
516
+ "div",
517
+ {
518
+ className: t.modelBreakdownFill,
519
+ style: { width: `${D[0] / V * 100}%` }
520
+ }
521
+ ) }),
522
+ /* @__PURE__ */ s("span", { className: t.modelBreakdownCount, children: [
523
+ D[0],
524
+ "次 / ",
525
+ D[1] + (D[2] || 0),
526
+ "tokens"
527
+ ] })
528
+ ] }, L)) });
529
+ }, Oe = [
530
+ {
531
+ title: "时间",
532
+ dataIndex: "createTime",
533
+ key: "createTime",
534
+ width: 160,
535
+ render: (d) => d ? new Date(d).toLocaleString("zh-CN") : "-"
536
+ },
537
+ { title: "模型", dataIndex: "model", key: "model", width: 140 },
538
+ {
539
+ title: "协议",
540
+ dataIndex: "protocol",
541
+ key: "protocol",
542
+ width: 90,
543
+ render: (d) => /* @__PURE__ */ e(W, { children: d })
544
+ },
545
+ {
546
+ title: "输入",
547
+ dataIndex: "promptTokens",
548
+ key: "promptTokens",
549
+ width: 70
550
+ },
551
+ {
552
+ title: "输出",
553
+ dataIndex: "completionTokens",
554
+ key: "completionTokens",
555
+ width: 70
556
+ },
557
+ {
558
+ title: "总Token",
559
+ dataIndex: "totalTokens",
560
+ key: "totalTokens",
561
+ width: 80
562
+ },
563
+ {
564
+ title: "耗时",
565
+ dataIndex: "latencyMs",
566
+ key: "latencyMs",
567
+ width: 70,
568
+ render: (d) => d ? `${d}ms` : "-"
569
+ },
570
+ {
571
+ title: "状态",
572
+ dataIndex: "statusCode",
573
+ key: "statusCode",
574
+ width: 60,
575
+ render: (d) => d ? /* @__PURE__ */ e(W, { color: d < 400 ? "green" : "red", children: d }) : "-"
576
+ }
577
+ ], Ce = (d, S) => {
578
+ const V = Array.isArray(d) ? d : [], L = R.trim().toLowerCase(), D = L ? V.filter(
579
+ (v) => `${v.description || ""} ${v.akPrefix || ""} ${v.defaultModel || ""}`.toLowerCase().includes(L)
580
+ ) : V;
581
+ return y ? /* @__PURE__ */ e("div", { style: { textAlign: "center", padding: 40 }, children: /* @__PURE__ */ e(Z, { tip: "加载中..." }) }) : V.length === 0 ? /* @__PURE__ */ e("div", { className: t.akEmpty, children: S ? "暂无应用 AK" : "暂无个人 AK,点击上方按钮生成" }) : D.length === 0 ? /* @__PURE__ */ e("div", { className: t.akEmpty, children: "无匹配 AK" }) : /* @__PURE__ */ e("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: D.map((v) => /* @__PURE__ */ s(
582
+ "div",
583
+ {
584
+ className: t.akCard,
585
+ onClick: () => se(v),
586
+ children: [
587
+ /* @__PURE__ */ s("div", { className: t.akCardRow, children: [
588
+ /* @__PURE__ */ e("span", { className: t.akTitle, children: v.description || v.akPrefix.replace("...", "**") }),
589
+ /* @__PURE__ */ e("code", { className: t.akPrefixSmall, children: v.akPrefix.replace("...", "**") }),
590
+ /* @__PURE__ */ e(
591
+ "span",
592
+ {
593
+ className: `${t.akStatus} ${v.active ? t.akStatusActive : t.akStatusRevoked}`,
594
+ children: v.active ? "活跃" : "已吊销"
595
+ }
596
+ ),
597
+ v.defaultModel && /* @__PURE__ */ s(W, { style: { fontSize: 11 }, children: [
598
+ "默认: ",
599
+ v.defaultModel
600
+ ] }),
601
+ /* @__PURE__ */ s(
602
+ "div",
603
+ {
604
+ className: t.akCardActions,
605
+ onClick: (me) => me.stopPropagation(),
606
+ children: [
607
+ /* @__PURE__ */ e(Y, { title: "复制完整 AK", children: /* @__PURE__ */ e(
608
+ H,
609
+ {
610
+ size: "small",
611
+ icon: /* @__PURE__ */ e(oe, {}),
612
+ onClick: () => F(v),
613
+ children: "复制"
614
+ }
615
+ ) }),
616
+ !S && v.active && /* @__PURE__ */ e(
617
+ H,
618
+ {
619
+ size: "small",
620
+ danger: !0,
621
+ icon: /* @__PURE__ */ e(Ue, {}),
622
+ onClick: () => ie(v.id),
623
+ children: "吊销"
624
+ }
625
+ )
626
+ ]
627
+ }
628
+ )
629
+ ] }),
630
+ /* @__PURE__ */ s("div", { className: t.akCardRow2, children: [
631
+ v.tokenQuota > 0 && /* @__PURE__ */ e("div", { className: t.akMiniBar, children: /* @__PURE__ */ e(
632
+ "div",
633
+ {
634
+ className: t.akMiniBarFill,
635
+ style: {
636
+ width: `${Math.min(
637
+ (v.totalTokens || 0) / v.tokenQuota * 100,
638
+ 100
639
+ )}%`
640
+ }
641
+ }
642
+ ) }),
643
+ /* @__PURE__ */ s("span", { className: t.akUsageText, children: [
644
+ Ne(v.totalTokens || 0),
645
+ v.tokenQuota > 0 ? ` / ${Ne(v.tokenQuota)}` : " tokens"
646
+ ] }),
647
+ /* @__PURE__ */ e("span", { className: t.akMetaText, children: v.lastUsedAt ? `最近使用 ${v.lastUsedAt}` : "尚未使用" }),
648
+ /* @__PURE__ */ e("span", { className: t.akMetaText, children: new Date(v.createTime).toLocaleDateString("zh-CN") })
649
+ ] })
650
+ ]
651
+ },
652
+ v.id
653
+ )) });
654
+ };
655
+ return /* @__PURE__ */ s("div", { className: t.akContainer, children: [
656
+ /* @__PURE__ */ s("div", { className: t.akIntegrationPanel, children: [
657
+ /* @__PURE__ */ e("h4", { className: t.akIntegrationTitle, children: "协议接入地址" }),
658
+ /* @__PURE__ */ s("div", { className: t.akBaseUrlRow, children: [
659
+ /* @__PURE__ */ s("div", { className: t.akBaseUrlItem, children: [
660
+ /* @__PURE__ */ e("span", { className: t.akBaseUrlLabel, children: "OpenAI 兼容" }),
661
+ /* @__PURE__ */ e("code", { className: t.akBaseUrlValue, children: h }),
662
+ /* @__PURE__ */ e(Y, { title: "复制 Base URL", children: /* @__PURE__ */ e(
663
+ oe,
664
+ {
665
+ className: t.akCopyIcon,
666
+ onClick: () => $(h)
667
+ }
668
+ ) })
669
+ ] }),
670
+ /* @__PURE__ */ s("div", { className: t.akBaseUrlItem, children: [
671
+ /* @__PURE__ */ e("span", { className: t.akBaseUrlLabel, children: "Anthropic 兼容" }),
672
+ /* @__PURE__ */ e("code", { className: t.akBaseUrlValue, children: h }),
673
+ /* @__PURE__ */ e(Y, { title: "复制 Base URL", children: /* @__PURE__ */ e(
674
+ oe,
675
+ {
676
+ className: t.akCopyIcon,
677
+ onClick: () => $(h)
678
+ }
679
+ ) })
680
+ ] })
681
+ ] }),
682
+ /* @__PURE__ */ s("div", { className: t.akIntegrationGrid, children: [
683
+ /* @__PURE__ */ s("div", { children: [
684
+ /* @__PURE__ */ e("p", { className: t.akCodeLabel, children: "OpenAI 兼容 — curl 示例" }),
685
+ /* @__PURE__ */ e("pre", { className: t.akCodeBlock, children: $a(h, w) })
686
+ ] }),
687
+ /* @__PURE__ */ s("div", { children: [
688
+ /* @__PURE__ */ e("p", { className: t.akCodeLabel, children: "Anthropic 兼容 — curl 示例" }),
689
+ /* @__PURE__ */ e("pre", { className: t.akCodeBlock, children: La(h, w) })
690
+ ] })
691
+ ] })
692
+ ] }),
693
+ /* @__PURE__ */ s("div", { children: [
694
+ /* @__PURE__ */ s(
695
+ "div",
696
+ {
697
+ style: {
698
+ display: "flex",
699
+ justifyContent: "space-between",
700
+ alignItems: "center",
701
+ marginBottom: 12
702
+ },
703
+ children: [
704
+ /* @__PURE__ */ e(
705
+ Be,
706
+ {
707
+ activeKey: a,
708
+ onChange: (d) => n(d),
709
+ items: [
710
+ { key: "app", label: "应用 AK" },
711
+ { key: "personal", label: "个人 AK" }
712
+ ],
713
+ style: { flex: 1 }
714
+ }
715
+ ),
716
+ /* @__PURE__ */ s("div", { style: { display: "flex", gap: 8 }, children: [
717
+ /* @__PURE__ */ e(
718
+ ke.Search,
719
+ {
720
+ allowClear: !0,
721
+ placeholder: "按名称 / 前缀过滤",
722
+ style: { width: 200 },
723
+ onChange: (d) => o(d.target.value)
724
+ }
725
+ ),
726
+ /* @__PURE__ */ e(H, { icon: /* @__PURE__ */ e(Te, {}), onClick: x, size: "small", children: "刷新" }),
727
+ a === "personal" && /* @__PURE__ */ e(
728
+ H,
729
+ {
730
+ type: "primary",
731
+ icon: /* @__PURE__ */ e(Se, {}),
732
+ onClick: b,
733
+ loading: k,
734
+ children: "生成 AK"
735
+ }
736
+ )
737
+ ] })
738
+ ]
739
+ }
740
+ ),
741
+ a === "app" ? Ce(l, !0) : Ce(u, !1)
742
+ ] }),
743
+ /* @__PURE__ */ s(
744
+ he,
745
+ {
746
+ open: U,
747
+ title: "生成新 AK",
748
+ onCancel: () => A(!1),
749
+ onOk: q,
750
+ okText: "确认生成",
751
+ cancelText: "取消",
752
+ confirmLoading: k,
753
+ children: [
754
+ /* @__PURE__ */ e(
755
+ "div",
756
+ {
757
+ style: {
758
+ marginBottom: 8,
759
+ color: "var(--text-secondary)",
760
+ fontSize: 13
761
+ },
762
+ children: "请输入 AK 名称(用于标识此密钥的用途)"
763
+ }
764
+ ),
765
+ /* @__PURE__ */ e(
766
+ ke,
767
+ {
768
+ placeholder: "例如:测试用 AK、生产网关 AK",
769
+ value: C,
770
+ onChange: (d) => T(d.target.value),
771
+ onPressEnter: q,
772
+ maxLength: 50,
773
+ autoFocus: !0
774
+ }
775
+ )
776
+ ]
777
+ }
778
+ ),
779
+ /* @__PURE__ */ s(
780
+ he,
781
+ {
782
+ open: p.open,
783
+ title: "AK 创建成功",
784
+ onCancel: () => i({ open: !1 }),
785
+ footer: [
786
+ /* @__PURE__ */ e(
787
+ H,
788
+ {
789
+ icon: /* @__PURE__ */ e(oe, {}),
790
+ onClick: () => p.apiKey && $(p.apiKey),
791
+ children: "复制 AK"
792
+ },
793
+ "copy"
794
+ ),
795
+ /* @__PURE__ */ e(
796
+ H,
797
+ {
798
+ type: "primary",
799
+ onClick: () => i({ open: !1 }),
800
+ children: "我已保存"
801
+ },
802
+ "close"
803
+ )
804
+ ],
805
+ children: [
806
+ /* @__PURE__ */ e("div", { style: { marginBottom: 8, color: "#faad14", fontSize: 14 }, children: "请立即保存此 AK,关闭后将无法再次查看完整密钥。" }),
807
+ /* @__PURE__ */ e(
808
+ "div",
809
+ {
810
+ style: {
811
+ background: "var(--bg-tertiary, #f6f8fa)",
812
+ padding: "12px 14px",
813
+ borderRadius: 8,
814
+ fontFamily: "SF Mono, Fira Code, monospace",
815
+ fontSize: 13,
816
+ wordBreak: "break-all",
817
+ userSelect: "all"
818
+ },
819
+ children: p.apiKey
820
+ }
821
+ ),
822
+ /* @__PURE__ */ s("div", { style: { marginTop: 8, fontSize: 12, color: "var(--text-muted)" }, children: [
823
+ "前缀: ",
824
+ p.akPrefix
825
+ ] })
826
+ ]
827
+ }
828
+ ),
829
+ /* @__PURE__ */ e(
830
+ xe,
831
+ {
832
+ title: g ? /* @__PURE__ */ s("span", { children: [
833
+ "AK 详情 — ",
834
+ /* @__PURE__ */ e("code", { children: g.akPrefix })
835
+ ] }) : "AK 详情",
836
+ open: !!g,
837
+ onClose: de,
838
+ size: "large",
839
+ children: G ? /* @__PURE__ */ e("div", { style: { textAlign: "center", padding: 60 }, children: /* @__PURE__ */ e(Z, { tip: "加载用量数据..." }) }) : B ? /* @__PURE__ */ s("div", { className: t.usageDrawerContent, children: [
840
+ /* @__PURE__ */ e("div", { style: { fontSize: 12, color: "#8c8c8c", marginBottom: 12 }, children: "以下为网关全局调用统计(近 7 天窗口), 监控侧不按 AK 留存;该 AK 自身的累计消耗见下方「本 AK 累计 Token」。" }),
841
+ /* @__PURE__ */ s("div", { className: t.usageStatsGrid, children: [
842
+ /* @__PURE__ */ e(E, { title: "总请求数", value: B.totalRequests }),
843
+ /* @__PURE__ */ e(E, { title: "总 Token", value: B.totalTokens }),
844
+ /* @__PURE__ */ e(
845
+ E,
846
+ {
847
+ title: "输入 Token",
848
+ value: B.totalPromptTokens
849
+ }
850
+ ),
851
+ /* @__PURE__ */ e(
852
+ E,
853
+ {
854
+ title: "输出 Token",
855
+ value: B.totalCompletionTokens
856
+ }
857
+ ),
858
+ /* @__PURE__ */ e(
859
+ E,
860
+ {
861
+ title: "平均耗时",
862
+ value: B.avgLatencyMs,
863
+ suffix: "ms"
864
+ }
865
+ ),
866
+ /* @__PURE__ */ e(
867
+ E,
868
+ {
869
+ title: "错误数",
870
+ value: B.errorCount,
871
+ styles: {
872
+ content: {
873
+ color: B.errorCount > 0 ? "#ff4d4f" : void 0
874
+ }
875
+ }
876
+ }
877
+ ),
878
+ /* @__PURE__ */ e(
879
+ E,
880
+ {
881
+ title: "本 AK 累计 Token",
882
+ value: (g == null ? void 0 : g.totalTokens) ?? 0
883
+ }
884
+ )
885
+ ] }),
886
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
887
+ /* @__PURE__ */ e("h4", { className: t.usageSectionTitle, children: "每日调用曲线(按最近调用明细聚合)" }),
888
+ $e(B.daily)
889
+ ] }),
890
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
891
+ /* @__PURE__ */ e("h4", { className: t.usageSectionTitle, children: "模型用量分布" }),
892
+ Le(B.models)
893
+ ] }),
894
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
895
+ /* @__PURE__ */ e("h4", { className: t.usageSectionTitle, children: "最近调用记录" }),
896
+ /* @__PURE__ */ e(
897
+ Me,
898
+ {
899
+ columns: Oe,
900
+ dataSource: B.recent,
901
+ rowKey: "id",
902
+ size: "small",
903
+ pagination: {
904
+ pageSize: 10,
905
+ size: "small",
906
+ showSizeChanger: !0,
907
+ pageSizeOptions: ["10", "20", "50", "100"],
908
+ showTotal: (d) => `共 ${d} 条`
909
+ },
910
+ scroll: { x: 760 }
911
+ }
912
+ )
913
+ ] })
914
+ ] }) : /* @__PURE__ */ e("div", { className: t.usageEmpty, children: "暂无用量数据" })
915
+ }
916
+ )
917
+ ] });
918
+ }
919
+ function Ua(a) {
920
+ const n = [];
921
+ if (!a) return n;
922
+ const l = /<(think|thinking|reasoning)>([\s\S]*?)<\/\1>/gi;
923
+ let c = 0, u;
924
+ for (; (u = l.exec(a)) !== null; )
925
+ u.index > c && n.push({ type: "text", text: a.slice(c, u.index) }), n.push({ type: "think", text: u[2] }), c = u.index + u[0].length;
926
+ return c < a.length && n.push({ type: "text", text: a.slice(c) }), n;
927
+ }
928
+ const le = 4;
929
+ let Ra = 0;
930
+ function Da({ initialModels: a }) {
931
+ const [n, l] = N([]), [c, u] = N([]), [f, y] = N(!0), [_, k] = N(null), [M, U] = N(""), [A, C] = N(!1), T = ue(""), p = ue(/* @__PURE__ */ new Map()), i = ue(/* @__PURE__ */ new Map());
932
+ X(() => {
933
+ (async () => {
934
+ try {
935
+ const o = await fe();
936
+ u(o), y(!1);
937
+ const h = a.length > 0 ? a : o.slice(0, 1).map((w) => w.modelName);
938
+ l(h.slice(0, le).map((w) => pe(w)));
939
+ } catch (o) {
940
+ y(!1), k(o instanceof Error ? o.message : "模型列表加载失败");
941
+ }
942
+ })();
943
+ }, []), X(() => {
944
+ if (a.length > 0 && c.length > 0) {
945
+ const o = a.slice(0, le).map((h) => pe(h));
946
+ l(o);
947
+ }
948
+ }, [a.join(",")]);
949
+ const g = j((o) => {
950
+ const h = i.current.get(o);
951
+ h && (h.scrollTop = h.scrollHeight);
952
+ }, []), m = j(
953
+ (o, h) => {
954
+ l((w) => w.map((K) => K.id === o ? h(K) : K));
955
+ },
956
+ []
957
+ ), B = j(async () => {
958
+ if (T.current) return T.current;
959
+ const o = await rt();
960
+ return T.current = o, o;
961
+ }, []), I = j(async () => {
962
+ const o = M.trim();
963
+ if (!o || A) return;
964
+ let h;
965
+ try {
966
+ h = await B();
967
+ } catch {
968
+ return;
969
+ }
970
+ U(""), C(!0);
971
+ const w = n.map((b) => ({
972
+ ...b,
973
+ messages: [
974
+ ...b.messages,
975
+ { role: "user", content: o },
976
+ { role: "assistant", content: "" }
977
+ ],
978
+ streamingContent: "",
979
+ isStreaming: !0,
980
+ error: null,
981
+ usage: null
982
+ }));
983
+ l(w);
984
+ const K = w;
985
+ K.forEach((b) => {
986
+ const q = new AbortController();
987
+ p.current.set(b.id, q);
988
+ const ie = b.messages.slice(0, -1);
989
+ at(h, b.model, ie, {
990
+ onDelta: ($) => {
991
+ m(b.id, (F) => ({
992
+ ...F,
993
+ streamingContent: F.streamingContent + $,
994
+ messages: F.messages.map(
995
+ (se, de) => de === F.messages.length - 1 ? { ...se, content: F.streamingContent + $ } : se
996
+ )
997
+ })), g(b.id);
998
+ },
999
+ onDone: ($) => {
1000
+ m(b.id, (F) => ({
1001
+ ...F,
1002
+ isStreaming: !1,
1003
+ usage: $ ? {
1004
+ promptTokens: $.promptTokens,
1005
+ completionTokens: $.completionTokens,
1006
+ totalTokens: $.totalTokens
1007
+ } : null
1008
+ })), p.current.delete(b.id);
1009
+ },
1010
+ onError: ($) => {
1011
+ ($.message.includes("401") || $.message.includes("API key")) && (Ee(), T.current = ""), m(b.id, (F) => ({
1012
+ ...F,
1013
+ isStreaming: !1,
1014
+ error: $.message
1015
+ })), p.current.delete(b.id);
1016
+ },
1017
+ signal: q.signal
1018
+ }).catch(() => {
1019
+ });
1020
+ });
1021
+ const x = setInterval(() => {
1022
+ K.every(
1023
+ (q) => !p.current.has(q.id)
1024
+ ) && (clearInterval(x), C(!1));
1025
+ }, 200);
1026
+ setTimeout(() => {
1027
+ clearInterval(x), C(!1);
1028
+ }, 300 * 1e3);
1029
+ }, [M, A, n, B, m, g]), G = j(() => {
1030
+ p.current.forEach((o) => o.abort()), p.current.clear(), l((o) => o.map((h) => ({ ...h, isStreaming: !1 }))), C(!1);
1031
+ }, []), Q = j(() => {
1032
+ var h;
1033
+ if (n.length >= le) return;
1034
+ const o = (h = c.find((w) => !n.some((K) => K.model === w.modelName))) == null ? void 0 : h.modelName;
1035
+ o && l((w) => [...w, pe(o)]);
1036
+ }, [n, c]), z = j(() => {
1037
+ p.current.forEach((o) => o.abort()), p.current.clear(), l(
1038
+ (o) => o.map((h) => ({
1039
+ ...h,
1040
+ messages: [],
1041
+ streamingContent: "",
1042
+ isStreaming: !1,
1043
+ error: null,
1044
+ usage: null
1045
+ }))
1046
+ ), C(!1);
1047
+ }, [A, n]), r = j((o) => {
1048
+ const h = p.current.get(o);
1049
+ h && h.abort(), p.current.delete(o), l((w) => w.filter((K) => K.id !== o));
1050
+ }, []), P = j(
1051
+ (o, h) => {
1052
+ m(o, (w) => ({ ...w, model: h }));
1053
+ },
1054
+ [m]
1055
+ ), R = c.map((o) => ({
1056
+ label: o.modelName,
1057
+ value: o.modelName
1058
+ }));
1059
+ return f ? /* @__PURE__ */ e("div", { style: { textAlign: "center", padding: 60 }, children: /* @__PURE__ */ e(Z, { tip: "加载模型列表..." }) }) : _ ? /* @__PURE__ */ s("div", { className: t.chatContainer, children: [
1060
+ /* @__PURE__ */ e("div", { className: t.chatHeader, children: /* @__PURE__ */ e("h3", { className: t.chatTitle, children: "模型对话" }) }),
1061
+ /* @__PURE__ */ s("div", { className: t.akEmpty, children: [
1062
+ "模型列表加载失败:",
1063
+ _
1064
+ ] })
1065
+ ] }) : /* @__PURE__ */ s("div", { className: t.chatContainer, children: [
1066
+ /* @__PURE__ */ s("div", { className: t.chatHeader, children: [
1067
+ /* @__PURE__ */ s("h3", { className: t.chatTitle, children: [
1068
+ "模型对话",
1069
+ n.length > 1 && /* @__PURE__ */ s(W, { color: "blue", style: { marginLeft: 12, fontSize: 12 }, children: [
1070
+ n.length,
1071
+ " 个模型对比"
1072
+ ] })
1073
+ ] }),
1074
+ /* @__PURE__ */ e(
1075
+ H,
1076
+ {
1077
+ size: "small",
1078
+ icon: /* @__PURE__ */ e(Re, {}),
1079
+ onClick: z,
1080
+ disabled: A || n.every((o) => o.messages.length === 0),
1081
+ children: "清空重新来"
1082
+ }
1083
+ )
1084
+ ] }),
1085
+ /* @__PURE__ */ s("div", { className: t.chatPanels, children: [
1086
+ n.map((o) => /* @__PURE__ */ s("div", { className: t.chatPanel, children: [
1087
+ /* @__PURE__ */ s("div", { className: t.chatPanelHeader, children: [
1088
+ /* @__PURE__ */ e(
1089
+ Ve,
1090
+ {
1091
+ size: "small",
1092
+ value: o.model,
1093
+ onChange: (h) => P(o.id, h),
1094
+ options: R,
1095
+ style: { minWidth: 140, flex: 1 },
1096
+ showSearch: !0,
1097
+ optionFilterProp: "label"
1098
+ }
1099
+ ),
1100
+ n.length > 1 && /* @__PURE__ */ e(
1101
+ "span",
1102
+ {
1103
+ className: t.chatPanelClose,
1104
+ onClick: () => r(o.id),
1105
+ children: /* @__PURE__ */ e(De, {})
1106
+ }
1107
+ )
1108
+ ] }),
1109
+ /* @__PURE__ */ s(
1110
+ "div",
1111
+ {
1112
+ className: t.chatPanelBody,
1113
+ ref: (h) => {
1114
+ i.current.set(o.id, h);
1115
+ },
1116
+ children: [
1117
+ o.messages.map((h, w) => /* @__PURE__ */ s(
1118
+ "div",
1119
+ {
1120
+ className: h.role === "user" ? t.chatMsgUser : t.chatMsgAI,
1121
+ children: [
1122
+ h.role === "assistant" ? Ua(h.content).map(
1123
+ (K, x) => K.type === "think" ? /* @__PURE__ */ s(
1124
+ "details",
1125
+ {
1126
+ className: t.chatThinkBlock,
1127
+ children: [
1128
+ /* @__PURE__ */ e("summary", { children: "思考过程" }),
1129
+ /* @__PURE__ */ e("pre", { children: K.text })
1130
+ ]
1131
+ },
1132
+ x
1133
+ ) : /* @__PURE__ */ e("span", { style: { whiteSpace: "pre-wrap" }, children: K.text }, x)
1134
+ ) : /* @__PURE__ */ e("span", { style: { whiteSpace: "pre-wrap" }, children: h.content }),
1135
+ o.isStreaming && w === o.messages.length - 1 && h.role === "assistant" && /* @__PURE__ */ e("span", { className: t.chatStreamingCursor })
1136
+ ]
1137
+ },
1138
+ w
1139
+ )),
1140
+ o.error && /* @__PURE__ */ e("div", { className: t.chatMsgError, children: o.error }),
1141
+ o.usage && /* @__PURE__ */ s("div", { className: t.chatUsageBar, children: [
1142
+ /* @__PURE__ */ s("span", { children: [
1143
+ "输入: ",
1144
+ o.usage.promptTokens
1145
+ ] }),
1146
+ /* @__PURE__ */ s("span", { children: [
1147
+ "输出: ",
1148
+ o.usage.completionTokens
1149
+ ] })
1150
+ ] })
1151
+ ]
1152
+ }
1153
+ )
1154
+ ] }, o.id)),
1155
+ n.length < le && /* @__PURE__ */ e(Y, { title: "添加面板", children: /* @__PURE__ */ e("div", { className: t.addPanelBtn, onClick: Q, children: /* @__PURE__ */ e(Se, {}) }) })
1156
+ ] }),
1157
+ /* @__PURE__ */ s("div", { className: t.chatInputBar, children: [
1158
+ /* @__PURE__ */ e(
1159
+ ke.TextArea,
1160
+ {
1161
+ className: t.chatInput,
1162
+ value: M,
1163
+ onChange: (o) => U(o.target.value),
1164
+ placeholder: "输入消息,所有面板将同时收到并流式输出...",
1165
+ autoSize: { minRows: 1, maxRows: 4 },
1166
+ onPressEnter: (o) => {
1167
+ o.shiftKey || (o.preventDefault(), I());
1168
+ },
1169
+ disabled: A
1170
+ }
1171
+ ),
1172
+ A ? /* @__PURE__ */ e(H, { danger: !0, onClick: G, children: "停止" }) : /* @__PURE__ */ s(H, { type: "primary", onClick: I, disabled: !M.trim(), children: [
1173
+ /* @__PURE__ */ e(He, {}),
1174
+ " 发送"
1175
+ ] })
1176
+ ] })
1177
+ ] });
1178
+ }
1179
+ function pe(a) {
1180
+ return {
1181
+ id: ++Ra,
1182
+ model: a,
1183
+ messages: [],
1184
+ streamingContent: "",
1185
+ isStreaming: !1,
1186
+ error: null,
1187
+ usage: null
1188
+ };
1189
+ }
1190
+ function Ha({ onStartChat: a }) {
1191
+ const [n, l] = N([]), [c, u] = N(!0), [f, y] = N(null), [_, k] = N(/* @__PURE__ */ new Set()), M = () => {
1192
+ u(!0), y(null), fe().then((i) => {
1193
+ l(i), u(!1);
1194
+ }).catch((i) => {
1195
+ l([]), y(i instanceof Error ? i.message : "加载失败"), u(!1);
1196
+ });
1197
+ };
1198
+ X(() => {
1199
+ M();
1200
+ }, []);
1201
+ const U = (i) => {
1202
+ k((g) => {
1203
+ const m = new Set(g);
1204
+ return m.has(i) ? m.delete(i) : m.add(i), m;
1205
+ });
1206
+ }, A = Array.from(_), C = (i) => {
1207
+ a([i]);
1208
+ }, T = () => {
1209
+ A.length > 0 && a(A);
1210
+ }, p = (i) => {
1211
+ if (!i) return "default";
1212
+ const g = i.toLowerCase();
1213
+ return g.includes("aliyun") || g.includes("ali") ? "blue" : g.includes("zhipu") || g.includes("glm") ? "purple" : g.includes("moonshot") || g.includes("kimi") ? "cyan" : g.includes("minimax") ? "orange" : "default";
1214
+ };
1215
+ return c ? /* @__PURE__ */ e("div", { style: { textAlign: "center", padding: 60 }, children: /* @__PURE__ */ e(Z, { tip: "加载模型列表..." }) }) : f ? /* @__PURE__ */ s("div", { children: [
1216
+ /* @__PURE__ */ s("div", { className: t.modelMgmtHeader, children: [
1217
+ /* @__PURE__ */ e("h3", { className: t.modelMgmtTitle, children: "模型管理" }),
1218
+ /* @__PURE__ */ e("p", { className: t.modelMgmtSubtitle, children: "数据库管理的可用模型,可选择单个或多个模型发起对话对比" })
1219
+ ] }),
1220
+ /* @__PURE__ */ s("div", { className: t.akEmpty, children: [
1221
+ "模型列表加载失败:",
1222
+ f,
1223
+ /* @__PURE__ */ e("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ e(H, { type: "primary", onClick: M, children: "重试" }) })
1224
+ ] })
1225
+ ] }) : /* @__PURE__ */ s("div", { children: [
1226
+ /* @__PURE__ */ s("div", { className: t.modelMgmtHeader, children: [
1227
+ /* @__PURE__ */ e("h3", { className: t.modelMgmtTitle, children: "模型管理" }),
1228
+ /* @__PURE__ */ e("p", { className: t.modelMgmtSubtitle, children: "数据库管理的可用模型,可选择单个或多个模型发起对话对比" })
1229
+ ] }),
1230
+ n.length === 0 && /* @__PURE__ */ e("div", { className: t.akEmpty, children: "后端暂无启用模型(z_team_model_config 中 enable=1 的行),请先在数据库或网关配置中启用" }),
1231
+ /* @__PURE__ */ e("div", { className: t.modelGrid, children: n.map((i) => {
1232
+ const g = _.has(i.modelName);
1233
+ return /* @__PURE__ */ s(
1234
+ "div",
1235
+ {
1236
+ className: `${t.modelCard} ${g ? t.modelCardSelected : ""}`,
1237
+ onClick: () => U(i.modelName),
1238
+ children: [
1239
+ /* @__PURE__ */ e(
1240
+ Ye,
1241
+ {
1242
+ className: t.modelCheckbox,
1243
+ checked: g,
1244
+ onChange: (m) => {
1245
+ m.stopPropagation(), U(i.modelName);
1246
+ }
1247
+ }
1248
+ ),
1249
+ /* @__PURE__ */ s("div", { className: t.modelCardHeader, children: [
1250
+ /* @__PURE__ */ e("div", { className: t.modelIconWrap, children: /* @__PURE__ */ e(we, {}) }),
1251
+ /* @__PURE__ */ s("div", { className: t.modelCardInfo, children: [
1252
+ /* @__PURE__ */ e("h4", { className: t.modelName, children: i.modelName }),
1253
+ /* @__PURE__ */ s("div", { className: t.modelTags, children: [
1254
+ i.modelProvider && /* @__PURE__ */ e(
1255
+ W,
1256
+ {
1257
+ color: p(i.modelProvider),
1258
+ style: { fontSize: 11, margin: 0 },
1259
+ children: i.modelProvider
1260
+ }
1261
+ ),
1262
+ /* @__PURE__ */ e(W, { style: { fontSize: 11, margin: 0 }, children: i.apiType })
1263
+ ] })
1264
+ ] })
1265
+ ] }),
1266
+ /* @__PURE__ */ e("p", { className: t.modelEndpoint, children: i.endpoint }),
1267
+ /* @__PURE__ */ e("div", { className: t.modelCardFooter, children: /* @__PURE__ */ e(
1268
+ H,
1269
+ {
1270
+ type: "link",
1271
+ size: "small",
1272
+ onClick: (m) => {
1273
+ m.stopPropagation(), C(i.modelName);
1274
+ },
1275
+ children: "发起对话"
1276
+ }
1277
+ ) })
1278
+ ]
1279
+ },
1280
+ i.modelName
1281
+ );
1282
+ }) }),
1283
+ A.length > 0 && /* @__PURE__ */ s("div", { className: t.modelActionBar, children: [
1284
+ /* @__PURE__ */ s("span", { className: t.modelSelectionCount, children: [
1285
+ "已选择 ",
1286
+ A.length,
1287
+ " 个模型"
1288
+ ] }),
1289
+ /* @__PURE__ */ e(
1290
+ H,
1291
+ {
1292
+ type: "primary",
1293
+ onClick: T,
1294
+ disabled: A.length === 0,
1295
+ children: "批量对比"
1296
+ }
1297
+ )
1298
+ ] })
1299
+ ] });
1300
+ }
1301
+ const za = "_container_15pgq_5", Fa = "_page_15pgq_10", ja = "_kpiGrid_15pgq_16", qa = "_kpiCard_15pgq_22", Ga = "_sectionCard_15pgq_29", Ja = "_sectionHead_15pgq_36", Wa = "_sectionHint_15pgq_42", Qa = "_akList_15pgq_47", Va = "_errorState_15pgq_54", Ya = "_errorTitle_15pgq_66", Xa = "_errorDetail_15pgq_72", O = {
1302
+ container: za,
1303
+ page: Fa,
1304
+ kpiGrid: ja,
1305
+ kpiCard: qa,
1306
+ sectionCard: Ga,
1307
+ sectionHead: Ja,
1308
+ sectionHint: Wa,
1309
+ akList: Qa,
1310
+ errorState: Va,
1311
+ errorTitle: Ya,
1312
+ errorDetail: Xa
1313
+ }, Za = Qe(
1314
+ () => import("@yuku123/z-agent-component").then((a) => ({ default: a.AgentDashboard }))
1315
+ );
1316
+ function ae(a) {
1317
+ return a >= 1e6 ? `${(a / 1e6).toFixed(2)}M` : a >= 1e3 ? `${(a / 1e3).toFixed(1)}K` : String(a ?? 0);
1318
+ }
1319
+ function en({ daily: a }) {
1320
+ const n = Object.entries(a);
1321
+ if (n.length === 0) return /* @__PURE__ */ e("span", { className: t.usageEmpty, children: "暂无数据" });
1322
+ const l = Math.max(...n.map(([, c]) => c[1] + c[2]), 1);
1323
+ return /* @__PURE__ */ e("div", { className: t.usageBarChart, children: n.map(([c, u]) => {
1324
+ const f = u[1] + u[2];
1325
+ return /* @__PURE__ */ s("div", { className: t.usageBarCol, children: [
1326
+ /* @__PURE__ */ e(Y, { title: `${c}: ${u[0]}次 / ${f} tokens`, children: /* @__PURE__ */ e(
1327
+ "div",
1328
+ {
1329
+ className: t.usageBar,
1330
+ style: { height: `${Math.max(f / l * 100, 2)}%` }
1331
+ }
1332
+ ) }),
1333
+ /* @__PURE__ */ e("span", { className: t.usageBarLabel, children: c })
1334
+ ] }, c);
1335
+ }) });
1336
+ }
1337
+ function ve({ models: a }) {
1338
+ const n = Object.entries(a);
1339
+ if (n.length === 0) return /* @__PURE__ */ e("span", { className: t.usageEmpty, children: "暂无数据" });
1340
+ const l = Math.max(...n.map(([, c]) => c[0]), 1);
1341
+ return /* @__PURE__ */ e("div", { className: t.modelBreakdown, children: n.sort((c, u) => u[1][0] - c[1][0]).map(([c, u]) => /* @__PURE__ */ s("div", { className: t.modelBreakdownRow, children: [
1342
+ /* @__PURE__ */ e("span", { className: t.modelBreakdownName, children: c }),
1343
+ /* @__PURE__ */ e("div", { className: t.modelBreakdownBar, children: /* @__PURE__ */ e(
1344
+ "div",
1345
+ {
1346
+ className: t.modelBreakdownFill,
1347
+ style: { width: `${u[0] / l * 100}%` }
1348
+ }
1349
+ ) }),
1350
+ /* @__PURE__ */ s("span", { className: t.modelBreakdownCount, children: [
1351
+ u[0],
1352
+ "次 / ",
1353
+ ae(u[1] + (u[2] || 0)),
1354
+ "tokens"
1355
+ ] })
1356
+ ] }, c)) });
1357
+ }
1358
+ const tn = [
1359
+ {
1360
+ title: "时间",
1361
+ dataIndex: "createTime",
1362
+ key: "createTime",
1363
+ width: 160,
1364
+ render: (a) => a ? new Date(a).toLocaleString("zh-CN") : "-"
1365
+ },
1366
+ { title: "模型", dataIndex: "model", key: "model", width: 150 },
1367
+ { title: "协议", dataIndex: "protocol", key: "protocol", width: 90, render: (a) => /* @__PURE__ */ e(W, { children: a }) },
1368
+ { title: "输入", dataIndex: "promptTokens", key: "promptTokens", width: 70 },
1369
+ { title: "输出", dataIndex: "completionTokens", key: "completionTokens", width: 70 },
1370
+ { title: "总Token", dataIndex: "totalTokens", key: "totalTokens", width: 80 },
1371
+ { title: "耗时", dataIndex: "latencyMs", key: "latencyMs", width: 70, render: (a) => a ? `${a}ms` : "-" },
1372
+ {
1373
+ title: "状态",
1374
+ dataIndex: "statusCode",
1375
+ key: "statusCode",
1376
+ width: 60,
1377
+ render: (a) => a ? /* @__PURE__ */ e(W, { color: a < 400 ? "green" : "red", children: a }) : "-"
1378
+ }
1379
+ ];
1380
+ function an(a) {
1381
+ var n;
1382
+ return ((n = a == null ? void 0 : a.stats) == null ? void 0 : n.recent) ?? [];
1383
+ }
1384
+ function nn() {
1385
+ var g, m, B, I, G, Q, z;
1386
+ const [a, n] = N(!0), [l, c] = N(null), [u, f] = N([]), [y, _] = N(null), [k, M] = N(null), U = String(be((r) => {
1387
+ var P;
1388
+ return ((P = r.currentUser) == null ? void 0 : P.id) ?? "";
1389
+ })), A = Array.from(
1390
+ new Set([U, Ie].filter((r) => r !== ""))
1391
+ ), C = j(async () => {
1392
+ n(!0), c(null);
1393
+ try {
1394
+ const r = await Promise.allSettled(
1395
+ A.map((x) => ce(x))
1396
+ ), P = [], R = /* @__PURE__ */ new Set();
1397
+ let o = 0;
1398
+ for (const x of r)
1399
+ if (x.status === "fulfilled")
1400
+ for (const b of x.value) {
1401
+ const q = String(b.id ?? b.akPrefix ?? "");
1402
+ R.has(q) || (R.add(q), P.push(b));
1403
+ }
1404
+ else o += 1;
1405
+ if (o === r.length)
1406
+ throw new Error("网关不可达:无法获取 AK 列表");
1407
+ P.sort((x, b) => (x.id ?? 0) - (b.id ?? 0));
1408
+ let h = null, w = null;
1409
+ try {
1410
+ h = await Ke(0);
1411
+ } catch (x) {
1412
+ w = x instanceof Error ? x.message : "获取用量失败";
1413
+ }
1414
+ _(h);
1415
+ const K = P.map((x) => ({
1416
+ key: x,
1417
+ stats: h,
1418
+ statsError: w
1419
+ }));
1420
+ f(K);
1421
+ } catch (r) {
1422
+ c(r instanceof Error ? r.message : "加载失败");
1423
+ } finally {
1424
+ n(!1);
1425
+ }
1426
+ }, [A.join(",")]);
1427
+ X(() => {
1428
+ C();
1429
+ }, [C]);
1430
+ const T = Ae(() => {
1431
+ const r = y, P = {};
1432
+ for (const [R, o] of Object.entries((r == null ? void 0 : r.models) ?? {}))
1433
+ P[R] = [o[0] ?? 0, o[1] ?? 0, o[2] ?? 0];
1434
+ return {
1435
+ requests: (r == null ? void 0 : r.totalRequests) ?? 0,
1436
+ tokens: (r == null ? void 0 : r.totalTokens) ?? 0,
1437
+ avgLatency: (r == null ? void 0 : r.avgLatencyMs) ?? 0,
1438
+ errors: (r == null ? void 0 : r.errorCount) ?? 0,
1439
+ models: P
1440
+ };
1441
+ }, [y]), p = u.reduce((r, P) => r + (P.key.tokenQuota || 0), 0), i = () => a ? /* @__PURE__ */ e("div", { style: { textAlign: "center", padding: 60 }, children: /* @__PURE__ */ e(Z, { tip: "加载监控数据..." }) }) : l ? /* @__PURE__ */ s("div", { className: O.errorState, children: [
1442
+ /* @__PURE__ */ e("div", { className: O.errorTitle, children: "模型监控数据加载失败" }),
1443
+ /* @__PURE__ */ e("div", { className: O.errorDetail, children: l }),
1444
+ /* @__PURE__ */ e(H, { icon: /* @__PURE__ */ e(Te, {}), onClick: C, type: "primary", children: "重试" })
1445
+ ] }) : /* @__PURE__ */ s("div", { className: O.page, children: [
1446
+ /* @__PURE__ */ s("div", { className: O.kpiGrid, children: [
1447
+ /* @__PURE__ */ e("div", { className: O.kpiCard, children: /* @__PURE__ */ e(E, { title: "总请求(近7天)", value: T.requests }) }),
1448
+ /* @__PURE__ */ e("div", { className: O.kpiCard, children: /* @__PURE__ */ e(E, { title: "总 Tokens", value: ae(T.tokens) }) }),
1449
+ /* @__PURE__ */ e("div", { className: O.kpiCard, children: /* @__PURE__ */ e(E, { title: "平均延迟", value: T.avgLatency, suffix: "ms" }) }),
1450
+ /* @__PURE__ */ e("div", { className: O.kpiCard, children: /* @__PURE__ */ e(
1451
+ E,
1452
+ {
1453
+ title: "错误数",
1454
+ value: T.errors,
1455
+ valueStyle: T.errors > 0 ? { color: "#ff4d4f" } : void 0
1456
+ }
1457
+ ) })
1458
+ ] }),
1459
+ /* @__PURE__ */ s("div", { className: O.sectionCard, children: [
1460
+ /* @__PURE__ */ s("div", { className: O.sectionHead, children: [
1461
+ /* @__PURE__ */ e("span", { className: t.usageSectionTitle, children: "AK 用量" }),
1462
+ p > 0 && /* @__PURE__ */ s("span", { className: O.sectionHint, children: [
1463
+ "合计额度 ",
1464
+ ae(p),
1465
+ " tokens"
1466
+ ] })
1467
+ ] }),
1468
+ u.length === 0 ? /* @__PURE__ */ e("div", { className: t.akEmpty, children: "网关下暂无 AK" }) : /* @__PURE__ */ e("div", { className: O.akList, children: u.map((r) => {
1469
+ const P = r.key.totalTokens ?? 0, R = r.key.tokenQuota || 0, o = R > 0 ? Math.min(P / R * 100, 100) : 0;
1470
+ return /* @__PURE__ */ s(
1471
+ "div",
1472
+ {
1473
+ className: t.akCard,
1474
+ onClick: () => M(r),
1475
+ children: [
1476
+ /* @__PURE__ */ s("div", { className: t.akCardRow, children: [
1477
+ /* @__PURE__ */ e("span", { className: t.akTitle, children: r.key.description || r.key.userName || `AK #${r.key.id}` }),
1478
+ /* @__PURE__ */ e("span", { className: t.akPrefixSmall, children: r.key.akPrefix }),
1479
+ /* @__PURE__ */ e(
1480
+ "span",
1481
+ {
1482
+ className: `${t.akStatus} ${r.key.active ? t.akStatusActive : t.akStatusRevoked}`,
1483
+ children: r.key.active ? "启用" : "吊销"
1484
+ }
1485
+ ),
1486
+ /* @__PURE__ */ e("span", { className: t.akMetaText, children: r.key.userId === "system-default" ? "系统对话" : r.key.userId })
1487
+ ] }),
1488
+ /* @__PURE__ */ s("div", { className: t.akCardRow2, children: [
1489
+ /* @__PURE__ */ e("div", { className: t.akMiniBar, children: /* @__PURE__ */ e(
1490
+ "div",
1491
+ {
1492
+ className: t.akMiniBarFill,
1493
+ style: { width: `${o}%` }
1494
+ }
1495
+ ) }),
1496
+ /* @__PURE__ */ s("span", { className: t.akUsageText, children: [
1497
+ ae(P),
1498
+ R > 0 ? ` / ${ae(R)}` : "",
1499
+ " tokens"
1500
+ ] }),
1501
+ /* @__PURE__ */ e("span", { className: t.akMetaText, children: r.statsError ? r.statsError : r.key.lastUsedAt ? `最近使用 ${r.key.lastUsedAt}` : "尚未使用" })
1502
+ ] })
1503
+ ]
1504
+ },
1505
+ r.key.id
1506
+ );
1507
+ }) })
1508
+ ] }),
1509
+ /* @__PURE__ */ s("div", { className: O.sectionCard, children: [
1510
+ /* @__PURE__ */ e("span", { className: t.usageSectionTitle, children: "模型用量分布(网关全局)" }),
1511
+ /* @__PURE__ */ e(ve, { models: T.models })
1512
+ ] })
1513
+ ] });
1514
+ return /* @__PURE__ */ s("div", { className: O.container, children: [
1515
+ /* @__PURE__ */ s("div", { className: t.modelMgmtHeader, children: [
1516
+ /* @__PURE__ */ e("h2", { className: t.modelMgmtTitle, children: "模型监控" }),
1517
+ /* @__PURE__ */ e("p", { className: t.modelMgmtSubtitle, children: "大模型网关管控视图 — 网关全局聚合调用量、Tokens 与延迟(近 7 天)" })
1518
+ ] }),
1519
+ /* @__PURE__ */ e(
1520
+ Be,
1521
+ {
1522
+ defaultActiveKey: "usage",
1523
+ items: [
1524
+ { key: "usage", label: "模型用量", children: i() },
1525
+ {
1526
+ key: "sessions",
1527
+ label: "会话统计",
1528
+ children: /* @__PURE__ */ e(We, { fallback: /* @__PURE__ */ e(Z, { tip: "加载会话统计..." }), children: /* @__PURE__ */ e(Za, {}) })
1529
+ }
1530
+ ]
1531
+ }
1532
+ ),
1533
+ /* @__PURE__ */ e(
1534
+ xe,
1535
+ {
1536
+ title: k ? `AK 用量 — ${k.key.description || k.key.akPrefix}` : "",
1537
+ width: 860,
1538
+ open: !!k,
1539
+ onClose: () => M(null),
1540
+ destroyOnHidden: !0,
1541
+ children: k && /* @__PURE__ */ s("div", { className: t.usageDrawerContent, children: [
1542
+ /* @__PURE__ */ e("div", { style: { fontSize: 12, color: "#8c8c8c", marginBottom: 12 }, children: "调用监控是网关全局维度(不按 AK 留存),以下统计覆盖全部 AK; 该 AK 自身的累计消耗见「本 AK 累计 Token」。" }),
1543
+ /* @__PURE__ */ s("div", { className: t.usageStatsGrid, children: [
1544
+ /* @__PURE__ */ e(E, { title: "总请求", value: ((g = k.stats) == null ? void 0 : g.totalRequests) ?? 0 }),
1545
+ /* @__PURE__ */ e(E, { title: "总 Tokens", value: ((m = k.stats) == null ? void 0 : m.totalTokens) ?? 0 }),
1546
+ /* @__PURE__ */ e(E, { title: "平均延迟", value: ((B = k.stats) == null ? void 0 : B.avgLatencyMs) ?? 0, suffix: "ms" }),
1547
+ /* @__PURE__ */ e(E, { title: "输入 Tokens", value: ((I = k.stats) == null ? void 0 : I.totalPromptTokens) ?? 0 }),
1548
+ /* @__PURE__ */ e(E, { title: "输出 Tokens", value: ((G = k.stats) == null ? void 0 : G.totalCompletionTokens) ?? 0 }),
1549
+ /* @__PURE__ */ e(
1550
+ E,
1551
+ {
1552
+ title: "本 AK 累计 Token",
1553
+ value: k.key.totalTokens ?? 0
1554
+ }
1555
+ ),
1556
+ /* @__PURE__ */ e(
1557
+ E,
1558
+ {
1559
+ title: "错误数",
1560
+ value: ((Q = k.stats) == null ? void 0 : Q.errorCount) ?? 0,
1561
+ valueStyle: (((z = k.stats) == null ? void 0 : z.errorCount) ?? 0) > 0 ? { color: "#ff4d4f" } : void 0
1562
+ }
1563
+ )
1564
+ ] }),
1565
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
1566
+ /* @__PURE__ */ e("span", { className: t.usageSectionTitle, children: "每日用量(按最近调用明细聚合)" }),
1567
+ k.stats ? /* @__PURE__ */ e(en, { daily: k.stats.daily ?? {} }) : /* @__PURE__ */ e("span", { className: t.usageEmpty, children: k.statsError ?? "暂无数据" })
1568
+ ] }),
1569
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
1570
+ /* @__PURE__ */ e("span", { className: t.usageSectionTitle, children: "模型用量分布(按最近调用明细聚合)" }),
1571
+ k.stats ? /* @__PURE__ */ e(ve, { models: k.stats.models ?? {} }) : /* @__PURE__ */ e("span", { className: t.usageEmpty, children: k.statsError ?? "暂无数据" })
1572
+ ] }),
1573
+ /* @__PURE__ */ s("div", { className: t.usageSection, children: [
1574
+ /* @__PURE__ */ e("span", { className: t.usageSectionTitle, children: "最近调用" }),
1575
+ /* @__PURE__ */ e(
1576
+ Me,
1577
+ {
1578
+ size: "small",
1579
+ columns: tn,
1580
+ dataSource: an(k),
1581
+ rowKey: "id",
1582
+ pagination: {
1583
+ pageSize: 8,
1584
+ showSizeChanger: !0,
1585
+ pageSizeOptions: ["8", "20", "50", "100"],
1586
+ showTotal: (r) => `共 ${r} 条`
1587
+ }
1588
+ }
1589
+ )
1590
+ ] })
1591
+ ] })
1592
+ }
1593
+ )
1594
+ ] });
1595
+ }
1596
+ const sn = [
1597
+ { key: "model-management", label: "模型管理", icon: /* @__PURE__ */ e(ze, {}) },
1598
+ { key: "model-chat", label: "模型对话", icon: /* @__PURE__ */ e(Fe, {}) },
1599
+ { key: "ak-management", label: "AK 管理", icon: /* @__PURE__ */ e(je, {}) },
1600
+ { key: "agent-app", label: "Agent 应用", icon: /* @__PURE__ */ e(we, {}) },
1601
+ { key: "mcp-service", label: "MCP 服务", icon: /* @__PURE__ */ e(qe, {}) },
1602
+ { key: "skill-market", label: "技能市场", icon: /* @__PURE__ */ e(Ge, {}) },
1603
+ { key: "model-monitor", label: "模型监控", icon: /* @__PURE__ */ e(Je, {}) }
1604
+ ];
1605
+ function un() {
1606
+ const [a, n] = N("model-management"), [l, c] = N([]), u = (_) => {
1607
+ c(_), n("model-chat");
1608
+ }, f = Ae(() => sn, []), y = (_, k, M = !1) => /* @__PURE__ */ e(
1609
+ "div",
1610
+ {
1611
+ style: {
1612
+ display: a === _ ? M ? "flex" : "block" : "none",
1613
+ height: "100%",
1614
+ ...M ? { flexDirection: "column" } : {}
1615
+ },
1616
+ children: k
1617
+ }
1618
+ );
1619
+ return /* @__PURE__ */ s("div", { className: t.container, children: [
1620
+ /* @__PURE__ */ e("aside", { className: t.sidebar, children: /* @__PURE__ */ e("nav", { className: t.menuList, children: f.map((_) => /* @__PURE__ */ s(
1621
+ "div",
1622
+ {
1623
+ className: `${t.menuItem} ${a === _.key ? t.menuItemActive : ""}`,
1624
+ onClick: () => n(_.key),
1625
+ children: [
1626
+ /* @__PURE__ */ e("span", { className: t.menuIcon, children: _.icon }),
1627
+ /* @__PURE__ */ e("span", { className: t.menuLabel, children: _.label })
1628
+ ]
1629
+ },
1630
+ _.key
1631
+ )) }) }),
1632
+ /* @__PURE__ */ s("main", { className: t.panelArea, children: [
1633
+ y("model-management", /* @__PURE__ */ e(Ha, { onStartChat: u })),
1634
+ y("model-chat", /* @__PURE__ */ e(Da, { initialModels: l }), !0),
1635
+ y("ak-management", /* @__PURE__ */ e(Oa, {})),
1636
+ y("agent-app", /* @__PURE__ */ e(Xe, {})),
1637
+ y("mcp-service", /* @__PURE__ */ e(Ze, {})),
1638
+ y("skill-market", /* @__PURE__ */ e(et, {})),
1639
+ y("model-monitor", /* @__PURE__ */ e(nn, {}))
1640
+ ] })
1641
+ ] });
1642
+ }
1643
+ export {
1644
+ un as default
1645
+ };