@yuku123/z-team-component 0.2.32 → 0.2.36

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