@chenpu17/cc-gw 0.7.6 → 0.7.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/src/server/dist/index.js +133 -70
  3. package/src/web/dist/assets/About-DCvCA-EN.js +6 -0
  4. package/src/web/dist/assets/{ApiKeys-DU4MstBL.js → ApiKeys-chBAE4F4.js} +1 -1
  5. package/src/web/dist/assets/Dashboard-B4kvSkr7.js +16 -0
  6. package/src/web/dist/assets/{Events-CWHxopwa.js → Events-D9F6cmSK.js} +1 -1
  7. package/src/web/dist/assets/{Help-DXyYkQj7.js → Help-WBFjl1uQ.js} +1 -1
  8. package/src/web/dist/assets/{Login-DNlwRCtC.js → Login-C2ITDdIa.js} +1 -1
  9. package/src/web/dist/assets/Logs-Cb_N4UAX.js +6 -0
  10. package/src/web/dist/assets/{ModelManagement-Csx-5GKf.js → ModelManagement-IWXiEI0s.js} +1 -1
  11. package/src/web/dist/assets/{PageHeader-BeW-Othf.js → PageHeader-xFKpGYn6.js} +1 -1
  12. package/src/web/dist/assets/{PageSection-DW84HFxm.js → PageSection-Vn4S3q9j.js} +1 -1
  13. package/src/web/dist/assets/{Settings-DrGMG3PK.js → Settings-DJ0_2N3_.js} +1 -1
  14. package/src/web/dist/assets/{card-DO6ly30k.js → card-C20_HqC6.js} +1 -1
  15. package/src/web/dist/assets/{copy-CSLiPZ3j.js → copy-CUEQDKMx.js} +1 -1
  16. package/src/web/dist/assets/{dialog-BTot8EYU.js → dialog-Cx1HX_hR.js} +1 -1
  17. package/src/web/dist/assets/{index-CJAz7pOx.js → index-DgjUxG8I.js} +1 -1
  18. package/src/web/dist/assets/{index-D_Dbqo2u.js → index-UV1Qa96f.js} +2 -2
  19. package/src/web/dist/assets/{info-XoeNrG0H.js → info-CewFzdVp.js} +1 -1
  20. package/src/web/dist/assets/{input-Ckx5qHOQ.js → input-CBGvcnZr.js} +1 -1
  21. package/src/web/dist/assets/{label-D2cIIMBu.js → label-BqSverDm.js} +1 -1
  22. package/src/web/dist/assets/{refresh-cw-C-S3w6yD.js → refresh-cw-ISOSG1Po.js} +1 -1
  23. package/src/web/dist/assets/{select-CMGw70tW.js → select-C8rWWJbl.js} +1 -1
  24. package/src/web/dist/assets/{switch-BYGfNhav.js → switch-ODrypdNp.js} +1 -1
  25. package/src/web/dist/assets/{useApiQuery-ByGFZwHE.js → useApiQuery-C2OD7H7U.js} +1 -1
  26. package/src/web/dist/index.html +1 -1
  27. package/src/web/dist/assets/About-B0d_J5xQ.js +0 -6
  28. package/src/web/dist/assets/Dashboard-DrjpMpn5.js +0 -16
  29. package/src/web/dist/assets/Logs-CzXUpOMo.js +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenpu17/cc-gw",
3
- "version": "0.7.6",
3
+ "version": "0.7.11",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -13779,16 +13779,26 @@ async function registerMessagesRoute(app) {
13779
13779
  }
