@chenpu17/cc-gw 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,10 +67,17 @@ UI 支持中英文、深色/浅色主题以及移动端响应式布局,提供
67
67
  1. 启动 cc-gw 并确认配置中 `host` 为 `127.0.0.1`,`port` 与 CLI 启动一致。
68
68
  2. 在安装了 Claude Code 的终端设置环境变量:
69
69
  ```bash
70
- export ANTHROPIC_BASE_URL=http://127.0.0.1:4100
70
+ export ANTHROPIC_BASE_URL=http://127.0.0.1:4100/anthropic
71
71
  claude "help me review this file"
72
72
  ```
73
- 3. cc-gw 会根据 `modelRoutes`/默认策略将 Claude 请求路由到已配置的目标模型(如 Kimi、火山 DeepSeek、OpenAI 或自建模型)。
73
+ 3. 如果使用 VS Code 插件(Claude Code),在“自定义 API”中同样填写 `http://127.0.0.1:4100/anthropic`,插件会自动追加 `/v1/messages` 与 `?beta=true`,最后粘贴 cc-gw Web UI CLI 创建的 API Key。
74
+ 4. cc-gw 会根据 `modelRoutes`/默认策略将 Claude 请求路由到已配置的目标模型(如 Kimi、火山 DeepSeek、OpenAI 或自建模型)。
75
+
76
+ ### 连接 Codex(原 Claude Code for Repo)
77
+ 1. 在 Web UI 的“模型管理 → 路由配置”中为 `/openai` 端点选择目标模型,默认会映射至配置中的 `defaults.completion`。
78
+ 2. 在 Codex 或其他需要 OpenAI 风格接口的客户端中,将 Base URL 设置为 `http://127.0.0.1:4100/openai/v1`;若需手动指定路径,请调用 `POST /openai/v1/responses`。
79
+ 3. 将 API Key 设置为 cc-gw 生成的密钥(支持 Bearer Header 或 `x-api-key` Header)。
80
+ 4. 触发一次 `hello` 或最小请求检查 Streaming 是否正常;若遇到 `Unsupported parameter: thinking` 等提示,说明 cc-gw 已自动剥离该字段并兼容上游。
74
81
 
75
82
  ### 使用场景 / Usage Scenarios
76
83
 
@@ -134,6 +141,7 @@ UI 支持中英文、深色/浅色主题以及移动端响应式布局,提供
134
141
  - `modelRoutes`:将 Claude 发起的模型名映射到上游模型;未命中时使用 `defaults`。
135
142
  - `storePayloads`:是否在 SQLite 中压缩保存原始请求/响应(Brotli),关闭后仅保留元信息。
136
143
  - `logLevel`:控制 Fastify/Pino 控制台日志级别(`fatal`/`error`/`warn`/`info`/`debug`/`trace`)。
144
+ - `providers[].authMode`:仅在 `type: "anthropic"` 时生效,可选 `apiKey`(默认,发送 `x-api-key`)或 `authToken`(发送 `Authorization: Bearer`)。配置 Claude Code 使用 `ANTHROPIC_AUTH_TOKEN` 时,请选择 `authToken` 并在 `apiKey` 输入框填入该值。
137
145
  - `requestLogging`:是否输出每个 HTTP 请求的进入日志。
138
146
  - `responseLogging`:是否输出每个 HTTP 请求完成的日志,可独立于 `requestLogging` 控制。
139
147
  - 推荐通过 Web UI 的“模型管理 / 系统设置”在线编辑并热加载,无需手工修改文件。
@@ -214,13 +222,24 @@ pnpm --filter @cc-gw/web build
214
222
  pnpm --filter @cc-gw/cli exec tsx index.ts start --daemon --port 4100
215
223
  ```
216
224
 
217
- Connect Claude Code by pointing `ANTHROPIC_BASE_URL` to your local gateway:
225
+ Connect Claude Code by pointing `ANTHROPIC_BASE_URL` to the Anthropic namespace on cc-gw. Both the CLI and editor clients append `/v1/messages` automatically:
218
226
 
219
227
  ```bash
220
- export ANTHROPIC_BASE_URL=http://127.0.0.1:4100
228
+ export ANTHROPIC_BASE_URL=http://127.0.0.1:4100/anthropic
221
229
  claude "help me review this file"
222
230
  ```
223
231
 
232
+ Using the Claude Code VS Code extension? Open the extension settings, enable the custom API mode, set the Base URL to the same `http://127.0.0.1:4100/anthropic`, and paste an API key generated from the cc-gw Web UI or CLI—the extension appends `/v1/messages?beta=true` automatically and cc-gw now forwards the query string upstream.
233
+
234
+ Connect Codex (or any OpenAI-compatible IDE integration) by targeting the OpenAI endpoint exposed by cc-gw:
235
+
236
+ ```bash
237
+ export OPENAI_BASE_URL=http://127.0.0.1:4100/openai/v1
238
+ export OPENAI_API_KEY="<your cc-gw api key>"
239
+ ```
240
+
241
+ If the client expects a full path, call `POST /openai/v1/responses`. The gateway strips unsupported fields (such as `thinking`) before forwarding to the upstream provider, so health checks like `hello` should stream back correctly.
242
+
224
243
  ### Configuration Snapshot
