@chenpu17/cc-gw 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/package.json +1 -1
- package/src/server/dist/index.js +201 -14
- package/src/web/dist/assets/{About-vzoNrrky.js → About-Cgfq_d7I.js} +1 -1
- package/src/web/dist/assets/{ApiKeys-siGZnxbR.js → ApiKeys-C4QbVKdv.js} +1 -1
- package/src/web/dist/assets/{Dashboard-C88n6cLG.js → Dashboard-28JGQst7.js} +1 -1
- package/src/web/dist/assets/{Help-mO3rJCfh.js → Help-BojpuZMh.js} +1 -1
- package/src/web/dist/assets/{Logs-VD_U4Flf.js → Logs-B1rVvkYR.js} +1 -1
- package/src/web/dist/assets/ModelManagement-DIMCLs1b.js +1 -0
- package/src/web/dist/assets/{Settings-COAQaOsg.js → Settings-CB4YZNh9.js} +1 -1
- package/src/web/dist/assets/{index-DJO5FEoj.js → index-B0rGDFRO.js} +1 -1
- package/src/web/dist/assets/{index-DTby9g2A.css → index-Gx2WWHJn.css} +1 -1
- package/src/web/dist/assets/{index-B-Zugt7w.js → index-wA9rsqII.js} +12 -12
- package/src/web/dist/assets/{useApiQuery-DwPXd5aD.js → useApiQuery-De0jYBDD.js} +1 -1
- package/src/web/dist/index.html +2 -2
- package/src/web/dist/assets/ModelManagement-BqF68byL.js +0 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ pnpm --filter @cc-gw/cli exec tsx index.ts start --daemon --port 4100
|
|
|
51
51
|
|
|
52
52
|
- **Dashboard**:展示请求量、Token 使用、缓存命中、各模型 TTFT(Time To First Token)/TPOT(Total Processing Time)、SQLite 数据库占用。
|
|
53
53
|
- **请求日志**:多条件筛选(时间、Provider、模型、状态),查看压缩日志详情,支持分页导出与清理。
|
|
54
|
-
- **模型管理**:维护 Provider 列表、预置模型、路由策略;一键测试连通性(发送诊断 PROMPT
|
|
54
|
+
- **模型管理**:维护 Provider 列表、预置模型、路由策略;一键测试连通性(发送诊断 PROMPT),支持保存并应用 Anthropic 路由模板,实现不同 Provider 方案的“一键切换”。
|
|
55
55
|
- **系统设置**:端口、日志保留策略、是否存储请求 payload、日志级别与访问日志开关、日志清理工具。
|
|
56
56
|
- **使用指南**:提供图文步骤、常见问题与排查提示,帮助团队成员快速熟悉配置流程。
|
|
57
57
|
|
|
@@ -83,7 +83,7 @@ UI 支持中英文、深色/浅色主题以及移动端响应式布局,提供
|
|
|
83
83
|
|
|
84
84
|
1. **双端点适配 / Dual Endpoint Support**:通过 `/anthropic` 与 `/openai` 端点,分别兼容 Claude Code 与 Codex 客户端。无需重启 cc-gw,即可在 Web UI 中为两个端点配置独立的默认模型与路由策略。
|
|
85
85
|
2. **日志追踪 / Request Auditing**:在“请求日志”页按端点、Provider、API Key 等维度筛选记录,可直接查看和复制完整的请求/响应 payload,辅助排查联调问题。
|
|
86
|
-
3. **模型切换 / Cross-Provider Routing**:利用“模型管理”页的路由映射,将 Claude Code 请求透明地转发到 GLM、Kimi K2、DeepSeek 等任意 OpenAI 兼容模型,实现一套 IDE
|
|
86
|
+
3. **模型切换 / Cross-Provider Routing**:利用“模型管理”页的路由映射,将 Claude Code 请求透明地转发到 GLM、Kimi K2、DeepSeek 等任意 OpenAI 兼容模型,实现一套 IDE 客户端、多家大模型的快速切换;对 Anthropic 端点可保存当前映射为模板(例如“fox”“glm”),后续一键切换整套路由。
|
|
87
87
|
4. **操作指引 / Built-in Guidance**:左侧“Help”导航提供分步配置、日常运维建议及 FAQ,可作为新人上手或问题排查的快速参考。
|
|
88
88
|
|
|
89
89
|
## 配置说明
|
|
@@ -139,6 +139,7 @@ UI 支持中英文、深色/浅色主题以及移动端响应式布局,提供
|
|
|
139
139
|
- `providers`:定义上游服务;`type` 支持 `openai | anthropic | kimi | deepseek | custom`。
|
|
140
140
|
- 模型标识使用 `providerId:modelId` 形式供路由引用。
|
|
141
141
|
- `modelRoutes`:将 Claude 发起的模型名映射到上游模型;未命中时使用 `defaults`。
|
|
142
|
+
- `routingPresets`:可选字段,保存多个 `anthropic`(或其他端点)路由模板,供 Web UI “一键切换”;每个模板仅包含 `name` 与 `modelRoutes`。
|
|
142
143
|
- `storePayloads`:是否在 SQLite 中压缩保存原始请求/响应(Brotli),关闭后仅保留元信息。
|
|
143
144
|
- `logLevel`:控制 Fastify/Pino 控制台日志级别(`fatal`/`error`/`warn`/`info`/`debug`/`trace`)。
|
|
144
145
|
- `providers[].authMode`:仅在 `type: "anthropic"` 时生效,可选 `apiKey`(默认,发送 `x-api-key`)或 `authToken`(发送 `Authorization: Bearer`)。配置 Claude Code 使用 `ANTHROPIC_AUTH_TOKEN` 时,请选择 `authToken` 并在 `apiKey` 输入框填入该值。
|
|
@@ -197,7 +198,7 @@ cc-gw is a local gateway tailored for Claude Code and similar Anthropic-compatib
|
|
|
197
198
|
| Feature | Details |
|
|
198
199
|
| ------- | ------- |
|
|
199
200
|
| Protocol adaptation | Converts Claude-style payloads into OpenAI-, Anthropic-, Kimi-, and DeepSeek-compatible requests while preserving tool calls and reasoning blocks. |
|
|
200
|
-
| Model routing | Maps incoming model IDs to configured upstream providers with fallbacks for long-context
|
|
201
|
+
| Model routing | Maps incoming model IDs to configured upstream providers with fallbacks for long-context/background tasks, plus Anthropic routing presets for one-click provider swaps. |
|
|
201
202
|
| Observability | Persists request logs, token usage (including cache hits), TTFT, TPOT, and daily aggregates via better-sqlite3 with Brotli-compressed payloads. |
|
|
202
203
|
| Web console | React + Vite UI with dashboards, filters, provider CRUD, bilingual copy, and responsive layout. |
|
|
203
204
|
| CLI daemon | `cc-gw` command wraps start/stop/restart/status, manages PID/log files, and scaffolds a default config on first launch. |
|
package/package.json
CHANGED
package/src/server/dist/index.js
CHANGED
|
@@ -138,6 +138,48 @@ function parseConfig(raw) {
|
|
|
138
138
|
data.endpointRouting = endpointRouting;
|
|
139
139
|
data.defaults = { ...endpointRouting.anthropic.defaults };
|
|
140
140
|
data.modelRoutes = { ...endpointRouting.anthropic.modelRoutes };
|
|
141
|
+
const rawPresets = data.routingPresets;
|
|
142
|
+
const routingPresets = {};
|
|
143
|
+
if (rawPresets && typeof rawPresets === "object") {
|
|
144
|
+
for (const endpoint of KNOWN_ENDPOINTS) {
|
|
145
|
+
const source = rawPresets[endpoint];
|
|
146
|
+
if (!Array.isArray(source))
|
|
147
|
+
continue;
|
|
148
|
+
const seen = /* @__PURE__ */ new Set();
|
|
149
|
+
const presets = [];
|
|
150
|
+
for (const item of source) {
|
|
151
|
+
if (!item || typeof item !== "object")
|
|
152
|
+
continue;
|
|
153
|
+
const rawName = item.name;
|
|
154
|
+
if (typeof rawName !== "string")
|
|
155
|
+
continue;
|
|
156
|
+
const name = rawName.trim();
|
|
157
|
+
if (!name)
|
|
158
|
+
continue;
|
|
159
|
+
const modelRoutes = {};
|
|
160
|
+
const rawRoutes = item.modelRoutes;
|
|
161
|
+
if (rawRoutes && typeof rawRoutes === "object") {
|
|
162
|
+
for (const [sourceModel, target] of Object.entries(rawRoutes)) {
|
|
163
|
+
if (typeof target === "string" && target.trim()) {
|
|
164
|
+
modelRoutes[sourceModel] = target;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const createdAtValue = Number(item.createdAt);
|
|
169
|
+
const createdAt = Number.isFinite(createdAtValue) ? createdAtValue : Date.now();
|
|
170
|
+
const key = name.toLowerCase();
|
|
171
|
+
if (seen.has(key))
|
|
172
|
+
continue;
|
|
173
|
+
seen.add(key);
|
|
174
|
+
presets.push({ name, modelRoutes, createdAt });
|
|
175
|
+
}
|
|
176
|
+
if (presets.length > 0) {
|
|
177
|
+
presets.sort((a, b) => a.name.localeCompare(b.name));
|
|
178
|
+
routingPresets[endpoint] = presets;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
data.routingPresets = routingPresets;
|
|
141
183
|
return data;
|
|
142
184
|
}
|
|
143
185
|
function loadConfig() {
|
|
@@ -3148,16 +3190,16 @@ async function queryLogs(options = {}) {
|
|
|
3148
3190
|
const conditions = [];
|
|
3149
3191
|
const params = {};
|
|
3150
3192
|
if (options.provider) {
|
|
3151
|
-
conditions.push("provider =
|
|
3152
|
-
params
|
|
3193
|
+
conditions.push("provider = @provider");
|
|
3194
|
+
params.provider = options.provider;
|
|
3153
3195
|
}
|
|
3154
3196
|
if (options.endpoint) {
|
|
3155
|
-
conditions.push("endpoint =
|
|
3156
|
-
params
|
|
3197
|
+
conditions.push("endpoint = @endpoint");
|
|
3198
|
+
params.endpoint = options.endpoint;
|
|
3157
3199
|
}
|
|
3158
3200
|
if (options.model) {
|
|
3159
|
-
conditions.push("model =
|
|
3160
|
-
params
|
|
3201
|
+
conditions.push("model = @model");
|
|
3202
|
+
params.model = options.model;
|
|
3161
3203
|
}
|
|
3162
3204
|
if (options.status === "success") {
|
|
3163
3205
|
conditions.push("error IS NULL");
|
|
@@ -3165,18 +3207,18 @@ async function queryLogs(options = {}) {
|
|
|
3165
3207
|
conditions.push("error IS NOT NULL");
|
|
3166
3208
|
}
|
|
3167
3209
|
if (typeof options.from === "number") {
|
|
3168
|
-
conditions.push("timestamp >=
|
|
3169
|
-
params
|
|
3210
|
+
conditions.push("timestamp >= @from");
|
|
3211
|
+
params.from = options.from;
|
|
3170
3212
|
}
|
|
3171
3213
|
if (typeof options.to === "number") {
|
|
3172
|
-
conditions.push("timestamp <=
|
|
3173
|
-
params
|
|
3214
|
+
conditions.push("timestamp <= @to");
|
|
3215
|
+
params.to = options.to;
|
|
3174
3216
|
}
|
|
3175
3217
|
if (options.apiKeyIds && options.apiKeyIds.length > 0) {
|
|
3176
3218
|
const placeholders = [];
|
|
3177
3219
|
options.apiKeyIds.forEach((id, index) => {
|
|
3178
|
-
const key =
|
|
3179
|
-
placeholders.push(key);
|
|
3220
|
+
const key = `apiKey${index}`;
|
|
3221
|
+
placeholders.push(`@${key}`);
|
|
3180
3222
|
params[key] = id;
|
|
3181
3223
|
});
|
|
3182
3224
|
conditions.push(`(api_key_id IN (${placeholders.join(", ")}))`);
|
|
@@ -3193,8 +3235,8 @@ async function queryLogs(options = {}) {
|
|
|
3193
3235
|
FROM request_logs
|
|
3194
3236
|
${whereClause}
|
|
3195
3237
|
ORDER BY timestamp DESC
|
|
3196
|
-
LIMIT
|
|
3197
|
-
{ ...params,
|
|
3238
|
+
LIMIT @limit OFFSET @offset`,
|
|
3239
|
+
{ ...params, limit, offset }
|
|
3198
3240
|
);
|
|
3199
3241
|
return {
|
|
3200
3242
|
total: totalRow?.count ?? 0,
|
|
@@ -3450,6 +3492,151 @@ async function registerAdminRoutes(app) {
|
|
|
3450
3492
|
updateConfig(body);
|
|
3451
3493
|
return { success: true };
|
|
3452
3494
|
});
|
|
3495
|
+
const parseEndpoint = (value) => {
|
|
3496
|
+
if (value === "anthropic" || value === "openai") {
|
|
3497
|
+
return value;
|
|
3498
|
+
}
|
|
3499
|
+
return null;
|
|
3500
|
+
};
|
|
3501
|
+
const cloneRoutes = (routes) => {
|
|
3502
|
+
const normalized = {};
|
|
3503
|
+
if (!routes)
|
|
3504
|
+
return normalized;
|
|
3505
|
+
for (const [source, target] of Object.entries(routes)) {
|
|
3506
|
+
if (typeof target === "string" && target.trim()) {
|
|
3507
|
+
normalized[source] = target;
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
return normalized;
|
|
3511
|
+
};
|
|
3512
|
+
app.post("/api/routing-presets/:endpoint", async (request, reply) => {
|
|
3513
|
+
const endpoint = parseEndpoint(String(request.params.endpoint));
|
|
3514
|
+
if (!endpoint) {
|
|
3515
|
+
reply.code(400);
|
|
3516
|
+
return { error: "Unsupported endpoint" };
|
|
3517
|
+
}
|
|
3518
|
+
const rawName = request.body?.name;
|
|
3519
|
+
if (typeof rawName !== "string") {
|
|
3520
|
+
reply.code(400);
|
|
3521
|
+
return { error: "Preset name is required" };
|
|
3522
|
+
}
|
|
3523
|
+
const name = rawName.trim();
|
|
3524
|
+
if (!name) {
|
|
3525
|
+
reply.code(400);
|
|
3526
|
+
return { error: "Preset name cannot be empty" };
|
|
3527
|
+
}
|
|
3528
|
+
const config = getConfig();
|
|
3529
|
+
const routingConfig = config.endpointRouting?.[endpoint];
|
|
3530
|
+
const baseRoutes = endpoint === "anthropic" ? routingConfig?.modelRoutes ?? config.modelRoutes ?? {} : routingConfig?.modelRoutes ?? {};
|
|
3531
|
+
const currentPresets = config.routingPresets?.[endpoint] ?? [];
|
|
3532
|
+
const duplicate = currentPresets.some((preset) => preset.name.toLowerCase() === name.toLowerCase());
|
|
3533
|
+
if (duplicate) {
|
|
3534
|
+
reply.code(409);
|
|
3535
|
+
return { error: "Preset name already exists" };
|
|
3536
|
+
}
|
|
3537
|
+
const nextPresets = [...currentPresets, {
|
|
3538
|
+
name,
|
|
3539
|
+
modelRoutes: cloneRoutes(baseRoutes),
|
|
3540
|
+
createdAt: Date.now()
|
|
3541
|
+
}];
|
|
3542
|
+
nextPresets.sort((a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "base" }));
|
|
3543
|
+
const nextConfig = {
|
|
3544
|
+
...config,
|
|
3545
|
+
routingPresets: {
|
|
3546
|
+
...config.routingPresets,
|
|
3547
|
+
[endpoint]: nextPresets
|
|
3548
|
+
}
|
|
3549
|
+
};
|
|
3550
|
+
updateConfig(nextConfig);
|
|
3551
|
+
const updated = getConfig();
|
|
3552
|
+
return {
|
|
3553
|
+
success: true,
|
|
3554
|
+
presets: updated.routingPresets?.[endpoint] ?? []
|
|
3555
|
+
};
|
|
3556
|
+
});
|
|
3557
|
+
app.post("/api/routing-presets/:endpoint/apply", async (request, reply) => {
|
|
3558
|
+
const endpoint = parseEndpoint(String(request.params.endpoint));
|
|
3559
|
+
if (!endpoint) {
|
|
3560
|
+
reply.code(400);
|
|
3561
|
+
return { error: "Unsupported endpoint" };
|
|
3562
|
+
}
|
|
3563
|
+
const rawName = request.body?.name;
|
|
3564
|
+
if (typeof rawName !== "string") {
|
|
3565
|
+
reply.code(400);
|
|
3566
|
+
return { error: "Preset name is required" };
|
|
3567
|
+
}
|
|
3568
|
+
const name = rawName.trim();
|
|
3569
|
+
if (!name) {
|
|
3570
|
+
reply.code(400);
|
|
3571
|
+
return { error: "Preset name cannot be empty" };
|
|
3572
|
+
}
|
|
3573
|
+
const config = getConfig();
|
|
3574
|
+
const presets = config.routingPresets?.[endpoint] ?? [];
|
|
3575
|
+
const preset = presets.find((item) => item.name.toLowerCase() === name.toLowerCase());
|
|
3576
|
+
if (!preset) {
|
|
3577
|
+
reply.code(404);
|
|
3578
|
+
return { error: "Preset not found" };
|
|
3579
|
+
}
|
|
3580
|
+
const routing = config.endpointRouting ?? {
|
|
3581
|
+
anthropic: {
|
|
3582
|
+
defaults: config.defaults,
|
|
3583
|
+
modelRoutes: config.modelRoutes ?? {}
|
|
3584
|
+
}
|
|
3585
|
+
};
|
|
3586
|
+
const nextRouting = {
|
|
3587
|
+
...routing,
|
|
3588
|
+
[endpoint]: {
|
|
3589
|
+
defaults: routing[endpoint]?.defaults ?? config.defaults,
|
|
3590
|
+
modelRoutes: cloneRoutes(preset.modelRoutes)
|
|
3591
|
+
}
|
|
3592
|
+
};
|
|
3593
|
+
const nextConfig = {
|
|
3594
|
+
...config,
|
|
3595
|
+
endpointRouting: nextRouting,
|
|
3596
|
+
modelRoutes: endpoint === "anthropic" ? cloneRoutes(preset.modelRoutes) : config.modelRoutes,
|
|
3597
|
+
routingPresets: config.routingPresets
|
|
3598
|
+
};
|
|
3599
|
+
updateConfig(nextConfig);
|
|
3600
|
+
const updated = getConfig();
|
|
3601
|
+
return {
|
|
3602
|
+
success: true,
|
|
3603
|
+
routes: updated.endpointRouting?.[endpoint]?.modelRoutes ?? {},
|
|
3604
|
+
config: updated
|
|
3605
|
+
};
|
|
3606
|
+
});
|
|
3607
|
+
app.delete("/api/routing-presets/:endpoint/:name", async (request, reply) => {
|
|
3608
|
+
const endpoint = parseEndpoint(String(request.params.endpoint));
|
|
3609
|
+
if (!endpoint) {
|
|
3610
|
+
reply.code(400);
|
|
3611
|
+
return { error: "Unsupported endpoint" };
|
|
3612
|
+
}
|
|
3613
|
+
const rawName = request.params.name;
|
|
3614
|
+
const name = typeof rawName === "string" ? decodeURIComponent(rawName).trim() : "";
|
|
3615
|
+
if (!name) {
|
|
3616
|
+
reply.code(400);
|
|
3617
|
+
return { error: "Preset name is required" };
|
|
3618
|
+
}
|
|
3619
|
+
const config = getConfig();
|
|
3620
|
+
const presets = config.routingPresets?.[endpoint] ?? [];
|
|
3621
|
+
const filtered = presets.filter((item) => item.name.toLowerCase() !== name.toLowerCase());
|
|
3622
|
+
if (filtered.length === presets.length) {
|
|
3623
|
+
reply.code(404);
|
|
3624
|
+
return { error: "Preset not found" };
|
|
3625
|
+
}
|
|
3626
|
+
const nextConfig = {
|
|
3627
|
+
...config,
|
|
3628
|
+
routingPresets: {
|
|
3629
|
+
...config.routingPresets,
|
|
3630
|
+
[endpoint]: filtered
|
|
3631
|
+
}
|
|
3632
|
+
};
|
|
3633
|
+
updateConfig(nextConfig);
|
|
3634
|
+
const updated = getConfig();
|
|
3635
|
+
return {
|
|
3636
|
+
success: true,
|
|
3637
|
+
presets: updated.routingPresets?.[endpoint] ?? []
|
|
3638
|
+
};
|
|
3639
|
+
});
|
|
3453
3640
|
app.post("/api/providers/:id/test", async (request, reply) => {
|
|
3454
3641
|
const id = String(request.params.id);
|
|
3455
3642
|
const config = getConfig();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as x,a as p,r as o,j as e}from"./index-
|
|
1
|
+
import{u as x,a as p,r as o,j as e}from"./index-wA9rsqII.js";import{u as m}from"./useApiQuery-De0jYBDD.js";const h="0.3.6",v={version:h},g={};function N(){const{t:s}=x(),{pushToast:l}=p(),t=m(["status","gateway"],{url:"/api/status",method:"GET"},{staleTime:6e4});o.useEffect(()=>{t.isError&&t.error&&l({title:s("about.toast.statusError.title"),description:t.error.message,variant:"error"})},[t.isError,t.error,l,s]);const d=v.version,r=o.useMemo(()=>{const a=g,u=a.VITE_BUILD_TIME??"-",b=a.VITE_NODE_VERSION??"-";return{buildTime:u,nodeVersion:b}},[]),i=()=>{l({title:s("about.toast.updatesPlanned"),variant:"info"})},n=[{label:s("about.app.labels.name"),value:"cc-local-gw"},{label:s("about.app.labels.version"),value:d},{label:s("about.app.labels.buildTime"),value:r.buildTime},{label:s("about.app.labels.node"),value:r.nodeVersion}],c=t.data?[{label:s("about.status.labels.host"),value:t.data.host??"127.0.0.1"},{label:s("about.status.labels.port"),value:t.data.port},{label:s("about.status.labels.providers"),value:t.data.providers},{label:s("about.status.labels.active"),value:t.data.activeRequests??0}]:[];return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("header",{className:"flex flex-col gap-2",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:s("about.title")}),e.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:s("about.description")})]}),e.jsxs("section",{className:"grid gap-4 rounded-lg border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-slate-900 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:s("about.app.title")}),e.jsx("dl",{className:"grid grid-cols-[160px_1fr] gap-2 text-sm text-slate-600 dark:text-slate-300",children:n.map(a=>e.jsxs("div",{className:"contents",children:[e.jsx("dt",{className:"font-medium",children:a.label}),e.jsx("dd",{children:a.value})]},a.label))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:s("about.status.title")}),t.isLoading?e.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:s("about.status.loading")}):t.data?e.jsx("dl",{className:"grid grid-cols-[160px_1fr] gap-2 text-sm text-slate-600 dark:text-slate-300",children:c.map(a=>e.jsxs("div",{className:"contents",children:[e.jsx("dt",{className:"font-medium",children:a.label}),e.jsx("dd",{children:a.value})]},a.label))}):e.jsx("p",{className:"text-sm text-red-500",children:s("about.status.empty")})]})]}),e.jsxs("section",{className:"rounded-lg border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:s("about.support.title")}),e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("about.support.subtitle")})]}),e.jsx("button",{type:"button",onClick:i,className:"rounded-md border border-slate-200 px-3 py-1 text-sm transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("about.support.actions.checkUpdates")})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-slate-600 dark:text-slate-300",children:s("about.support.description")})]})]})}export{N as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as g,u as R,a as U,r as d,j as e,L as k,K as W}from"./index-
|
|
1
|
+
import{c as g,u as R,a as U,r as d,j as e,L as k,K as W}from"./index-wA9rsqII.js";import{E as L}from"./index-B0rGDFRO.js";import{u as N,a as v}from"./useApiQuery-De0jYBDD.js";/**
|
|
2
2
|
* @license lucide-react v0.344.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as A,a as R,r as h,j as t,L as D}from"./index-B-Zugt7w.js";import{E as O}from"./index-DJO5FEoj.js";import{u as v}from"./useApiQuery-DwPXd5aD.js";function N(e,a,s){return e==null?"-":`${e.toLocaleString(void 0,s)} ${a}`}function B(e){if(e==null)return"-";if(e<1024)return`${e} B`;const a=["KB","MB","GB","TB"];let s=e/1024,d=0;for(;s>=1024&&d<a.length-1;)s/=1024,d+=1;return`${s.toFixed(s>=100?0:s>=10?1:2)} ${a[d]}`}function _(){var S;const{t:e}=A(),{pushToast:a}=R(),[s,d]=h.useState("all"),l=s==="all"?void 0:s,b=v(["stats","overview",s],{url:"/api/stats/overview",method:"GET",params:l?{endpoint:l}:void 0}),p=v(["stats","daily",14,s],{url:"/api/stats/daily",method:"GET",params:{days:14,...l?{endpoint:l}:{}}}),u=v(["stats","model",7,6,s],{url:"/api/stats/model",method:"GET",params:{days:7,limit:6,...l?{endpoint:l}:{}}}),g=v(["status"],{url:"/api/status",method:"GET"}),f=v(["db","info"],{url:"/api/db/info",method:"GET"}),y=v(["logs","recent",s],{url:"/api/logs",method:"GET",params:{limit:5,...l?{endpoint:l}:{}}},{refetchInterval:3e4});h.useEffect(()=>{b.isError&&b.error&&a({title:e("dashboard.toast.overviewError"),description:b.error.message,variant:"error"})},[b.isError,b.error,a,e]),h.useEffect(()=>{p.isError&&p.error&&a({title:e("dashboard.toast.dailyError"),description:p.error.message,variant:"error"})},[p.isError,p.error,a,e]),h.useEffect(()=>{u.isError&&u.error&&a({title:e("dashboard.toast.modelError"),description:u.error.message,variant:"error"})},[u.isError,u.error,a,e]),h.useEffect(()=>{g.isError&&g.error&&a({title:e("dashboard.toast.statusError"),description:g.error.message,variant:"error"})},[g.isError,g.error,a,e]),h.useEffect(()=>{f.isError&&f.error&&a({title:e("dashboard.toast.dbError"),description:f.error.message,variant:"error"})},[f.isError,f.error,a,e]),h.useEffect(()=>{y.isError&&y.error&&a({title:e("dashboard.toast.recentError"),description:y.error.message,variant:"error"})},[y.isError,y.error,a,e]);const c=b.data,j=p.data??[],n=u.data??[],k=g.data,M=f.data,$=((S=y.data)==null?void 0:S.items)??[],q=h.useMemo(()=>{const i=j.map(o=>o.date),x=e("dashboard.charts.barRequests"),r=e("dashboard.charts.lineInput"),m=e("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[x,r,m]},grid:{left:40,right:20,top:40,bottom:40},xAxis:{type:"category",data:i},yAxis:{type:"value"},series:[{name:x,type:"bar",data:j.map(o=>o.requestCount),itemStyle:{color:"#2563eb"}},{name:r,type:"line",yAxisIndex:0,data:j.map(o=>o.inputTokens),smooth:!0,itemStyle:{color:"#22c55e"}},{name:m,type:"line",yAxisIndex:0,data:j.map(o=>o.outputTokens),smooth:!0,itemStyle:{color:"#f97316"}}]}},[j,e]),w=h.useMemo(()=>{const i=n.map(o=>`${o.provider}/${o.model}`),x=e("dashboard.charts.barRequests"),r=e("dashboard.charts.lineInput"),m=e("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[x,r,m]},grid:{left:50,right:40,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:[{type:"value",name:x},{type:"value",name:e("dashboard.charts.axisTokens"),position:"right"}],series:[{name:x,type:"bar",data:n.map(o=>o.requests),itemStyle:{color:"#6366f1"},yAxisIndex:0},{name:r,type:"line",yAxisIndex:1,smooth:!0,data:n.map(o=>o.inputTokens??0),itemStyle:{color:"#22c55e"}},{name:m,type:"line",yAxisIndex:1,smooth:!0,data:n.map(o=>o.outputTokens??0),itemStyle:{color:"#f97316"}}]}},[n,e]),I=h.useMemo(()=>{const i=n.map(r=>`${r.provider}/${r.model}`),x=e("dashboard.charts.ttftLabel");return{tooltip:{trigger:"axis",formatter(r){var T;if(!Array.isArray(r)||r.length===0)return"";const m=((T=r[0])==null?void 0:T.dataIndex)??0,o=n[m];return o?`<strong>${i[m]}</strong><br/>${x}: ${N(o.avgTtftMs,e("common.units.ms"))}`:""}},grid:{left:50,right:30,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:{type:"value",name:e("dashboard.charts.ttftAxis")},series:[{name:x,type:"bar",data:n.map(r=>r.avgTtftMs??0),itemStyle:{color:"#2563eb"}}]}},[n,e]),P=h.useMemo(()=>{const i=n.map(r=>`${r.provider}/${r.model}`),x=e("dashboard.charts.tpotLabel");return{tooltip:{trigger:"axis",formatter(r){var T;if(!Array.isArray(r)||r.length===0)return"";const m=((T=r[0])==null?void 0:T.dataIndex)??0,o=n[m];return o?`<strong>${i[m]}</strong><br/>${x}: ${N(o.avgTpotMs,e("common.units.msPerToken"),{maximumFractionDigits:2})}`:""}},grid:{left:50,right:30,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:{type:"value",name:e("dashboard.charts.tpotAxis")},series:[{name:x,type:"bar",data:n.map(r=>r.avgTpotMs??0),itemStyle:{color:"#f97316"}}]}},[n,e]);return b.isPending||g.isPending||f.isPending?t.jsx(D,{}):t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsxs("section",{className:"flex flex-col gap-2",children:[t.jsx("h1",{className:"text-2xl font-semibold",children:e("nav.dashboard")}),t.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:e("dashboard.description")}),k?t.jsxs("div",{className:"flex flex-wrap gap-3 rounded-lg border border-slate-200 bg-white p-4 text-sm shadow-sm dark:border-slate-800 dark:bg-slate-900","aria-live":"polite",children:[t.jsx("span",{className:"font-medium",children:e("dashboard.status.listening",{host:k.host??"0.0.0.0",port:k.port})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.providers",{value:k.providers})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.todayRequests",{value:((c==null?void 0:c.today.requests)??0).toLocaleString()})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.active",{value:(k.activeRequests??0).toLocaleString()})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.dbSize",{value:M?B(M.sizeBytes):"-"})})]}):null,t.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2 text-sm text-slate-500 dark:text-slate-400",children:[t.jsx("label",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:e("dashboard.filters.endpoint")}),t.jsxs("select",{value:s,onChange:i=>d(i.target.value),className:"h-9 rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[t.jsx("option",{value:"all",children:e("dashboard.filters.endpointAll")}),t.jsx("option",{value:"anthropic",children:e("dashboard.filters.endpointAnthropic")}),t.jsx("option",{value:"openai",children:e("dashboard.filters.endpointOpenAI")})]})]})]}),t.jsxs("section",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[t.jsx(E,{title:e("dashboard.cards.todayRequests"),value:(c==null?void 0:c.today.requests)??0,suffix:e("common.units.request")}),t.jsx(E,{title:e("dashboard.cards.todayInput"),value:(c==null?void 0:c.today.inputTokens)??0,suffix:e("common.units.token")}),t.jsx(E,{title:e("dashboard.cards.todayOutput"),value:(c==null?void 0:c.today.outputTokens)??0,suffix:e("common.units.token")}),t.jsx(E,{title:e("dashboard.cards.avgLatency"),value:(c==null?void 0:c.today.avgLatencyMs)??0,suffix:e("common.units.ms")})]}),t.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[t.jsx(L,{title:e("dashboard.charts.requestsTitle"),description:e("dashboard.charts.requestsDesc"),loading:p.isPending,option:q,empty:!j.length,emptyText:e("dashboard.charts.empty")}),t.jsx(L,{title:e("dashboard.charts.modelTitle"),description:e("dashboard.charts.modelDesc"),loading:u.isPending,option:w,empty:!n.length,emptyText:e("dashboard.charts.empty")})]}),t.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[t.jsx(L,{title:e("dashboard.charts.ttftTitle"),description:e("dashboard.charts.ttftDesc"),loading:u.isPending,option:I,empty:!n.some(i=>i.avgTtftMs!=null&&i.avgTtftMs>0),emptyText:e("dashboard.charts.ttftEmpty")}),t.jsx(L,{title:e("dashboard.charts.tpotTitle"),description:e("dashboard.charts.tpotDesc"),loading:u.isPending,option:P,empty:!n.some(i=>i.avgTpotMs!=null&&i.avgTpotMs>0),emptyText:e("dashboard.charts.tpotEmpty")})]}),t.jsx(G,{models:n,loading:u.isPending}),t.jsx(Q,{loading:y.isPending,records:$})]})}function E({title:e,value:a,suffix:s}){return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:e}),t.jsxs("p",{className:"mt-2 text-2xl font-semibold",children:[a.toLocaleString(),s?t.jsx("span",{className:"ml-1 text-base font-normal text-slate-500 dark:text-slate-400",children:s}):null]})]})}function L({title:e,description:a,option:s,loading:d,empty:l,emptyText:b}){const{t:p}=A();return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsxs("div",{className:"mb-4",children:[t.jsx("p",{className:"text-sm font-semibold",children:e}),t.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:a})]}),d?t.jsx("div",{className:"flex h-60 items-center justify-center text-sm text-slate-400",children:p("common.loadingShort")}):l?t.jsx("div",{className:"flex h-60 items-center justify-center text-sm text-slate-400",children:b??p("dashboard.charts.empty")}):t.jsx(O,{option:s,style:{height:260},notMerge:!0,lazyUpdate:!0,theme:void 0})]})}function G({models:e,loading:a}){const{t:s}=A(),d=e.length>0;return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("div",{className:"flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800",children:t.jsxs("div",{children:[t.jsx("p",{className:"text-sm font-semibold",children:s("dashboard.modelTable.title")}),t.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.description")})]})}),a?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("common.loadingShort")}):d?t.jsx("div",{className:"max-h-80 overflow-x-auto",children:t.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[t.jsx("caption",{className:"sr-only",children:s("dashboard.modelTable.title")}),t.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:t.jsxs("tr",{children:[t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.model")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.requests")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.latency")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.ttft")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.tpot")})]})}),t.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:e.map(l=>t.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[t.jsx("td",{className:"px-4 py-2",children:t.jsxs("div",{className:"flex flex-col",children:[t.jsx("span",{className:"font-medium text-slate-700 dark:text-slate-100",children:l.provider}),t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:l.model})]})}),t.jsx("td",{className:"px-4 py-2 text-right",children:l.requests.toLocaleString()}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgLatencyMs,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgTtftMs,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgTpotMs,s("common.units.msPerToken"),{maximumFractionDigits:2})})]},`${l.provider}/${l.model}`))})]})}):t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.modelTable.empty")})]})}function Q({records:e,loading:a}){const{t:s}=A();return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsxs("div",{className:"flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800",children:[t.jsx("p",{className:"text-sm font-semibold",children:s("dashboard.recent.title")}),t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("dashboard.recent.subtitle",{count:5})})]}),a?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.recent.loading")}):e.length===0?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.recent.empty")}):t.jsx("div",{className:"max-h-80 overflow-auto",children:t.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[t.jsx("caption",{className:"sr-only",children:s("dashboard.recent.title")}),t.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:t.jsxs("tr",{children:[t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.time")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.endpoint")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.provider")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.route")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.latency")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.status")})]})}),t.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:e.map(d=>t.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[t.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:new Date(d.timestamp).toLocaleString()}),t.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:d.endpoint==="anthropic"?s("logs.table.endpointAnthropic"):d.endpoint==="openai"?s("logs.table.endpointOpenAI"):d.endpoint}),t.jsx("td",{className:"px-4 py-2",children:d.provider}),t.jsxs("td",{className:"px-4 py-2",children:[t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:d.client_model??s("dashboard.recent.routePlaceholder")}),t.jsx("span",{className:"mx-1 text-slate-400",children:"→"}),t.jsx("span",{className:"font-medium text-slate-700 dark:text-slate-100",children:d.model})]}),t.jsx("td",{className:"px-4 py-2",children:N(d.latency_ms,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2",children:t.jsxs("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${d.error?"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-200":"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-200"}`,children:[(d.status_code??200).toString(),t.jsx("span",{className:"ml-1",children:d.error?s("common.status.error"):s("common.status.success")})]})})]},d.id))})]})})]})}export{_ as default};
|
|
1
|
+
import{u as A,a as R,r as h,j as t,L as D}from"./index-wA9rsqII.js";import{E as O}from"./index-B0rGDFRO.js";import{u as v}from"./useApiQuery-De0jYBDD.js";function N(e,a,s){return e==null?"-":`${e.toLocaleString(void 0,s)} ${a}`}function B(e){if(e==null)return"-";if(e<1024)return`${e} B`;const a=["KB","MB","GB","TB"];let s=e/1024,d=0;for(;s>=1024&&d<a.length-1;)s/=1024,d+=1;return`${s.toFixed(s>=100?0:s>=10?1:2)} ${a[d]}`}function _(){var S;const{t:e}=A(),{pushToast:a}=R(),[s,d]=h.useState("all"),l=s==="all"?void 0:s,b=v(["stats","overview",s],{url:"/api/stats/overview",method:"GET",params:l?{endpoint:l}:void 0}),p=v(["stats","daily",14,s],{url:"/api/stats/daily",method:"GET",params:{days:14,...l?{endpoint:l}:{}}}),u=v(["stats","model",7,6,s],{url:"/api/stats/model",method:"GET",params:{days:7,limit:6,...l?{endpoint:l}:{}}}),g=v(["status"],{url:"/api/status",method:"GET"}),f=v(["db","info"],{url:"/api/db/info",method:"GET"}),y=v(["logs","recent",s],{url:"/api/logs",method:"GET",params:{limit:5,...l?{endpoint:l}:{}}},{refetchInterval:3e4});h.useEffect(()=>{b.isError&&b.error&&a({title:e("dashboard.toast.overviewError"),description:b.error.message,variant:"error"})},[b.isError,b.error,a,e]),h.useEffect(()=>{p.isError&&p.error&&a({title:e("dashboard.toast.dailyError"),description:p.error.message,variant:"error"})},[p.isError,p.error,a,e]),h.useEffect(()=>{u.isError&&u.error&&a({title:e("dashboard.toast.modelError"),description:u.error.message,variant:"error"})},[u.isError,u.error,a,e]),h.useEffect(()=>{g.isError&&g.error&&a({title:e("dashboard.toast.statusError"),description:g.error.message,variant:"error"})},[g.isError,g.error,a,e]),h.useEffect(()=>{f.isError&&f.error&&a({title:e("dashboard.toast.dbError"),description:f.error.message,variant:"error"})},[f.isError,f.error,a,e]),h.useEffect(()=>{y.isError&&y.error&&a({title:e("dashboard.toast.recentError"),description:y.error.message,variant:"error"})},[y.isError,y.error,a,e]);const c=b.data,j=p.data??[],n=u.data??[],k=g.data,M=f.data,$=((S=y.data)==null?void 0:S.items)??[],q=h.useMemo(()=>{const i=j.map(o=>o.date),x=e("dashboard.charts.barRequests"),r=e("dashboard.charts.lineInput"),m=e("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[x,r,m]},grid:{left:40,right:20,top:40,bottom:40},xAxis:{type:"category",data:i},yAxis:{type:"value"},series:[{name:x,type:"bar",data:j.map(o=>o.requestCount),itemStyle:{color:"#2563eb"}},{name:r,type:"line",yAxisIndex:0,data:j.map(o=>o.inputTokens),smooth:!0,itemStyle:{color:"#22c55e"}},{name:m,type:"line",yAxisIndex:0,data:j.map(o=>o.outputTokens),smooth:!0,itemStyle:{color:"#f97316"}}]}},[j,e]),w=h.useMemo(()=>{const i=n.map(o=>`${o.provider}/${o.model}`),x=e("dashboard.charts.barRequests"),r=e("dashboard.charts.lineInput"),m=e("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[x,r,m]},grid:{left:50,right:40,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:[{type:"value",name:x},{type:"value",name:e("dashboard.charts.axisTokens"),position:"right"}],series:[{name:x,type:"bar",data:n.map(o=>o.requests),itemStyle:{color:"#6366f1"},yAxisIndex:0},{name:r,type:"line",yAxisIndex:1,smooth:!0,data:n.map(o=>o.inputTokens??0),itemStyle:{color:"#22c55e"}},{name:m,type:"line",yAxisIndex:1,smooth:!0,data:n.map(o=>o.outputTokens??0),itemStyle:{color:"#f97316"}}]}},[n,e]),I=h.useMemo(()=>{const i=n.map(r=>`${r.provider}/${r.model}`),x=e("dashboard.charts.ttftLabel");return{tooltip:{trigger:"axis",formatter(r){var T;if(!Array.isArray(r)||r.length===0)return"";const m=((T=r[0])==null?void 0:T.dataIndex)??0,o=n[m];return o?`<strong>${i[m]}</strong><br/>${x}: ${N(o.avgTtftMs,e("common.units.ms"))}`:""}},grid:{left:50,right:30,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:{type:"value",name:e("dashboard.charts.ttftAxis")},series:[{name:x,type:"bar",data:n.map(r=>r.avgTtftMs??0),itemStyle:{color:"#2563eb"}}]}},[n,e]),P=h.useMemo(()=>{const i=n.map(r=>`${r.provider}/${r.model}`),x=e("dashboard.charts.tpotLabel");return{tooltip:{trigger:"axis",formatter(r){var T;if(!Array.isArray(r)||r.length===0)return"";const m=((T=r[0])==null?void 0:T.dataIndex)??0,o=n[m];return o?`<strong>${i[m]}</strong><br/>${x}: ${N(o.avgTpotMs,e("common.units.msPerToken"),{maximumFractionDigits:2})}`:""}},grid:{left:50,right:30,top:40,bottom:70},xAxis:{type:"category",data:i,axisLabel:{rotate:30}},yAxis:{type:"value",name:e("dashboard.charts.tpotAxis")},series:[{name:x,type:"bar",data:n.map(r=>r.avgTpotMs??0),itemStyle:{color:"#f97316"}}]}},[n,e]);return b.isPending||g.isPending||f.isPending?t.jsx(D,{}):t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsxs("section",{className:"flex flex-col gap-2",children:[t.jsx("h1",{className:"text-2xl font-semibold",children:e("nav.dashboard")}),t.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:e("dashboard.description")}),k?t.jsxs("div",{className:"flex flex-wrap gap-3 rounded-lg border border-slate-200 bg-white p-4 text-sm shadow-sm dark:border-slate-800 dark:bg-slate-900","aria-live":"polite",children:[t.jsx("span",{className:"font-medium",children:e("dashboard.status.listening",{host:k.host??"0.0.0.0",port:k.port})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.providers",{value:k.providers})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.todayRequests",{value:((c==null?void 0:c.today.requests)??0).toLocaleString()})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.active",{value:(k.activeRequests??0).toLocaleString()})}),t.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:e("dashboard.status.dbSize",{value:M?B(M.sizeBytes):"-"})})]}):null,t.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2 text-sm text-slate-500 dark:text-slate-400",children:[t.jsx("label",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:e("dashboard.filters.endpoint")}),t.jsxs("select",{value:s,onChange:i=>d(i.target.value),className:"h-9 rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[t.jsx("option",{value:"all",children:e("dashboard.filters.endpointAll")}),t.jsx("option",{value:"anthropic",children:e("dashboard.filters.endpointAnthropic")}),t.jsx("option",{value:"openai",children:e("dashboard.filters.endpointOpenAI")})]})]})]}),t.jsxs("section",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[t.jsx(E,{title:e("dashboard.cards.todayRequests"),value:(c==null?void 0:c.today.requests)??0,suffix:e("common.units.request")}),t.jsx(E,{title:e("dashboard.cards.todayInput"),value:(c==null?void 0:c.today.inputTokens)??0,suffix:e("common.units.token")}),t.jsx(E,{title:e("dashboard.cards.todayOutput"),value:(c==null?void 0:c.today.outputTokens)??0,suffix:e("common.units.token")}),t.jsx(E,{title:e("dashboard.cards.avgLatency"),value:(c==null?void 0:c.today.avgLatencyMs)??0,suffix:e("common.units.ms")})]}),t.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[t.jsx(L,{title:e("dashboard.charts.requestsTitle"),description:e("dashboard.charts.requestsDesc"),loading:p.isPending,option:q,empty:!j.length,emptyText:e("dashboard.charts.empty")}),t.jsx(L,{title:e("dashboard.charts.modelTitle"),description:e("dashboard.charts.modelDesc"),loading:u.isPending,option:w,empty:!n.length,emptyText:e("dashboard.charts.empty")})]}),t.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[t.jsx(L,{title:e("dashboard.charts.ttftTitle"),description:e("dashboard.charts.ttftDesc"),loading:u.isPending,option:I,empty:!n.some(i=>i.avgTtftMs!=null&&i.avgTtftMs>0),emptyText:e("dashboard.charts.ttftEmpty")}),t.jsx(L,{title:e("dashboard.charts.tpotTitle"),description:e("dashboard.charts.tpotDesc"),loading:u.isPending,option:P,empty:!n.some(i=>i.avgTpotMs!=null&&i.avgTpotMs>0),emptyText:e("dashboard.charts.tpotEmpty")})]}),t.jsx(G,{models:n,loading:u.isPending}),t.jsx(Q,{loading:y.isPending,records:$})]})}function E({title:e,value:a,suffix:s}){return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:e}),t.jsxs("p",{className:"mt-2 text-2xl font-semibold",children:[a.toLocaleString(),s?t.jsx("span",{className:"ml-1 text-base font-normal text-slate-500 dark:text-slate-400",children:s}):null]})]})}function L({title:e,description:a,option:s,loading:d,empty:l,emptyText:b}){const{t:p}=A();return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsxs("div",{className:"mb-4",children:[t.jsx("p",{className:"text-sm font-semibold",children:e}),t.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:a})]}),d?t.jsx("div",{className:"flex h-60 items-center justify-center text-sm text-slate-400",children:p("common.loadingShort")}):l?t.jsx("div",{className:"flex h-60 items-center justify-center text-sm text-slate-400",children:b??p("dashboard.charts.empty")}):t.jsx(O,{option:s,style:{height:260},notMerge:!0,lazyUpdate:!0,theme:void 0})]})}function G({models:e,loading:a}){const{t:s}=A(),d=e.length>0;return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("div",{className:"flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800",children:t.jsxs("div",{children:[t.jsx("p",{className:"text-sm font-semibold",children:s("dashboard.modelTable.title")}),t.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.description")})]})}),a?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("common.loadingShort")}):d?t.jsx("div",{className:"max-h-80 overflow-x-auto",children:t.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[t.jsx("caption",{className:"sr-only",children:s("dashboard.modelTable.title")}),t.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:t.jsxs("tr",{children:[t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.model")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.requests")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.latency")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.ttft")}),t.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.modelTable.columns.tpot")})]})}),t.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:e.map(l=>t.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[t.jsx("td",{className:"px-4 py-2",children:t.jsxs("div",{className:"flex flex-col",children:[t.jsx("span",{className:"font-medium text-slate-700 dark:text-slate-100",children:l.provider}),t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:l.model})]})}),t.jsx("td",{className:"px-4 py-2 text-right",children:l.requests.toLocaleString()}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgLatencyMs,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgTtftMs,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2 text-right",children:N(l.avgTpotMs,s("common.units.msPerToken"),{maximumFractionDigits:2})})]},`${l.provider}/${l.model}`))})]})}):t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.modelTable.empty")})]})}function Q({records:e,loading:a}){const{t:s}=A();return t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[t.jsxs("div",{className:"flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800",children:[t.jsx("p",{className:"text-sm font-semibold",children:s("dashboard.recent.title")}),t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("dashboard.recent.subtitle",{count:5})})]}),a?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.recent.loading")}):e.length===0?t.jsx("div",{className:"flex h-40 items-center justify-center text-sm text-slate-400",children:s("dashboard.recent.empty")}):t.jsx("div",{className:"max-h-80 overflow-auto",children:t.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[t.jsx("caption",{className:"sr-only",children:s("dashboard.recent.title")}),t.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:t.jsxs("tr",{children:[t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.time")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.endpoint")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.provider")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.route")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.latency")}),t.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:s("dashboard.recent.columns.status")})]})}),t.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:e.map(d=>t.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[t.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:new Date(d.timestamp).toLocaleString()}),t.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:d.endpoint==="anthropic"?s("logs.table.endpointAnthropic"):d.endpoint==="openai"?s("logs.table.endpointOpenAI"):d.endpoint}),t.jsx("td",{className:"px-4 py-2",children:d.provider}),t.jsxs("td",{className:"px-4 py-2",children:[t.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:d.client_model??s("dashboard.recent.routePlaceholder")}),t.jsx("span",{className:"mx-1 text-slate-400",children:"→"}),t.jsx("span",{className:"font-medium text-slate-700 dark:text-slate-100",children:d.model})]}),t.jsx("td",{className:"px-4 py-2",children:N(d.latency_ms,s("common.units.ms"))}),t.jsx("td",{className:"px-4 py-2",children:t.jsxs("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${d.error?"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-200":"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-200"}`,children:[(d.status_code??200).toString(),t.jsx("span",{className:"ml-1",children:d.error?s("common.status.error"):s("common.status.success")})]})})]},d.id))})]})})]})}export{_ as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as c,r as d,j as e}from"./index-
|
|
1
|
+
import{u as c,r as d,j as e}from"./index-wA9rsqII.js";function o(){const{t:s}=c(),a=d.useMemo(()=>{const t=s("help.sections.configuration.items",{returnObjects:!0}),l=s("help.sections.usage.items",{returnObjects:!0}),i=s("help.sections.tips.items",{returnObjects:!0});return[{title:s("help.sections.configuration.title"),items:t},{title:s("help.sections.usage.title"),items:l},{title:s("help.sections.tips.title"),items:i}]},[s]),r=s("help.faq.items",{returnObjects:!0});return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-8",children:[e.jsxs("header",{className:"space-y-3",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:s("help.title")}),e.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-300",children:s("help.intro")}),e.jsx("div",{className:"rounded-md border border-blue-100 bg-blue-50 px-4 py-3 text-xs text-blue-700 dark:border-blue-900/40 dark:bg-blue-950/60 dark:text-blue-200",children:s("help.note")})]}),a.map(t=>e.jsxs("section",{className:"space-y-3 rounded-lg border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsx("h2",{className:"text-lg font-semibold",children:t.title}),e.jsx("ol",{className:"list-decimal space-y-2 pl-6 text-sm text-slate-700 dark:text-slate-300",children:t.items.map(l=>e.jsx("li",{children:l},l))})]},t.title)),e.jsxs("section",{className:"space-y-3 rounded-lg border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsx("h2",{className:"text-lg font-semibold",children:s("help.faq.title")}),e.jsx("dl",{className:"space-y-4 text-sm text-slate-700 dark:text-slate-300",children:r.map(t=>e.jsxs("div",{className:"space-y-1",children:[e.jsx("dt",{className:"font-medium text-slate-900 dark:text-slate-100",children:t.q}),e.jsx("dd",{children:t.a})]},t.q))})]})]})}export{o as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as L,a as J,r as d,j as e,b as ae,L as le}from"./index-B-Zugt7w.js";import{u as C}from"./useApiQuery-DwPXd5aD.js";const W=[20,50,100];function z(t,r=!1){if(!t)return;const n=r?`${t}T23:59:59.999`:`${t}T00:00:00.000`,h=Date.parse(n);return Number.isFinite(h)?h:void 0}function Y(t){const r=new Date(t);return`${r.getFullYear()}-${`${r.getMonth()+1}`.padStart(2,"0")}-${`${r.getDate()}`.padStart(2,"0")} ${`${r.getHours()}`.padStart(2,"0")}:${`${r.getMinutes()}`.padStart(2,"0")}:${`${r.getSeconds()}`.padStart(2,"0")}`}function w(t){return t==null?"-":t.toLocaleString()}function N(t,r){const n=w(t);return n==="-"?"-":`${n} ${r}`}function P(t){return t?"true":"false"}function H(t,r){if(!t||t.trim().length===0)return r;try{const n=JSON.parse(t);return JSON.stringify(n,null,2)}catch{return t}}function ce(){var B,G;const{t}=L(),{pushToast:r}=J(),[n,h]=d.useState("all"),[i,s]=d.useState("all"),[m,y]=d.useState(""),[p,c]=d.useState("all"),[b,a]=d.useState(""),[x,o]=d.useState(""),[f,v]=d.useState(1),[u,_]=d.useState(W[0]),[D,E]=d.useState(null),[V,R]=d.useState(!1),[T,A]=d.useState([]);d.useEffect(()=>{v(1)},[n,i,m,p,b,x,u,T]);const M=d.useMemo(()=>{const l={limit:u,offset:(f-1)*u};n!=="all"&&(l.provider=n),i!=="all"&&(l.endpoint=i),m.trim().length>0&&(l.model=m.trim()),p!=="all"&&(l.status=p);const j=z(b),Q=z(x,!0);return j!==void 0&&(l.from=j),Q!==void 0&&(l.to=Q),T.length>0&&(l.apiKeys=T.join(",")),l},[n,i,m,p,b,x,f,u,T]),g=C(["logs",M],{url:"/api/logs",method:"GET",params:M}),S=C(["providers","all"],{url:"/api/providers",method:"GET"}),q=C(["api-keys"],{url:"/api/keys",method:"GET"});d.useEffect(()=>{g.isError&&g.error&&r({title:t("logs.toast.listError.title"),description:t("logs.toast.listError.desc",{message:g.error.message}),variant:"error"})},[g.isError,g.error,r,t]),d.useEffect(()=>{S.isError&&S.error&&r({title:t("logs.toast.providerError.title"),description:t("logs.toast.providerError.desc",{message:S.error.message}),variant:"error"})},[S.isError,S.error,r,t]);const $=((B=g.data)==null?void 0:B.total)??0,k=$>0?Math.ceil($/u):0,O=((G=g.data)==null?void 0:G.items)??[];d.useEffect(()=>{k>0&&f>k&&v(k)},[k,f]);const F=S.data??[],U=d.useMemo(()=>{const l=new Map;for(const j of F)j.id&&l.set(j.id,j.label??j.id);return l},[F]),K=q.data??[],I=d.useMemo(()=>{const l=new Map;for(const j of K)l.set(j.id,j);return l},[K]),X=d.useMemo(()=>[{value:"all",label:t("logs.filters.statusAll")},{value:"success",label:t("logs.filters.statusSuccess")},{value:"error",label:t("logs.filters.statusError")}],[t]),ee=()=>{h("all"),y(""),s("all"),c("all"),a(""),o(""),A([])},te=d.useCallback(l=>{E(l),R(!0)},[]),se=d.useCallback(()=>{R(!1),E(null)},[]);return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold",children:t("logs.title")}),e.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:t("logs.description")})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm text-slate-500 dark:text-slate-400","aria-live":"polite",children:[e.jsx("span",{children:t("logs.summary.total",{value:$.toLocaleString()})}),e.jsx("button",{type:"button",className:"rounded-md border border-slate-200 px-3 py-1 transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",onClick:()=>g.refetch(),disabled:g.isFetching,children:g.isFetching?t("common.actions.refreshing"):t("logs.actions.manualRefresh")})]})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3 rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.provider")}),e.jsxs("select",{value:n,onChange:l=>h(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[e.jsx("option",{value:"all",children:t("logs.filters.providerAll")}),F.map(l=>e.jsx("option",{value:l.id,children:l.label??l.id},l.id))]})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.endpoint")}),e.jsxs("select",{value:i,onChange:l=>s(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[e.jsx("option",{value:"all",children:t("logs.filters.endpointAll")}),e.jsx("option",{value:"anthropic",children:t("logs.filters.endpointAnthropic")}),e.jsx("option",{value:"openai",children:t("logs.filters.endpointOpenAI")})]})]}),e.jsx(oe,{apiKeys:K,selected:T,disabled:q.isLoading,onChange:A}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.modelId")}),e.jsx("input",{value:m,onChange:l=>y(l.target.value),placeholder:t("logs.filters.modelPlaceholder"),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.status")}),e.jsx("select",{value:p,onChange:l=>c(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:X.map(l=>e.jsx("option",{value:l.value,children:l.label},l.value))})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.startDate")}),e.jsx("input",{type:"date",value:b,onChange:l=>a(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.endDate")}),e.jsx("input",{type:"date",value:x,onChange:l=>o(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsx("div",{className:"ml-auto flex items-center gap-2 text-sm",children:e.jsx("button",{type:"button",onClick:ee,className:"rounded-md border border-slate-200 px-3 py-2 transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:t("common.actions.reset")})})]})]}),e.jsxs("section",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[e.jsx("caption",{className:"sr-only",children:t("logs.title")}),e.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.time")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.endpoint")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.provider")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.requestedModel")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.routedModel")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.apiKey")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.inputTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.cachedTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.outputTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.stream")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.latency")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.ttft")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.tpot")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.status")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.error")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.actions")})]})}),e.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:g.isPending?e.jsx("tr",{children:e.jsx("td",{colSpan:16,className:"px-4 py-10 text-center text-sm text-slate-400",children:t("logs.table.loading")})}):O.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:15,className:"px-4 py-10 text-center text-sm text-slate-400",children:t("logs.table.empty")})}):O.map(l=>e.jsx(re,{record:l,providerLabelMap:U,apiKeyMap:I,onSelect:te},l.id))})]})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-slate-200 px-4 py-3 text-sm dark:border-slate-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{children:t("logs.table.pagination.perPage")}),e.jsx("select",{value:u,onChange:l=>_(Number(l.target.value)),className:"rounded-md border border-slate-200 bg-white px-2 py-1 text-sm dark:border-slate-700 dark:bg-slate-800",children:W.map(l=>e.jsx("option",{value:l,children:l},l))}),e.jsx("span",{children:t("logs.table.pagination.unit")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:()=>v(l=>Math.max(l-1,1)),disabled:f<=1,className:"rounded-md border border-slate-200 px-3 py-1 transition enabled:hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:enabled:hover:bg-slate-800",children:t("logs.table.pagination.previous")}),e.jsx("span",{children:t("logs.table.pagination.pageLabel",{page:k===0?0:f,total:k})}),e.jsx("button",{type:"button",onClick:()=>v(l=>k===0?l:Math.min(l+1,k)),disabled:k===0||f>=k,className:"rounded-md border border-slate-200 px-3 py-1 transition enabled:hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:enabled:hover:bg-slate-800",children:t("logs.table.pagination.next")})]})]})]}),e.jsx(de,{open:V,logId:D,onClose:se,providerLabelMap:U,apiKeyMap:I})]})}function re({record:t,providerLabelMap:r,apiKeyMap:n,onSelect:h}){const{t:i}=L(),s=r.get(t.provider)??t.provider,m=t.endpoint||"-",y=!!t.error,p=t.client_model??i("logs.table.requestedModelFallback"),c=t.api_key_id!=null?n.get(t.api_key_id):void 0,b=t.api_key_id==null?i("logs.table.apiKeyUnknown"):c!=null&&c.isWildcard?i("apiKeys.wildcard"):c!=null&&c.name?c.name:t.api_key_name?t.api_key_name:i("logs.table.apiKeyUnknown");return e.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[e.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:Y(t.timestamp)}),e.jsx("td",{className:"px-4 py-2",children:m}),e.jsx("td",{className:"px-4 py-2",children:s}),e.jsx("td",{className:"px-4 py-2",children:p}),e.jsx("td",{className:"px-4 py-2",children:t.model}),e.jsx("td",{className:"px-4 py-2",children:e.jsx("span",{className:"block truncate",title:b,children:b})}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.input_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.cached_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.output_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:P(t.stream)}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.latency_ms,i("common.units.ms"))}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.ttft_ms,i("common.units.ms"))}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.tpot_ms,i("common.units.msPerToken"))}),e.jsx("td",{className:"px-4 py-2",children:e.jsx(Z,{success:!y,statusCode:t.status_code})}),e.jsx("td",{className:"max-w-xs px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:e.jsx("span",{className:"block truncate",title:t.error??"",children:t.error?t.error:"-"})}),e.jsx("td",{className:"px-4 py-2",children:e.jsx("button",{type:"button",onClick:()=>h(t.id),"aria-haspopup":"dialog",className:"rounded-md border border-slate-200 px-3 py-1 text-sm transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:i("logs.actions.detail")})})]})}function Z({success:t,statusCode:r}){const{t:n}=L(),h="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",i=t?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-200":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-200";return e.jsxs("span",{className:`${h} ${i}`,children:[n(t?"common.status.success":"common.status.error"),r?` · ${r}`:""]})}function de({open:t,logId:r,onClose:n,providerLabelMap:h,apiKeyMap:i}){var f,v;const{t:s}=L(),{pushToast:m}=J(),y=d.useRef(null),p=d.useRef(null),c=C(["log-detail",r],{url:`/api/logs/${r}`,method:"GET"},{enabled:t&&r!==null,staleTime:3e4});d.useEffect(()=>{c.isError&&c.error&&m({title:s("logs.detail.loadError"),description:c.error.message,variant:"error"})},[c.isError,c.error,m,s]),d.useEffect(()=>{if(!t)return;const u=_=>{_.key==="Escape"&&n()};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[t,n]),d.useEffect(()=>{t&&p.current&&p.current.focus()},[t,r]);const b=d.useCallback(async(u,_,D)=>{if(!_){m({title:s("logs.detail.copy.empty",{label:u}),variant:"info"});return}try{await navigator.clipboard.writeText(_),m({title:s(D),variant:"success"})}catch(E){m({title:s("logs.detail.copy.failure"),description:E instanceof Error?E.message:s("logs.detail.copy.failureFallback"),variant:"error"})}},[m,s]);if(!t)return null;const a=c.data,x=a?h.get(a.provider)??a.provider:"",o=a&&a.api_key_id!=null?i.get(a.api_key_id):void 0;return typeof document>"u"?null:ae.createPortal(e.jsxs("div",{className:"fixed inset-0 z-50 flex",children:[e.jsx("div",{className:"flex-1 bg-slate-900/60",onClick:n,"aria-hidden":"true"}),e.jsxs("aside",{ref:y,role:"dialog","aria-modal":"true","aria-labelledby":"log-detail-title","aria-describedby":"log-detail-content",className:"flex h-full w-full max-w-xl flex-col border-l border-slate-200 bg-white shadow-xl transition-transform dark:border-slate-800 dark:bg-slate-900",children:[e.jsxs("header",{className:"flex items-center justify-between border-b border-slate-200 px-6 py-4 dark:border-slate-800",children:[e.jsxs("div",{children:[e.jsx("h2",{id:"log-detail-title",className:"text-lg font-semibold",children:s("logs.detail.title")}),a?e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.id",{id:a.id})}):null]}),e.jsx("button",{type:"button",ref:p,onClick:n,className:"rounded-md border border-slate-200 px-3 py-1 text-sm transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.close")})]}),e.jsx("div",{id:"log-detail-content",className:"flex-1 overflow-y-auto",children:c.isPending?e.jsx(le,{}):a?e.jsxs("div",{className:"flex flex-col gap-6 px-6 py-5 text-sm",children:[e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.infoSection")}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-md bg-slate-100 px-3 py-2 text-xs text-slate-600 dark:bg-slate-800/60 dark:text-slate-300",children:[e.jsx("span",{className:"text-sm font-medium text-slate-700 dark:text-slate-100",children:s("logs.detail.summary.route",{from:a.client_model??s("logs.detail.info.noRequestedModel"),to:a.model})}),e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.latency",{value:N(a.latency_ms,s("common.units.ms"))})}),a.ttft_ms!==null?e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.ttft",{value:N(a.ttft_ms,s("common.units.ms"))})}):null,a.tpot_ms!==null?e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.tpot",{value:N(a.tpot_ms,s("common.units.msPerToken"))})}):null,e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.stream",{value:P(a.stream)})}),e.jsx(Z,{success:!a.error,statusCode:a.status_code})]}),e.jsxs("dl",{className:"grid grid-cols-2 gap-x-4 gap-y-3",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.time")}),e.jsx("dd",{className:"font-medium",children:Y(a.timestamp)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.sessionId")}),e.jsx("dd",{className:"font-medium",children:a.session_id??"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.endpoint")}),e.jsx("dd",{className:"font-medium",children:a.endpoint||"-"}),e.jsx("dt",{className:"mt-2 text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.provider")}),e.jsx("dd",{className:"font-medium",children:x})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.requestedModel")}),e.jsx("dd",{className:"font-medium",children:a.client_model??s("logs.detail.info.noRequestedModel")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.model")}),e.jsx("dd",{className:"font-medium",children:a.model})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.stream")}),e.jsx("dd",{className:"font-medium",children:P(a.stream)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.inputTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.input_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.cachedTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.cached_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.outputTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.output_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.ttft")}),e.jsx("dd",{className:"font-medium",children:N(a.ttft_ms,s("common.units.ms"))})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.tpot")}),e.jsx("dd",{className:"font-medium",children:N(a.tpot_ms,s("common.units.msPerToken"))})]})]}),a.error?e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.error")}),e.jsx("p",{className:"rounded-md border border-red-200 bg-red-50 p-3 text-xs leading-5 text-red-700 dark:border-red-800/70 dark:bg-red-900/40 dark:text-red-200",children:a.error})]}):null]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.title")}),e.jsxs("dl",{className:"grid gap-x-4 gap-y-3 text-sm sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.name")}),e.jsx("dd",{className:"font-medium",children:a.api_key_id==null&&!a.api_key_name?s("logs.detail.apiKey.missing"):o!=null&&o.isWildcard?s("apiKeys.wildcard"):(o==null?void 0:o.name)??a.api_key_name??s("logs.detail.apiKey.missing")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.identifier")}),e.jsx("dd",{className:"font-medium",children:a.api_key_id??s("common.noData")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.masked")}),e.jsx("dd",{className:"font-medium",children:o!=null&&o.isWildcard?s("apiKeys.wildcard"):(o==null?void 0:o.maskedKey)??a.api_key_name??s("logs.detail.apiKey.maskedUnavailable")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.lastUsed")}),e.jsx("dd",{className:"font-medium",children:o!=null&&o.lastUsedAt?new Date(o.lastUsedAt).toLocaleString():s("common.noData")})]})]}),e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600 dark:border-slate-800 dark:bg-slate-800/60 dark:text-slate-300",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium text-slate-700 dark:text-slate-200",children:s("logs.detail.apiKey.raw")}),e.jsx("p",{className:"mt-1 text-xs",children:a.api_key_value?a.api_key_value:s("logs.detail.apiKey.rawUnavailable")})]}),e.jsx("button",{type:"button",disabled:!a.api_key_value,onClick:()=>b(s("logs.detail.apiKey.raw"),a.api_key_value,"logs.detail.copy.keySuccess"),className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 disabled:opacity-50 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("header",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.payload.request")}),e.jsx("button",{type:"button",onClick:()=>{var u;return b(s("logs.detail.payload.request"),(u=a.payload)==null?void 0:u.prompt,"logs.detail.copy.requestSuccess")},className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border border-slate-200 bg-slate-50 p-3 text-xs leading-5 text-slate-700 dark:border-slate-800 dark:bg-slate-900/80 dark:text-slate-200",children:H((f=a.payload)==null?void 0:f.prompt,s("logs.detail.payload.emptyRequest"))})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("header",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.payload.response")}),e.jsx("button",{type:"button",onClick:()=>{var u;return b(s("logs.detail.payload.response"),(u=a.payload)==null?void 0:u.response,"logs.detail.copy.responseSuccess")},className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border border-slate-200 bg-slate-50 p-3 text-xs leading-5 text-slate-700 dark:border-slate-800 dark:bg-slate-900/80 dark:text-slate-200",children:H((v=a.payload)==null?void 0:v.response,s("logs.detail.payload.emptyResponse"))})]})]}):e.jsx("div",{className:"flex h-full items-center justify.center p-8 text-sm text-slate-500 dark:text-slate-400",children:s("logs.detail.loadError")})})]})]}),document.body)}function oe({apiKeys:t,selected:r,onChange:n,disabled:h}){const{t:i}=L(),[s,m]=d.useState(!1),y=d.useRef(null);d.useEffect(()=>{if(!s)return;const a=x=>{var o;(o=y.current)!=null&&o.contains(x.target)||m(!1)};return window.addEventListener("mousedown",a),()=>window.removeEventListener("mousedown",a)},[s]);const p=d.useMemo(()=>{if(r.length===0)return[];const a=new Map;for(const x of t)a.set(x.id,x);return r.map(x=>{const o=a.get(x);return o?o.isWildcard?i("apiKeys.wildcard"):o.name:null}).filter(x=>!!x)},[t,r,i]),c=r.length===0?i("logs.filters.apiKeyAll"):i("logs.filters.apiKeySelected",{count:r.length}),b=a=>{r.includes(a)?n(r.filter(x=>x!==a)):n([...r,a])};return e.jsxs("div",{className:"relative flex flex-col text-sm",ref:y,children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:i("logs.filters.apiKey")}),e.jsxs("button",{type:"button",onClick:()=>m(a=>!a),disabled:h||t.length===0,title:i("logs.filters.apiKeyHint"),className:`flex w-48 items-center justify-between rounded-md border px-3 py-2 text-left text-sm transition focus:outline-none focus:ring-2 focus:ring-blue-200 disabled:opacity-50 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:ring-blue-400/40 ${r.length>0?"border-blue-500 dark:border-blue-500":"border-slate-200"}`,"aria-haspopup":"listbox","aria-expanded":s,children:[e.jsxs("span",{className:"truncate",children:[c,p.length>0&&e.jsx("span",{className:"ml-1 text-xs text-slate-500 dark:text-slate-400",children:p.join(", ")})]}),e.jsx("svg",{className:`h-4 w-4 text-slate-500 transition-transform dark:text-slate-300 ${s?"rotate-180":""}`,viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{fillRule:"evenodd",d:"M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.24 4.25a.75.75 0 01-1.06 0L5.21 8.29a.75.75 0 01.02-1.08z",clipRule:"evenodd"})})]}),s&&e.jsxs("div",{className:"absolute left-0 top-full z-20 mt-2 w-56 rounded-lg border border-slate-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-slate-200 px-3 py-2 text-xs text-slate-500 dark:border-slate-700 dark:text-slate-300",children:[e.jsx("span",{children:c}),e.jsx("button",{type:"button",onClick:()=>n([]),disabled:r.length===0,className:"text-blue-600 hover:underline disabled:opacity-40 dark:text-blue-400",children:i("common.actions.reset")})]}),e.jsxs("div",{className:"max-h-56 overflow-y-auto px-2 py-2",children:[t.map(a=>{const x=a.isWildcard?i("apiKeys.wildcard"):a.name,o=r.includes(a.id);return e.jsxs("label",{className:`flex items-center gap-2 rounded px-2 py-2 text-sm transition hover:bg-slate-100 dark:hover:bg-slate-800 ${o?"bg-slate-100 dark:bg-slate-800/70":""}`,children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4",checked:o,onChange:()=>b(a.id)}),e.jsx("span",{className:"truncate",children:x})]},a.id)}),t.length===0&&e.jsx("p",{className:"px-2 py-2 text-xs text-slate-500 dark:text-slate-400",children:i("logs.filters.apiKeyAll")})]})]})]})}export{ce as default};
|
|
1
|
+
import{u as L,a as J,r as d,j as e,b as ae,L as le}from"./index-wA9rsqII.js";import{u as C}from"./useApiQuery-De0jYBDD.js";const W=[20,50,100];function z(t,r=!1){if(!t)return;const n=r?`${t}T23:59:59.999`:`${t}T00:00:00.000`,h=Date.parse(n);return Number.isFinite(h)?h:void 0}function Y(t){const r=new Date(t);return`${r.getFullYear()}-${`${r.getMonth()+1}`.padStart(2,"0")}-${`${r.getDate()}`.padStart(2,"0")} ${`${r.getHours()}`.padStart(2,"0")}:${`${r.getMinutes()}`.padStart(2,"0")}:${`${r.getSeconds()}`.padStart(2,"0")}`}function w(t){return t==null?"-":t.toLocaleString()}function N(t,r){const n=w(t);return n==="-"?"-":`${n} ${r}`}function P(t){return t?"true":"false"}function H(t,r){if(!t||t.trim().length===0)return r;try{const n=JSON.parse(t);return JSON.stringify(n,null,2)}catch{return t}}function ce(){var B,G;const{t}=L(),{pushToast:r}=J(),[n,h]=d.useState("all"),[i,s]=d.useState("all"),[m,y]=d.useState(""),[p,c]=d.useState("all"),[b,a]=d.useState(""),[x,o]=d.useState(""),[f,v]=d.useState(1),[u,_]=d.useState(W[0]),[D,E]=d.useState(null),[V,R]=d.useState(!1),[T,A]=d.useState([]);d.useEffect(()=>{v(1)},[n,i,m,p,b,x,u,T]);const M=d.useMemo(()=>{const l={limit:u,offset:(f-1)*u};n!=="all"&&(l.provider=n),i!=="all"&&(l.endpoint=i),m.trim().length>0&&(l.model=m.trim()),p!=="all"&&(l.status=p);const j=z(b),Q=z(x,!0);return j!==void 0&&(l.from=j),Q!==void 0&&(l.to=Q),T.length>0&&(l.apiKeys=T.join(",")),l},[n,i,m,p,b,x,f,u,T]),g=C(["logs",M],{url:"/api/logs",method:"GET",params:M}),S=C(["providers","all"],{url:"/api/providers",method:"GET"}),q=C(["api-keys"],{url:"/api/keys",method:"GET"});d.useEffect(()=>{g.isError&&g.error&&r({title:t("logs.toast.listError.title"),description:t("logs.toast.listError.desc",{message:g.error.message}),variant:"error"})},[g.isError,g.error,r,t]),d.useEffect(()=>{S.isError&&S.error&&r({title:t("logs.toast.providerError.title"),description:t("logs.toast.providerError.desc",{message:S.error.message}),variant:"error"})},[S.isError,S.error,r,t]);const $=((B=g.data)==null?void 0:B.total)??0,k=$>0?Math.ceil($/u):0,O=((G=g.data)==null?void 0:G.items)??[];d.useEffect(()=>{k>0&&f>k&&v(k)},[k,f]);const F=S.data??[],U=d.useMemo(()=>{const l=new Map;for(const j of F)j.id&&l.set(j.id,j.label??j.id);return l},[F]),K=q.data??[],I=d.useMemo(()=>{const l=new Map;for(const j of K)l.set(j.id,j);return l},[K]),X=d.useMemo(()=>[{value:"all",label:t("logs.filters.statusAll")},{value:"success",label:t("logs.filters.statusSuccess")},{value:"error",label:t("logs.filters.statusError")}],[t]),ee=()=>{h("all"),y(""),s("all"),c("all"),a(""),o(""),A([])},te=d.useCallback(l=>{E(l),R(!0)},[]),se=d.useCallback(()=>{R(!1),E(null)},[]);return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold",children:t("logs.title")}),e.jsx("p",{className:"text-sm text-slate-500 dark:text-slate-400",children:t("logs.description")})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm text-slate-500 dark:text-slate-400","aria-live":"polite",children:[e.jsx("span",{children:t("logs.summary.total",{value:$.toLocaleString()})}),e.jsx("button",{type:"button",className:"rounded-md border border-slate-200 px-3 py-1 transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",onClick:()=>g.refetch(),disabled:g.isFetching,children:g.isFetching?t("common.actions.refreshing"):t("logs.actions.manualRefresh")})]})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3 rounded-lg border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.provider")}),e.jsxs("select",{value:n,onChange:l=>h(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[e.jsx("option",{value:"all",children:t("logs.filters.providerAll")}),F.map(l=>e.jsx("option",{value:l.id,children:l.label??l.id},l.id))]})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.endpoint")}),e.jsxs("select",{value:i,onChange:l=>s(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:[e.jsx("option",{value:"all",children:t("logs.filters.endpointAll")}),e.jsx("option",{value:"anthropic",children:t("logs.filters.endpointAnthropic")}),e.jsx("option",{value:"openai",children:t("logs.filters.endpointOpenAI")})]})]}),e.jsx(oe,{apiKeys:K,selected:T,disabled:q.isLoading,onChange:A}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.modelId")}),e.jsx("input",{value:m,onChange:l=>y(l.target.value),placeholder:t("logs.filters.modelPlaceholder"),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.status")}),e.jsx("select",{value:p,onChange:l=>c(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40",children:X.map(l=>e.jsx("option",{value:l.value,children:l.label},l.value))})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.startDate")}),e.jsx("input",{type:"date",value:b,onChange:l=>a(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsxs("div",{className:"flex flex-col text-sm",children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:t("logs.filters.endDate")}),e.jsx("input",{type:"date",value:x,onChange:l=>o(l.target.value),className:"h-10 w-full rounded-md border border-slate-200 bg-white px-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-blue-400 dark:focus:ring-blue-400/40"})]}),e.jsx("div",{className:"ml-auto flex items-center gap-2 text-sm",children:e.jsx("button",{type:"button",onClick:ee,className:"rounded-md border border-slate-200 px-3 py-2 transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:t("common.actions.reset")})})]})]}),e.jsxs("section",{className:"rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900",children:[e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800",children:[e.jsx("caption",{className:"sr-only",children:t("logs.title")}),e.jsx("thead",{className:"bg-slate-100 dark:bg-slate-800/50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.time")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.endpoint")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.provider")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.requestedModel")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.routedModel")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.apiKey")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.inputTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.cachedTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.outputTokens")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.stream")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.latency")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.ttft")}),e.jsx("th",{className:"px-4 py-2 text-right font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.tpot")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.status")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.error")}),e.jsx("th",{className:"px-4 py-2 text-left font-medium text-slate-500 dark:text-slate-400",children:t("logs.table.columns.actions")})]})}),e.jsx("tbody",{className:"divide-y divide-slate-200 dark:divide-slate-800",children:g.isPending?e.jsx("tr",{children:e.jsx("td",{colSpan:16,className:"px-4 py-10 text-center text-sm text-slate-400",children:t("logs.table.loading")})}):O.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:15,className:"px-4 py-10 text-center text-sm text-slate-400",children:t("logs.table.empty")})}):O.map(l=>e.jsx(re,{record:l,providerLabelMap:U,apiKeyMap:I,onSelect:te},l.id))})]})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-slate-200 px-4 py-3 text-sm dark:border-slate-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{children:t("logs.table.pagination.perPage")}),e.jsx("select",{value:u,onChange:l=>_(Number(l.target.value)),className:"rounded-md border border-slate-200 bg-white px-2 py-1 text-sm dark:border-slate-700 dark:bg-slate-800",children:W.map(l=>e.jsx("option",{value:l,children:l},l))}),e.jsx("span",{children:t("logs.table.pagination.unit")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:()=>v(l=>Math.max(l-1,1)),disabled:f<=1,className:"rounded-md border border-slate-200 px-3 py-1 transition enabled:hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:enabled:hover:bg-slate-800",children:t("logs.table.pagination.previous")}),e.jsx("span",{children:t("logs.table.pagination.pageLabel",{page:k===0?0:f,total:k})}),e.jsx("button",{type:"button",onClick:()=>v(l=>k===0?l:Math.min(l+1,k)),disabled:k===0||f>=k,className:"rounded-md border border-slate-200 px-3 py-1 transition enabled:hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:enabled:hover:bg-slate-800",children:t("logs.table.pagination.next")})]})]})]}),e.jsx(de,{open:V,logId:D,onClose:se,providerLabelMap:U,apiKeyMap:I})]})}function re({record:t,providerLabelMap:r,apiKeyMap:n,onSelect:h}){const{t:i}=L(),s=r.get(t.provider)??t.provider,m=t.endpoint||"-",y=!!t.error,p=t.client_model??i("logs.table.requestedModelFallback"),c=t.api_key_id!=null?n.get(t.api_key_id):void 0,b=t.api_key_id==null?i("logs.table.apiKeyUnknown"):c!=null&&c.isWildcard?i("apiKeys.wildcard"):c!=null&&c.name?c.name:t.api_key_name?t.api_key_name:i("logs.table.apiKeyUnknown");return e.jsxs("tr",{className:"hover:bg-slate-50 dark:hover:bg-slate-800/60",children:[e.jsx("td",{className:"px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:Y(t.timestamp)}),e.jsx("td",{className:"px-4 py-2",children:m}),e.jsx("td",{className:"px-4 py-2",children:s}),e.jsx("td",{className:"px-4 py-2",children:p}),e.jsx("td",{className:"px-4 py-2",children:t.model}),e.jsx("td",{className:"px-4 py-2",children:e.jsx("span",{className:"block truncate",title:b,children:b})}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.input_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.cached_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:w(t.output_tokens)}),e.jsx("td",{className:"px-4 py-2 text-right",children:P(t.stream)}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.latency_ms,i("common.units.ms"))}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.ttft_ms,i("common.units.ms"))}),e.jsx("td",{className:"px-4 py-2 text-right",children:N(t.tpot_ms,i("common.units.msPerToken"))}),e.jsx("td",{className:"px-4 py-2",children:e.jsx(Z,{success:!y,statusCode:t.status_code})}),e.jsx("td",{className:"max-w-xs px-4 py-2 text-xs text-slate-500 dark:text-slate-400",children:e.jsx("span",{className:"block truncate",title:t.error??"",children:t.error?t.error:"-"})}),e.jsx("td",{className:"px-4 py-2",children:e.jsx("button",{type:"button",onClick:()=>h(t.id),"aria-haspopup":"dialog",className:"rounded-md border border-slate-200 px-3 py-1 text-sm transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:i("logs.actions.detail")})})]})}function Z({success:t,statusCode:r}){const{t:n}=L(),h="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",i=t?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-200":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-200";return e.jsxs("span",{className:`${h} ${i}`,children:[n(t?"common.status.success":"common.status.error"),r?` · ${r}`:""]})}function de({open:t,logId:r,onClose:n,providerLabelMap:h,apiKeyMap:i}){var f,v;const{t:s}=L(),{pushToast:m}=J(),y=d.useRef(null),p=d.useRef(null),c=C(["log-detail",r],{url:`/api/logs/${r}`,method:"GET"},{enabled:t&&r!==null,staleTime:3e4});d.useEffect(()=>{c.isError&&c.error&&m({title:s("logs.detail.loadError"),description:c.error.message,variant:"error"})},[c.isError,c.error,m,s]),d.useEffect(()=>{if(!t)return;const u=_=>{_.key==="Escape"&&n()};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[t,n]),d.useEffect(()=>{t&&p.current&&p.current.focus()},[t,r]);const b=d.useCallback(async(u,_,D)=>{if(!_){m({title:s("logs.detail.copy.empty",{label:u}),variant:"info"});return}try{await navigator.clipboard.writeText(_),m({title:s(D),variant:"success"})}catch(E){m({title:s("logs.detail.copy.failure"),description:E instanceof Error?E.message:s("logs.detail.copy.failureFallback"),variant:"error"})}},[m,s]);if(!t)return null;const a=c.data,x=a?h.get(a.provider)??a.provider:"",o=a&&a.api_key_id!=null?i.get(a.api_key_id):void 0;return typeof document>"u"?null:ae.createPortal(e.jsxs("div",{className:"fixed inset-0 z-50 flex",children:[e.jsx("div",{className:"flex-1 bg-slate-900/60",onClick:n,"aria-hidden":"true"}),e.jsxs("aside",{ref:y,role:"dialog","aria-modal":"true","aria-labelledby":"log-detail-title","aria-describedby":"log-detail-content",className:"flex h-full w-full max-w-xl flex-col border-l border-slate-200 bg-white shadow-xl transition-transform dark:border-slate-800 dark:bg-slate-900",children:[e.jsxs("header",{className:"flex items-center justify-between border-b border-slate-200 px-6 py-4 dark:border-slate-800",children:[e.jsxs("div",{children:[e.jsx("h2",{id:"log-detail-title",className:"text-lg font-semibold",children:s("logs.detail.title")}),a?e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.id",{id:a.id})}):null]}),e.jsx("button",{type:"button",ref:p,onClick:n,className:"rounded-md border border-slate-200 px-3 py-1 text-sm transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.close")})]}),e.jsx("div",{id:"log-detail-content",className:"flex-1 overflow-y-auto",children:c.isPending?e.jsx(le,{}):a?e.jsxs("div",{className:"flex flex-col gap-6 px-6 py-5 text-sm",children:[e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.infoSection")}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-md bg-slate-100 px-3 py-2 text-xs text-slate-600 dark:bg-slate-800/60 dark:text-slate-300",children:[e.jsx("span",{className:"text-sm font-medium text-slate-700 dark:text-slate-100",children:s("logs.detail.summary.route",{from:a.client_model??s("logs.detail.info.noRequestedModel"),to:a.model})}),e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.latency",{value:N(a.latency_ms,s("common.units.ms"))})}),a.ttft_ms!==null?e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.ttft",{value:N(a.ttft_ms,s("common.units.ms"))})}):null,a.tpot_ms!==null?e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.tpot",{value:N(a.tpot_ms,s("common.units.msPerToken"))})}):null,e.jsx("span",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.summary.stream",{value:P(a.stream)})}),e.jsx(Z,{success:!a.error,statusCode:a.status_code})]}),e.jsxs("dl",{className:"grid grid-cols-2 gap-x-4 gap-y-3",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.time")}),e.jsx("dd",{className:"font-medium",children:Y(a.timestamp)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.sessionId")}),e.jsx("dd",{className:"font-medium",children:a.session_id??"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.endpoint")}),e.jsx("dd",{className:"font-medium",children:a.endpoint||"-"}),e.jsx("dt",{className:"mt-2 text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.provider")}),e.jsx("dd",{className:"font-medium",children:x})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.requestedModel")}),e.jsx("dd",{className:"font-medium",children:a.client_model??s("logs.detail.info.noRequestedModel")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.model")}),e.jsx("dd",{className:"font-medium",children:a.model})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.stream")}),e.jsx("dd",{className:"font-medium",children:P(a.stream)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.inputTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.input_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.cachedTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.cached_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.outputTokens")}),e.jsx("dd",{className:"font-medium",children:w(a.output_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.ttft")}),e.jsx("dd",{className:"font-medium",children:N(a.ttft_ms,s("common.units.ms"))})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.tpot")}),e.jsx("dd",{className:"font-medium",children:N(a.tpot_ms,s("common.units.msPerToken"))})]})]}),a.error?e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.info.error")}),e.jsx("p",{className:"rounded-md border border-red-200 bg-red-50 p-3 text-xs leading-5 text-red-700 dark:border-red-800/70 dark:bg-red-900/40 dark:text-red-200",children:a.error})]}):null]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.title")}),e.jsxs("dl",{className:"grid gap-x-4 gap-y-3 text-sm sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.name")}),e.jsx("dd",{className:"font-medium",children:a.api_key_id==null&&!a.api_key_name?s("logs.detail.apiKey.missing"):o!=null&&o.isWildcard?s("apiKeys.wildcard"):(o==null?void 0:o.name)??a.api_key_name??s("logs.detail.apiKey.missing")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.identifier")}),e.jsx("dd",{className:"font-medium",children:a.api_key_id??s("common.noData")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.masked")}),e.jsx("dd",{className:"font-medium",children:o!=null&&o.isWildcard?s("apiKeys.wildcard"):(o==null?void 0:o.maskedKey)??a.api_key_name??s("logs.detail.apiKey.maskedUnavailable")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-slate-500 dark:text-slate-400",children:s("logs.detail.apiKey.lastUsed")}),e.jsx("dd",{className:"font-medium",children:o!=null&&o.lastUsedAt?new Date(o.lastUsedAt).toLocaleString():s("common.noData")})]})]}),e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600 dark:border-slate-800 dark:bg-slate-800/60 dark:text-slate-300",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium text-slate-700 dark:text-slate-200",children:s("logs.detail.apiKey.raw")}),e.jsx("p",{className:"mt-1 text-xs",children:a.api_key_value?a.api_key_value:s("logs.detail.apiKey.rawUnavailable")})]}),e.jsx("button",{type:"button",disabled:!a.api_key_value,onClick:()=>b(s("logs.detail.apiKey.raw"),a.api_key_value,"logs.detail.copy.keySuccess"),className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 disabled:opacity-50 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("header",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.payload.request")}),e.jsx("button",{type:"button",onClick:()=>{var u;return b(s("logs.detail.payload.request"),(u=a.payload)==null?void 0:u.prompt,"logs.detail.copy.requestSuccess")},className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border border-slate-200 bg-slate-50 p-3 text-xs leading-5 text-slate-700 dark:border-slate-800 dark:bg-slate-900/80 dark:text-slate-200",children:H((f=a.payload)==null?void 0:f.prompt,s("logs.detail.payload.emptyRequest"))})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("header",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:s("logs.detail.payload.response")}),e.jsx("button",{type:"button",onClick:()=>{var u;return b(s("logs.detail.payload.response"),(u=a.payload)==null?void 0:u.response,"logs.detail.copy.responseSuccess")},className:"rounded-md border border-slate-200 px-2 py-1 text-xs transition hover:bg-slate-100 dark:border-slate-700 dark:hover:bg-slate-800",children:s("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border border-slate-200 bg-slate-50 p-3 text-xs leading-5 text-slate-700 dark:border-slate-800 dark:bg-slate-900/80 dark:text-slate-200",children:H((v=a.payload)==null?void 0:v.response,s("logs.detail.payload.emptyResponse"))})]})]}):e.jsx("div",{className:"flex h-full items-center justify.center p-8 text-sm text-slate-500 dark:text-slate-400",children:s("logs.detail.loadError")})})]})]}),document.body)}function oe({apiKeys:t,selected:r,onChange:n,disabled:h}){const{t:i}=L(),[s,m]=d.useState(!1),y=d.useRef(null);d.useEffect(()=>{if(!s)return;const a=x=>{var o;(o=y.current)!=null&&o.contains(x.target)||m(!1)};return window.addEventListener("mousedown",a),()=>window.removeEventListener("mousedown",a)},[s]);const p=d.useMemo(()=>{if(r.length===0)return[];const a=new Map;for(const x of t)a.set(x.id,x);return r.map(x=>{const o=a.get(x);return o?o.isWildcard?i("apiKeys.wildcard"):o.name:null}).filter(x=>!!x)},[t,r,i]),c=r.length===0?i("logs.filters.apiKeyAll"):i("logs.filters.apiKeySelected",{count:r.length}),b=a=>{r.includes(a)?n(r.filter(x=>x!==a)):n([...r,a])};return e.jsxs("div",{className:"relative flex flex-col text-sm",ref:y,children:[e.jsx("label",{className:"mb-1 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400",children:i("logs.filters.apiKey")}),e.jsxs("button",{type:"button",onClick:()=>m(a=>!a),disabled:h||t.length===0,title:i("logs.filters.apiKeyHint"),className:`flex w-48 items-center justify-between rounded-md border px-3 py-2 text-left text-sm transition focus:outline-none focus:ring-2 focus:ring-blue-200 disabled:opacity-50 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:ring-blue-400/40 ${r.length>0?"border-blue-500 dark:border-blue-500":"border-slate-200"}`,"aria-haspopup":"listbox","aria-expanded":s,children:[e.jsxs("span",{className:"truncate",children:[c,p.length>0&&e.jsx("span",{className:"ml-1 text-xs text-slate-500 dark:text-slate-400",children:p.join(", ")})]}),e.jsx("svg",{className:`h-4 w-4 text-slate-500 transition-transform dark:text-slate-300 ${s?"rotate-180":""}`,viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{fillRule:"evenodd",d:"M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.24 4.25a.75.75 0 01-1.06 0L5.21 8.29a.75.75 0 01.02-1.08z",clipRule:"evenodd"})})]}),s&&e.jsxs("div",{className:"absolute left-0 top-full z-20 mt-2 w-56 rounded-lg border border-slate-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-slate-200 px-3 py-2 text-xs text-slate-500 dark:border-slate-700 dark:text-slate-300",children:[e.jsx("span",{children:c}),e.jsx("button",{type:"button",onClick:()=>n([]),disabled:r.length===0,className:"text-blue-600 hover:underline disabled:opacity-40 dark:text-blue-400",children:i("common.actions.reset")})]}),e.jsxs("div",{className:"max-h-56 overflow-y-auto px-2 py-2",children:[t.map(a=>{const x=a.isWildcard?i("apiKeys.wildcard"):a.name,o=r.includes(a.id);return e.jsxs("label",{className:`flex items-center gap-2 rounded px-2 py-2 text-sm transition hover:bg-slate-100 dark:hover:bg-slate-800 ${o?"bg-slate-100 dark:bg-slate-800/70":""}`,children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4",checked:o,onChange:()=>b(a.id)}),e.jsx("span",{className:"truncate",children:x})]},a.id)}),t.length===0&&e.jsx("p",{className:"px-2 py-2 text-xs text-slate-500 dark:text-slate-400",children:i("logs.filters.apiKeyAll")})]})]})]})}export{ce as default};
|