@yuku123/z-team-component 0.2.80 → 0.2.83

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