225
244
 
226
245
  - Providers include `type`, `baseUrl`, `apiKey`, and `models` descriptions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenpu17/cc-gw",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -51,7 +51,7 @@
51
51
  ],
52
52
  "repository": {
53
53
  "type": "git",
54
- "url": "https://github.com/chenpu17/cc-gw.git"
54
+ "url": "git+https://github.com/chenpu17/cc-gw.git"
55
55
  },
56
56
  "dependencies": {
57
57
  "@fastify/cors": "^9.0.1",
@@ -91,6 +91,16 @@ function parseConfig(raw) {
91
91
  if (!Array.isArray(data.providers)) {
92
92
  data.providers = [];
93
93
  }
94
+ data.providers = data.providers.map((provider) => {
95
+ if (!provider || typeof provider !== "object")
96
+ return provider;
97
+ if (provider.type === "anthropic") {
98
+ provider.authMode = provider.authMode === "authToken" ? "authToken" : "apiKey";
99
+ } else if ("authMode" in provider) {
100
+ delete provider.authMode;
101
+ }
102
+ return provider;
103
+ });
94
104
  const legacyDefaults = sanitizeDefaults(data.defaults);
95
105
  if (typeof data.logRetentionDays !== "number") {
96
106
  data.logRetentionDays = 30;
@@ -572,6 +582,12 @@ function buildAnthropicBody(payload, options = {}) {
572
582
  if (typeof options.temperature === "number") {
573
583
  body.temperature = options.temperature;
574
584
  }
585
+ if (payload.original && typeof payload.original === "object") {
586
+ const original = payload.original;
587
+ if (original.metadata && typeof original.metadata === "object") {
588
+ body.metadata = original.metadata;
589
+ }
590
+ }
575
591
  const tools = options.overrideTools ?? payload.tools;
576
592
  if (tools && tools.length > 0) {
577
593
  body.tools = tools.map((tool) => ({
@@ -590,6 +606,41 @@ function buildAnthropicBody(payload, options = {}) {
590
606
  // providers/openai.ts
591
607
  import { fetch } from "undici";
592
608
  import { ReadableStream } from "stream/web";
609
+
610
+ // providers/utils.ts
611
+ function appendQuery(url, query) {
612
+ if (!query)
613
+ return url;
614
+ const baseHasQuery = url.includes("?");
615
+ if (typeof query === "string") {
616
+ const normalized = query.startsWith("?") ? query.slice(1) : query;
617
+ if (!normalized) {
618
+ return baseHasQuery ? url : `${url}?`;
619
+ }
620
+ return baseHasQuery ? `${url}&${normalized}` : `${url}?${normalized}`;
621
+ }
622
+ const params = new URLSearchParams();
623
+ for (const [key, value] of Object.entries(query)) {
624
+ if (value == null)
625
+ continue;
626
+ if (Array.isArray(value)) {
627
+ for (const item of value) {
628
+ if (item == null)
629
+ continue;
630
+ params.append(key, String(item));
631
+ }
632
+ } else {
633
+ params.append(key, String(value));
634
+ }
635
+ }
636
+ const serialized = params.toString();
637
+ if (!serialized) {
638
+ return baseHasQuery ? url : `${url}?`;
639
+ }
640
+ return baseHasQuery ? `${url}&${serialized}` : `${url}?${serialized}`;
641
+ }
642
+
643
+ // providers/openai.ts
593
644
  var encoder = new TextEncoder();
594
645
  function createJsonStream(payload) {
595
646
  const text = typeof payload === "string" ? payload : JSON.stringify(payload);
@@ -619,7 +670,7 @@ function resolveEndpoint(config, options) {
619
670
  }
620
671
  function createOpenAIConnector(config, options) {
621
672
  const url = resolveEndpoint(config, options);
622
- const shouldLogEndpoint = process.env.CC_GW_DEBUG_ENDPOINTS === "1";
673
+ const shouldLogEndpoint = process.env.CC_GW_DEBUG_ENDPOINTS === "1" || process.env.CC_GW_DEBUG_OPENAI === "1";
623
674
  return {
624
675
  id: config.id,
625
676
  async send(request) {
@@ -637,10 +688,11 @@ function createOpenAIConnector(config, options) {
637
688
  stream: request.stream ?? false
638
689
  };
639
690
  const payload = options?.mutateBody ? options.mutateBody(body) : body;
691
+ const finalUrl = appendQuery(url, request.query);
640
692
  if (shouldLogEndpoint) {
641
- console.info(`[cc-gw] provider=${config.id} endpoint=${url}`);
693
+ console.info(`[cc-gw] provider=${config.id} endpoint=${finalUrl}`);
642
694
  }
643
- const res = await fetch(url, {
695
+ const res = await fetch(finalUrl, {
644
696
  method: "POST",
645
697
  headers,
646
698
  body: JSON.stringify(payload)
@@ -749,18 +801,26 @@ import { fetch as fetch2 } from "undici";
749
801
  var DEFAULT_VERSION = "2023-06-01";
750
802
  function createAnthropicConnector(config) {
751
803
  const baseUrl = config.baseUrl.replace(/\/$/, "");
804
+ const endpoint = resolveAnthropicEndpoint(baseUrl);
805
+ const shouldLogEndpoint = process.env.CC_GW_DEBUG_ENDPOINTS === "1" || process.env.CC_GW_DEBUG_OPENAI === "1";
752
806
  return {
753
807
  id: config.id,
754
808
  async send(request) {
755
- const headers = {
756
- "Content-Type": "application/json",
809
+ const headers = normalizeHeaders({
810
+ "content-type": "application/json",
757
811
  "anthropic-version": DEFAULT_VERSION,
758
812
  ...config.extraHeaders,
759
813
  ...request.headers
760
- };
761
- delete headers.Authorization;
814
+ });
815
+ delete headers.authorization;
816
+ delete headers["x-api-key"];
762
817
  if (config.apiKey) {
763
- headers["x-api-key"] = config.apiKey;
818
+ const mode = config.authMode === "authToken" ? "authToken" : "apiKey";
819
+ if (mode === "authToken") {
820
+ headers.authorization = `Bearer ${config.apiKey}`;
821
+ } else {
822
+ headers["x-api-key"] = config.apiKey;
823
+ }
764
824
  }
765
825
  if (!headers["anthropic-version"]) {
766
826
  headers["anthropic-version"] = DEFAULT_VERSION;
@@ -770,11 +830,37 @@ function createAnthropicConnector(config) {
770
830
  model: request.model,
771
831
  stream: request.stream ?? false
772
832
  };
773
- const response = await fetch2(`${baseUrl}/messages`, {
833
+ const finalUrl = appendQuery(endpoint, request.query);
834
+ if (shouldLogEndpoint) {
835
+ console.info(`[cc-gw] provider=${config.id} endpoint=${finalUrl}`);
836
+ if (process.env.CC_GW_DEBUG_HEADERS === "1") {
837
+ const safeHeaders = {};
838
+ for (const [key, value] of Object.entries(headers)) {
839
+ if (key.toLowerCase().includes("authorization")) {
840
+ safeHeaders[key] = "<redacted>";
841
+ } else {
842
+ safeHeaders[key] = value;
843
+ }
844
+ }
845
+ console.info(`[cc-gw] provider=${config.id} headers`, safeHeaders);
846
+ try {
847
+ console.info(`[cc-gw] provider=${config.id} payload`, JSON.stringify(payload).slice(0, 500));
848
+ } catch {
849
+ console.info(`[cc-gw] provider=${config.id} payload`, "[unserializable payload]");
850
+ }
851
+ }
852
+ }
853
+ if (headers["content-length"]) {
854
+ delete headers["content-length"];
855
+ }
856
+ const response = await fetch2(finalUrl, {
774
857
  method: "POST",
775
858
  headers,
776
859
  body: JSON.stringify(payload)
777
860
  });
861
+ if (shouldLogEndpoint) {
862
+ console.info(`[cc-gw] provider=${config.id} status=${response.status}`);
863
+ }
778
864
  return {
779
865
  status: response.status,
780
866
  headers: response.headers,
@@ -783,6 +869,39 @@ function createAnthropicConnector(config) {
783
869
  }
784
870
  };
785
871
  }
872
+ function normalizeHeaders(source) {
873
+ const result = {};
874
+ for (const [key, value] of Object.entries(source)) {
875
+ if (value == null)
876
+ continue;
877
+ const normalizedKey = key.toLowerCase();
878
+ if (Array.isArray(value)) {
879
+ const candidate = value.find((item) => item != null);
880
+ if (candidate != null) {
881
+ result[normalizedKey] = String(candidate);
882
+ }
883
+ } else {
884
+ result[normalizedKey] = String(value);
885
+ }
886
+ }
887
+ return result;
888
+ }
889
+ function resolveAnthropicEndpoint(baseUrl) {
890
+ const normalized = baseUrl.replace(/\/$/, "");
891
+ if (normalized.endsWith("/messages") || normalized.match(/\/v\d+\/messages$/)) {
892
+ return normalized;
893
+ }
894
+ if (normalized.match(/\/v\d+$/)) {
895
+ return `${normalized}/messages`;
896
+ }
897
+ if (normalized.endsWith("/anthropic")) {
898
+ return `${normalized}/v1/messages`;
899
+ }
900
+ if (normalized.endsWith("/anthropic/v1")) {
901
+ return `${normalized}/messages`;
902
+ }
903
+ return `${normalized}/v1/messages`;
904
+ }
786
905
 
787
906
  // providers/registry.ts
788
907
  var connectors = /* @__PURE__ */ new Map();
@@ -1808,13 +1927,18 @@ async function registerMessagesRoute(app) {
1808
1927
  };
1809
1928
  const rawUrl = typeof request.raw?.url === "string" ? request.raw.url : request.url ?? "";
1810
1929
  let querySuffix = null;
1811
- if (typeof rawUrl === "string" && rawUrl.includes("?")) {
1812
- querySuffix = rawUrl.slice(rawUrl.indexOf("?"));
1813
- } else if (typeof request.querystring === "string" && request.querystring.length > 0) {
1814
- querySuffix = `?${request.querystring}`;
1930
+ if (typeof rawUrl === "string") {
1931
+ const questionIndex = rawUrl.indexOf("?");
1932
+ if (questionIndex !== -1) {
1933
+ querySuffix = rawUrl.slice(questionIndex + 1);
1934
+ }
1815
1935
  }
1816
- if (querySuffix) {
1817
- console.info(`[cc-gw] inbound url ${rawUrl} query ${querySuffix}`);
1936
+ if (!querySuffix && typeof request.querystring === "string") {
1937
+ querySuffix = request.querystring || null;
1938
+ }
1939
+ if (querySuffix !== null) {
1940
+ const displaySuffix = querySuffix.length > 0 ? `?${querySuffix}` : "?";
1941
+ console.info(`[cc-gw] inbound url ${rawUrl} query ${displaySuffix}`);
1818
1942
  }
1819
1943
  const normalized = normalizeClaudePayload(payload);
1820
1944
  const requestedModel = typeof payload.model === "string" ? payload.model : void 0;
@@ -2472,6 +2596,7 @@ data: ${JSON.stringify(data)}
2472
2596
  };
2473
2597
  app.post("/v1/messages", handler);
2474
2598
  app.post("/anthropic/v1/messages", handler);
2599
+ app.post("/anthropic/v1/v1/messages", handler);
2475
2600
  }
2476
2601
 
2477
2602
  // protocol/normalize-openai.ts
@@ -3742,13 +3867,19 @@ async function createServer() {
3742
3867
  }
3743
3868
  if (responseLogEnabled) {
3744
3869
  app.addHook("onResponse", (request, reply, done) => {
3870
+ let elapsedTime;
3871
+ if (typeof reply.elapsedTime === "number") {
3872
+ elapsedTime = reply.elapsedTime;
3873
+ } else if (typeof reply.getResponseTime === "function") {
3874
+ elapsedTime = reply.getResponseTime();
3875
+ }
3745
3876
  app.log.info(
3746
3877
  {
3747
3878
  reqId: request.id,
3748
3879
  res: {
3749
3880
  statusCode: reply.statusCode
3750
3881
  },
3751
- responseTime: typeof reply.getResponseTime === "function" ? reply.getResponseTime() : void 0
3882
+ responseTime: elapsedTime
3752
3883
  },
3753
3884
  "request completed"
3754
3885
  );
@@ -1 +1 @@
1
- import{u as x,a as p,r as o,j as e}from"./index-CDJfhjXI.js";import{u as m}from"./useApiQuery-Bna2BImG.js";const h="0.3.0",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
+ import{u as x,a as p,r as o,j as e}from"./index-BekAYLv4.js";import{u as m}from"./useApiQuery-CUC2GmXO.js";const h="0.3.1",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-CDJfhjXI.js";import{E as L}from"./index-DG02tgGK.js";import{u as N,a as v}from"./useApiQuery-Bna2BImG.js";/**
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-BekAYLv4.js";import{E as L}from"./index-D14cSZuL.js";import{u as N,a as v}from"./useApiQuery-CUC2GmXO.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-CDJfhjXI.js";import{E as O}from"./index-DG02tgGK.js";import{u as v}from"./useApiQuery-Bna2BImG.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-BekAYLv4.js";import{E as O}from"./index-D14cSZuL.js";import{u as v}from"./useApiQuery-CUC2GmXO.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-CDJfhjXI.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
+ import{u as c,r as d,j as e}from"./index-BekAYLv4.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-CDJfhjXI.js";import{u as C}from"./useApiQuery-Bna2BImG.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-BekAYLv4.js";import{u as C}from"./useApiQuery-CUC2GmXO.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};