@chenpu17/cc-gw 0.7.2 → 0.7.4

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +19 -6
  3. package/{server → src/server/dist}/index.js +199 -5
  4. package/src/web/dist/assets/About-DtotMOVX.js +6 -0
  5. package/src/web/dist/assets/ApiKeys-JMEe4vio.js +16 -0
  6. package/src/web/dist/assets/Dashboard-YSr86yyX.js +16 -0
  7. package/src/web/dist/assets/Events-BllB4NJb.js +16 -0
  8. package/src/web/dist/assets/Help--0pC64iM.js +23 -0
  9. package/src/web/dist/assets/Login-C032JoOm.js +1 -0
  10. package/src/web/dist/assets/Logs-CtQRHEIo.js +6 -0
  11. package/src/web/dist/assets/ModelManagement-Ct_X5FY3.js +1 -0
  12. package/src/web/dist/assets/PageHeader-mDU5G7Wl.js +1 -0
  13. package/src/web/dist/assets/PageSection-tyXkbtRe.js +1 -0
  14. package/src/web/dist/assets/Settings-B9Xm-ZZ7.js +11 -0
  15. package/src/web/dist/assets/card-Bo-S3Rlt.js +1 -0
  16. package/{web/assets/copy-DMW-t8h3.js → src/web/dist/assets/copy-jtNMLGaB.js} +1 -1
  17. package/src/web/dist/assets/dialog-BaUjtxEu.js +10 -0
  18. package/{web/assets/index-BM-Zc1f-.js → src/web/dist/assets/index-Bktfd8Ti.js} +23 -36
  19. package/src/web/dist/assets/index-CHrsfYJ0.js +280 -0
  20. package/src/web/dist/assets/index-PIl6QtJn.css +1 -0
  21. package/{web/assets/info-ByJJXVcp.js → src/web/dist/assets/info-iVJjf7Iu.js} +1 -1
  22. package/src/web/dist/assets/input-Nvkz2m3Y.js +1 -0
  23. package/src/web/dist/assets/label-D1_YxFJP.js +1 -0
  24. package/{web/assets/refresh-cw-BF1LiBLP.js → src/web/dist/assets/refresh-cw-BYq1FKR4.js} +1 -1
  25. package/src/web/dist/assets/select-BzsGk5RC.js +11 -0
  26. package/src/web/dist/assets/switch-BHcjSBqV.js +1 -0
  27. package/src/web/dist/assets/useApiQuery-xxHtqlFp.js +1 -0
  28. package/{web → src/web/dist}/index.html +2 -2
  29. package/web/assets/About-BY3JDEBL.js +0 -6
  30. package/web/assets/ApiKeys-qhC2jZqJ.js +0 -16
  31. package/web/assets/Button-6f5FYqHp.js +0 -1
  32. package/web/assets/Dashboard-xs4UfKRq.js +0 -16
  33. package/web/assets/Events-D_RJKNNo.js +0 -21
  34. package/web/assets/FormField-DKWx0tXD.js +0 -1
  35. package/web/assets/Help-CXLtGK8v.js +0 -23
  36. package/web/assets/Input-Iev5RCKK.js +0 -1
  37. package/web/assets/Login-qc-n0iUi.js +0 -1
  38. package/web/assets/Logs-DSGqxauM.js +0 -1
  39. package/web/assets/ModelManagement-D11jx2bC.js +0 -1
  40. package/web/assets/PageSection-BJJ735Qk.js +0 -1
  41. package/web/assets/Settings-BT-6W3GT.js +0 -11
  42. package/web/assets/StatusBadge-9lxhNpvi.js +0 -1
  43. package/web/assets/index-CJMKkw2H.css +0 -1
  44. package/web/assets/index-dFe_7qSp.js +0 -212
  45. package/web/assets/useApiQuery-i7GI_aGQ.js +0 -1
  46. /package/{cli → src/cli/dist}/index.d.ts +0 -0
  47. /package/{cli → src/cli/dist}/index.js +0 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 chenpu17
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,18 +1,31 @@
1
1
  {
2
2
  "name": "@chenpu17/cc-gw",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "pnpm run build:server && pnpm run build:web"
7
+ "dev": "pnpm --filter server dev",
8
+ "build": "pnpm run build:server && pnpm run build:web",
9
+ "build:server": "pnpm --filter @cc-gw/server build",
10
+ "build:cli": "pnpm --filter @cc-gw/cli build",
11
+ "build:web": "pnpm --filter @cc-gw/web build",
12
+ "build:all": "pnpm run build:server && pnpm run build:cli && pnpm run build:web",
13
+ "release:bundle": "pnpm run build:all && node scripts/build-release.mjs",
14
+ "prepack": "pnpm run build:all",
15
+ "lint": "pnpm exec eslint .",
16
+ "format": "pnpm exec prettier --check .",
17
+ "format:write": "pnpm exec prettier --write .",
18
+ "typecheck": "pnpm -r exec tsc --noEmit",
19
+ "test": "pnpm exec vitest run",
20
+ "test:playwright": "playwright test"
8
21
  },
9
22
  "bin": {
10
- "cc-gw": "cli/index.js"
23
+ "cc-gw": "src/cli/dist/index.js"
11
24
  },
12
25
  "files": [
13
- "cli",
14
- "server",
15
- "web",
26
+ "src/cli/dist",
27
+ "src/server/dist",
28
+ "src/web/dist",
16
29
  "README.md",
17
30
  "LICENSE"
18
31
  ],