13780
13780
  } else {
13781
13781
  const collected = {};
13782
- const skip = /* @__PURE__ */ new Set(["content-length", "host", "connection", "transfer-encoding"]);
13783
- const allowedPrefixes = ["x-stainless-", "anthropic-"];
13784
- const allowedHeaders = /* @__PURE__ */ new Set(["user-agent", "content-type", "accept"]);
13782
+ const excludedHeaders = /* @__PURE__ */ new Set([
13783
+ "host",
13784
+ "connection",
13785
+ "content-length",
13786
+ "transfer-encoding",
13787
+ "keep-alive",
13788
+ "upgrade",
13789
+ "proxy-connection",
13790
+ "proxy-authenticate",
13791
+ "proxy-authorization",
13792
+ "te",
13793
+ "trailer",
13794
+ "upgrade-insecure-requests",
13795
+ "authorization",
13796
+ "x-api-key"
13797
+ ]);
13785
13798
  const sourceHeaders = request.raw?.headers ?? request.headers;
13786
13799
  for (const [headerKey, headerValue] of Object.entries(sourceHeaders)) {
13787
13800
  const lower = headerKey.toLowerCase();
13788
- if (skip.has(lower))
13789
- continue;
13790
- const shouldForward = allowedHeaders.has(lower) || allowedPrefixes.some((prefix) => lower.startsWith(prefix));
13791
- if (!shouldForward)
13801
+ if (excludedHeaders.has(lower))
13792
13802
  continue;
13793
13803
  let value;
13794
13804
  if (typeof headerValue === "string") {
@@ -15069,12 +15079,27 @@ function filterForwardedAnthropicHeaders(headers) {
15069
15079
  if (!headers)
15070
15080
  return {};
15071
15081
  const result = {};
15072
- const allowContentHeaders = /* @__PURE__ */ new Set(["content-type", "accept", "user-agent"]);
15082
+ const excludedHeaders = /* @__PURE__ */ new Set([
15083
+ "host",
15084
+ "connection",
15085
+ "content-length",
15086
+ "transfer-encoding",
15087
+ "keep-alive",
15088
+ "upgrade",
15089
+ "proxy-connection",
15090
+ "proxy-authenticate",
15091
+ "proxy-authorization",
15092
+ "te",
15093
+ "trailer",
15094
+ "upgrade-insecure-requests",
15095
+ "authorization",
15096
+ "x-api-key"
15097
+ ]);
15073
15098
  for (const [key, value] of Object.entries(headers)) {
15074
15099
  if (!value)
15075
15100
  continue;
15076
15101
  const lower = key.toLowerCase();
15077
- if (lower.startsWith("anthropic-") || lower.startsWith("x-stainless-") || allowContentHeaders.has(lower)) {
15102
+ if (!excludedHeaders.has(lower)) {
15078
15103
  result[lower] = value;
15079
15104
  }
15080
15105
  }
@@ -15440,6 +15465,18 @@ async function registerOpenAiRoutes(app) {
15440
15465
  const rawHeaders = request.raw?.headers ?? request.headers;
15441
15466
  const forwarded = collectAnthropicForwardHeaders(rawHeaders);
15442
15467
  providerHeaders = filterForwardedAnthropicHeaders(forwarded);
15468
+ if (OPENAI_DEBUG) {
15469
+ debugLog("responses non-anthropic forwarded headers", providerHeaders);
15470
+ }
15471
+ request.log.info(
15472
+ {
15473
+ event: "responses.forward_headers",
15474
+ provider: target.providerId,
15475
+ model: target.modelId,
15476
+ headers: providerHeaders
15477
+ },
15478
+ "forwarding headers (responses, non-anthropic provider)"
15479
+ );
15443
15480
  providerBody = { ...payload };
15444
15481
  providerBody.model = target.modelId;
15445
15482
  if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
@@ -16024,6 +16061,18 @@ async function registerOpenAiRoutes(app) {
16024
16061
  const rawHeaders = request.raw?.headers ?? request.headers;
16025
16062
  const forwarded = collectAnthropicForwardHeaders(rawHeaders);
16026
16063
  providerHeaders = filterForwardedAnthropicHeaders(forwarded);
16064
+ if (OPENAI_DEBUG) {
16065
+ debugLog("chat completions non-anthropic forwarded headers", providerHeaders);
16066
+ }
16067
+ request.log.info(
16068
+ {
16069
+ event: "chat.completions.forward_headers",
16070
+ provider: target.providerId,
16071
+ model: target.modelId,
16072
+ headers: providerHeaders
16073
+ },
16074
+ "forwarding headers (chat completions, non-anthropic provider)"
16075
+ );
16027
16076
  providerBody = buildProviderBody(normalized, {
16028
16077
  maxTokens: typeof payload.max_tokens === "number" ? payload.max_tokens : void 0,
16029
16078
  temperature: typeof payload.temperature === "number" ? payload.temperature : void 0,
@@ -16998,7 +17047,7 @@ async function registerAdminRoutes(app) {
16998
17047
  const model = typeof raw.model === "string" && raw.model.length > 0 ? raw.model : void 0;
16999
17048
  const statusParam = typeof raw.status === "string" ? raw.status : void 0;
17000
17049
  const status = statusParam === "success" || statusParam === "error" ? statusParam : void 0;
17001
- const endpoint = isEndpoint(raw.endpoint) ? raw.endpoint : void 0;
17050
+ const endpoint = typeof raw.endpoint === "string" && raw.endpoint.length > 0 ? raw.endpoint : void 0;
17002
17051
  const from = parseTimestamp(raw.from);
17003
17052
  const to = parseTimestamp(raw.to);
17004
17053
  const apiKeyIdsRaw = parseApiKeyIds(raw.apiKeys ?? raw.apiKeyIds ?? raw.apiKey);
@@ -17706,14 +17755,14 @@ async function registerAdminRoutes(app) {
17706
17755
  });
17707
17756
  app.get("/api/stats/overview", async (request) => {
17708
17757
  const query = request.query ?? {};
17709
- const endpoint = isEndpoint(query.endpoint) ? query.endpoint : void 0;
17758
+ const endpoint = typeof query.endpoint === "string" && query.endpoint.length > 0 ? query.endpoint : void 0;
17710
17759
  return getMetricsOverview(endpoint);
17711
17760
  });
17712
17761
  app.get("/api/stats/daily", async (request) => {
17713
17762
  const query = request.query ?? {};
17714
17763
  const daysRaw = Number(query.days ?? 7);
17715
17764
  const days = Number.isFinite(daysRaw) ? Math.max(1, Math.min(daysRaw, 30)) : 7;
17716
- const endpoint = isEndpoint(query.endpoint) ? query.endpoint : void 0;
17765
+ const endpoint = typeof query.endpoint === "string" && query.endpoint.length > 0 ? query.endpoint : void 0;
17717
17766
  return getDailyMetrics(days, endpoint);
17718
17767
  });
17719
17768
  app.get("/api/stats/model", async (request) => {
@@ -17722,14 +17771,14 @@ async function registerAdminRoutes(app) {
17722
17771
  const limitRaw = Number(query.limit ?? 10);
17723
17772
  const days = Number.isFinite(daysRaw) ? Math.max(1, Math.min(daysRaw, 90)) : 7;
17724
17773
  const limit = Number.isFinite(limitRaw) ? Math.max(1, Math.min(limitRaw, 50)) : 10;
17725
- const endpoint = isEndpoint(query.endpoint) ? query.endpoint : void 0;
17774
+ const endpoint = typeof query.endpoint === "string" && query.endpoint.length > 0 ? query.endpoint : void 0;
17726
17775
  return getModelUsageMetrics(days, limit, endpoint);
17727
17776
  });
17728
17777
  app.get("/api/stats/api-keys/overview", async (request) => {
17729
17778
  const query = request.query ?? {};
17730
17779
  const daysRaw = Number(query.days ?? 7);
17731
17780
  const rangeDays = Number.isFinite(daysRaw) ? Math.max(1, Math.min(daysRaw, 90)) : 7;
17732
- const endpoint = isEndpoint(query.endpoint) ? query.endpoint : void 0;
17781
+ const endpoint = typeof query.endpoint === "string" && query.endpoint.length > 0 ? query.endpoint : void 0;
17733
17782
  return getApiKeyOverviewMetrics(rangeDays, endpoint);
17734
17783
  });
17735
17784
  app.get("/api/stats/api-keys/usage", async (request) => {
@@ -17738,7 +17787,7 @@ async function registerAdminRoutes(app) {
17738
17787
  const limitRaw = Number(query.limit ?? 10);
17739
17788
  const days = Number.isFinite(daysRaw) ? Math.max(1, Math.min(daysRaw, 90)) : 7;
17740
17789
  const limit = Number.isFinite(limitRaw) ? Math.max(1, Math.min(limitRaw, 50)) : 10;
17741
- const endpoint = isEndpoint(query.endpoint) ? query.endpoint : void 0;
17790
+ const endpoint = typeof query.endpoint === "string" && query.endpoint.length > 0 ? query.endpoint : void 0;
17742
17791
  return getApiKeyUsageMetrics(days, limit, endpoint);
17743
17792
  });
17744
17793
  app.get("/api/keys", async () => {
@@ -18037,7 +18086,6 @@ async function registerAdminRoutes(app) {
18037
18086
  }
18038
18087
  });
18039
18088
  }
18040
- var isEndpoint = (value) => value === "anthropic" || value === "openai";
18041
18089
 
18042
18090
  // routes/events.ts
18043
18091
  async function registerEventsRoutes(app) {
@@ -18436,24 +18484,29 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
18436
18484
  const validationConfig = endpoint.routing?.validation ?? configSnapshot.endpointRouting?.anthropic?.validation;
18437
18485
  const validationMode = validationConfig?.mode ?? "off";
18438
18486
  const providerHeaders = {};
18439
- const headersToForward = [
18440
- "user-agent",
18441
- "anthropic-version",
18442
- "anthropic-beta",
18443
- "x-stainless-arch",
18444
- "x-stainless-async",
18445
- "x-stainless-lang",
18446
- "x-stainless-os",
18447
- "x-stainless-package-version",
18448
- "x-stainless-runtime",
18449
- "x-stainless-runtime-version"
18450
- ];
18451
- for (const key of headersToForward) {
18452
- const value = request.headers[key];
18453
- if (typeof value === "string" && value.length > 0) {
18454
- providerHeaders[key] = value;
18455
- } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
18456
- providerHeaders[key] = value[0];
18487
+ const excludedHeaders = /* @__PURE__ */ new Set([
18488
+ "host",
18489
+ "connection",
18490
+ "content-length",
18491
+ "transfer-encoding",
18492
+ "keep-alive",
18493
+ "upgrade",
18494
+ "proxy-connection",
18495
+ "proxy-authenticate",
18496
+ "proxy-authorization",
18497
+ "te",
18498
+ "trailer",
18499
+ "upgrade-insecure-requests",
18500
+ "authorization",
18501
+ "x-api-key"
18502
+ ]);
18503
+ for (const [key, rawValue] of Object.entries(request.headers)) {
18504
+ const lower = key.toLowerCase();
18505
+ if (excludedHeaders.has(lower))
18506
+ continue;
18507
+ const value = typeof rawValue === "string" ? rawValue : Array.isArray(rawValue) ? rawValue[0] : void 0;
18508
+ if (value && value.length > 0) {
18509
+ providerHeaders[lower] = value;
18457
18510
  }
18458
18511
  }
18459
18512
  const providedApiKey = extractApiKeyFromRequest2(request);
@@ -18906,24 +18959,29 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
18906
18959
  querySuffix = request.querystring || null;
18907
18960
  }
18908
18961
  const providerHeaders = {};
18909
- const headersToForward = [
18910
- "user-agent",
18911
- "anthropic-version",
18912
- "anthropic-beta",
18913
- "x-stainless-arch",
18914
- "x-stainless-async",
18915
- "x-stainless-lang",
18916
- "x-stainless-os",
18917
- "x-stainless-package-version",
18918
- "x-stainless-runtime",
18919
- "x-stainless-runtime-version"
18920
- ];
18921
- for (const key of headersToForward) {
18922
- const value = request.headers[key];
18923
- if (typeof value === "string" && value.length > 0) {
18924
- providerHeaders[key] = value;
18925
- } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
18926
- providerHeaders[key] = value[0];
18962
+ const excludedHeaders = /* @__PURE__ */ new Set([
18963
+ "host",
18964
+ "connection",
18965
+ "content-length",
18966
+ "transfer-encoding",
18967
+ "keep-alive",
18968
+ "upgrade",
18969
+ "proxy-connection",
18970
+ "proxy-authenticate",
18971
+ "proxy-authorization",
18972
+ "te",
18973
+ "trailer",
18974
+ "upgrade-insecure-requests",
18975
+ "authorization",
18976
+ "x-api-key"
18977
+ ]);
18978
+ for (const [key, rawValue] of Object.entries(request.headers)) {
18979
+ const lower = key.toLowerCase();
18980
+ if (excludedHeaders.has(lower))
18981
+ continue;
18982
+ const value = typeof rawValue === "string" ? rawValue : Array.isArray(rawValue) ? rawValue[0] : void 0;
18983
+ if (value && value.length > 0) {
18984
+ providerHeaders[lower] = value;
18927
18985
  }
18928
18986
  }
18929
18987
  const providedApiKey = extractApiKeyFromRequest2(request);
@@ -19260,24 +19318,29 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
19260
19318
  querySuffix = request.querystring || null;
19261
19319
  }
19262
19320
  const providerHeaders = {};
19263
- const headersToForward = [
19264
- "user-agent",
19265
- "anthropic-version",
19266
- "anthropic-beta",
19267
- "x-stainless-arch",
19268
- "x-stainless-async",
19269
- "x-stainless-lang",
19270
- "x-stainless-os",
19271
- "x-stainless-package-version",
19272
- "x-stainless-runtime",
19273
- "x-stainless-runtime-version"
19274
- ];
19275
- for (const key of headersToForward) {
19276
- const value = request.headers[key];
19277
- if (typeof value === "string" && value.length > 0) {
19278
- providerHeaders[key] = value;
19279
- } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
19280
- providerHeaders[key] = value[0];
19321
+ const excludedHeaders = /* @__PURE__ */ new Set([
19322
+ "host",
19323
+ "connection",
19324
+ "content-length",
19325
+ "transfer-encoding",
19326
+ "keep-alive",
19327
+ "upgrade",
19328
+ "proxy-connection",
19329
+ "proxy-authenticate",
19330
+ "proxy-authorization",
19331
+ "te",
19332
+ "trailer",
19333
+ "upgrade-insecure-requests",
19334
+ "authorization",
19335
+ "x-api-key"
19336
+ ]);
19337
+ for (const [key, rawValue] of Object.entries(request.headers)) {
19338
+ const lower = key.toLowerCase();
19339
+ if (excludedHeaders.has(lower))
19340
+ continue;
19341
+ const value = typeof rawValue === "string" ? rawValue : Array.isArray(rawValue) ? rawValue[0] : void 0;
19342
+ if (value && value.length > 0) {
19343
+ providerHeaders[lower] = value;
19281
19344
  }
19282
19345
  }
19283
19346
  const providedApiKey = extractApiKeyFromRequest2(request);
@@ -0,0 +1,6 @@
1
+ import{c as j,u as g,b as v,r as i,j as e,e as d,a5 as N}from"./index-UV1Qa96f.js";import{u as y}from"./useApiQuery-C2OD7H7U.js";import{P as E}from"./PageHeader-xFKpGYn6.js";import{P as n}from"./PageSection-Vn4S3q9j.js";import{C as m,a as p}from"./card-C20_HqC6.js";import{I}from"./info-CewFzdVp.js";import{R as T}from"./refresh-cw-ISOSG1Po.js";/**
2
+ * @license lucide-react v0.344.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const k=j("Sparkles",[["path",{d:"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z",key:"17u4zn"}],["path",{d:"M5 3v4",key:"bklmnn"}],["path",{d:"M19 17v4",key:"iiml17"}],["path",{d:"M3 5h4",key:"nem4j1"}],["path",{d:"M17 19h4",key:"lbex7p"}]]),_="0.7.11",w={version:_},L={VITE_BUILD_TIME:"2025-12-15T01:57:09.233Z",VITE_NODE_VERSION:"v22.16.0"};function u({items:t}){return t.length===0?null:e.jsx("dl",{className:"grid gap-4 sm:grid-cols-2",children:t.map(a=>e.jsx(m,{children:e.jsxs(p,{className:"pt-4",children:[e.jsx("dt",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a.label}),e.jsx("dd",{className:"mt-1 text-sm font-semibold",children:a.value}),a.hint&&e.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:a.hint})]})},a.label))})}function D(){const{t}=g(),{pushToast:a}=v(),s=y(["status","gateway"],{url:"/api/status",method:"GET"},{staleTime:6e4});i.useEffect(()=>{s.isError&&s.error&&a({title:t("about.toast.statusError.title"),description:s.error.message,variant:"error"})},[s.isError,s.error,a,t]);const o=w.version,r=i.useMemo(()=>{const c=L,b=c.VITE_BUILD_TIME,f=c.VITE_NODE_VERSION;return{buildTime:b,nodeVersion:f}},[]),x=i.useMemo(()=>[{label:t("about.app.labels.name"),value:e.jsx("span",{className:"font-mono",children:"cc-gw"})},{label:t("about.app.labels.version"),value:e.jsxs("span",{className:"font-mono text-primary",children:["v",o]})},{label:t("about.app.labels.buildTime"),value:r.buildTime,hint:t("about.app.hint.buildTime")},{label:t("about.app.labels.node"),value:e.jsx("span",{className:"font-mono",children:r.nodeVersion})}],[o,r.buildTime,r.nodeVersion,t]),l=i.useMemo(()=>s.data?[{label:t("about.status.labels.host"),value:s.data.host??"127.0.0.1"},{label:t("about.status.labels.port"),value:s.data.port.toLocaleString()},{label:t("about.status.labels.providers"),value:s.data.providers.toLocaleString()},{label:t("about.status.labels.active"),value:(s.data.activeRequests??0).toLocaleString(),hint:t("about.status.hint.active")}]:[],[s.data,t]),h=()=>{a({title:t("about.toast.updatesPlanned"),variant:"info"})};return e.jsxs("div",{className:"space-y-6",children:[e.jsx(E,{icon:e.jsx(I,{className:"h-5 w-5","aria-hidden":"true"}),title:t("about.title"),description:t("about.description"),badge:`v${o}`,actions:e.jsxs(d,{onClick:h,children:[e.jsx(k,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),t("about.support.actions.checkUpdates")]})}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(n,{title:t("about.app.title"),description:t("about.app.subtitle"),children:e.jsx(u,{items:x})}),e.jsx(n,{title:t("about.status.title"),description:t("about.status.subtitle"),actions:e.jsxs(d,{variant:"outline",size:"sm",onClick:()=>s.refetch(),disabled:s.isFetching,children:[e.jsx(T,{className:`mr-2 h-4 w-4 ${s.isFetching?"animate-spin":""}`,"aria-hidden":"true"}),s.isFetching?t("common.actions.refreshing"):t("common.actions.refresh")]}),children:s.isLoading?e.jsxs("div",{className:"flex h-32 flex-col items-center justify-center gap-2 text-center",children:[e.jsx("div",{className:"h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t("about.status.loading")})]}):l.length>0?e.jsx(u,{items:l}):e.jsxs("div",{className:"flex h-32 flex-col items-center justify-center gap-1 rounded-lg border border-dashed p-6 text-center",children:[e.jsx("p",{className:"text-sm font-medium",children:t("about.status.empty")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t("common.actions.refresh")})]})})]}),e.jsx(n,{title:t("about.support.title"),description:e.jsxs("span",{className:"space-y-1",children:[e.jsx("span",{className:"block text-sm font-medium text-primary",children:t("about.support.subtitle")}),e.jsx("span",{children:t("about.support.description")})]}),children:e.jsx(m,{children:e.jsxs(p,{className:"flex flex-col gap-4 pt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start gap-4",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary",children:e.jsx(N,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx("p",{className:"flex-1 text-sm text-muted-foreground",children:t("about.support.tip")})]}),e.jsx("code",{className:"inline-flex self-start rounded-md bg-muted px-3 py-1.5 text-xs font-medium",children:"~/.cc-gw/config.json"})]})})})]})}export{D as default};
@@ -1,4 +1,4 @@
1
- import{c as D,r as c,j as e,a as $,u as Z,b as de,L as pe,e as o,K as me,v as ue,d as K}from"./index-D_Dbqo2u.js";import{E as ye}from"./index-CJAz7pOx.js";import{u as w}from"./useApiQuery-ByGFZwHE.js";import{P as xe,B as q}from"./PageHeader-BeW-Othf.js";import{P as z}from"./PageSection-DW84HFxm.js";import{c as he}from"./clipboard-CALi6bTW.js";import{I as ge}from"./input-Ckx5qHOQ.js";import{L as I}from"./label-D2cIIMBu.js";import{C as T,a as S}from"./card-DO6ly30k.js";import{P as fe,D as W,a as H,b as V,c as G,d as je,e as Q}from"./dialog-BTot8EYU.js";import{C as U}from"./copy-CSLiPZ3j.js";/**
1
+ import{c as D,r as c,j as e,a as $,u as Z,b as de,L as pe,e as o,K as me,v as ue,d as K}from"./index-UV1Qa96f.js";import{E as ye}from"./index-DgjUxG8I.js";import{u as w}from"./useApiQuery-C2OD7H7U.js";import{P as xe,B as q}from"./PageHeader-xFKpGYn6.js";import{P as z}from"./PageSection-Vn4S3q9j.js";import{c as he}from"./clipboard-CALi6bTW.js";import{I as ge}from"./input-CBGvcnZr.js";import{L as I}from"./label-BqSverDm.js";import{C as T,a as S}from"./card-C20_HqC6.js";import{P as fe,D as W,a as H,b as V,c as G,d as je,e as Q}from"./dialog-Cx1HX_hR.js";import{C as U}from"./copy-CUEQDKMx.js";/**
2
2
  * @license lucide-react v0.344.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1,16 @@
1
+ import{c as O,r as d,j as e,a as f,u as I,b as ne,d as ie,t as le,L as ce,B as D,e as me}from"./index-UV1Qa96f.js";import{E as he}from"./index-DgjUxG8I.js";import{P as ue,B as k}from"./PageHeader-xFKpGYn6.js";import{P as X}from"./PageSection-Vn4S3q9j.js";import{u as S}from"./useApiQuery-C2OD7H7U.js";import{C as G,a as Q}from"./card-C20_HqC6.js";import{S as xe,a as pe,b as be,c as ge,d as q}from"./select-C8rWWJbl.js";/**
2
+ * @license lucide-react v0.344.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const $=O("Activity",[["path",{d:"M22 12h-4l-3 9L9 3l-3 9H2",key:"d5dnw9"}]]);/**
7
+ * @license lucide-react v0.344.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const fe=O("Timer",[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]]);/**
12
+ * @license lucide-react v0.344.0 - ISC
13
+ *
14
+ * This source code is licensed under the ISC license.
15
+ * See the LICENSE file in the root directory of this source tree.
16
+ */const ye=O("TrendingUp",[["polyline",{points:"22 7 13.5 15.5 8.5 10.5 2 17",key:"126l90"}],["polyline",{points:"16 7 22 7 22 13",key:"kwv8wd"}]]),F=d.forwardRef(({className:t,...s},a)=>e.jsx("div",{className:"relative w-full overflow-auto rounded-lg",children:e.jsx("table",{ref:a,className:f("w-full caption-bottom text-sm border-collapse",t),...s})}));F.displayName="Table";const H=d.forwardRef(({className:t,...s},a)=>e.jsx("thead",{ref:a,className:f("bg-muted/40 [&_tr]:border-b [&_tr]:border-border/60",t),...s}));H.displayName="TableHeader";const _=d.forwardRef(({className:t,...s},a)=>e.jsx("tbody",{ref:a,className:f("[&_tr:last-child]:border-0",t),...s}));_.displayName="TableBody";const je=d.forwardRef(({className:t,...s},a)=>e.jsx("tfoot",{ref:a,className:f("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",t),...s}));je.displayName="TableFooter";const A=d.forwardRef(({className:t,...s},a)=>e.jsx("tr",{ref:a,className:f("border-b border-border/50 transition-all duration-150","hover:bg-primary/5 data-[state=selected]:bg-primary/10","group",t),...s}));A.displayName="TableRow";const h=d.forwardRef(({className:t,...s},a)=>e.jsx("th",{ref:a,className:f("h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-wider text-muted-foreground/80","[&:has([role=checkbox])]:pr-0",t),...s}));h.displayName="TableHead";const u=d.forwardRef(({className:t,...s},a)=>e.jsx("td",{ref:a,className:f("px-4 py-3 align-middle text-sm","[&:has([role=checkbox])]:pr-0","group-hover:text-foreground transition-colors",t),...s}));u.displayName="TableCell";const ve=d.forwardRef(({className:t,...s},a)=>e.jsx("caption",{ref:a,className:f("mt-4 text-sm text-muted-foreground",t),...s}));ve.displayName="TableCaption";function P(t,s,a){return t==null?"-":`${t.toLocaleString(void 0,a)} ${s}`}function W(t){if(t==null)return"-";if(t<1024)return`${t} B`;const s=["KB","MB","GB","TB"];let a=t/1024,r=0;for(;a>=1024&&r<s.length-1;)a/=1024,r+=1;return`${a.toFixed(a>=100?0:a>=10?1:2)} ${s[r]}`}function Ae(){var U,V,K;const{t}=I(),{pushToast:s}=ne(),[a,r]=d.useState("all"),[i,y]=d.useState(!1),x=a==="all"?void 0:a,Y=S(["custom-endpoints"],{url:"/api/custom-endpoints",method:"GET"}),N=S(["stats","overview",a],{url:"/api/stats/overview",method:"GET",params:x?{endpoint:x}:void 0}),T=S(["stats","daily",14,a],{url:"/api/stats/daily",method:"GET",params:{days:14,...x?{endpoint:x}:{}}}),g=S(["stats","model",7,6,a],{url:"/api/stats/model",method:"GET",params:{days:7,limit:6,...x?{endpoint:x}:{}}}),E=S(["status"],{url:"/api/status",method:"GET"}),j=S(["db","info"],{url:"/api/db/info",method:"GET"}),z=j.refetch??(async()=>{}),C=S(["logs","recent",a],{url:"/api/logs",method:"GET",params:{limit:5,...x?{endpoint:x}:{}}},{refetchInterval:3e4});d.useEffect(()=>{N.isError&&N.error&&s({title:t("dashboard.toast.overviewError"),description:N.error.message,variant:"error"})},[N.isError,N.error,s,t]),d.useEffect(()=>{T.isError&&T.error&&s({title:t("dashboard.toast.dailyError"),description:T.error.message,variant:"error"})},[T.isError,T.error,s,t]),d.useEffect(()=>{g.isError&&g.error&&s({title:t("dashboard.toast.modelError"),description:g.error.message,variant:"error"})},[g.isError,g.error,s,t]),d.useEffect(()=>{E.isError&&E.error&&s({title:t("dashboard.toast.statusError"),description:E.error.message,variant:"error"})},[E.isError,E.error,s,t]),d.useEffect(()=>{j.isError&&j.error&&s({title:t("dashboard.toast.dbError"),description:j.error.message,variant:"error"})},[j.isError,j.error,s,t]);const Z=d.useCallback(async()=>{if(!i){y(!0);try{await ie.post("/api/db/compact"),await z(),s({title:t("dashboard.toast.compactSuccess.title"),description:t("dashboard.toast.compactSuccess.desc"),variant:"success"})}catch(n){const m=le(n);s({title:t("dashboard.toast.compactError.title"),description:m.message,variant:"error"})}finally{y(!1)}}},[i,s,z,t]);d.useEffect(()=>{C.isError&&C.error&&s({title:t("dashboard.toast.recentError"),description:C.error.message,variant:"error"})},[C.isError,C.error,s,t]);const o=N.data,v=T.data??[],l=g.data??[],L=E.data,R=j.data,ee=((U=C.data)==null?void 0:U.items)??[],te=R?W(R.totalBytes??R.sizeBytes):"-",ae=R?W(R.memoryRssBytes??0):"-",se=d.useMemo(()=>{const n=v.map(b=>b.date),m=t("dashboard.charts.barRequests"),c=t("dashboard.charts.lineInput"),B=t("dashboard.charts.lineOutput"),p=t("dashboard.charts.lineCacheRead"),J=t("dashboard.charts.lineCacheCreation");return{tooltip:{trigger:"axis"},legend:{data:[m,c,B,p,J]},grid:{left:60,right:40,top:60,bottom:60},xAxis:{type:"category",data:n},yAxis:{type:"value"},series:[{name:m,type:"bar",data:v.map(b=>b.requestCount),itemStyle:{color:"hsl(var(--primary))",borderRadius:[4,4,0,0]}},{name:c,type:"line",data:v.map(b=>b.inputTokens),smooth:!0,itemStyle:{color:"#10b981"},lineStyle:{width:2}},{name:B,type:"line",data:v.map(b=>b.outputTokens),smooth:!0,itemStyle:{color:"#f59e0b"},lineStyle:{width:2}},{name:p,type:"line",data:v.map(b=>b.cacheReadTokens),smooth:!0,itemStyle:{color:"#8b5cf6"},lineStyle:{width:2}},{name:J,type:"line",data:v.map(b=>b.cacheCreationTokens),smooth:!0,itemStyle:{color:"#ec4899"},lineStyle:{width:2}}]}},[v,t]),re=d.useMemo(()=>{const n=l.map(p=>`${p.provider}/${p.model}`),m=t("dashboard.charts.barRequests"),c=t("dashboard.charts.lineInput"),B=t("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[m,c,B]},grid:{left:80,right:60,top:60,bottom:100},xAxis:{type:"category",data:n,axisLabel:{rotate:30}},yAxis:[{type:"value",name:m},{type:"value",name:t("dashboard.charts.axisTokens"),position:"right"}],series:[{name:m,type:"bar",data:l.map(p=>p.requests),itemStyle:{color:"#6366f1",borderRadius:[4,4,0,0]}},{name:c,type:"line",yAxisIndex:1,smooth:!0,data:l.map(p=>p.inputTokens??0),itemStyle:{color:"#10b981"}},{name:B,type:"line",yAxisIndex:1,smooth:!0,data:l.map(p=>p.outputTokens??0),itemStyle:{color:"#f59e0b"}}]}},[l,t]),oe=d.useMemo(()=>{const n=l.map(c=>`${c.provider}/${c.model}`),m=t("dashboard.charts.ttftLabel");return{tooltip:{trigger:"axis"},grid:{left:80,right:50,top:60,bottom:100},xAxis:{type:"category",data:n,axisLabel:{rotate:30}},yAxis:{type:"value",name:t("dashboard.charts.ttftAxis")},series:[{name:m,type:"bar",data:l.map(c=>c.avgTtftMs??0),itemStyle:{color:"hsl(var(--primary))",borderRadius:[4,4,0,0]}}]}},[l,t]),de=d.useMemo(()=>{const n=l.map(c=>`${c.provider}/${c.model}`),m=t("dashboard.charts.tpotLabel");return{tooltip:{trigger:"axis"},grid:{left:80,right:50,top:60,bottom:100},xAxis:{type:"category",data:n,axisLabel:{rotate:30}},yAxis:{type:"value",name:t("dashboard.charts.tpotAxis")},series:[{name:m,type:"bar",data:l.map(c=>c.avgTpotMs??0),itemStyle:{color:"#f59e0b",borderRadius:[4,4,0,0]}}]}},[l,t]);return N.isPending||E.isPending||j.isPending?e.jsx(ce,{}):e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ue,{icon:e.jsx(D,{className:"h-5 w-5","aria-hidden":"true"}),title:t("nav.dashboard"),description:t("dashboard.description"),actions:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:t("dashboard.filters.endpoint")}),e.jsxs(xe,{value:a,onValueChange:r,children:[e.jsx(pe,{className:"w-[140px]",children:e.jsx(be,{})}),e.jsxs(ge,{children:[e.jsx(q,{value:"all",children:t("dashboard.filters.endpointAll")}),e.jsx(q,{value:"anthropic",children:t("dashboard.filters.endpointAnthropic")}),e.jsx(q,{value:"openai",children:t("dashboard.filters.endpointOpenAI")}),(K=(V=Y.data)==null?void 0:V.endpoints)==null?void 0:K.map(n=>e.jsx(q,{value:n.id,children:n.label||n.id},n.id))]})]})]})}),L&&e.jsx(G,{children:e.jsxs(Q,{className:"flex flex-wrap items-center gap-3 pt-4",children:[e.jsx(k,{variant:"default",className:"bg-emerald-500",children:t("dashboard.status.listening",{host:L.host??"0.0.0.0",port:L.port})}),e.jsx(k,{variant:"secondary",children:t("dashboard.status.providers",{value:L.providers.toLocaleString()})}),e.jsx(k,{variant:"secondary",children:t("dashboard.status.todayRequests",{value:((o==null?void 0:o.today.requests)??0).toLocaleString()})}),e.jsx(k,{variant:"outline",children:t("dashboard.status.active",{value:(L.activeRequests??0).toLocaleString()})}),e.jsx(k,{variant:"outline",children:t("dashboard.status.dbSize",{value:te})}),e.jsx(k,{variant:"outline",children:t("dashboard.status.memory",{value:ae})}),e.jsx(me,{variant:"outline",size:"sm",onClick:Z,disabled:i,children:t(i?"dashboard.actions.compacting":"dashboard.actions.compact")})]})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-3",children:[e.jsx(w,{icon:e.jsx($,{className:"h-5 w-5"}),title:t("dashboard.cards.todayRequests"),value:(o==null?void 0:o.today.requests)??0,suffix:t("common.units.request"),color:"blue"}),e.jsx(w,{icon:e.jsx(ye,{className:"h-5 w-5"}),title:t("dashboard.cards.todayInput"),value:(o==null?void 0:o.today.inputTokens)??0,suffix:t("common.units.token"),color:"emerald"}),e.jsx(w,{icon:e.jsx($,{className:"h-5 w-5"}),title:t("dashboard.cards.todayCacheRead"),value:(o==null?void 0:o.today.cacheReadTokens)??0,suffix:t("common.units.token"),color:"violet"}),e.jsx(w,{icon:e.jsx($,{className:"h-5 w-5"}),title:t("dashboard.cards.todayCacheCreation"),value:(o==null?void 0:o.today.cacheCreationTokens)??0,suffix:t("common.units.token"),color:"rose"}),e.jsx(w,{icon:e.jsx(D,{className:"h-5 w-5"}),title:t("dashboard.cards.todayOutput"),value:(o==null?void 0:o.today.outputTokens)??0,suffix:t("common.units.token"),color:"amber"}),e.jsx(w,{icon:e.jsx(fe,{className:"h-5 w-5"}),title:t("dashboard.cards.avgLatency"),value:(o==null?void 0:o.today.avgLatencyMs)??0,suffix:t("common.units.ms"),color:"cyan"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(M,{title:t("dashboard.charts.requestsTitle"),description:t("dashboard.charts.requestsDesc"),loading:T.isPending,option:se,empty:!v.length,emptyText:t("dashboard.charts.empty")}),e.jsx(M,{title:t("dashboard.charts.modelTitle"),description:t("dashboard.charts.modelDesc"),loading:g.isPending,option:re,empty:!l.length,emptyText:t("dashboard.charts.empty")})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(M,{title:t("dashboard.charts.ttftTitle"),description:t("dashboard.charts.ttftDesc"),loading:g.isPending,option:oe,empty:!l.some(n=>n.avgTtftMs!=null&&n.avgTtftMs>0),emptyText:t("dashboard.charts.ttftEmpty")}),e.jsx(M,{title:t("dashboard.charts.tpotTitle"),description:t("dashboard.charts.tpotDesc"),loading:g.isPending,option:de,empty:!l.some(n=>n.avgTpotMs!=null&&n.avgTpotMs>0),emptyText:t("dashboard.charts.tpotEmpty")})]}),e.jsx(Te,{models:l,loading:g.isPending}),e.jsx(Ee,{loading:C.isPending,records:ee})]})}const Ne={blue:{gradient:"bg-gradient-to-br from-blue-500/10 via-blue-500/5 to-transparent",iconBg:"bg-blue-500/15",iconColor:"text-blue-600 dark:text-blue-400"},emerald:{gradient:"bg-gradient-to-br from-emerald-500/10 via-emerald-500/5 to-transparent",iconBg:"bg-emerald-500/15",iconColor:"text-emerald-600 dark:text-emerald-400"},amber:{gradient:"bg-gradient-to-br from-amber-500/10 via-amber-500/5 to-transparent",iconBg:"bg-amber-500/15",iconColor:"text-amber-600 dark:text-amber-400"},violet:{gradient:"bg-gradient-to-br from-violet-500/10 via-violet-500/5 to-transparent",iconBg:"bg-violet-500/15",iconColor:"text-violet-600 dark:text-violet-400"},rose:{gradient:"bg-gradient-to-br from-rose-500/10 via-rose-500/5 to-transparent",iconBg:"bg-rose-500/15",iconColor:"text-rose-600 dark:text-rose-400"},cyan:{gradient:"bg-gradient-to-br from-cyan-500/10 via-cyan-500/5 to-transparent",iconBg:"bg-cyan-500/15",iconColor:"text-cyan-600 dark:text-cyan-400"}};function w({icon:t,title:s,value:a,suffix:r,color:i="blue"}){const y=Ne[i];return e.jsx(G,{variant:"interactive",className:f("overflow-hidden",y.gradient),children:e.jsxs(Q,{className:"pt-5",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground",children:s}),t&&e.jsx("div",{className:f("flex h-10 w-10 items-center justify-center rounded-xl",y.iconBg,y.iconColor),children:t})]}),e.jsxs("p",{className:"text-3xl font-bold tracking-tight",children:[a.toLocaleString(),r&&e.jsx("span",{className:"ml-1.5 text-sm font-medium text-muted-foreground",children:r})]})]})})}function M({title:t,description:s,option:a,loading:r,empty:i,emptyText:y}){const{t:x}=I();return e.jsx(G,{children:e.jsxs(Q,{className:"space-y-4 pt-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-base font-semibold",children:t}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:s})]}),r?e.jsx("div",{className:"flex h-[320px] items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:x("common.loadingShort")})}):i?e.jsxs("div",{className:"flex h-[320px] flex-col items-center justify-center rounded-lg border border-dashed",children:[e.jsx(D,{className:"mb-2 h-10 w-10 text-muted-foreground/50"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:y??x("dashboard.charts.empty")})]}):e.jsx(he,{option:a,style:{height:320},notMerge:!0,lazyUpdate:!0})]})})}function Te({models:t,loading:s}){const{t:a}=I(),r=t.length>0;return e.jsx(X,{title:a("dashboard.modelTable.title"),description:a("dashboard.modelTable.description"),children:s?e.jsx("div",{className:"flex h-32 items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:a("common.loadingShort")})}):r?e.jsx("div",{className:"max-h-80 overflow-auto rounded-md border",children:e.jsxs(F,{children:[e.jsx(H,{children:e.jsxs(A,{children:[e.jsx(h,{children:a("dashboard.modelTable.columns.model")}),e.jsx(h,{className:"text-right",children:a("dashboard.modelTable.columns.requests")}),e.jsx(h,{className:"text-right",children:a("dashboard.modelTable.columns.latency")}),e.jsx(h,{className:"text-right",children:a("dashboard.modelTable.columns.ttft")}),e.jsx(h,{className:"text-right",children:a("dashboard.modelTable.columns.tpot")})]})}),e.jsx(_,{children:t.map(i=>e.jsxs(A,{children:[e.jsx(u,{children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"font-medium",children:i.provider}),e.jsx("span",{className:"text-xs text-muted-foreground",children:i.model})]})}),e.jsx(u,{className:"text-right font-medium",children:i.requests.toLocaleString()}),e.jsx(u,{className:"text-right",children:P(i.avgLatencyMs,a("common.units.ms"))}),e.jsx(u,{className:"text-right",children:P(i.avgTtftMs,a("common.units.ms"))}),e.jsx(u,{className:"text-right",children:P(i.avgTpotMs,a("common.units.msPerToken"),{maximumFractionDigits:2})})]},`${i.provider}/${i.model}`))})]})}):e.jsx("div",{className:"flex h-32 items-center justify-center rounded-lg border border-dashed",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:a("dashboard.modelTable.empty")})})})}function Ee({records:t,loading:s}){const{t:a}=I();return e.jsx(X,{title:a("dashboard.recent.title"),description:a("dashboard.recent.subtitle",{count:5}),children:s?e.jsx("div",{className:"flex h-32 items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:a("dashboard.recent.loading")})}):t.length===0?e.jsx("div",{className:"flex h-32 items-center justify-center rounded-lg border border-dashed",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:a("dashboard.recent.empty")})}):e.jsx("div",{className:"max-h-80 overflow-auto rounded-md border",children:e.jsxs(F,{children:[e.jsx(H,{children:e.jsxs(A,{children:[e.jsx(h,{children:a("dashboard.recent.columns.time")}),e.jsx(h,{children:a("dashboard.recent.columns.endpoint")}),e.jsx(h,{children:a("dashboard.recent.columns.provider")}),e.jsx(h,{children:a("dashboard.recent.columns.route")}),e.jsx(h,{className:"text-right",children:a("dashboard.recent.columns.latency")}),e.jsx(h,{children:a("dashboard.recent.columns.status")})]})}),e.jsx(_,{children:t.map(r=>e.jsxs(A,{children:[e.jsx(u,{className:"text-xs",children:new Date(r.timestamp).toLocaleString()}),e.jsx(u,{className:"text-xs text-muted-foreground",children:r.endpoint==="anthropic"?a("logs.table.endpointAnthropic"):r.endpoint==="openai"?a("logs.table.endpointOpenAI"):r.endpoint}),e.jsx(u,{className:"font-medium",children:r.provider}),e.jsx(u,{children:e.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[e.jsx("span",{children:r.client_model??a("dashboard.recent.routePlaceholder")}),e.jsx("span",{children:"→"}),e.jsx("span",{className:"font-medium text-foreground",children:r.model})]})}),e.jsx(u,{className:"text-right font-medium",children:P(r.latency_ms,a("common.units.ms"))}),e.jsx(u,{children:e.jsx(k,{variant:r.error?"destructive":"default",children:(r.status_code??(r.error?500:200)).toString()})})]},r.id))})]})})})}export{Ae as default};
@@ -1,4 +1,4 @@
1
- import{c as N,u as E,b as L,r as i,j as e,e as h,C as R,a as $,g as I,h as T,t as P}from"./index-D_Dbqo2u.js";import{P as z,B as j}from"./PageHeader-BeW-Othf.js";import{I as F}from"./input-Ckx5qHOQ.js";import{C as w,a as C,b as V}from"./card-DO6ly30k.js";import{S as B,a as D,b as K,c as H,d as f}from"./select-CMGw70tW.js";import{R as J}from"./refresh-cw-C-S3w6yD.js";/**
1
+ import{c as N,u as E,b as L,r as i,j as e,e as h,C as R,a as $,g as I,h as T,t as P}from"./index-UV1Qa96f.js";import{P as z,B as j}from"./PageHeader-xFKpGYn6.js";import{I as F}from"./input-CBGvcnZr.js";import{C as w,a as C,b as V}from"./card-C20_HqC6.js";import{S as B,a as D,b as K,c as H,d as f}from"./select-C8rWWJbl.js";import{R as J}from"./refresh-cw-ISOSG1Po.js";/**
2
2
  * @license lucide-react v0.344.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as x,u,r as g,j as e,e as h}from"./index-D_Dbqo2u.js";import{P as N}from"./PageHeader-BeW-Othf.js";import{P as d}from"./PageSection-DW84HFxm.js";import{c as p}from"./clipboard-CALi6bTW.js";import{C as j,a as f}from"./card-DO6ly30k.js";import{I as v}from"./info-XoeNrG0H.js";/**
1
+ import{c as x,u,r as g,j as e,e as h}from"./index-UV1Qa96f.js";import{P as N}from"./PageHeader-xFKpGYn6.js";import{P as d}from"./PageSection-Vn4S3q9j.js";import{c as p}from"./clipboard-CALi6bTW.js";import{C as j,a as f}from"./card-C20_HqC6.js";import{I as v}from"./info-CewFzdVp.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 C,ai as E,aj as F,ak as L,r as n,j as e,L as S,e as k}from"./index-D_Dbqo2u.js";import{I as j}from"./input-Ckx5qHOQ.js";import{L as b}from"./label-D2cIIMBu.js";import{C as v,a as w,b as P,c as T,d as A,e as D}from"./card-DO6ly30k.js";function H(){const{t:s}=C(),i=E(),u=F(),{authEnabled:l,isAuthenticated:m,loading:o,login:N,error:x}=L(),[t,f]=n.useState({username:"",password:""}),[p,d]=n.useState(null),[h,g]=n.useState(!1),c=n.useMemo(()=>{var r;const a=u.state;return((r=a==null?void 0:a.from)==null?void 0:r.pathname)??"/"},[u.state]);n.useEffect(()=>{if(!l&&!o){i(c,{replace:!0});return}l&&m&&!o&&i(c,{replace:!0})},[l,m,o,i,c]);const y=async a=>{if(a.preventDefault(),d(null),!t.username.trim()||!t.password){d(s("login.validation.required"));return}g(!0);try{await N(t.username.trim(),t.password),i(c,{replace:!0})}catch(r){d(r instanceof Error?r.message:s("login.validation.failed"))}finally{g(!1)}};return o?e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-background",children:e.jsx(v,{className:"w-full max-w-md",children:e.jsx(w,{className:"flex min-h-[320px] items-center justify-center",children:e.jsx(S,{})})})}):l?e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-background px-4",children:e.jsxs(v,{className:"w-full max-w-md",children:[e.jsxs(P,{className:"text-center",children:[e.jsx("div",{className:"mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-primary text-lg font-bold text-primary-foreground",children:"GW"}),e.jsx(T,{className:"text-2xl",children:s("login.title")}),e.jsx(A,{className:"text-sm",children:s("login.description")})]}),e.jsx(w,{children:e.jsxs("form",{className:"space-y-4",onSubmit:y,children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"username",children:s("login.fields.username")}),e.jsx(j,{id:"username",value:t.username,autoComplete:"username",autoFocus:!0,onChange:a=>f(r=>({...r,username:a.target.value})),placeholder:s("login.fields.usernamePlaceholder")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"password",children:s("login.fields.password")}),e.jsx(j,{id:"password",type:"password",value:t.password,autoComplete:"current-password",onChange:a=>f(r=>({...r,password:a.target.value})),placeholder:s("login.fields.passwordPlaceholder")})]}),(p||x)&&e.jsx("div",{className:"rounded-md border border-destructive/50 bg-destructive/10 px-4 py-3 text-sm text-destructive",children:p||x}),e.jsx(k,{type:"submit",className:"w-full",disabled:h,children:s(h?"common.actions.loading":"login.actions.submit")})]})}),e.jsx(D,{className:"justify-center",children:e.jsx("p",{className:"text-center text-xs text-muted-foreground",children:s("login.hint")})})]})}):null}export{H as default};
1
+ import{u as C,ai as E,aj as F,ak as L,r as n,j as e,L as S,e as k}from"./index-UV1Qa96f.js";import{I as j}from"./input-CBGvcnZr.js";import{L as b}from"./label-BqSverDm.js";import{C as v,a as w,b as P,c as T,d as A,e as D}from"./card-C20_HqC6.js";function H(){const{t:s}=C(),i=E(),u=F(),{authEnabled:l,isAuthenticated:m,loading:o,login:N,error:x}=L(),[t,f]=n.useState({username:"",password:""}),[p,d]=n.useState(null),[h,g]=n.useState(!1),c=n.useMemo(()=>{var r;const a=u.state;return((r=a==null?void 0:a.from)==null?void 0:r.pathname)??"/"},[u.state]);n.useEffect(()=>{if(!l&&!o){i(c,{replace:!0});return}l&&m&&!o&&i(c,{replace:!0})},[l,m,o,i,c]);const y=async a=>{if(a.preventDefault(),d(null),!t.username.trim()||!t.password){d(s("login.validation.required"));return}g(!0);try{await N(t.username.trim(),t.password),i(c,{replace:!0})}catch(r){d(r instanceof Error?r.message:s("login.validation.failed"))}finally{g(!1)}};return o?e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-background",children:e.jsx(v,{className:"w-full max-w-md",children:e.jsx(w,{className:"flex min-h-[320px] items-center justify-center",children:e.jsx(S,{})})})}):l?e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-background px-4",children:e.jsxs(v,{className:"w-full max-w-md",children:[e.jsxs(P,{className:"text-center",children:[e.jsx("div",{className:"mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-primary text-lg font-bold text-primary-foreground",children:"GW"}),e.jsx(T,{className:"text-2xl",children:s("login.title")}),e.jsx(A,{className:"text-sm",children:s("login.description")})]}),e.jsx(w,{children:e.jsxs("form",{className:"space-y-4",onSubmit:y,children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"username",children:s("login.fields.username")}),e.jsx(j,{id:"username",value:t.username,autoComplete:"username",autoFocus:!0,onChange:a=>f(r=>({...r,username:a.target.value})),placeholder:s("login.fields.usernamePlaceholder")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"password",children:s("login.fields.password")}),e.jsx(j,{id:"password",type:"password",value:t.password,autoComplete:"current-password",onChange:a=>f(r=>({...r,password:a.target.value})),placeholder:s("login.fields.passwordPlaceholder")})]}),(p||x)&&e.jsx("div",{className:"rounded-md border border-destructive/50 bg-destructive/10 px-4 py-3 text-sm text-destructive",children:p||x}),e.jsx(k,{type:"submit",className:"w-full",disabled:h,children:s(h?"common.actions.loading":"login.actions.submit")})]})}),e.jsx(D,{className:"justify-center",children:e.jsx("p",{className:"text-center text-xs text-muted-foreground",children:s("login.hint")})})]})}):null}export{H as default};
@@ -0,0 +1,6 @@
1
+ import{c as be,u as U,b as me,r as n,d as we,t as ke,j as e,e as k,a as L,F as _e,f as Se,X as Ee,L as Te}from"./index-UV1Qa96f.js";import{u as F}from"./useApiQuery-C2OD7H7U.js";import{P as Ce,B as xe}from"./PageHeader-xFKpGYn6.js";import{c as Le}from"./clipboard-CALi6bTW.js";import{I as Q}from"./input-CBGvcnZr.js";import{L as S}from"./label-BqSverDm.js";import{C as re,a as ne}from"./card-C20_HqC6.js";import{S as M,a as z,b as O,c as q,d as w}from"./select-C8rWWJbl.js";import{R as De}from"./refresh-cw-ISOSG1Po.js";/**
2
+ * @license lucide-react v0.344.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Re=be("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]),oe=[20,50,100];function de(s,r=!1){if(!s)return;const o=r?`${s}T23:59:59.999`:`${s}T00:00:00.000`,g=Date.parse(o);return Number.isFinite(g)?g:void 0}function ue(s){const r=new Date(s);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 _(s){return s==null?"-":s.toLocaleString()}function E(s,r){const o=_(s);return o==="-"?"-":`${o} ${r}`}function Fe(s){return s?"true":"false"}function ce(s,r){if(!s||s.trim().length===0)return r;try{const o=JSON.parse(s);return JSON.stringify(o,null,2)}catch{return s}}function Qe(){var se,te,le,ae;const{t:s}=U(),{pushToast:r}=me(),[o,g]=n.useState("all"),[j,t]=n.useState("all"),[d,y]=n.useState(""),[m,v]=n.useState("all"),[l,h]=n.useState(""),[i,x]=n.useState(""),[c,p]=n.useState(1),[N,I]=n.useState(oe[0]),[K,H]=n.useState(null),[pe,V]=n.useState(!1),[D,W]=n.useState([]),[P,J]=n.useState(!1);n.useEffect(()=>{p(1)},[o,j,d,m,l,i,N,D]);const $=n.useMemo(()=>{const a={limit:N,offset:(c-1)*N};o!=="all"&&(a.provider=o),j!=="all"&&(a.endpoint=j),d.trim().length>0&&(a.model=d.trim()),m!=="all"&&(a.status=m);const u=de(l),A=de(i,!0);return u!==void 0&&(a.from=u),A!==void 0&&(a.to=A),D.length>0&&(a.apiKeys=D.join(",")),a},[o,j,d,m,l,i,c,N,D]),f=F(["logs",$],{url:"/api/logs",method:"GET",params:$}),T=F(["providers","all"],{url:"/api/providers",method:"GET"}),X=F(["api-keys"],{url:"/api/keys",method:"GET"}),he=F(["custom-endpoints"],{url:"/api/custom-endpoints",method:"GET"});n.useEffect(()=>{f.isError&&f.error&&r({title:s("logs.toast.listError.title"),description:s("logs.toast.listError.desc",{message:f.error.message}),variant:"error"})},[f.isError,f.error,r,s]),n.useEffect(()=>{T.isError&&T.error&&r({title:s("logs.toast.providerError.title"),description:s("logs.toast.providerError.desc",{message:T.error.message}),variant:"error"})},[T.isError,T.error,r,s]);const C=((se=f.data)==null?void 0:se.total)??0,b=C>0?Math.ceil(C/N):0,Y=((te=f.data)==null?void 0:te.items)??[];n.useEffect(()=>{b>0&&c>b&&p(b)},[b,c]);const B=T.data??[],Z=n.useMemo(()=>{const a=new Map;for(const u of B)u.id&&a.set(u.id,u.label??u.id);return a},[B]),G=X.data??[],ee=n.useMemo(()=>{const a=new Map;for(const u of G)a.set(u.id,u);return a},[G]),fe=()=>{g("all"),y(""),t("all"),v("all"),h(""),x(""),W([])},ge=n.useCallback(async()=>{if(!P){J(!0);try{const a=C>0?Math.min(C,5e3):1e3,u={...$,limit:a,offset:0},A=await we.post("/api/logs/export",u,{responseType:"blob"}),Ne=new Blob([A.data],{type:"application/zip"}),ve=new Date().toISOString().replace(/[:.]/g,"-"),ie=URL.createObjectURL(Ne),R=document.createElement("a");R.href=ie,R.download=`cc-gw-logs-${ve}.zip`,document.body.appendChild(R),R.click(),R.remove(),URL.revokeObjectURL(ie),r({title:s("logs.toast.exportSuccess.title"),description:s("logs.toast.exportSuccess.desc"),variant:"success"})}catch(a){const u=ke(a);r({title:s("logs.toast.exportError.title"),description:s("logs.toast.exportError.desc",{message:u.message}),variant:"error"})}finally{J(!1)}}},[P,r,$,s,C]),je=n.useCallback(a=>{H(a),V(!0)},[]),ye=n.useCallback(()=>{V(!1),H(null)},[]);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Ce,{icon:e.jsx(_e,{className:"h-5 w-5","aria-hidden":"true"}),title:s("logs.title"),description:s("logs.description"),actions:e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(k,{onClick:ge,disabled:P,children:[e.jsx(Re,{className:"mr-2 h-4 w-4"}),s(P?"common.actions.loading":"logs.actions.export")]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:s("logs.summary.total",{value:C.toLocaleString()})}),e.jsxs(k,{variant:"outline",size:"sm",onClick:()=>f.refetch(),disabled:f.isFetching,children:[e.jsx(De,{className:L("mr-2 h-4 w-4",f.isFetching&&"animate-spin")}),f.isFetching?s("common.actions.refreshing"):s("logs.actions.manualRefresh")]})]})}),e.jsx(re,{children:e.jsxs(ne,{className:"pt-4",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium",children:s("logs.filtersTitle")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s("logs.filtersDescription")})]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:fe,children:s("common.actions.reset")})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.provider")}),e.jsxs(M,{value:o,onValueChange:g,children:[e.jsx(z,{children:e.jsx(O,{})}),e.jsxs(q,{children:[e.jsx(w,{value:"all",children:s("logs.filters.providerAll")}),B.map(a=>e.jsx(w,{value:a.id,children:a.label??a.id},a.id))]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.endpoint")}),e.jsxs(M,{value:j,onValueChange:t,children:[e.jsx(z,{children:e.jsx(O,{})}),e.jsxs(q,{children:[e.jsx(w,{value:"all",children:s("logs.filters.endpointAll")}),e.jsx(w,{value:"anthropic",children:s("logs.filters.endpointAnthropic")}),e.jsx(w,{value:"openai",children:s("logs.filters.endpointOpenAI")}),(ae=(le=he.data)==null?void 0:le.endpoints)==null?void 0:ae.map(a=>e.jsx(w,{value:a.id,children:a.label||a.id},a.id))]})]})]}),e.jsx($e,{className:"md:col-span-2",apiKeys:G,selected:D,disabled:X.isLoading,onChange:W}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.modelId")}),e.jsx(Q,{value:d,onChange:a=>y(a.target.value),placeholder:s("logs.filters.modelPlaceholder")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.status")}),e.jsxs(M,{value:m,onValueChange:a=>v(a),children:[e.jsx(z,{children:e.jsx(O,{})}),e.jsxs(q,{children:[e.jsx(w,{value:"all",children:s("logs.filters.statusAll")}),e.jsx(w,{value:"success",children:s("logs.filters.statusSuccess")}),e.jsx(w,{value:"error",children:s("logs.filters.statusError")})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.startDate")}),e.jsx(Q,{type:"date",value:l,onChange:a=>h(a.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(S,{children:s("logs.filters.endDate")}),e.jsx(Q,{type:"date",value:i,onChange:a=>x(a.target.value)})]})]})]})}),e.jsx(re,{children:e.jsxs(ne,{className:"p-0",children:[e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full min-w-[1200px] text-sm",children:[e.jsx("thead",{className:"border-b bg-muted/50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.time")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.endpoint")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.provider")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.requestedModel")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.routedModel")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.apiKey")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.inputTokens")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.cacheReadTokens")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.cacheCreationTokens")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.outputTokens")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.latency")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.ttft")}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium",children:s("logs.table.columns.tpot")}),e.jsx("th",{className:"px-3 py-2 text-center text-xs font-medium",children:s("logs.table.columns.status")}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium",children:s("logs.table.columns.error")}),e.jsx("th",{className:"px-3 py-2 text-center text-xs font-medium",children:s("logs.table.columns.actions")})]})}),e.jsx("tbody",{className:"divide-y",children:f.isPending?e.jsx("tr",{children:e.jsx("td",{colSpan:16,className:"px-3 py-8 text-center text-sm text-muted-foreground",children:s("logs.table.loading")})}):Y.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:16,className:"px-3 py-8 text-center text-sm text-muted-foreground",children:s("logs.table.empty")})}):Y.map((a,u)=>e.jsx(Ke,{record:a,providerLabelMap:Z,apiKeyMap:ee,onSelect:je,isEven:u%2===0},a.id))})]})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4 border-t p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("logs.table.pagination.perPage")}),e.jsxs(M,{value:N.toString(),onValueChange:a=>I(Number(a)),children:[e.jsx(z,{className:"w-[80px]",children:e.jsx(O,{})}),e.jsx(q,{children:oe.map(a=>e.jsx(w,{value:a.toString(),children:a},a))})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{variant:"outline",size:"sm",onClick:()=>p(a=>Math.max(a-1,1)),disabled:c<=1,children:s("logs.table.pagination.previous")}),e.jsx("span",{className:"text-sm text-muted-foreground",children:s("logs.table.pagination.pageLabel",{page:b===0?0:c,total:b})}),e.jsx(k,{variant:"outline",size:"sm",onClick:()=>p(a=>b===0?a:Math.min(a+1,b)),disabled:b===0||c>=b,children:s("logs.table.pagination.next")})]})]})]})}),e.jsx(Pe,{open:pe,logId:K,onClose:ye,providerLabelMap:Z,apiKeyMap:ee})]})}function Ke({record:s,providerLabelMap:r,apiKeyMap:o,onSelect:g,isEven:j}){const{t}=U(),d=r.get(s.provider)??s.provider,y=s.endpoint||"-",m=!!s.error,v=s.status_code,l=s.client_model??t("logs.table.requestedModelFallback"),h=s.api_key_id!=null?o.get(s.api_key_id):void 0,i=s.api_key_id==null?t("logs.table.apiKeyUnknown"):h!=null&&h.isWildcard?t("apiKeys.wildcard"):h!=null&&h.name?h.name:s.api_key_name?s.api_key_name:t("logs.table.apiKeyUnknown");return e.jsxs("tr",{className:L("transition-colors",j?"bg-muted/30":"","hover:bg-muted/50"),children:[e.jsx("td",{className:"px-3 py-2 text-xs",children:ue(s.timestamp)}),e.jsx("td",{className:"px-3 py-2 text-xs",children:y}),e.jsx("td",{className:"px-3 py-2 text-xs",children:e.jsx("div",{className:"max-w-[100px] truncate",title:d,children:d})}),e.jsx("td",{className:"px-3 py-2 text-xs text-muted-foreground",children:e.jsx("div",{className:"max-w-[120px] truncate",title:l,children:l})}),e.jsx("td",{className:"px-3 py-2 text-xs",children:e.jsx("div",{className:"max-w-[120px] truncate",title:s.model,children:s.model})}),e.jsx("td",{className:"px-3 py-2 text-xs text-muted-foreground",children:e.jsx("div",{className:"max-w-[90px] truncate",title:i,children:i})}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:_(s.input_tokens)}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:_(s.cache_read_tokens)}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:_(s.cache_creation_tokens)}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:_(s.output_tokens)}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:E(s.latency_ms,"ms")}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:E(s.ttft_ms,"ms")}),e.jsx("td",{className:"px-3 py-2 text-right text-xs tabular-nums",children:E(s.tpot_ms,"ms/tk")}),e.jsx("td",{className:"px-3 py-2 text-center",children:e.jsx(xe,{variant:m?"destructive":"default",className:"text-xs",children:v??(m?500:200)})}),e.jsx("td",{className:"px-3 py-2 text-xs text-muted-foreground",children:e.jsx("div",{className:"max-w-[100px] truncate",title:s.error??"",children:s.error?s.error:"-"})}),e.jsx("td",{className:"px-3 py-2 text-center",children:e.jsx(k,{variant:"outline",size:"sm",onClick:()=>g(s.id),children:t("logs.actions.detail")})})]})}function Pe({open:s,logId:r,onClose:o,providerLabelMap:g,apiKeyMap:j}){var x,c;const{t}=U(),{pushToast:d}=me(),y=n.useRef(null),m=F(["log-detail",r],{url:`/api/logs/${r}`,method:"GET"},{enabled:s&&r!==null,staleTime:3e4});n.useEffect(()=>{m.isError&&m.error&&d({title:t("logs.detail.loadError"),description:m.error.message,variant:"error"})},[m.isError,m.error,d,t]),n.useEffect(()=>{if(!s)return;const p=N=>{N.key==="Escape"&&o()};return window.addEventListener("keydown",p),()=>window.removeEventListener("keydown",p)},[s,o]),n.useEffect(()=>{s&&y.current&&y.current.focus()},[s,r]);const v=n.useCallback(async(p,N,I)=>{if(!N){d({title:t("logs.detail.copy.empty",{label:p}),variant:"info"});return}try{await Le(N),d({title:t(I),variant:"success"})}catch(K){d({title:t("logs.detail.copy.failure"),description:K instanceof Error?K.message:t("logs.detail.copy.failureFallback"),variant:"error"})}},[d,t]);if(!s)return null;const l=m.data,h=l?g.get(l.provider)??l.provider:"",i=l&&l.api_key_id!=null?j.get(l.api_key_id):void 0;return typeof document>"u"?null:Se.createPortal(e.jsxs("div",{className:"fixed inset-0 z-50 flex",children:[e.jsx("div",{className:"flex-1 bg-background/80 backdrop-blur-sm",onClick:o}),e.jsxs("aside",{role:"dialog","aria-modal":"true",className:"flex h-full w-full max-w-xl flex-col border-l bg-card shadow-xl",children:[e.jsxs("header",{className:"flex items-center justify-between border-b px-6 py-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:t("logs.detail.title")}),l&&e.jsx("p",{className:"text-xs text-muted-foreground",children:t("logs.detail.id",{id:l.id})})]}),e.jsxs(k,{ref:y,variant:"outline",size:"sm",onClick:o,children:[e.jsx(Ee,{className:"mr-2 h-4 w-4"}),t("common.actions.close")]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:m.isPending?e.jsx(Te,{}):l?e.jsxs("div",{className:"flex flex-col gap-6 px-6 py-5 text-sm",children:[e.jsxs("section",{className:"space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:t("logs.detail.infoSection")}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-md bg-muted p-3 text-xs",children:[e.jsx("span",{className:"font-medium",children:t("logs.detail.summary.route",{from:l.client_model??t("logs.detail.info.noRequestedModel"),to:l.model})}),e.jsx("span",{className:"text-muted-foreground",children:t("logs.detail.summary.latency",{value:E(l.latency_ms,t("common.units.ms"))})}),l.ttft_ms!==null&&e.jsxs("span",{className:"text-muted-foreground",children:["TTFT: ",E(l.ttft_ms,t("common.units.ms"))]}),e.jsx(xe,{variant:l.error?"destructive":"default",children:(l.status_code??(l.error?500:200)).toString()})]}),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-muted-foreground",children:t("logs.detail.info.time")}),e.jsx("dd",{className:"font-medium",children:ue(l.timestamp)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.sessionId")}),e.jsx("dd",{className:"font-medium",children:l.session_id??"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.endpoint")}),e.jsx("dd",{className:"font-medium",children:l.endpoint||"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.provider")}),e.jsx("dd",{className:"font-medium",children:h})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.requestedModel")}),e.jsx("dd",{className:"font-medium",children:l.client_model??t("logs.detail.info.noRequestedModel")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.model")}),e.jsx("dd",{className:"font-medium",children:l.model})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.stream")}),e.jsx("dd",{className:"font-medium",children:Fe(l.stream)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.inputTokens")}),e.jsx("dd",{className:"font-medium",children:_(l.input_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.cacheReadTokens")}),e.jsx("dd",{className:"font-medium",children:_(l.cache_read_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.cacheCreationTokens")}),e.jsx("dd",{className:"font-medium",children:_(l.cache_creation_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.outputTokens")}),e.jsx("dd",{className:"font-medium",children:_(l.output_tokens)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.ttft")}),e.jsx("dd",{className:"font-medium",children:E(l.ttft_ms,t("common.units.ms"))})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.tpot")}),e.jsx("dd",{className:"font-medium",children:E(l.tpot_ms,t("common.units.msPerToken"))})]})]}),l.error&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:t("logs.detail.info.error")}),e.jsx("p",{className:"rounded-md border border-destructive/50 bg-destructive/10 p-3 text-xs text-destructive",children:l.error})]})]}),e.jsxs("section",{className:"space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:t("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-muted-foreground",children:t("logs.detail.apiKey.name")}),e.jsx("dd",{className:"font-medium",children:l.api_key_id==null&&!l.api_key_name?t("logs.detail.apiKey.missing"):i!=null&&i.isWildcard?t("apiKeys.wildcard"):(i==null?void 0:i.name)??l.api_key_name??t("logs.detail.apiKey.missing")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.apiKey.identifier")}),e.jsx("dd",{className:"font-medium",children:l.api_key_id??t("common.noData")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.apiKey.masked")}),e.jsx("dd",{className:"font-medium",children:i!=null&&i.isWildcard?t("apiKeys.wildcard"):(i==null?void 0:i.maskedKey)??l.api_key_name??t("logs.detail.apiKey.maskedUnavailable")})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-xs text-muted-foreground",children:t("logs.detail.apiKey.lastUsed")}),e.jsx("dd",{className:"font-medium",children:i!=null&&i.lastUsedAt?new Date(i.lastUsedAt).toLocaleString():t("common.noData")})]})]}),e.jsxs("div",{className:"rounded-md border bg-muted p-3 text-xs",children:[e.jsx("p",{className:"font-medium",children:t("logs.detail.apiKey.rawMasked")}),e.jsx("p",{className:"mt-1 break-all font-mono",children:l.api_key_value_available?l.api_key_value_masked??t("logs.detail.apiKey.rawUnavailable"):t("logs.detail.apiKey.rawUnavailable")}),e.jsx("p",{className:"mt-2 text-[11px] text-muted-foreground",children:t("logs.detail.apiKey.rawMaskedHint")})]})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:t("logs.detail.payload.request")}),e.jsx(k,{variant:"outline",size:"sm",onClick:()=>{var p;return v(t("logs.detail.payload.request"),(p=l.payload)==null?void 0:p.prompt,"logs.detail.copy.requestSuccess")},children:t("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border bg-muted p-3 text-xs",children:ce((x=l.payload)==null?void 0:x.prompt,t("logs.detail.payload.emptyRequest"))})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:t("logs.detail.payload.response")}),e.jsx(k,{variant:"outline",size:"sm",onClick:()=>{var p;return v(t("logs.detail.payload.response"),(p=l.payload)==null?void 0:p.response,"logs.detail.copy.responseSuccess")},children:t("common.actions.copy")})]}),e.jsx("pre",{className:"max-h-64 overflow-auto whitespace-pre-wrap rounded-md border bg-muted p-3 text-xs",children:ce((c=l.payload)==null?void 0:c.response,t("logs.detail.payload.emptyResponse"))})]})]}):e.jsx("div",{className:"flex h-full items-center justify-center p-8 text-sm text-muted-foreground",children:t("logs.detail.loadError")})})]})]}),document.body)}function $e({apiKeys:s,selected:r,onChange:o,disabled:g,className:j}){const{t}=U(),[d,y]=n.useState(!1),m=n.useRef(null);n.useEffect(()=>{if(!d)return;const i=x=>{var c;(c=m.current)!=null&&c.contains(x.target)||y(!1)};return window.addEventListener("mousedown",i),()=>window.removeEventListener("mousedown",i)},[d]);const v=n.useMemo(()=>{if(r.length===0)return[];const i=new Map;for(const x of s)i.set(x.id,x);return r.map(x=>{const c=i.get(x);return c?c.isWildcard?t("apiKeys.wildcard"):c.name:null}).filter(x=>!!x)},[s,r,t]),l=r.length===0?t("logs.filters.apiKeyAll"):t("logs.filters.apiKeySelected",{count:r.length}),h=i=>{r.includes(i)?o(r.filter(x=>x!==i)):o([...r,i])};return e.jsxs("div",{className:L("relative space-y-2",j),ref:m,children:[e.jsx(S,{children:t("logs.filters.apiKey")}),e.jsxs("button",{type:"button",onClick:()=>y(i=>!i),disabled:g||s.length===0,title:t("logs.filters.apiKeyHint"),className:L("flex h-10 w-full items-center justify-between rounded-md border bg-background px-3 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",r.length>0&&"border-primary",d&&"ring-2 ring-ring ring-offset-2"),children:[e.jsxs("span",{className:"truncate",children:[l,v.length>0&&e.jsx("span",{className:"ml-1 text-xs text-muted-foreground",children:v.join(", ")})]}),e.jsx("svg",{className:L("h-4 w-4 opacity-50 transition-transform",d&&"rotate-180"),viewBox:"0 0 20 20",fill:"currentColor",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"})})]}),d&&e.jsxs("div",{className:"absolute left-0 top-full z-30 mt-1 w-64 rounded-md border bg-popover p-2 shadow-lg",children:[e.jsxs("div",{className:"flex items-center justify-between rounded-md bg-muted px-3 py-2 text-xs",children:[e.jsx("span",{children:l}),e.jsx("button",{type:"button",onClick:()=>o([]),disabled:r.length===0,className:"text-primary hover:underline disabled:opacity-40",children:t("common.actions.reset")})]}),e.jsxs("div",{className:"max-h-56 overflow-y-auto py-2",children:[s.map(i=>{const x=i.isWildcard?t("apiKeys.wildcard"):i.name,c=r.includes(i.id);return e.jsxs("label",{className:L("flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-sm transition hover:bg-muted",c&&"bg-primary/10 text-primary"),children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4 rounded border",checked:c,onChange:()=>h(i.id)}),e.jsx("span",{className:"truncate",children:x})]},i.id)}),s.length===0&&e.jsx("p",{className:"px-2 py-2 text-xs text-muted-foreground",children:t("logs.filters.apiKeyAll")})]})]})]})}export{Qe as default};