@@ -12959,6 +12959,20 @@ async function recordApiKeyUsage(id, delta) {
12959
12959
  async function decryptApiKeyValue(value) {
12960
12960
  return decryptSecret(value);
12961
12961
  }
12962
+ async function revealApiKey(id) {
12963
+ const row = await getOne("SELECT id, key_ciphertext, is_wildcard FROM api_keys WHERE id = ?", [id]);
12964
+ if (!row) {
12965
+ return null;
12966
+ }
12967
+ if (row.is_wildcard) {
12968
+ return null;
12969
+ }
12970
+ const decrypted = await decryptSecret(row.key_ciphertext);
12971
+ if (!decrypted) {
12972
+ return null;
12973
+ }
12974
+ return { key: decrypted };
12975
+ }
12962
12976
  async function ensureWildcardMetadata() {
12963
12977
  const wildcard = await fetchWildcard();
12964
12978
  if (!wildcard) {
@@ -13015,7 +13029,7 @@ async function listEvents(options = {}) {
13015
13029
 
13016
13030
  // routes/anthropic-validator.ts
13017
13031
  var ALLOWED_ROLES = /* @__PURE__ */ new Set(["user", "assistant"]);
13018
- var KNOWN_BLOCK_TYPES = /* @__PURE__ */ new Set(["text", "tool_use", "tool_result", "thinking", "output_text", "input_text", "image"]);
13032
+ var KNOWN_BLOCK_TYPES = /* @__PURE__ */ new Set(["text", "tool_use", "tool_result", "thinking", "output_text", "input_text", "image", "document"]);
13019
13033
  var ALLOWED_TYPE_PREFIXES = ["input_", "output_", "data_", "media_"];
13020
13034
  function isPlainObject(value) {
13021
13035
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13136,6 +13150,24 @@ function validateContentBlock(block, opts) {
13136
13150
  }
13137
13151
  break;
13138
13152
  }
13153
+ case "document": {
13154
+ if (!block.source || !isPlainObject(block.source)) {
13155
+ return fail("document \u5757\u5FC5\u987B\u5305\u542B source \u5BF9\u8C61", appendPath(opts.path, "source"), "invalid_content_block");
13156
+ }
13157
+ if (typeof block.source.type !== "string") {
13158
+ return fail("document \u5757 source.type \u5FC5\u987B\u662F\u5B57\u7B26\u4E32", appendPath(opts.path, "source.type"), "invalid_content_block");
13159
+ }
13160
+ if (block.source.media_type !== void 0 && typeof block.source.media_type !== "string") {
13161
+ return fail("document \u5757 source.media_type \u5FC5\u987B\u662F\u5B57\u7B26\u4E32", appendPath(opts.path, "source.media_type"), "invalid_content_block");
13162
+ }
13163
+ if (block.title !== void 0 && typeof block.title !== "string") {
13164
+ return fail("document \u5757 title \u5FC5\u987B\u662F\u5B57\u7B26\u4E32", appendPath(opts.path, "title"), "invalid_content_block");
13165
+ }
13166
+ if (block.context !== void 0 && typeof block.context !== "string") {
13167
+ return fail("document \u5757 context \u5FC5\u987B\u662F\u5B57\u7B26\u4E32", appendPath(opts.path, "context"), "invalid_content_block");
13168
+ }
13169
+ break;
13170
+ }
13139
13171
  case "tool_use": {
13140
13172
  if (typeof block.id !== "string" || block.id.trim().length === 0) {
13141
13173
  return fail("tool_use \u5757\u9700\u8981\u5B57\u7B26\u4E32\u7C7B\u578B\u7684 id", appendPath(opts.path, "id"), "invalid_tool_use");
@@ -14864,6 +14896,146 @@ function resolveCachedTokens2(usage) {
14864
14896
  }
14865
14897
  return result;
14866
14898
  }
14899
+ function parseSSEToSummary(chunks, format, modelId) {
14900
+ const allChunks = chunks.join("");
14901
+ const lines = allChunks.split("\n");
14902
+ let accumulatedContent = "";
14903
+ let finishReason = null;
14904
+ const toolCalls = /* @__PURE__ */ new Map();
14905
+ let usagePrompt = null;
14906
+ let usageCompletion = null;
14907
+ let usageCached = null;
14908
+ for (const line of lines) {
14909
+ const trimmed = line.trim();
14910
+ if (!trimmed.startsWith("data:"))
14911
+ continue;
14912
+ const dataStr = trimmed.slice(5).trim();
14913
+ if (dataStr === "[DONE]")
14914
+ continue;
14915
+ try {
14916
+ const data = JSON.parse(dataStr);
14917
+ if (format === "chat") {
14918
+ const choice = data?.choices?.[0];
14919
+ if (choice) {
14920
+ const delta = choice.delta;
14921
+ if (delta?.content) {
14922
+ accumulatedContent += delta.content;
14923
+ }
14924
+ if (delta?.tool_calls) {
14925
+ for (const tc of delta.tool_calls) {
14926
+ const idx = tc.index ?? 0;
14927
+ const existing = toolCalls.get(idx);
14928
+ if (!existing && tc.id) {
14929
+ toolCalls.set(idx, {
14930
+ id: tc.id,
14931
+ type: tc.type || "function",
14932
+ name: tc.function?.name || "",
14933
+ arguments: tc.function?.arguments || ""
14934
+ });
14935
+ } else if (existing) {
14936
+ if (tc.function?.arguments) {
14937
+ existing.arguments += tc.function.arguments;
14938
+ }
14939
+ }
14940
+ }
14941
+ }
14942
+ if (choice.finish_reason) {
14943
+ finishReason = choice.finish_reason;
14944
+ }
14945
+ }
14946
+ if (data?.usage) {
14947
+ usagePrompt = data.usage.prompt_tokens ?? usagePrompt;
14948
+ usageCompletion = data.usage.completion_tokens ?? usageCompletion;
14949
+ const cached2 = resolveCachedTokens2(data.usage);
14950
+ if (cached2.read > 0 || cached2.creation > 0) {
14951
+ usageCached = cached2.read + cached2.creation;
14952
+ }
14953
+ }
14954
+ } else {
14955
+ const eventType = data?.type;
14956
+ if (eventType === "response.output_text.delta") {
14957
+ const delta = data?.delta;
14958
+ if (typeof delta === "string") {
14959
+ accumulatedContent += delta;
14960
+ }
14961
+ } else if (eventType === "response.content_part.delta") {
14962
+ const delta = data?.delta?.text;
14963
+ if (typeof delta === "string") {
14964
+ accumulatedContent += delta;
14965
+ }
14966
+ } else if (eventType === "response.function_call_arguments.delta") {
14967
+ const itemId = data?.item_id;
14968
+ const delta = data?.delta;
14969
+ if (itemId && typeof delta === "string") {
14970
+ let found = false;
14971
+ for (const tc of toolCalls.values()) {
14972
+ if (tc.id === itemId) {
14973
+ tc.arguments += delta;
14974
+ found = true;
14975
+ break;
14976
+ }
14977
+ }
14978
+ if (!found) {
14979
+ toolCalls.set(toolCalls.size, {
14980
+ id: itemId,
14981
+ type: "function",
14982
+ name: "",
14983
+ arguments: delta
14984
+ });
14985
+ }
14986
+ }
14987
+ } else if (eventType === "response.output_item.added") {
14988
+ const item = data?.item;
14989
+ if (item?.type === "function_call" && item?.call_id) {
14990
+ toolCalls.set(toolCalls.size, {
14991
+ id: item.call_id,
14992
+ type: "function",
14993
+ name: item.name || "",
14994
+ arguments: ""
14995
+ });
14996
+ }
14997
+ } else if (eventType === "response.completed" || eventType === "response.done") {
14998
+ const response = data?.response;
14999
+ if (response?.status) {
15000
+ finishReason = response.status;
15001
+ }
15002
+ if (response?.usage) {
15003
+ usagePrompt = response.usage.input_tokens ?? response.usage.prompt_tokens ?? usagePrompt;
15004
+ usageCompletion = response.usage.output_tokens ?? response.usage.completion_tokens ?? usageCompletion;
15005
+ const cached2 = resolveCachedTokens2(response.usage);
15006
+ if (cached2.read > 0 || cached2.creation > 0) {
15007
+ usageCached = cached2.read + cached2.creation;
15008
+ }
15009
+ }
15010
+ }
15011
+ }
15012
+ } catch {
15013
+ }
15014
+ }
15015
+ const summary = {
15016
+ content: accumulatedContent,
15017
+ model: modelId,
15018
+ finish_reason: finishReason
15019
+ };
15020
+ if (usagePrompt != null || usageCompletion != null || usageCached != null) {
15021
+ summary.usage = {
15022
+ prompt_tokens: usagePrompt,
15023
+ completion_tokens: usageCompletion,
15024
+ cached_tokens: usageCached
15025
+ };
15026
+ }
15027
+ if (toolCalls.size > 0) {
15028
+ summary.tool_calls = Array.from(toolCalls.values()).map((tc) => ({
15029
+ id: tc.id,
15030
+ type: tc.type,
15031
+ function: {
15032
+ name: tc.name,
15033
+ arguments: tc.arguments
15034
+ }
15035
+ }));
15036
+ }
15037
+ return summary;
15038
+ }
14867
15039
  var isText = (input) => typeof input === "string" && input.length > 0;
14868
15040
  function filterForwardedAnthropicHeaders(headers) {
14869
15041
  if (!headers)
@@ -15469,7 +15641,8 @@ async function registerOpenAiRoutes(app) {
15469
15641
  });
15470
15642
  if (storeResponsePayloads && capturedResponseChunks2) {
15471
15643
  try {
15472
- await upsertLogPayload(logId, { response: capturedResponseChunks2.join("") });
15644
+ const summary = parseSSEToSummary(capturedResponseChunks2, "responses", target.modelId);
15645
+ await upsertLogPayload(logId, { response: JSON.stringify(summary) });
15473
15646
  } catch (error) {
15474
15647
  debugLog("failed to persist streamed payload", error);
15475
15648
  }
@@ -15605,7 +15778,8 @@ async function registerOpenAiRoutes(app) {
15605
15778
  debugLog("stream finished", { chunkCount, usagePrompt, usageCompletion, usageReasoning, usageCached });
15606
15779
  if (capturedResponseChunks && capturedResponseChunks.length > 0) {
15607
15780
  try {
15608
- await upsertLogPayload(logId, { response: capturedResponseChunks.join("") });
15781
+ const summary = parseSSEToSummary(capturedResponseChunks, "responses", target.modelId);
15782
+ await upsertLogPayload(logId, { response: JSON.stringify(summary) });
15609
15783
  } catch (error) {
15610
15784
  debugLog("failed to persist streamed payload", error);
15611
15785
  }
@@ -16049,7 +16223,8 @@ async function registerOpenAiRoutes(app) {
16049
16223
  });
16050
16224
  if (storeResponsePayloads && capturedResponseChunks2) {
16051
16225
  try {
16052
- await upsertLogPayload(logId, { response: capturedResponseChunks2.join("") });
16226
+ const summary = parseSSEToSummary(capturedResponseChunks2, "chat", target.modelId);
16227
+ await upsertLogPayload(logId, { response: JSON.stringify(summary) });
16053
16228
  } catch (error) {
16054
16229
  debugLog("failed to persist streamed payload", error);
16055
16230
  }
@@ -16162,7 +16337,8 @@ async function registerOpenAiRoutes(app) {
16162
16337
  reply.raw.removeListener("close", replyClosed);
16163
16338
  if (capturedResponseChunks && capturedResponseChunks.length > 0) {
16164
16339
  try {
16165
- await upsertLogPayload(logId, { response: capturedResponseChunks.join("") });
16340
+ const summary = parseSSEToSummary(capturedResponseChunks, "chat", target.modelId);
16341
+ await upsertLogPayload(logId, { response: JSON.stringify(summary) });
16166
16342
  } catch (error) {
16167
16343
  debugLog("failed to persist streamed payload", error);
16168
16344
  }
@@ -17590,6 +17766,24 @@ async function registerAdminRoutes(app) {
17590
17766
  return { error: error instanceof Error ? error.message : "Failed to delete API key" };
17591
17767
  }
17592
17768
  });
17769
+ app.get("/api/keys/:id/reveal", async (request, reply) => {
17770
+ const id = Number(request.params.id);
17771
+ if (!Number.isFinite(id)) {
17772
+ reply.code(400);
17773
+ return { error: "Invalid id" };
17774
+ }
17775
+ try {
17776
+ const result = await revealApiKey(id);
17777
+ if (!result) {
17778
+ reply.code(404);
17779
+ return { error: "API key not found or cannot be revealed" };
17780
+ }
17781
+ return result;
17782
+ } catch (error) {
17783
+ reply.code(500);
17784
+ return { error: error instanceof Error ? error.message : "Failed to reveal API key" };
17785
+ }
17786
+ });
17593
17787
  const normalizePath = (path5) => {
17594
17788
  const trimmed = path5.trim();
17595
17789
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -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-CHrsfYJ0.js";import{u as y}from"./useApiQuery-xxHtqlFp.js";import{P as E}from"./PageHeader-mDU5G7Wl.js";import{P as n}from"./PageSection-tyXkbtRe.js";import{C as m,a as p}from"./card-Bo-S3Rlt.js";import{I}from"./info-iVJjf7Iu.js";import{R as T}from"./refresh-cw-BYq1FKR4.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.4",w={version:_},L={VITE_BUILD_TIME:"2025-12-06T01:32:02.413Z",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};
@@ -0,0 +1,16 @@
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-CHrsfYJ0.js";import{E as ye}from"./index-Bktfd8Ti.js";import{u as k}from"./useApiQuery-xxHtqlFp.js";import{P as xe,B as q}from"./PageHeader-mDU5G7Wl.js";import{P as z}from"./PageSection-tyXkbtRe.js";import{I as he}from"./input-Nvkz2m3Y.js";import{L as I}from"./label-D1_YxFJP.js";import{C as T,a as S}from"./card-Bo-S3Rlt.js";import{P as ge,D as W,a as H,b as V,c as G,d as fe,e as Q}from"./dialog-BaUjtxEu.js";import{C as U}from"./copy-jtNMLGaB.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 je=D("EyeOff",[["path",{d:"M9.88 9.88a3 3 0 1 0 4.24 4.24",key:"1jxqfv"}],["path",{d:"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68",key:"9wicm4"}],["path",{d:"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61",key:"1jreej"}],["line",{x1:"2",x2:"22",y1:"2",y2:"22",key:"a6p6uj"}]]);/**
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 ve=D("Eye",[["path",{d:"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z",key:"rwhkz3"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);/**
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 Ke=D("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]),_=c.forwardRef(({className:a,...r},y)=>e.jsx("textarea",{className:$("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",a),ref:y,...r}));_.displayName="Textarea";const Ne=[{value:1,labelKey:"apiKeys.analytics.range.today"},{value:7,labelKey:"apiKeys.analytics.range.week"},{value:30,labelKey:"apiKeys.analytics.range.month"}];function Ae(){const{t:a}=Z(),{pushToast:r}=de(),[y,m]=c.useState(!1),[x,h]=c.useState(""),[L,N]=c.useState(""),[l,b]=c.useState(null),[J,E]=c.useState(null),[p,X]=c.useState(7),[M,A]=c.useState(new Map),[Y,O]=c.useState(null),g=k(["api-keys"],{url:"/api/keys",method:"GET"}),j=k(["api-keys","overview",p],{url:"/api/stats/api-keys/overview",method:"GET",params:{days:p}}),f=k(["api-keys","usage",p],{url:"/api/stats/api-keys/usage",method:"GET",params:{days:p,limit:10}}),w=g.data??[],u=j.data,d=f.data??[],ee=w.some(s=>s.isWildcard),ae=u?u.totalKeys.toLocaleString():"-",se=u?u.enabledKeys.toLocaleString():"-",te=u?u.activeKeys.toLocaleString():"-",P=async()=>{var s,t;if(!x.trim()){r({title:a("apiKeys.errors.nameRequired"),variant:"error"});return}try{const i=await K.post("/api/keys",{name:x.trim(),description:L.trim()||void 0});b(i.data),m(!1),h(""),N(""),g.refetch(),j.refetch(),f.refetch(),r({title:a("apiKeys.toast.keyCreated"),variant:"success"})}catch(i){r({title:a("apiKeys.toast.createFailure",{message:((t=(s=i.response)==null?void 0:s.data)==null?void 0:t.error)||i.message}),variant:"error"})}},ie=async(s,t)=>{var i,n;try{await K.patch(`/api/keys/${s}`,{enabled:!t}),g.refetch(),j.refetch(),r({title:a("apiKeys.toast.keyUpdated"),variant:"success"})}catch(v){r({title:a("apiKeys.toast.updateFailure",{message:((n=(i=v.response)==null?void 0:i.data)==null?void 0:n.error)||v.message}),variant:"error"})}},re=async s=>{var t,i;if(confirm(a("apiKeys.confirmDelete"))){E(s);try{await K.delete(`/api/keys/${s}`),g.refetch(),j.refetch(),f.refetch(),r({title:a("apiKeys.toast.keyDeleted"),variant:"success"})}catch(n){r({title:a("apiKeys.toast.deleteFailure",{message:((i=(t=n.response)==null?void 0:t.data)==null?void 0:i.error)||n.message}),variant:"error"})}finally{E(null)}}},ne=async s=>{var t,i;if(!M.has(s)){O(s);try{const n=await K.get(`/api/keys/${s}/reveal`);A(v=>new Map(v).set(s,n.data.key))}catch(n){r({title:a("apiKeys.toast.revealFailure"),description:((i=(t=n.response)==null?void 0:t.data)==null?void 0:i.error)||n.message,variant:"error"})}finally{O(null)}}},le=s=>{A(t=>{const i=new Map(t);return i.delete(s),i})},R=async s=>{try{await navigator.clipboard.writeText(s),r({title:a("apiKeys.toast.keyCopied"),variant:"success"})}catch(t){r({title:a("apiKeys.toast.copyFailure"),description:t instanceof Error?t.message:a("common.unknownError"),variant:"error"})}},F=s=>s?new Date(s).toLocaleString():a("common.noData"),ce=c.useMemo(()=>{const s=d.map(t=>t.apiKeyName??a("apiKeys.analytics.unknownKey"));return{tooltip:{trigger:"axis"},grid:{left:60,right:20,top:40,bottom:40},xAxis:{type:"category",data:s,axisLabel:{interval:0,rotate:20}},yAxis:{type:"value"},series:[{name:a("apiKeys.analytics.requestsSeries"),type:"bar",data:d.map(t=>t.requests),itemStyle:{color:"hsl(var(--primary))"}}]}},[d,a]),oe=c.useMemo(()=>{const s=d.map(t=>t.apiKeyName??a("apiKeys.analytics.unknownKey"));return{tooltip:{trigger:"axis"},legend:{data:[a("apiKeys.analytics.tokens.input"),a("apiKeys.analytics.tokens.output")]},grid:{left:60,right:20,top:50,bottom:40},xAxis:{type:"category",data:s,axisLabel:{interval:0,rotate:20}},yAxis:{type:"value"},series:[{name:a("apiKeys.analytics.tokens.input"),type:"bar",stack:"tokens",itemStyle:{color:"#22c55e"},data:d.map(t=>t.inputTokens)},{name:a("apiKeys.analytics.tokens.output"),type:"bar",stack:"tokens",itemStyle:{color:"#0ea5e9"},data:d.map(t=>t.outputTokens)}]}},[d,a]);return g.isLoading?e.jsx(pe,{}):e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(xe,{icon:e.jsx(me,{className:"h-5 w-5","aria-hidden":"true"}),title:a("apiKeys.title"),description:a("apiKeys.description"),actions:e.jsxs(o,{onClick:()=>m(!0),children:[e.jsx(ge,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),a("apiKeys.createNew")]})}),e.jsx(z,{title:a("apiKeys.analytics.title"),description:a("apiKeys.analytics.description",{days:p}),actions:e.jsx("div",{className:"flex items-center gap-1 rounded-lg border p-1",children:Ne.map(s=>{const t=p===s.value;return e.jsx("button",{type:"button",onClick:()=>X(s.value),className:$("inline-flex h-7 items-center rounded-md px-3 text-xs font-medium transition-colors",t?"bg-primary text-primary-foreground":"text-muted-foreground hover:bg-muted"),children:a(s.labelKey)},s.value)})}),children:e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-3",children:[e.jsx(C,{label:a("apiKeys.analytics.cards.total"),value:ae}),e.jsx(C,{label:a("apiKeys.analytics.cards.enabled"),value:se}),e.jsx(C,{label:a("apiKeys.analytics.cards.active",{days:p}),value:te})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(B,{title:a("apiKeys.analytics.charts.requests"),loading:f.isLoading,empty:d.length===0,emptyText:a("apiKeys.analytics.empty"),option:ce}),e.jsx(B,{title:a("apiKeys.analytics.charts.tokens"),loading:f.isLoading,empty:d.length===0,emptyText:a("apiKeys.analytics.empty"),option:oe})]})]})}),e.jsx(z,{title:a("apiKeys.list.title"),description:ee?a("apiKeys.wildcardHint"):void 0,children:w.length===0?e.jsx("div",{className:"flex h-32 items-center justify-center rounded-lg border border-dashed",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:a("apiKeys.list.empty")})}):e.jsx("div",{className:"grid gap-4",children:w.map(s=>{const t=(s.totalInputTokens+s.totalOutputTokens).toLocaleString(),i=M.get(s.id),n=Y===s.id;return e.jsx(T,{children:e.jsx(S,{className:"space-y-4 pt-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h3",{className:"text-base font-semibold",children:s.name}),s.isWildcard&&e.jsx(q,{variant:"secondary",children:a("apiKeys.wildcard")}),e.jsx(q,{variant:s.enabled?"default":"outline",children:s.enabled?a("apiKeys.status.enabled"):a("apiKeys.status.disabled")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"rounded-md bg-muted px-3 py-1.5 font-mono text-sm",children:s.isWildcard?a("apiKeys.wildcard"):i??s.maskedKey??"********"}),!s.isWildcard&&e.jsx("div",{className:"flex items-center gap-1",children:i?e.jsxs(e.Fragment,{children:[e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>void R(i),"aria-label":a("common.actions.copy"),title:a("common.actions.copy"),children:e.jsx(U,{className:"h-4 w-4","aria-hidden":"true"})}),e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>le(s.id),"aria-label":a("apiKeys.actions.hide"),title:a("apiKeys.actions.hide"),children:e.jsx(je,{className:"h-4 w-4","aria-hidden":"true"})})]}):e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>void ne(s.id),disabled:n,"aria-label":a("apiKeys.actions.reveal"),title:a("apiKeys.actions.reveal"),children:e.jsx(ve,{className:"h-4 w-4","aria-hidden":"true"})})})]}),s.isWildcard?e.jsx("p",{className:"text-sm text-muted-foreground",children:a("apiKeys.wildcardHint")}):s.description?e.jsx("p",{className:"whitespace-pre-wrap text-sm text-muted-foreground",children:s.description}):null,e.jsxs("div",{className:"grid gap-3 text-sm sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a("apiKeys.created")}),e.jsx("p",{className:"font-medium",children:F(s.createdAt)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a("apiKeys.lastUsed")}),e.jsx("p",{className:"font-medium",children:F(s.lastUsedAt)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a("apiKeys.requestCount")}),e.jsx("p",{className:"font-medium",children:s.requestCount.toLocaleString()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a("apiKeys.totalTokens")}),e.jsx("p",{className:"font-medium",children:t})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(o,{variant:s.enabled?"outline":"default",size:"sm",onClick:()=>ie(s.id,s.enabled),children:s.enabled?a("apiKeys.actions.disable"):a("apiKeys.actions.enable")}),!s.isWildcard&&e.jsx(o,{variant:"ghost",size:"icon",className:"h-8 w-8 text-destructive hover:bg-destructive/10 hover:text-destructive",onClick:()=>re(s.id),disabled:J===s.id,"aria-label":a("apiKeys.actions.delete"),children:e.jsx(Ke,{className:"h-4 w-4","aria-hidden":"true"})})]})]})})},s.id)})})}),e.jsx(W,{open:y,onOpenChange:m,children:e.jsxs(H,{children:[e.jsxs(V,{children:[e.jsx(G,{children:a("apiKeys.createNew")}),e.jsx(fe,{children:a("apiKeys.createDescription")})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(I,{htmlFor:"keyName",children:[a("apiKeys.keyNamePlaceholder")," *"]}),e.jsx(he,{id:"keyName",value:x,onChange:s=>h(s.target.value),placeholder:a("apiKeys.keyNamePlaceholder"),onKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),P())}})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(I,{htmlFor:"keyDescription",children:a("apiKeys.descriptionLabel")}),e.jsx(_,{id:"keyDescription",value:L,onChange:s=>N(s.target.value),placeholder:a("apiKeys.keyDescriptionPlaceholder"),rows:3})]})]}),e.jsxs(Q,{children:[e.jsx(o,{variant:"outline",onClick:()=>{m(!1),h(""),N("")},children:a("common.actions.cancel")}),e.jsx(o,{onClick:()=>void P(),children:a("apiKeys.createAction")})]})]})}),e.jsx(W,{open:!!l,onOpenChange:()=>b(null),children:e.jsxs(H,{children:[e.jsx(V,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600",children:e.jsx(ue,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx(G,{children:a("apiKeys.keyCreated")})]})}),e.jsx("p",{className:"text-sm font-medium text-amber-600 dark:text-amber-400",children:a("apiKeys.saveKeyWarning")}),e.jsx("div",{className:"rounded-md bg-muted px-4 py-3 font-mono text-sm",children:l==null?void 0:l.key}),(l==null?void 0:l.description)&&e.jsx("p",{className:"whitespace-pre-wrap text-sm text-muted-foreground",children:l.description}),e.jsxs(Q,{children:[e.jsxs(o,{onClick:()=>void R((l==null?void 0:l.key)??""),children:[e.jsx(U,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),a("common.actions.copy")]}),e.jsx(o,{variant:"outline",onClick:()=>b(null),children:a("common.actions.close")})]})]})})]})}function C({label:a,value:r}){return e.jsx(T,{children:e.jsxs(S,{className:"pt-4",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a}),e.jsx("p",{className:"mt-2 text-2xl font-semibold",children:r})]})})}function B({title:a,option:r,loading:y,empty:m,emptyText:x}){const{t:h}=Z();return e.jsx(T,{children:e.jsxs(S,{className:"space-y-4 pt-4",children:[e.jsx("h3",{className:"text-base font-semibold",children:a}),y?e.jsx("div",{className:"flex h-[280px] items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:h("common.loadingShort")})}):m?e.jsx("div",{className:"flex h-[280px] items-center justify-center rounded-lg border border-dashed",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:x})}):e.jsx(ye,{option:r,style:{height:280},notMerge:!0,lazyUpdate:!0})]})})}export{Ae as default};
@@ -0,0 +1,16 @@
1
+ import{c as O,r as d,j as e,a as j,u as B,b as re,d as oe,t as de,L as ne,B as D,e as ie}from"./index-CHrsfYJ0.js";import{E as le}from"./index-Bktfd8Ti.js";import{P as ce,B as S}from"./PageHeader-mDU5G7Wl.js";import{P as J}from"./PageSection-tyXkbtRe.js";import{u as L}from"./useApiQuery-xxHtqlFp.js";import{C as G,a as Q}from"./card-Bo-S3Rlt.js";import{S as me,a as he,b as ue,c as xe,d as I}from"./select-BzsGk5RC.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 pe=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 be=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,...a},s)=>e.jsx("div",{className:"relative w-full overflow-auto",children:e.jsx("table",{ref:s,className:j("w-full caption-bottom text-sm",t),...a})}));F.displayName="Table";const H=d.forwardRef(({className:t,...a},s)=>e.jsx("thead",{ref:s,className:j("[&_tr]:border-b",t),...a}));H.displayName="TableHeader";const z=d.forwardRef(({className:t,...a},s)=>e.jsx("tbody",{ref:s,className:j("[&_tr:last-child]:border-0",t),...a}));z.displayName="TableBody";const fe=d.forwardRef(({className:t,...a},s)=>e.jsx("tfoot",{ref:s,className:j("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",t),...a}));fe.displayName="TableFooter";const A=d.forwardRef(({className:t,...a},s)=>e.jsx("tr",{ref:s,className:j("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",t),...a}));A.displayName="TableRow";const h=d.forwardRef(({className:t,...a},s)=>e.jsx("th",{ref:s,className:j("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",t),...a}));h.displayName="TableHead";const u=d.forwardRef(({className:t,...a},s)=>e.jsx("td",{ref:s,className:j("p-4 align-middle [&:has([role=checkbox])]:pr-0",t),...a}));u.displayName="TableCell";const ge=d.forwardRef(({className:t,...a},s)=>e.jsx("caption",{ref:s,className:j("mt-4 text-sm text-muted-foreground",t),...a}));ge.displayName="TableCaption";function P(t,a,s){return t==null?"-":`${t.toLocaleString(void 0,s)} ${a}`}function K(t){if(t==null)return"-";if(t<1024)return`${t} B`;const a=["KB","MB","GB","TB"];let s=t/1024,r=0;for(;s>=1024&&r<a.length-1;)s/=1024,r+=1;return`${s.toFixed(s>=100?0:s>=10?1:2)} ${a[r]}`}function Ce(){var U;const{t}=B(),{pushToast:a}=re(),[s,r]=d.useState("all"),[i,q]=d.useState(!1),x=s==="all"?void 0:s,N=L(["stats","overview",s],{url:"/api/stats/overview",method:"GET",params:x?{endpoint:x}:void 0}),v=L(["stats","daily",14,s],{url:"/api/stats/daily",method:"GET",params:{days:14,...x?{endpoint:x}:{}}}),f=L(["stats","model",7,6,s],{url:"/api/stats/model",method:"GET",params:{days:7,limit:6,...x?{endpoint:x}:{}}}),T=L(["status"],{url:"/api/status",method:"GET"}),g=L(["db","info"],{url:"/api/db/info",method:"GET"}),_=g.refetch??(async()=>{}),E=L(["logs","recent",s],{url:"/api/logs",method:"GET",params:{limit:5,...x?{endpoint:x}:{}}},{refetchInterval:3e4});d.useEffect(()=>{N.isError&&N.error&&a({title:t("dashboard.toast.overviewError"),description:N.error.message,variant:"error"})},[N.isError,N.error,a,t]),d.useEffect(()=>{v.isError&&v.error&&a({title:t("dashboard.toast.dailyError"),description:v.error.message,variant:"error"})},[v.isError,v.error,a,t]),d.useEffect(()=>{f.isError&&f.error&&a({title:t("dashboard.toast.modelError"),description:f.error.message,variant:"error"})},[f.isError,f.error,a,t]),d.useEffect(()=>{T.isError&&T.error&&a({title:t("dashboard.toast.statusError"),description:T.error.message,variant:"error"})},[T.isError,T.error,a,t]),d.useEffect(()=>{g.isError&&g.error&&a({title:t("dashboard.toast.dbError"),description:g.error.message,variant:"error"})},[g.isError,g.error,a,t]);const W=d.useCallback(async()=>{if(!i){q(!0);try{await oe.post("/api/db/compact"),await _(),a({title:t("dashboard.toast.compactSuccess.title"),description:t("dashboard.toast.compactSuccess.desc"),variant:"success"})}catch(n){const m=de(n);a({title:t("dashboard.toast.compactError.title"),description:m.message,variant:"error"})}finally{q(!1)}}},[i,a,_,t]);d.useEffect(()=>{E.isError&&E.error&&a({title:t("dashboard.toast.recentError"),description:E.error.message,variant:"error"})},[E.isError,E.error,a,t]);const o=N.data,y=v.data??[],l=f.data??[],C=T.data,R=g.data,X=((U=E.data)==null?void 0:U.items)??[],Y=R?K(R.totalBytes??R.sizeBytes):"-",Z=R?K(R.memoryRssBytes??0):"-",ee=d.useMemo(()=>{const n=y.map(b=>b.date),m=t("dashboard.charts.barRequests"),c=t("dashboard.charts.lineInput"),k=t("dashboard.charts.lineOutput"),p=t("dashboard.charts.lineCacheRead"),V=t("dashboard.charts.lineCacheCreation");return{tooltip:{trigger:"axis"},legend:{data:[m,c,k,p,V]},grid:{left:60,right:40,top:60,bottom:60},xAxis:{type:"category",data:n},yAxis:{type:"value"},series:[{name:m,type:"bar",data:y.map(b=>b.requestCount),itemStyle:{color:"hsl(var(--primary))",borderRadius:[4,4,0,0]}},{name:c,type:"line",data:y.map(b=>b.inputTokens),smooth:!0,itemStyle:{color:"#10b981"},lineStyle:{width:2}},{name:k,type:"line",data:y.map(b=>b.outputTokens),smooth:!0,itemStyle:{color:"#f59e0b"},lineStyle:{width:2}},{name:p,type:"line",data:y.map(b=>b.cacheReadTokens),smooth:!0,itemStyle:{color:"#8b5cf6"},lineStyle:{width:2}},{name:V,type:"line",data:y.map(b=>b.cacheCreationTokens),smooth:!0,itemStyle:{color:"#ec4899"},lineStyle:{width:2}}]}},[y,t]),te=d.useMemo(()=>{const n=l.map(p=>`${p.provider}/${p.model}`),m=t("dashboard.charts.barRequests"),c=t("dashboard.charts.lineInput"),k=t("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis"},legend:{data:[m,c,k]},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:k,type:"line",yAxisIndex:1,smooth:!0,data:l.map(p=>p.outputTokens??0),itemStyle:{color:"#f59e0b"}}]}},[l,t]),se=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]),ae=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||T.isPending||g.isPending?e.jsx(ne,{}):e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ce,{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(me,{value:s,onValueChange:n=>r(n),children:[e.jsx(he,{className:"w-[140px]",children:e.jsx(ue,{})}),e.jsxs(xe,{children:[e.jsx(I,{value:"all",children:t("dashboard.filters.endpointAll")}),e.jsx(I,{value:"anthropic",children:t("dashboard.filters.endpointAnthropic")}),e.jsx(I,{value:"openai",children:t("dashboard.filters.endpointOpenAI")})]})]})]})}),C&&e.jsx(G,{children:e.jsxs(Q,{className:"flex flex-wrap items-center gap-3 pt-4",children:[e.jsx(S,{variant:"default",className:"bg-emerald-500",children:t("dashboard.status.listening",{host:C.host??"0.0.0.0",port:C.port})}),e.jsx(S,{variant:"secondary",children:t("dashboard.status.providers",{value:C.providers.toLocaleString()})}),e.jsx(S,{variant:"secondary",children:t("dashboard.status.todayRequests",{value:((o==null?void 0:o.today.requests)??0).toLocaleString()})}),e.jsx(S,{variant:"outline",children:t("dashboard.status.active",{value:(C.activeRequests??0).toLocaleString()})}),e.jsx(S,{variant:"outline",children:t("dashboard.status.dbSize",{value:Y})}),e.jsx(S,{variant:"outline",children:t("dashboard.status.memory",{value:Z})}),e.jsx(ie,{variant:"outline",size:"sm",onClick:W,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-4 w-4"}),title:t("dashboard.cards.todayRequests"),value:(o==null?void 0:o.today.requests)??0,suffix:t("common.units.request")}),e.jsx(w,{icon:e.jsx(be,{className:"h-4 w-4"}),title:t("dashboard.cards.todayInput"),value:(o==null?void 0:o.today.inputTokens)??0,suffix:t("common.units.token")}),e.jsx(w,{icon:e.jsx($,{className:"h-4 w-4"}),title:t("dashboard.cards.todayCacheRead"),value:(o==null?void 0:o.today.cacheReadTokens)??0,suffix:t("common.units.token")}),e.jsx(w,{icon:e.jsx($,{className:"h-4 w-4"}),title:t("dashboard.cards.todayCacheCreation"),value:(o==null?void 0:o.today.cacheCreationTokens)??0,suffix:t("common.units.token")}),e.jsx(w,{icon:e.jsx(D,{className:"h-4 w-4"}),title:t("dashboard.cards.todayOutput"),value:(o==null?void 0:o.today.outputTokens)??0,suffix:t("common.units.token")}),e.jsx(w,{icon:e.jsx(pe,{className:"h-4 w-4"}),title:t("dashboard.cards.avgLatency"),value:(o==null?void 0:o.today.avgLatencyMs)??0,suffix:t("common.units.ms")})]}),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:v.isPending,option:ee,empty:!y.length,emptyText:t("dashboard.charts.empty")}),e.jsx(M,{title:t("dashboard.charts.modelTitle"),description:t("dashboard.charts.modelDesc"),loading:f.isPending,option:te,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:f.isPending,option:se,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:f.isPending,option:ae,empty:!l.some(n=>n.avgTpotMs!=null&&n.avgTpotMs>0),emptyText:t("dashboard.charts.tpotEmpty")})]}),e.jsx(ye,{models:l,loading:f.isPending}),e.jsx(je,{loading:E.isPending,records:X})]})}function w({icon:t,title:a,value:s,suffix:r}){return e.jsx(G,{children:e.jsxs(Q,{className:"pt-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:a}),t&&e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary",children:t})]}),e.jsxs("p",{className:"text-2xl font-semibold",children:[s.toLocaleString(),r&&e.jsx("span",{className:"ml-1 text-sm font-normal text-muted-foreground",children:r})]})]})})}function M({title:t,description:a,option:s,loading:r,empty:i,emptyText:q}){const{t:x}=B();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:a})]}),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:q??x("dashboard.charts.empty")})]}):e.jsx(le,{option:s,style:{height:320},notMerge:!0,lazyUpdate:!0})]})})}function ye({models:t,loading:a}){const{t:s}=B(),r=t.length>0;return e.jsx(J,{title:s("dashboard.modelTable.title"),description:s("dashboard.modelTable.description"),children:a?e.jsx("div",{className:"flex h-32 items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:s("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:s("dashboard.modelTable.columns.model")}),e.jsx(h,{className:"text-right",children:s("dashboard.modelTable.columns.requests")}),e.jsx(h,{className:"text-right",children:s("dashboard.modelTable.columns.latency")}),e.jsx(h,{className:"text-right",children:s("dashboard.modelTable.columns.ttft")}),e.jsx(h,{className:"text-right",children:s("dashboard.modelTable.columns.tpot")})]})}),e.jsx(z,{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,s("common.units.ms"))}),e.jsx(u,{className:"text-right",children:P(i.avgTtftMs,s("common.units.ms"))}),e.jsx(u,{className:"text-right",children:P(i.avgTpotMs,s("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:s("dashboard.modelTable.empty")})})})}function je({records:t,loading:a}){const{t:s}=B();return e.jsx(J,{title:s("dashboard.recent.title"),description:s("dashboard.recent.subtitle",{count:5}),children:a?e.jsx("div",{className:"flex h-32 items-center justify-center",children:e.jsx("span",{className:"text-sm text-muted-foreground",children:s("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:s("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:s("dashboard.recent.columns.time")}),e.jsx(h,{children:s("dashboard.recent.columns.endpoint")}),e.jsx(h,{children:s("dashboard.recent.columns.provider")}),e.jsx(h,{children:s("dashboard.recent.columns.route")}),e.jsx(h,{className:"text-right",children:s("dashboard.recent.columns.latency")}),e.jsx(h,{children:s("dashboard.recent.columns.status")})]})}),e.jsx(z,{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"?s("logs.table.endpointAnthropic"):r.endpoint==="openai"?s("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??s("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,s("common.units.ms"))}),e.jsx(u,{children:e.jsx(S,{variant:r.error?"destructive":"default",children:(r.status_code??(r.error?500:200)).toString()})})]},r.id))})]})})})}export{Ce as default};
@@ -0,0 +1,16 @@
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-CHrsfYJ0.js";import{P as z,B as j}from"./PageHeader-mDU5G7Wl.js";import{I as F}from"./input-Nvkz2m3Y.js";import{C as w,a as C,b as V}from"./card-Bo-S3Rlt.js";import{S as B,a as D,b as K,c as H,d as f}from"./select-BzsGk5RC.js";import{R as J}from"./refresh-cw-BYq1FKR4.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=N("ChevronLeft",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);/**
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 U=N("Filter",[["polygon",{points:"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3",key:"1yg77f"}]]);/**
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 _=N("ShieldAlert",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]]);function q(t){const l=Date.now()-t,r=Math.abs(l),m=60*1e3,c=60*m,d=24*c;if(r<m){const a=Math.max(Math.round(r/1e3),1);return l>=0?`${a}s ago`:`in ${a}s`}if(r<c){const a=Math.round(r/m);return l>=0?`${a}m ago`:`in ${a}m`}if(r<d){const a=Math.round(r/c);return l>=0?`${a}h ago`:`in ${a}h`}const x=Math.round(r/d);return l>=0?`${x}d ago`:`in ${x}d`}function G(t){return new Date(t).toLocaleString()}const Q={info:"secondary",warn:"outline",error:"destructive"};function te(){const{t}=E(),{pushToast:p}=L(),[l,r]=i.useState([]),[m,c]=i.useState(!0),[d,x]=i.useState(null),[a,b]=i.useState(null),[o,v]=i.useState({level:"",type:""}),[g,y]=i.useState(!1),u=async s=>{c(!0);try{const n=await T.list({cursor:(s==null?void 0:s.cursor)??void 0,limit:50,level:o.level||void 0,type:o.type||void 0});r(n.events),b(n.nextCursor),x((s==null?void 0:s.cursor)??null)}catch(n){const M=P(n);p({title:t("events.toast.loadFailure",{message:M.message}),variant:"error"})}finally{c(!1),y(!1)}};i.useEffect(()=>{u({reset:!0})},[o.level,o.type]);const S=()=>{y(!0),u({cursor:d,reset:!1})},A=()=>{v({level:"",type:""})},k=i.useMemo(()=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(h,{variant:"outline",size:"sm",disabled:!d,onClick:()=>void u({cursor:void 0}),children:[e.jsx(O,{className:"mr-1 h-4 w-4"})," ",t("events.actions.newest")]}),e.jsxs(h,{variant:"outline",size:"sm",disabled:!a,onClick:()=>void u({cursor:a??void 0}),children:[t("events.actions.older")," ",e.jsx(R,{className:"ml-1 h-4 w-4"})]})]}),[d,a,t]);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(z,{icon:e.jsx(_,{className:"h-5 w-5"}),title:t("events.title"),description:t("events.description"),actions:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[k,e.jsxs(h,{variant:"outline",size:"sm",onClick:S,disabled:g,children:[e.jsx(J,{className:$("mr-2 h-4 w-4",g&&"animate-spin")}),t(g?"common.actions.refreshing":"common.actions.refresh")]})]})}),e.jsx(w,{children:e.jsx(C,{className:"pt-4",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(U,{className:"h-4 w-4"}),t("events.filters.title")]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(B,{value:o.level,onValueChange:s=>v(n=>({...n,level:s==="all"?"":s})),children:[e.jsx(D,{className:"w-[140px]",children:e.jsx(K,{placeholder:t("events.filters.allLevels")})}),e.jsxs(H,{children:[e.jsx(f,{value:"all",children:t("events.filters.allLevels")}),e.jsx(f,{value:"info",children:t("events.levels.info")}),e.jsx(f,{value:"warn",children:t("events.levels.warn")}),e.jsx(f,{value:"error",children:t("events.levels.error")})]})]}),e.jsx(F,{className:"w-[180px]",placeholder:t("events.filters.typePlaceholder"),value:o.type,onChange:s=>v(n=>({...n,type:s.target.value}))}),e.jsx(h,{variant:"ghost",size:"sm",onClick:A,children:t("common.actions.reset")})]})]})})}),m?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(I,{})}):l.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center rounded-lg border border-dashed p-10 text-center",children:[e.jsx("p",{className:"text-base font-medium",children:t("events.empty.title")}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:t("events.empty.subtitle")})]}):e.jsx("div",{className:"grid gap-4",children:l.map(s=>e.jsxs(w,{children:[e.jsx(V,{className:"pb-3",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(j,{variant:Q[s.level]||"secondary",children:t(`events.levels.${s.level}`)}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[G(s.createdAt)," · ",q(s.createdAt)]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(j,{variant:"outline",children:["#",s.id]}),s.mode&&e.jsx(j,{variant:"secondary",children:s.mode})]})]})}),e.jsxs(C,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h3",{className:"text-base font-semibold",children:s.title||t("events.defaultTitle")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.message||t("events.defaultMessage")})]}),e.jsxs("div",{className:"grid gap-3 text-sm sm:grid-cols-2 lg:grid-cols-3",children:[s.ipAddress&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"IP"}),e.jsx("p",{children:s.ipAddress})]}),s.apiKeyName&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"API Key"}),e.jsx("p",{children:s.apiKeyName})]}),s.userAgent&&e.jsxs("div",{className:"space-y-1 sm:col-span-2 lg:col-span-3",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"User Agent"}),e.jsx("p",{className:"truncate",children:s.userAgent})]})]}),s.details&&e.jsxs("details",{className:"rounded-md border p-3 text-sm",children:[e.jsx("summary",{className:"cursor-pointer text-sm font-medium text-primary",children:t("events.details")}),e.jsx("pre",{className:"mt-3 overflow-x-auto rounded-md bg-muted p-3 text-xs",children:JSON.stringify(s.details,null,2)})]})]})]},s.id))})]})}export{te as default};
@@ -0,0 +1,23 @@
1
+ import{c as x,u,r as f,j as e,e as h}from"./index-CHrsfYJ0.js";import{P as g}from"./PageHeader-mDU5G7Wl.js";import{P as d}from"./PageSection-tyXkbtRe.js";import{C as p,a as j}from"./card-Bo-S3Rlt.js";import{I as N}from"./info-iVJjf7Iu.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 v=x("BookOpen",[["path",{d:"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z",key:"vv98re"}],["path",{d:"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z",key:"1cyq3y"}]]);/**
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 b=x("Code",[["polyline",{points:"16 18 22 12 16 6",key:"z7tu5w"}],["polyline",{points:"8 6 2 12 8 18",key:"1eg1df"}]]);/**
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 y=x("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]);function T(){const{t:s}=u(),t=f.useMemo(()=>{const r=s("help.sections.configuration.items",{returnObjects:!0}),l=s("help.sections.claudeCodeConfig.items",{returnObjects:!0}),n=s("help.sections.codexConfig.items",{returnObjects:!0}),c=s("help.sections.usage.items",{returnObjects:!0}),a=s("help.sections.tips.items",{returnObjects:!0});return[{title:s("help.sections.configuration.title"),items:r},{title:s("help.sections.claudeCodeConfig.title"),items:l},{title:s("help.sections.codexConfig.title"),items:n},{title:s("help.sections.usage.title"),items:c},{title:s("help.sections.tips.title"),items:a}]},[s]),i=s("help.faq.items",{returnObjects:!0});return e.jsxs("div",{className:"space-y-6",children:[e.jsx(g,{icon:e.jsx(v,{className:"h-5 w-5","aria-hidden":"true"}),title:s("help.title"),description:s("help.intro")}),e.jsx(p,{children:e.jsxs(j,{className:"flex items-start gap-4 pt-4",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 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:"text-sm text-muted-foreground",children:s("help.note")})]})}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(d,{title:t[0].title,children:e.jsx(o,{items:t[0].items})}),e.jsxs("div",{className:"space-y-1 text-center",children:[e.jsx("h2",{className:"text-xl font-semibold",children:s("help.clientConfig.title")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("help.clientConfig.subtitle")})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsxs(d,{title:t[1].title,children:[e.jsxs("div",{className:"mb-4 flex items-center gap-3 rounded-lg bg-primary/5 p-3",children:[e.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg bg-primary text-primary-foreground",children:e.jsx(b,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium",children:"Claude Code"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"IDE 插件配置"})]})]}),e.jsx(o,{items:t[1].items})]}),e.jsxs(d,{title:t[2].title,children:[e.jsxs("div",{className:"mb-4 flex items-center gap-3 rounded-lg bg-emerald-500/5 p-3 dark:bg-emerald-500/10",children:[e.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg bg-emerald-500 text-white",children:e.jsx(y,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium",children:"Codex CLI"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"命令行工具配置"})]})]}),e.jsx(o,{items:t[2].items})]})]}),e.jsxs("div",{className:"mt-8",children:[e.jsxs("div",{className:"mb-6 space-y-1 text-center",children:[e.jsx("h2",{className:"text-lg font-semibold",children:s("help.advancedGuide.title")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("help.advancedGuide.subtitle")})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(d,{title:t[3].title,children:e.jsx(o,{items:t[3].items})}),e.jsx(d,{title:t[4].title,children:e.jsx(o,{items:t[4].items})})]})]})]}),e.jsx(d,{title:s("help.faq.title"),children:e.jsx(C,{items:i})})]})}function o({items:s}){return e.jsx("ol",{className:"flex flex-col gap-3",children:s.map((t,i)=>e.jsxs("li",{className:"flex gap-3 rounded-lg border p-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-medium text-primary-foreground",children:i+1}),e.jsx("div",{className:"flex-1 text-sm text-muted-foreground",children:e.jsx(w,{content:t})})]},`${i}-${t}`))})}function w({content:s}){const{t}=u();if(s.includes("```")){const i=s.split("```");return e.jsx("div",{className:"space-y-2",children:i.map((r,l)=>{if(l%2===0)return r?e.jsx("div",{className:"whitespace-pre-line",children:m(r)},l):null;{const[n,...c]=r.split(`
17
+ `),a=c.join(`
18
+ `);return e.jsxs("div",{className:"relative",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:n||"bash"}),e.jsx(h,{variant:"ghost",size:"sm",className:"h-6 px-2 text-xs",onClick:()=>navigator.clipboard.writeText(a),children:t("common.actions.copy")})]}),e.jsx("pre",{className:"overflow-x-auto rounded-md border bg-muted p-3 text-xs",children:e.jsx("code",{children:a})})]},l)}})})}return s.includes(`
19
+ `)?e.jsx("div",{className:"whitespace-pre-line",children:m(s)}):e.jsx("div",{children:m(s)})}function m(s){return s.split(/(\*\*[^*]+\*\*)/g).map((i,r)=>i.startsWith("**")&&i.endsWith("**")?e.jsx("strong",{className:"font-medium text-foreground",children:i.slice(2,-2)},r):e.jsx("span",{children:i},r))}function C({items:s}){return s.length===0?null:e.jsx("dl",{className:"flex flex-col gap-3",children:s.map(t=>e.jsx(p,{children:e.jsxs(j,{className:"pt-4",children:[e.jsx("dt",{className:"text-sm font-medium",children:t.q}),e.jsx("dd",{className:"mt-2 text-sm text-muted-foreground",children:e.jsx(k,{content:t.a})})]})},t.q))})}function k({content:s}){const{t}=u();if(s.includes("1)")||s.includes("2)")){const i=s.split(`
20
+ `).filter(l=>l.trim());if(i.some(l=>/^\d+\)/.test(l.trim())))return e.jsx("div",{className:"space-y-1",children:i.map((l,n)=>{const c=l.match(/^\d+\)\s*(.*)/);return c?e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"text-muted-foreground",children:"•"}),e.jsx("span",{children:c[1]})]},n):e.jsx("div",{children:l},n)})})}if(s.includes("```")){const i=s.split("```");return e.jsx("div",{className:"space-y-2",children:i.map((r,l)=>{if(l%2===0)return r?e.jsx("div",{className:"whitespace-pre-line",children:r},l):null;{const[n,...c]=r.split(`
21
+ `),a=c.join(`
22
+ `);return e.jsxs("div",{className:"relative",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:n||"bash"}),e.jsx(h,{variant:"ghost",size:"sm",className:"h-6 px-2 text-xs",onClick:()=>navigator.clipboard.writeText(a),children:t("common.actions.copy")})]}),e.jsx("pre",{className:"overflow-x-auto rounded-md border bg-muted p-3 text-xs",children:e.jsx("code",{children:a})})]},l)}})})}return s.includes(`
23
+ `)?e.jsx("div",{className:"whitespace-pre-line",children:s}):e.jsx("div",{children:s})}export{T as default};
@@ -0,0 +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-CHrsfYJ0.js";import{I as j}from"./input-Nvkz2m3Y.js";import{L as b}from"./label-D1_YxFJP.js";import{C as v,a as w,b as P,c as T,d as A,e as D}from"./card-Bo-S3Rlt.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 ye,u as U,b as de,r as n,d as Ne,t as ve,j as e,e as k,a as L,F as be,f as we,X as ke,L as _e}from"./index-CHrsfYJ0.js";import{u as q}from"./useApiQuery-xxHtqlFp.js";import{P as Se,B as ce}from"./PageHeader-mDU5G7Wl.js";import{I as H}from"./input-Nvkz2m3Y.js";import{L as S}from"./label-D1_YxFJP.js";import{C as ae,a as ie}from"./card-Bo-S3Rlt.js";import{S as A,a as M,b as z,c as O,d as w}from"./select-BzsGk5RC.js";import{R as Ee}from"./refresh-cw-BYq1FKR4.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 Te=ye("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"}]]),re=[20,50,100];function ne(s,r=!1){if(!s)return;const o=r?`${s}T23:59:59.999`:`${s}T00:00:00.000`,f=Date.parse(o);return Number.isFinite(f)?f:void 0}function me(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 Ce(s){return s?"true":"false"}function oe(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;const{t:s}=U(),{pushToast:r}=de(),[o,f]=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(re[0]),[F,Q]=n.useState(null),[xe,V]=n.useState(!1),[D,W]=n.useState([]),[K,J]=n.useState(!1);n.useEffect(()=>{p(1)},[o,j,d,m,l,i,N,D]);const P=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=ne(l),$=ne(i,!0);return u!==void 0&&(a.from=u),$!==void 0&&(a.to=$),D.length>0&&(a.apiKeys=D.join(",")),a},[o,j,d,m,l,i,c,N,D]),g=q(["logs",P],{url:"/api/logs",method:"GET",params:P}),T=q(["providers","all"],{url:"/api/providers",method:"GET"}),X=q(["api-keys"],{url:"/api/keys",method:"GET"});n.useEffect(()=>{g.isError&&g.error&&r({title:s("logs.toast.listError.title"),description:s("logs.toast.listError.desc",{message:g.error.message}),variant:"error"})},[g.isError,g.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=g.data)==null?void 0:se.total)??0,b=C>0?Math.ceil(C/N):0,Y=((te=g.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]),ue=()=>{f("all"),y(""),t("all"),v("all"),h(""),x(""),W([])},pe=n.useCallback(async()=>{if(!K){J(!0);try{const a=C>0?Math.min(C,5e3):1e3,u={...P,limit:a,offset:0},$=await Ne.post("/api/logs/export",u,{responseType:"blob"}),fe=new Blob([$.data],{type:"application/zip"}),je=new Date().toISOString().replace(/[:.]/g,"-"),le=URL.createObjectURL(fe),R=document.createElement("a");R.href=le,R.download=`cc-gw-logs-${je}.zip`,document.body.appendChild(R),R.click(),R.remove(),URL.revokeObjectURL(le),r({title:s("logs.toast.exportSuccess.title"),description:s("logs.toast.exportSuccess.desc"),variant:"success"})}catch(a){const u=ve(a);r({title:s("logs.toast.exportError.title"),description:s("logs.toast.exportError.desc",{message:u.message}),variant:"error"})}finally{J(!1)}}},[K,r,P,s,C]),he=n.useCallback(a=>{Q(a),V(!0)},[]),ge=n.useCallback(()=>{V(!1),Q(null)},[]);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Se,{icon:e.jsx(be,{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:pe,disabled:K,children:[e.jsx(Te,{className:"mr-2 h-4 w-4"}),s(K?"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:()=>g.refetch(),disabled:g.isFetching,children:[e.jsx(Ee,{className:L("mr-2 h-4 w-4",g.isFetching&&"animate-spin")}),g.isFetching?s("common.actions.refreshing"):s("logs.actions.manualRefresh")]})]})}),e.jsx(ae,{children:e.jsxs(ie,{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:ue,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(A,{value:o,onValueChange:f,children:[e.jsx(M,{children:e.jsx(z,{})}),e.jsxs(O,{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(A,{value:j,onValueChange:a=>t(a),children:[e.jsx(M,{children:e.jsx(z,{})}),e.jsxs(O,{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")})]})]})]}),e.jsx(Re,{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(H,{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(A,{value:m,onValueChange:a=>v(a),children:[e.jsx(M,{children:e.jsx(z,{})}),e.jsxs(O,{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(H,{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(H,{type:"date",value:i,onChange:a=>x(a.target.value)})]})]})]})}),e.jsx(ae,{children:e.jsxs(ie,{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:g.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(Le,{record:a,providerLabelMap:Z,apiKeyMap:ee,onSelect:he,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(A,{value:N.toString(),onValueChange:a=>I(Number(a)),children:[e.jsx(M,{className:"w-[80px]",children:e.jsx(z,{})}),e.jsx(O,{children:re.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(De,{open:xe,logId:F,onClose:ge,providerLabelMap:Z,apiKeyMap:ee})]})}function Le({record:s,providerLabelMap:r,apiKeyMap:o,onSelect:f,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:me(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(ce,{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:()=>f(s.id),children:t("logs.actions.detail")})})]})}function De({open:s,logId:r,onClose:o,providerLabelMap:f,apiKeyMap:j}){var x,c;const{t}=U(),{pushToast:d}=de(),y=n.useRef(null),m=q(["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 navigator.clipboard.writeText(N),d({title:t(I),variant:"success"})}catch(F){d({title:t("logs.detail.copy.failure"),description:F instanceof Error?F.message:t("logs.detail.copy.failureFallback"),variant:"error"})}},[d,t]);if(!s)return null;const l=m.data,h=l?f.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:we.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(ke,{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(_e,{}):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(ce,{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:me(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:Ce(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:oe((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:oe((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 Re({apiKeys:s,selected:r,onChange:o,disabled:f,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:f||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};