@chenpu17/cc-gw 0.4.2 → 0.4.3

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 (22) hide show
  1. package/package.json +1 -1
  2. package/src/server/dist/index.js +130 -72
  3. package/src/web/dist/assets/{About-CfWemXks.js → About-BWcLLdLY.js} +2 -2
  4. package/src/web/dist/assets/{ApiKeys-jGq-kKf8.js → ApiKeys-DsYmx21U.js} +1 -1
  5. package/src/web/dist/assets/{Button-DdVyALkb.js → Button-CZXniSHM.js} +1 -1
  6. package/src/web/dist/assets/Dashboard-H7fcVgwO.js +16 -0
  7. package/src/web/dist/assets/{FormField-Dyi1Kr0k.js → FormField-SZpxR702.js} +1 -1
  8. package/src/web/dist/assets/{Help-iZXiqNPj.js → Help-CgWIUFIO.js} +1 -1
  9. package/src/web/dist/assets/{Input-DACzKnnk.js → Input-BdyQWPOU.js} +1 -1
  10. package/src/web/dist/assets/{Login-mm-NJUOP.js → Login-0_Y4Go8x.js} +1 -1
  11. package/src/web/dist/assets/{Logs-DNxTsrk3.js → Logs-MTopPD6L.js} +1 -1
  12. package/src/web/dist/assets/{ModelManagement-B4f8RUk8.js → ModelManagement-DBVBITho.js} +1 -1
  13. package/src/web/dist/assets/{PageSection-BfMkaweN.js → PageSection-B08EcVAN.js} +1 -1
  14. package/src/web/dist/assets/{Settings-DRLUoVLq.js → Settings-DEloCGp7.js} +1 -1
  15. package/src/web/dist/assets/{StatusBadge-OH4R_aKr.js → StatusBadge-8KAMZvYW.js} +1 -1
  16. package/src/web/dist/assets/{copy-BVgnqUsP.js → copy-BdNskWTP.js} +1 -1
  17. package/src/web/dist/assets/{index-CAbsGgAq.js → index-BK1UNVMz.js} +5 -5
  18. package/src/web/dist/assets/{index-C2xoexDc.js → index-CyrAg0Ev.js} +1 -1
  19. package/src/web/dist/assets/{info-CpmSkfUl.js → info-BTcWJb9B.js} +1 -1
  20. package/src/web/dist/assets/{useApiQuery-CNbY7eTZ.js → useApiQuery-BNTE55UK.js} +1 -1
  21. package/src/web/dist/index.html +1 -1
  22. package/src/web/dist/assets/Dashboard-uoI9oSjK.js +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenpu17/cc-gw",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11103,7 +11103,11 @@ async function migrateDailyMetricsTable(db) {
11103
11103
  if (!hasEndpointColumn || !hasCompositePrimaryKey) {
11104
11104
  const endpointSelector = hasEndpointColumn ? "COALESCE(endpoint, 'anthropic')" : "'anthropic'";
11105
11105
  const hasCachedTokensColumn = columns.some((column) => column.name === "total_cached_tokens");
11106
+ const hasCacheReadColumn = columns.some((column) => column.name === "total_cache_read_tokens");
11107
+ const hasCacheCreationColumn = columns.some((column) => column.name === "total_cache_creation_tokens");
11106
11108
  const cachedTokensSelector = hasCachedTokensColumn ? "COALESCE(total_cached_tokens, 0)" : "0";
11109
+ const cacheReadSelector = hasCacheReadColumn ? "COALESCE(total_cache_read_tokens, 0)" : "0";
11110
+ const cacheCreationSelector = hasCacheCreationColumn ? "COALESCE(total_cache_creation_tokens, 0)" : "0";
11107
11111
  await exec(
11108
11112
  db,
11109
11113
  `ALTER TABLE daily_metrics RENAME TO daily_metrics_old;
@@ -11114,16 +11118,20 @@ async function migrateDailyMetricsTable(db) {
11114
11118
  total_input_tokens INTEGER DEFAULT 0,
11115
11119
  total_output_tokens INTEGER DEFAULT 0,
11116
11120
  total_cached_tokens INTEGER DEFAULT 0,
11121
+ total_cache_read_tokens INTEGER DEFAULT 0,
11122
+ total_cache_creation_tokens INTEGER DEFAULT 0,
11117
11123
  total_latency_ms INTEGER DEFAULT 0,
11118
11124
  PRIMARY KEY (date, endpoint)
11119
11125
  );
11120
- INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_latency_ms)
11126
+ INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_cache_read_tokens, total_cache_creation_tokens, total_latency_ms)
11121
11127
  SELECT date,
11122
11128
  ${endpointSelector},
11123
11129
  request_count,
11124
11130
  total_input_tokens,
11125
11131
  total_output_tokens,
11126
11132
  ${cachedTokensSelector},
11133
+ ${cacheReadSelector},
11134
+ ${cacheCreationSelector},
11127
11135
  total_latency_ms
11128
11136
  FROM daily_metrics_old;
11129
11137
  DROP TABLE daily_metrics_old;`
@@ -11181,6 +11189,8 @@ async function ensureSchema(db) {
11181
11189
  total_input_tokens INTEGER DEFAULT 0,
11182
11190
  total_output_tokens INTEGER DEFAULT 0,
11183
11191
  total_cached_tokens INTEGER DEFAULT 0,
11192
+ total_cache_read_tokens INTEGER DEFAULT 0,
11193
+ total_cache_creation_tokens INTEGER DEFAULT 0,
11184
11194
  total_latency_ms INTEGER DEFAULT 0,
11185
11195
  PRIMARY KEY (date, endpoint)
11186
11196
  );
@@ -11239,6 +11249,8 @@ async function ensureSchema(db) {
11239
11249
  await maybeAddColumn(db, "api_keys", "total_output_tokens", "INTEGER DEFAULT 0");
11240
11250
  await migrateDailyMetricsTable(db);
11241
11251
  await maybeAddColumn(db, "daily_metrics", "total_cached_tokens", "INTEGER DEFAULT 0");
11252
+ await maybeAddColumn(db, "daily_metrics", "total_cache_read_tokens", "INTEGER DEFAULT 0");
11253
+ await maybeAddColumn(db, "daily_metrics", "total_cache_creation_tokens", "INTEGER DEFAULT 0");
11242
11254
  await run(db, "CREATE UNIQUE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash) WHERE key_hash IS NOT NULL");
11243
11255
  await run(db, "UPDATE api_keys SET key_hash = '*' WHERE is_wildcard = 1 AND (key_hash IS NULL OR key_hash = '')");
11244
11256
  await run(db, "UPDATE api_keys SET updated_at = created_at WHERE updated_at IS NULL");
@@ -11455,25 +11467,33 @@ async function upsertLogPayload(requestId, payload) {
11455
11467
  );
11456
11468
  }
11457
11469
  async function updateMetrics(date, endpoint, delta) {
11458
- await runQuery(
11459
- `INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_latency_ms)
11460
- VALUES (?, ?, ?, ?, ?, ?, ?)
11461
- ON CONFLICT(date, endpoint) DO UPDATE SET
11462
- request_count = daily_metrics.request_count + excluded.request_count,
11463
- total_input_tokens = daily_metrics.total_input_tokens + excluded.total_input_tokens,
11464
- total_output_tokens = daily_metrics.total_output_tokens + excluded.total_output_tokens,
11465
- total_cached_tokens = daily_metrics.total_cached_tokens + excluded.total_cached_tokens,
11466
- total_latency_ms = daily_metrics.total_latency_ms + excluded.total_latency_ms`,
11467
- [
11468
- date,
11469
- endpoint,
11470
- delta.requests,
11471
- delta.inputTokens,
11472
- delta.outputTokens,
11473
- delta.cachedTokens ?? 0,
11474
- delta.latencyMs
11475
- ]
11476
- );
11470
+ try {
11471
+ await runQuery(
11472
+ `INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_cache_read_tokens, total_cache_creation_tokens, total_latency_ms)
11473
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
11474
+ ON CONFLICT(date, endpoint) DO UPDATE SET
11475
+ request_count = daily_metrics.request_count + excluded.request_count,
11476
+ total_input_tokens = daily_metrics.total_input_tokens + excluded.total_input_tokens,
11477
+ total_output_tokens = daily_metrics.total_output_tokens + excluded.total_output_tokens,
11478
+ total_cached_tokens = daily_metrics.total_cached_tokens + excluded.total_cached_tokens,
11479
+ total_cache_read_tokens = daily_metrics.total_cache_read_tokens + excluded.total_cache_read_tokens,
11480
+ total_cache_creation_tokens = daily_metrics.total_cache_creation_tokens + excluded.total_cache_creation_tokens,
11481
+ total_latency_ms = daily_metrics.total_latency_ms + excluded.total_latency_ms`,
11482
+ [
11483
+ date,
11484
+ endpoint,
11485
+ delta.requests,
11486
+ delta.inputTokens,
11487
+ delta.outputTokens,
11488
+ delta.cachedTokens ?? 0,
11489
+ delta.cacheReadTokens ?? 0,
11490
+ delta.cacheCreationTokens ?? 0,
11491
+ delta.latencyMs
11492
+ ]
11493
+ );
11494
+ } catch (err) {
11495
+ console.error("[updateMetrics] Failed to update metrics:", err);
11496
+ }
11477
11497
  }
11478
11498
 
11479
11499
  // metrics/activity.ts
@@ -11943,23 +11963,24 @@ function computeTpot(totalLatencyMs, outputTokens, options) {
11943
11963
  return Number.isFinite(raw) ? roundTwoDecimals(raw) : null;
11944
11964
  }
11945
11965
  function resolveCachedTokens(usage) {
11966
+ const result = { read: 0, creation: 0 };
11946
11967
  if (!usage || typeof usage !== "object") {
11947
- return null;
11968
+ return result;
11969
+ }
11970
+ if (typeof usage.cache_read_input_tokens === "number") {
11971
+ result.read = usage.cache_read_input_tokens;
11972
+ }
11973
+ if (typeof usage.cache_creation_input_tokens === "number") {
11974
+ result.creation = usage.cache_creation_input_tokens;
11948
11975
  }
11949
11976
  if (typeof usage.cached_tokens === "number") {
11950
- return usage.cached_tokens;
11977
+ result.read = usage.cached_tokens;
11951
11978
  }
11952
11979
  const promptDetails = usage.prompt_tokens_details;
11953
11980
  if (promptDetails && typeof promptDetails.cached_tokens === "number") {
11954
- return promptDetails.cached_tokens;
11955
- }
11956
- if (typeof usage.cache_read_input_tokens === "number") {
11957
- return usage.cache_read_input_tokens;
11958
- }
11959
- if (typeof usage.cache_creation_input_tokens === "number") {
11960
- return usage.cache_creation_input_tokens;
11981
+ result.read = promptDetails.cached_tokens;
11961
11982
  }
11962
- return null;
11983
+ return result;
11963
11984
  }
11964
11985
  function cloneOriginalPayload(value) {
11965
11986
  const structuredCloneFn = globalThis.structuredClone;
@@ -12222,7 +12243,8 @@ async function registerMessagesRoute(app) {
12222
12243
  if (providerType === "anthropic") {
12223
12244
  let inputTokens2 = json.usage?.input_tokens ?? 0;
12224
12245
  let outputTokens2 = json.usage?.output_tokens ?? 0;
12225
- const cachedTokens3 = resolveCachedTokens(json.usage);
12246
+ const cached3 = resolveCachedTokens(json.usage);
12247
+ const cachedTokens3 = cached3.read + cached3.creation;
12226
12248
  if (!inputTokens2) {
12227
12249
  inputTokens2 = target.tokenEstimate || estimateTokens(normalized, target.modelId);
12228
12250
  }
@@ -12249,6 +12271,8 @@ async function registerMessagesRoute(app) {
12249
12271
  inputTokens: inputTokens2,
12250
12272
  outputTokens: outputTokens2,
12251
12273
  cachedTokens: cachedTokens3,
12274
+ cacheReadTokens: cached3.read,
12275
+ cacheCreationTokens: cached3.creation,
12252
12276
  latencyMs: latencyMs2
12253
12277
  });
12254
12278
  if (storeResponsePayloads) {
@@ -12269,7 +12293,8 @@ async function registerMessagesRoute(app) {
12269
12293
  const claudeResponse = buildClaudeResponse(json, target.modelId);
12270
12294
  let inputTokens = json.usage?.prompt_tokens ?? 0;
12271
12295
  let outputTokens = json.usage?.completion_tokens ?? 0;
12272
- const cachedTokens2 = resolveCachedTokens(json.usage);
12296
+ const cached2 = resolveCachedTokens(json.usage);
12297
+ const cachedTokens2 = cached2.read + cached2.creation;
12273
12298
  if (!inputTokens) {
12274
12299
  inputTokens = target.tokenEstimate || estimateTokens(normalized, target.modelId);
12275
12300
  }
@@ -12295,6 +12320,9 @@ async function registerMessagesRoute(app) {
12295
12320
  requests: 1,
12296
12321
  inputTokens,
12297
12322
  outputTokens,
12323
+ cachedTokens: cachedTokens2,
12324
+ cacheReadTokens: cached2.read,
12325
+ cacheCreationTokens: cached2.creation,
12298
12326
  latencyMs
12299
12327
  });
12300
12328
  if (storeResponsePayloads) {
@@ -12466,9 +12494,7 @@ async function registerMessagesRoute(app) {
12466
12494
  usagePrompt2 = payload2.usage.input_tokens ?? usagePrompt2;
12467
12495
  usageCompletion2 = payload2.usage.output_tokens ?? usageCompletion2;
12468
12496
  const maybeCached = resolveCachedTokens(payload2.usage);
12469
- if (maybeCached !== null) {
12470
- usageCached2 = maybeCached;
12471
- }
12497
+ usageCached2 = maybeCached.read + maybeCached.creation;
12472
12498
  lastUsagePayload = payload2.usage;
12473
12499
  }
12474
12500
  if (payload2?.delta) {
@@ -12495,9 +12521,7 @@ async function registerMessagesRoute(app) {
12495
12521
  usagePrompt2 = payload2.usage.input_tokens ?? usagePrompt2;
12496
12522
  usageCompletion2 = payload2.usage.output_tokens ?? usageCompletion2;
12497
12523
  const maybeCached = resolveCachedTokens(payload2.usage);
12498
- if (maybeCached !== null) {
12499
- usageCached2 = maybeCached;
12500
- }
12524
+ usageCached2 = maybeCached.read + maybeCached.creation;
12501
12525
  lastUsagePayload = payload2.usage;
12502
12526
  }
12503
12527
  if (payload2?.stop_reason) {
@@ -12549,8 +12573,9 @@ async function registerMessagesRoute(app) {
12549
12573
  }
12550
12574
  const totalLatencyMs = Date.now() - requestStart;
12551
12575
  const ttftMs = firstTokenAt2 ? firstTokenAt2 - requestStart : null;
12576
+ const cached2 = resolveCachedTokens(lastUsagePayload);
12552
12577
  if (usageCached2 === null) {
12553
- usageCached2 = resolveCachedTokens(lastUsagePayload);
12578
+ usageCached2 = cached2.read + cached2.creation;
12554
12579
  }
12555
12580
  logUsage("stream.anthropic.final", {
12556
12581
  input: usagePrompt2,
@@ -12573,6 +12598,8 @@ async function registerMessagesRoute(app) {
12573
12598
  inputTokens: usagePrompt2,
12574
12599
  outputTokens: usageCompletion2,
12575
12600
  cachedTokens: usageCached2,
12601
+ cacheReadTokens: cached2.read,
12602
+ cacheCreationTokens: cached2.creation,
12576
12603
  latencyMs: totalLatencyMs
12577
12604
  });
12578
12605
  if (storeResponsePayloads) {
@@ -12743,7 +12770,9 @@ data: ${JSON.stringify(data)}
12743
12770
  requests: 1,
12744
12771
  inputTokens: finalPromptTokens,
12745
12772
  outputTokens: finalCompletionTokens,
12746
- cachedTokens: usageCached,
12773
+ cachedTokens: usageCached ?? 0,
12774
+ cacheReadTokens: 0,
12775
+ cacheCreationTokens: 0,
12747
12776
  latencyMs: totalLatencyMs
12748
12777
  });
12749
12778
  if (storeResponsePayloads) {
@@ -12905,7 +12934,9 @@ data: ${JSON.stringify(data)}
12905
12934
  requests: 1,
12906
12935
  inputTokens: fallbackPrompt,
12907
12936
  outputTokens: fallbackCompletion,
12908
- cachedTokens: usageCached,
12937
+ cachedTokens: usageCached ?? 0,
12938
+ cacheReadTokens: 0,
12939
+ cacheCreationTokens: 0,
12909
12940
  latencyMs: totalLatencyMs
12910
12941
  });
12911
12942
  if (storeResponsePayloads) {
@@ -13306,27 +13337,28 @@ function computeTpot2(totalLatencyMs, outputTokens, options) {
13306
13337
  return Number.isFinite(raw) ? roundTwoDecimals2(raw) : null;
13307
13338
  }
13308
13339
  function resolveCachedTokens2(usage) {
13340
+ const result = { read: 0, creation: 0 };
13309
13341
  if (!usage || typeof usage !== "object") {
13310
- return null;
13342
+ return result;
13343
+ }
13344
+ if (typeof usage.cache_read_input_tokens === "number") {
13345
+ result.read = usage.cache_read_input_tokens;
13346
+ }
13347
+ if (typeof usage.cache_creation_input_tokens === "number") {
13348
+ result.creation = usage.cache_creation_input_tokens;
13311
13349
  }
13312
13350
  if (typeof usage.cached_tokens === "number") {
13313
- return usage.cached_tokens;
13351
+ result.read = usage.cached_tokens;
13314
13352
  }
13315
13353
  const promptDetails = usage.prompt_tokens_details;
13316
13354
  if (promptDetails && typeof promptDetails.cached_tokens === "number") {
13317
- return promptDetails.cached_tokens;
13355
+ result.read = promptDetails.cached_tokens;
13318
13356
  }
13319
13357
  const inputDetails = usage.input_tokens_details;
13320
13358
  if (inputDetails && typeof inputDetails.cached_tokens === "number") {
13321
- return inputDetails.cached_tokens;
13359
+ result.read = inputDetails.cached_tokens;
13322
13360
  }
13323
- if (typeof usage.cache_read_input_tokens === "number") {
13324
- return usage.cache_read_input_tokens;
13325
- }
13326
- if (typeof usage.cache_creation_input_tokens === "number") {
13327
- return usage.cache_creation_input_tokens;
13328
- }
13329
- return null;
13361
+ return result;
13330
13362
  }
13331
13363
  var generateId = (prefix) => `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
13332
13364
  var isText = (input) => typeof input === "string" && input.length > 0;
@@ -13848,7 +13880,8 @@ async function registerOpenAiRoutes(app) {
13848
13880
  if (!Number.isFinite(inputTokens3) || inputTokens3 <= 0) {
13849
13881
  inputTokens3 = target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
13850
13882
  }
13851
- const cachedTokens3 = resolveCachedTokens2(usagePayload2);
13883
+ const cached3 = resolveCachedTokens2(usagePayload2);
13884
+ const cachedTokens3 = cached3.read + cached3.creation;
13852
13885
  const latencyMs3 = Date.now() - requestStart;
13853
13886
  const openAIResponse = buildOpenAIResponseFromClaude(parsed, target.modelId, converted, {
13854
13887
  inputTokens: inputTokens3,
@@ -13902,7 +13935,8 @@ async function registerOpenAiRoutes(app) {
13902
13935
  return 0;
13903
13936
  })();
13904
13937
  const outputTokens2 = baseOutputTokens + reasoningTokens2;
13905
- const cachedTokens2 = resolveCachedTokens2(usagePayload);
13938
+ const cached2 = resolveCachedTokens2(usagePayload);
13939
+ const cachedTokens2 = cached2.read + cached2.creation;
13906
13940
  const latencyMs2 = Date.now() - requestStart;
13907
13941
  await updateLogTokens(logId, {
13908
13942
  inputTokens: inputTokens2,
@@ -14306,6 +14340,8 @@ async function registerOpenAiRoutes(app) {
14306
14340
  inputTokens: finalPromptTokens,
14307
14341
  outputTokens: finalCompletionTokens,
14308
14342
  cachedTokens: usageCached2,
14343
+ cacheReadTokens: cached.read,
14344
+ cacheCreationTokens: cached.creation,
14309
14345
  latencyMs: totalLatencyMs
14310
14346
  });
14311
14347
  if (storeResponsePayloads && capturedResponseChunks2) {
@@ -14713,7 +14749,8 @@ async function registerOpenAiRoutes(app) {
14713
14749
  inputTokens: inputTokens3,
14714
14750
  outputTokens: outputTokens3
14715
14751
  });
14716
- const cachedTokens3 = resolveCachedTokens2(usagePayload2);
14752
+ const cached3 = resolveCachedTokens2(usagePayload2);
14753
+ const cachedTokens3 = cached3.read + cached3.creation;
14717
14754
  const latencyMs3 = Date.now() - requestStart;
14718
14755
  await updateLogTokens(logId, {
14719
14756
  inputTokens: inputTokens3,
@@ -14757,7 +14794,8 @@ async function registerOpenAiRoutes(app) {
14757
14794
  })(),
14758
14795
  target.modelId
14759
14796
  );
14760
- const cachedTokens2 = resolveCachedTokens2(usagePayload);
14797
+ const cached2 = resolveCachedTokens2(usagePayload);
14798
+ const cachedTokens2 = cached2.read + cached2.creation;
14761
14799
  const latencyMs2 = Date.now() - requestStart;
14762
14800
  await updateLogTokens(logId, {
14763
14801
  inputTokens: inputTokens2,
@@ -15204,6 +15242,8 @@ async function registerOpenAiRoutes(app) {
15204
15242
  inputTokens: finalPromptTokens,
15205
15243
  outputTokens: finalCompletionTokens,
15206
15244
  cachedTokens: usageCached2,
15245
+ cacheReadTokens: cached.read,
15246
+ cacheCreationTokens: cached.creation,
15207
15247
  latencyMs: totalLatencyMs
15208
15248
  });
15209
15249
  if (storeResponsePayloads && capturedResponseChunks2) {
@@ -15614,6 +15654,8 @@ async function getDailyMetrics(days = 7, endpoint) {
15614
15654
  total_input_tokens AS inputTokens,
15615
15655
  total_output_tokens AS outputTokens,
15616
15656
  total_cached_tokens AS cachedTokens,
15657
+ total_cache_read_tokens AS cacheReadTokens,
15658
+ total_cache_creation_tokens AS cacheCreationTokens,
15617
15659
  total_latency_ms AS totalLatency
15618
15660
  FROM daily_metrics
15619
15661
  ${whereClause}
@@ -15627,6 +15669,8 @@ async function getDailyMetrics(days = 7, endpoint) {
15627
15669
  inputTokens: row.inputTokens ?? 0,
15628
15670
  outputTokens: row.outputTokens ?? 0,
15629
15671
  cachedTokens: row.cachedTokens ?? 0,
15672
+ cacheReadTokens: row.cacheReadTokens ?? 0,
15673
+ cacheCreationTokens: row.cacheCreationTokens ?? 0,
15630
15674
  avgLatencyMs: row.requestCount ? Math.round((row.totalLatency ?? 0) / row.requestCount) : 0
15631
15675
  })).reverse();
15632
15676
  }
@@ -15638,6 +15682,8 @@ async function getMetricsOverview(endpoint) {
15638
15682
  COALESCE(SUM(total_input_tokens), 0) AS inputTokens,
15639
15683
  COALESCE(SUM(total_output_tokens), 0) AS outputTokens,
15640
15684
  COALESCE(SUM(total_cached_tokens), 0) AS cachedTokens,
15685
+ COALESCE(SUM(total_cache_read_tokens), 0) AS cacheReadTokens,
15686
+ COALESCE(SUM(total_cache_creation_tokens), 0) AS cacheCreationTokens,
15641
15687
  COALESCE(SUM(total_latency_ms), 0) AS totalLatency
15642
15688
  FROM daily_metrics
15643
15689
  ${totalsWhere}`,
@@ -15649,6 +15695,8 @@ async function getMetricsOverview(endpoint) {
15649
15695
  total_input_tokens AS inputTokens,
15650
15696
  total_output_tokens AS outputTokens,
15651
15697
  total_cached_tokens AS cachedTokens,
15698
+ total_cache_read_tokens AS cacheReadTokens,
15699
+ total_cache_creation_tokens AS cacheCreationTokens,
15652
15700
  total_latency_ms AS totalLatency
15653
15701
  FROM daily_metrics
15654
15702
  WHERE date = ?
@@ -15666,6 +15714,8 @@ async function getMetricsOverview(endpoint) {
15666
15714
  inputTokens: totalsRow?.inputTokens ?? 0,
15667
15715
  outputTokens: totalsRow?.outputTokens ?? 0,
15668
15716
  cachedTokens: totalsRow?.cachedTokens ?? 0,
15717
+ cacheReadTokens: totalsRow?.cacheReadTokens ?? 0,
15718
+ cacheCreationTokens: totalsRow?.cacheCreationTokens ?? 0,
15669
15719
  avgLatencyMs: resolveAvg(totalsLatency, totalsRequests)
15670
15720
  },
15671
15721
  today: {
@@ -15673,6 +15723,8 @@ async function getMetricsOverview(endpoint) {
15673
15723
  inputTokens: todayRow?.inputTokens ?? 0,
15674
15724
  outputTokens: todayRow?.outputTokens ?? 0,
15675
15725
  cachedTokens: todayRow?.cachedTokens ?? 0,
15726
+ cacheReadTokens: todayRow?.cacheReadTokens ?? 0,
15727
+ cacheCreationTokens: todayRow?.cacheCreationTokens ?? 0,
15676
15728
  avgLatencyMs: resolveAvg(todayLatency, todayRequests)
15677
15729
  }
15678
15730
  };
@@ -17097,23 +17149,24 @@ function getPathsToRegister(basePath, protocol) {
17097
17149
  }
17098
17150
  }
17099
17151
  function resolveCachedTokens3(usage) {
17152
+ const result = { read: 0, creation: 0 };
17100
17153
  if (!usage || typeof usage !== "object") {
17101
- return null;
17154
+ return result;
17155
+ }
17156
+ if (typeof usage.cache_read_input_tokens === "number") {
17157
+ result.read = usage.cache_read_input_tokens;
17158
+ }
17159
+ if (typeof usage.cache_creation_input_tokens === "number") {
17160
+ result.creation = usage.cache_creation_input_tokens;
17102
17161
  }
17103
17162
  if (typeof usage.cached_tokens === "number") {
17104
- return usage.cached_tokens;
17163
+ result.read = usage.cached_tokens;
17105
17164
  }
17106
17165
  const promptDetails = usage.prompt_tokens_details;
17107
17166
  if (promptDetails && typeof promptDetails.cached_tokens === "number") {
17108
- return promptDetails.cached_tokens;
17167
+ result.read = promptDetails.cached_tokens;
17109
17168
  }
17110
- if (typeof usage.cache_read_input_tokens === "number") {
17111
- return usage.cache_read_input_tokens;
17112
- }
17113
- if (typeof usage.cache_creation_input_tokens === "number") {
17114
- return usage.cache_creation_input_tokens;
17115
- }
17116
- return null;
17169
+ return result;
17117
17170
  }
17118
17171
  var roundTwoDecimals3 = (value) => Math.round(value * 100) / 100;
17119
17172
  function cloneOriginalPayload2(value) {
@@ -17470,7 +17523,8 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17470
17523
  const json = await new Response(upstream.body).json();
17471
17524
  const inputTokens = json.usage?.input_tokens ?? estimateTokens(normalized, target.modelId);
17472
17525
  const outputTokens = json.usage?.output_tokens ?? 0;
17473
- const cachedTokens2 = resolveCachedTokens3(json.usage);
17526
+ const cached2 = resolveCachedTokens3(json.usage);
17527
+ const cachedTokens2 = cached2.read + cached2.creation;
17474
17528
  const latencyMs = Date.now() - requestStart;
17475
17529
  await updateLogTokens(logId, {
17476
17530
  inputTokens,
@@ -17540,9 +17594,9 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17540
17594
  if (parsed?.usage) {
17541
17595
  usagePrompt = parsed.usage.input_tokens ?? usagePrompt;
17542
17596
  usageCompletion = parsed.usage.output_tokens ?? usageCompletion;
17543
- const cached = resolveCachedTokens3(parsed.usage);
17544
- if (cached !== null) {
17545
- usageCached = cached;
17597
+ const cached2 = resolveCachedTokens3(parsed.usage);
17598
+ if (cached2 !== null) {
17599
+ usageCached = cached2;
17546
17600
  }
17547
17601
  }
17548
17602
  if (!firstTokenAt && (parsed?.type === "content_block_delta" || parsed?.delta?.text)) {
@@ -17582,6 +17636,8 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17582
17636
  inputTokens: usagePrompt,
17583
17637
  outputTokens: usageCompletion,
17584
17638
  cachedTokens: usageCached,
17639
+ cacheReadTokens: cached.read,
17640
+ cacheCreationTokens: cached.creation,
17585
17641
  latencyMs: totalLatencyMs
17586
17642
  });
17587
17643
  if (storeResponsePayloads && capturedChunks) {
@@ -17761,7 +17817,8 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
17761
17817
  const usagePayload = json?.usage ?? null;
17762
17818
  const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
17763
17819
  const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(json?.choices?.[0]?.message?.content ?? "", target.modelId);
17764
- const cachedTokens2 = resolveCachedTokens3(usagePayload);
17820
+ const cached2 = resolveCachedTokens3(usagePayload);
17821
+ const cachedTokens2 = cached2.read + cached2.creation;
17765
17822
  const latencyMs2 = Date.now() - requestStart;
17766
17823
  await updateLogTokens(logId, {
17767
17824
  inputTokens: inputTokens2,
@@ -18041,7 +18098,8 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
18041
18098
  const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
18042
18099
  const content = json?.response?.body?.content ?? json?.choices?.[0]?.message?.content ?? "";
18043
18100
  const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(content, target.modelId);
18044
- const cachedTokens2 = resolveCachedTokens3(usagePayload);
18101
+ const cached2 = resolveCachedTokens3(usagePayload);
18102
+ const cachedTokens2 = cached2.read + cached2.creation;
18045
18103
  const latencyMs2 = Date.now() - requestStart;
18046
18104
  await updateLogTokens(logId, {
18047
18105
  inputTokens: inputTokens2,
@@ -1,4 +1,4 @@
1
- import{c as p,u as v,a as k,r,j as e,d as o,U as j,m as i}from"./index-CAbsGgAq.js";import{u as N}from"./useApiQuery-CNbY7eTZ.js";import{P as w,a as d}from"./PageSection-BfMkaweN.js";import"./Input-DACzKnnk.js";import{B as b}from"./Button-DdVyALkb.js";import{I as y}from"./info-CpmSkfUl.js";/**
1
+ import{c as p,u as v,a as k,r,j as e,d as o,U as j,m as i}from"./index-BK1UNVMz.js";import{u as N}from"./useApiQuery-BNTE55UK.js";import{P as w,a as d}from"./PageSection-B08EcVAN.js";import"./Input-BdyQWPOU.js";import{B as b}from"./Button-CZXniSHM.js";import{I as y}from"./info-BTcWJb9B.js";/**
2
2
  * @license lucide-react v0.344.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -8,4 +8,4 @@ import{c as p,u as v,a as k,r,j as e,d as o,U as j,m as i}from"./index-CAbsGgAq.
8
8
  *
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
- */const E=p("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"}]]),I="0.4.2",_={version:I},L={VITE_BUILD_TIME:"2025-10-29T03:49:27.299Z",VITE_NODE_VERSION:"v22.14.0"};function m({items:t}){return t.length===0?null:e.jsx("dl",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-2",children:t.map(s=>e.jsxs("div",{className:"rounded-2xl border border-slate-200/50 bg-white p-4 shadow-sm shadow-slate-200/30 transition-all duration-200 hover:-translate-y-0.5 hover:border-slate-200/70 hover:shadow-md hover:shadow-slate-200/40 dark:border-slate-700/50 dark:bg-slate-900/80 dark:shadow-lg dark:shadow-slate-900/30 dark:hover:border-slate-600/70",children:[e.jsx("dt",{className:"text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400",children:s.label}),e.jsx("dd",{className:"mt-2 text-base font-semibold text-slate-900 dark:text-slate-100",children:s.value}),s.hint?e.jsx("p",{className:o(i,"mt-2 text-xs leading-relaxed"),children:s.hint}):null]},s.label))})}function P(){const{t}=v(),{pushToast:s}=k(),a=N(["status","gateway"],{url:"/api/status",method:"GET"},{staleTime:6e4});r.useEffect(()=>{a.isError&&a.error&&s({title:t("about.toast.statusError.title"),description:a.error.message,variant:"error"})},[a.isError,a.error,s,t]);const n=_.version,l=r.useMemo(()=>{const u=L,f=u.VITE_BUILD_TIME,g=u.VITE_NODE_VERSION;return{buildTime:f,nodeVersion:g}},[]),h=r.useMemo(()=>[{label:t("about.app.labels.name"),value:e.jsx("span",{className:"font-mono text-sm font-semibold text-slate-900 dark:text-slate-100",children:"cc-gw"})},{label:t("about.app.labels.version"),value:e.jsxs("span",{className:"font-mono text-sm font-semibold text-blue-700 dark:text-blue-200",children:["v",n]})},{label:t("about.app.labels.buildTime"),value:l.buildTime,hint:t("about.app.hint.buildTime")},{label:t("about.app.labels.node"),value:e.jsx("span",{className:"font-mono text-sm text-slate-800 dark:text-slate-200",children:l.nodeVersion})}],[n,l.buildTime,l.nodeVersion,t]),c=r.useMemo(()=>a.data?[{label:t("about.status.labels.host"),value:a.data.host??"127.0.0.1"},{label:t("about.status.labels.port"),value:a.data.port.toLocaleString()},{label:t("about.status.labels.providers"),value:a.data.providers.toLocaleString()},{label:t("about.status.labels.active"),value:(a.data.activeRequests??0).toLocaleString(),hint:t("about.status.hint.active")}]:[],[a.data,t]),x=()=>{s({title:t("about.toast.updatesPlanned"),variant:"info"})};return e.jsxs("div",{className:"space-y-8",children:[e.jsx(w,{icon:e.jsx(y,{className:"h-6 w-6","aria-hidden":"true"}),title:t("about.title"),description:t("about.description"),badge:`v${n}`,actions:e.jsx(b,{variant:"primary",icon:e.jsx(E,{className:"h-4 w-4","aria-hidden":"true"}),onClick:x,children:t("about.support.actions.checkUpdates")})}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(d,{title:t("about.app.title"),description:t("about.app.subtitle"),className:"h-full",contentClassName:"gap-4",children:e.jsx(m,{items:h})}),e.jsx(d,{title:t("about.status.title"),description:t("about.status.subtitle"),className:"h-full",contentClassName:"gap-4",actions:e.jsx(b,{variant:"subtle",size:"sm",icon:e.jsx(T,{className:"h-4 w-4","aria-hidden":"true"}),onClick:()=>a.refetch(),loading:a.isFetching,children:a.isFetching?t("common.actions.refreshing"):t("common.actions.refresh")}),children:a.isLoading?e.jsxs("div",{className:"flex h-36 flex-col items-center justify-center gap-3 text-center",children:[e.jsx("div",{className:"h-10 w-10 animate-spin rounded-full border-[3px] border-blue-500/30 border-t-blue-600 dark:border-blue-400/20 dark:border-t-blue-300"}),e.jsx("p",{className:o(i,"text-sm"),children:t("about.status.loading")})]}):c.length>0?e.jsx(m,{items:c}):e.jsxs("div",{className:"flex h-36 flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-slate-200/60 bg-white p-6 text-center shadow-inner dark:border-slate-700/60 dark:bg-slate-900/60",children:[e.jsx("p",{className:"text-sm font-semibold text-slate-700 dark:text-slate-200",children:t("about.status.empty")}),e.jsx("p",{className:o(i,"text-xs"),children:t("common.actions.refresh")})]})})]}),e.jsx(d,{title:t("about.support.title"),description:e.jsxs("span",{className:"space-y-1",children:[e.jsx("span",{className:"block text-sm font-semibold text-blue-600 dark:text-blue-300",children:t("about.support.subtitle")}),e.jsx("span",{children:t("about.support.description")})]}),className:"relative overflow-hidden",contentClassName:"gap-6",children:e.jsxs("div",{className:"flex flex-col gap-4 rounded-3xl border border-slate-200/50 bg-white p-6 shadow-lg shadow-slate-200/30 backdrop-blur-md dark:border-slate-700/50 dark:bg-slate-900/80 dark:shadow-slate-900/40",children:[e.jsxs("div",{className:"flex flex-wrap items-start gap-4",children:[e.jsx("div",{className:"grid h-12 w-12 place-items-center rounded-2xl bg-gradient-to-br from-blue-500/20 to-indigo-500/20 text-blue-600 shadow-inner dark:text-blue-200",children:e.jsx(j,{className:"h-6 w-6","aria-hidden":"true"})}),e.jsx("p",{className:o(i,"text-sm leading-6"),children:t("about.support.tip")})]}),e.jsx("code",{className:"inline-flex items-center gap-2 self-start rounded-full border border-blue-200/50 bg-blue-50/80 px-4 py-2 text-xs font-semibold tracking-wide text-blue-700 shadow-sm dark:border-blue-500/30 dark:bg-blue-900/30 dark:text-blue-200",children:"~/.cc-gw/config.json"})]})})]})}export{P as default};
11
+ */const E=p("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"}]]),I="0.4.3",_={version:I},L={VITE_BUILD_TIME:"2025-10-30T03:41:36.581Z",VITE_NODE_VERSION:"v22.14.0"};function m({items:t}){return t.length===0?null:e.jsx("dl",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-2",children:t.map(s=>e.jsxs("div",{className:"rounded-2xl border border-slate-200/50 bg-white p-4 shadow-sm shadow-slate-200/30 transition-all duration-200 hover:-translate-y-0.5 hover:border-slate-200/70 hover:shadow-md hover:shadow-slate-200/40 dark:border-slate-700/50 dark:bg-slate-900/80 dark:shadow-lg dark:shadow-slate-900/30 dark:hover:border-slate-600/70",children:[e.jsx("dt",{className:"text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400",children:s.label}),e.jsx("dd",{className:"mt-2 text-base font-semibold text-slate-900 dark:text-slate-100",children:s.value}),s.hint?e.jsx("p",{className:o(i,"mt-2 text-xs leading-relaxed"),children:s.hint}):null]},s.label))})}function P(){const{t}=v(),{pushToast:s}=k(),a=N(["status","gateway"],{url:"/api/status",method:"GET"},{staleTime:6e4});r.useEffect(()=>{a.isError&&a.error&&s({title:t("about.toast.statusError.title"),description:a.error.message,variant:"error"})},[a.isError,a.error,s,t]);const n=_.version,l=r.useMemo(()=>{const u=L,f=u.VITE_BUILD_TIME,g=u.VITE_NODE_VERSION;return{buildTime:f,nodeVersion:g}},[]),h=r.useMemo(()=>[{label:t("about.app.labels.name"),value:e.jsx("span",{className:"font-mono text-sm font-semibold text-slate-900 dark:text-slate-100",children:"cc-gw"})},{label:t("about.app.labels.version"),value:e.jsxs("span",{className:"font-mono text-sm font-semibold text-blue-700 dark:text-blue-200",children:["v",n]})},{label:t("about.app.labels.buildTime"),value:l.buildTime,hint:t("about.app.hint.buildTime")},{label:t("about.app.labels.node"),value:e.jsx("span",{className:"font-mono text-sm text-slate-800 dark:text-slate-200",children:l.nodeVersion})}],[n,l.buildTime,l.nodeVersion,t]),c=r.useMemo(()=>a.data?[{label:t("about.status.labels.host"),value:a.data.host??"127.0.0.1"},{label:t("about.status.labels.port"),value:a.data.port.toLocaleString()},{label:t("about.status.labels.providers"),value:a.data.providers.toLocaleString()},{label:t("about.status.labels.active"),value:(a.data.activeRequests??0).toLocaleString(),hint:t("about.status.hint.active")}]:[],[a.data,t]),x=()=>{s({title:t("about.toast.updatesPlanned"),variant:"info"})};return e.jsxs("div",{className:"space-y-8",children:[e.jsx(w,{icon:e.jsx(y,{className:"h-6 w-6","aria-hidden":"true"}),title:t("about.title"),description:t("about.description"),badge:`v${n}`,actions:e.jsx(b,{variant:"primary",icon:e.jsx(E,{className:"h-4 w-4","aria-hidden":"true"}),onClick:x,children:t("about.support.actions.checkUpdates")})}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(d,{title:t("about.app.title"),description:t("about.app.subtitle"),className:"h-full",contentClassName:"gap-4",children:e.jsx(m,{items:h})}),e.jsx(d,{title:t("about.status.title"),description:t("about.status.subtitle"),className:"h-full",contentClassName:"gap-4",actions:e.jsx(b,{variant:"subtle",size:"sm",icon:e.jsx(T,{className:"h-4 w-4","aria-hidden":"true"}),onClick:()=>a.refetch(),loading:a.isFetching,children:a.isFetching?t("common.actions.refreshing"):t("common.actions.refresh")}),children:a.isLoading?e.jsxs("div",{className:"flex h-36 flex-col items-center justify-center gap-3 text-center",children:[e.jsx("div",{className:"h-10 w-10 animate-spin rounded-full border-[3px] border-blue-500/30 border-t-blue-600 dark:border-blue-400/20 dark:border-t-blue-300"}),e.jsx("p",{className:o(i,"text-sm"),children:t("about.status.loading")})]}):c.length>0?e.jsx(m,{items:c}):e.jsxs("div",{className:"flex h-36 flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-slate-200/60 bg-white p-6 text-center shadow-inner dark:border-slate-700/60 dark:bg-slate-900/60",children:[e.jsx("p",{className:"text-sm font-semibold text-slate-700 dark:text-slate-200",children:t("about.status.empty")}),e.jsx("p",{className:o(i,"text-xs"),children:t("common.actions.refresh")})]})})]}),e.jsx(d,{title:t("about.support.title"),description:e.jsxs("span",{className:"space-y-1",children:[e.jsx("span",{className:"block text-sm font-semibold text-blue-600 dark:text-blue-300",children:t("about.support.subtitle")}),e.jsx("span",{children:t("about.support.description")})]}),className:"relative overflow-hidden",contentClassName:"gap-6",children:e.jsxs("div",{className:"flex flex-col gap-4 rounded-3xl border border-slate-200/50 bg-white p-6 shadow-lg shadow-slate-200/30 backdrop-blur-md dark:border-slate-700/50 dark:bg-slate-900/80 dark:shadow-slate-900/40",children:[e.jsxs("div",{className:"flex flex-wrap items-start gap-4",children:[e.jsx("div",{className:"grid h-12 w-12 place-items-center rounded-2xl bg-gradient-to-br from-blue-500/20 to-indigo-500/20 text-blue-600 shadow-inner dark:text-blue-200",children:e.jsx(j,{className:"h-6 w-6","aria-hidden":"true"})}),e.jsx("p",{className:o(i,"text-sm leading-6"),children:t("about.support.tip")})]}),e.jsx("code",{className:"inline-flex items-center gap-2 self-start rounded-full border border-blue-200/50 bg-blue-50/80 px-4 py-2 text-xs font-semibold tracking-wide text-blue-700 shadow-sm dark:border-blue-500/30 dark:bg-blue-900/30 dark:text-blue-200",children:"~/.cc-gw/config.json"})]})})]})}export{P as default};
@@ -1,4 +1,4 @@
1
- import{c as T,u as W,a as J,r as d,j as e,L as X,N as Y,d as t,b as K,m as r,H as m,E as Z,k as ee,l as ae,f as se,h as te}from"./index-CAbsGgAq.js";import{E as le}from"./index-C2xoexDc.js";import{u as w}from"./useApiQuery-CNbY7eTZ.js";import{P as ie,a as q}from"./PageSection-BfMkaweN.js";import{F as I}from"./FormField-Dyi1Kr0k.js";import{I as re}from"./Input-DACzKnnk.js";import{B as C}from"./Button-DdVyALkb.js";import{S as ne}from"./StatusBadge-OH4R_aKr.js";import{C as ce}from"./copy-BVgnqUsP.js";/**
1
+ import{c as T,u as W,a as J,r as d,j as e,L as X,N as Y,d as t,b as K,m as r,H as m,E as Z,k as ee,l as ae,f as se,h as te}from"./index-BK1UNVMz.js";import{E as le}from"./index-CyrAg0Ev.js";import{u as w}from"./useApiQuery-BNTE55UK.js";import{P as ie,a as q}from"./PageSection-B08EcVAN.js";import{F as I}from"./FormField-SZpxR702.js";import{I as re}from"./Input-BdyQWPOU.js";import{B as C}from"./Button-CZXniSHM.js";import{S as ne}from"./StatusBadge-8KAMZvYW.js";import{C as ce}from"./copy-BdNskWTP.js";/**
2
2
  * @license lucide-react v0.344.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as s,d as c,J as i,E as p,k as b}from"./index-CAbsGgAq.js";function h({variant:n="subtle",size:o="md",children:a,loading:t,icon:e,className:l,disabled:r,...u}){const m={subtle:b,primary:p,danger:i}[n],x={sm:"h-8 px-3 text-xs",md:"h-10 px-4 text-sm",lg:"h-12 px-6 text-base"}[o];return s.jsx("button",{className:c(m,x,t&&"cursor-wait opacity-70",r&&"cursor-not-allowed opacity-50",l),disabled:r||t,...u,children:t?s.jsx("div",{className:"inline-block animate-spin rounded-full h-4 w-4 border-b-2 border-current"}):e?s.jsxs(s.Fragment,{children:[e,a]}):a})}export{h as B};
1
+ import{j as s,d as c,J as i,E as p,k as b}from"./index-BK1UNVMz.js";function h({variant:n="subtle",size:o="md",children:a,loading:t,icon:e,className:l,disabled:r,...u}){const m={subtle:b,primary:p,danger:i}[n],x={sm:"h-8 px-3 text-xs",md:"h-10 px-4 text-sm",lg:"h-12 px-6 text-base"}[o];return s.jsx("button",{className:c(m,x,t&&"cursor-wait opacity-70",r&&"cursor-not-allowed opacity-50",l),disabled:r||t,...u,children:t?s.jsx("div",{className:"inline-block animate-spin rounded-full h-4 w-4 border-b-2 border-current"}):e?s.jsxs(s.Fragment,{children:[e,a]}):a})}export{h as B};
@@ -0,0 +1,16 @@
1
+ import{c as O,u as q,a as te,r as h,b as se,t as ae,j as e,L as re,B,d as o,m as g,g as z,e as $,f as G,h as oe,l as _,s as le,i as M,k as ie,n as P}from"./index-BK1UNVMz.js";import{E as ne}from"./index-CyrAg0Ev.js";import{P as de,a as H}from"./PageSection-B08EcVAN.js";import{S as ce}from"./Input-BdyQWPOU.js";import{S as me}from"./StatusBadge-8KAMZvYW.js";import{u as C}from"./useApiQuery-BNTE55UK.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 D=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 xe=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 he=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"}]]);function w(t,a,s){return t==null?"-":`${t.toLocaleString(void 0,s)} ${a}`}function U(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 ve(){var F;const{t}=q(),{pushToast:a}=te(),[s,r]=h.useState("all"),[n,L]=h.useState(!1),p=s==="all"?void 0:s,v=C(["stats","overview",s],{url:"/api/stats/overview",method:"GET",params:p?{endpoint:p}:void 0}),k=C(["stats","daily",14,s],{url:"/api/stats/daily",method:"GET",params:{days:14,...p?{endpoint:p}:{}}}),y=C(["stats","model",7,6,s],{url:"/api/stats/model",method:"GET",params:{days:7,limit:6,...p?{endpoint:p}:{}}}),S=C(["status"],{url:"/api/status",method:"GET"}),f=C(["db","info"],{url:"/api/db/info",method:"GET"}),Q=f.refetch??(async()=>{}),T=C(["logs","recent",s],{url:"/api/logs",method:"GET",params:{limit:5,...p?{endpoint:p}:{}}},{refetchInterval:3e4});h.useEffect(()=>{v.isError&&v.error&&a({title:t("dashboard.toast.overviewError"),description:v.error.message,variant:"error"})},[v.isError,v.error,a,t]),h.useEffect(()=>{k.isError&&k.error&&a({title:t("dashboard.toast.dailyError"),description:k.error.message,variant:"error"})},[k.isError,k.error,a,t]),h.useEffect(()=>{y.isError&&y.error&&a({title:t("dashboard.toast.modelError"),description:y.error.message,variant:"error"})},[y.isError,y.error,a,t]),h.useEffect(()=>{S.isError&&S.error&&a({title:t("dashboard.toast.statusError"),description:S.error.message,variant:"error"})},[S.isError,S.error,a,t]),h.useEffect(()=>{f.isError&&f.error&&a({title:t("dashboard.toast.dbError"),description:f.error.message,variant:"error"})},[f.isError,f.error,a,t]);const K=h.useCallback(async()=>{if(!n){L(!0);try{await se.post("/api/db/compact"),await Q(),a({title:t("dashboard.toast.compactSuccess.title"),description:t("dashboard.toast.compactSuccess.desc"),variant:"success"})}catch(d){const x=ae(d);a({title:t("dashboard.toast.compactError.title"),description:x.message,variant:"error"})}finally{L(!1)}}},[n,a,Q,t]);h.useEffect(()=>{T.isError&&T.error&&a({title:t("dashboard.toast.recentError"),description:T.error.message,variant:"error"})},[T.isError,T.error,a,t]);const i=v.data,j=k.data??[],c=y.data??[],A=S.data,I=f.data,V=((F=T.data)==null?void 0:F.items)??[],J=I?U(I.totalBytes??I.sizeBytes):"-",W=I?U(I.memoryRssBytes??0):"-",X=h.useMemo(()=>{const d=j.map(b=>b.date),x=t("dashboard.charts.barRequests"),l=t("dashboard.charts.lineInput"),u=t("dashboard.charts.lineOutput"),m=t("dashboard.charts.lineCacheRead"),N=t("dashboard.charts.lineCacheCreation");return{tooltip:{trigger:"axis",backgroundColor:"rgba(15, 23, 42, 0.9)",borderColor:"rgba(59, 130, 246, 0.3)",textStyle:{color:"#e2e8f0"}},legend:{data:[x,l,u,m,N],textStyle:{color:"#64748b"}},grid:{left:60,right:40,top:60,bottom:60},xAxis:{type:"category",data:d,axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}}},yAxis:{type:"value",axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}},splitLine:{lineStyle:{color:"#1e293b"}}},series:[{name:x,type:"bar",data:j.map(b=>b.requestCount),itemStyle:{color:"#3b82f6",borderRadius:[4,4,0,0]},emphasis:{itemStyle:{color:"#2563eb"}}},{name:l,type:"line",yAxisIndex:0,data:j.map(b=>b.inputTokens),smooth:!0,itemStyle:{color:"#10b981"},lineStyle:{width:3},symbol:"circle",symbolSize:6},{name:u,type:"line",yAxisIndex:0,data:j.map(b=>b.outputTokens),smooth:!0,itemStyle:{color:"#f59e0b"},lineStyle:{width:3},symbol:"circle",symbolSize:6},{name:m,type:"line",yAxisIndex:0,data:j.map(b=>b.cacheReadTokens),smooth:!0,itemStyle:{color:"#8b5cf6"},lineStyle:{width:3},symbol:"circle",symbolSize:6},{name:N,type:"line",yAxisIndex:0,data:j.map(b=>b.cacheCreationTokens),smooth:!0,itemStyle:{color:"#ec4899"},lineStyle:{width:3},symbol:"circle",symbolSize:6}]}},[j,t]),Y=h.useMemo(()=>{const d=c.map(m=>`${m.provider}/${m.model}`),x=t("dashboard.charts.barRequests"),l=t("dashboard.charts.lineInput"),u=t("dashboard.charts.lineOutput");return{tooltip:{trigger:"axis",backgroundColor:"rgba(15, 23, 42, 0.9)",borderColor:"rgba(59, 130, 246, 0.3)",textStyle:{color:"#e2e8f0"}},legend:{data:[x,l,u],textStyle:{color:"#64748b"}},grid:{left:80,right:60,top:60,bottom:100},xAxis:{type:"category",data:d,axisLabel:{rotate:30,color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}}},yAxis:[{type:"value",name:x,axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}},splitLine:{lineStyle:{color:"#1e293b"}}},{type:"value",name:t("dashboard.charts.axisTokens"),position:"right",axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}}}],series:[{name:x,type:"bar",data:c.map(m=>m.requests),itemStyle:{color:"#6366f1",borderRadius:[4,4,0,0]},yAxisIndex:0},{name:l,type:"line",yAxisIndex:1,smooth:!0,data:c.map(m=>m.inputTokens??0),itemStyle:{color:"#10b981"},lineStyle:{width:3}},{name:u,type:"line",yAxisIndex:1,smooth:!0,data:c.map(m=>m.outputTokens??0),itemStyle:{color:"#f59e0b"},lineStyle:{width:3}}]}},[c,t]),Z=h.useMemo(()=>{const d=c.map(l=>`${l.provider}/${l.model}`),x=t("dashboard.charts.ttftLabel");return{tooltip:{trigger:"axis",backgroundColor:"rgba(15, 23, 42, 0.9)",borderColor:"rgba(59, 130, 246, 0.3)",textStyle:{color:"#e2e8f0"},formatter(l){var N;if(!Array.isArray(l)||l.length===0)return"";const u=((N=l[0])==null?void 0:N.dataIndex)??0,m=c[u];return m?`<strong>${d[u]}</strong><br/>${x}: ${w(m.avgTtftMs,t("common.units.ms"))}`:""}},grid:{left:80,right:50,top:60,bottom:100},xAxis:{type:"category",data:d,axisLabel:{rotate:30,color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}}},yAxis:{type:"value",name:t("dashboard.charts.ttftAxis"),axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}},splitLine:{lineStyle:{color:"#1e293b"}}},series:[{name:x,type:"bar",data:c.map(l=>l.avgTtftMs??0),itemStyle:{color:"#3b82f6",borderRadius:[4,4,0,0]}}]}},[c,t]),ee=h.useMemo(()=>{const d=c.map(l=>`${l.provider}/${l.model}`),x=t("dashboard.charts.tpotLabel");return{tooltip:{trigger:"axis",backgroundColor:"rgba(15, 23, 42, 0.9)",borderColor:"rgba(59, 130, 246, 0.3)",textStyle:{color:"#e2e8f0"},formatter(l){var N;if(!Array.isArray(l)||l.length===0)return"";const u=((N=l[0])==null?void 0:N.dataIndex)??0,m=c[u];return m?`<strong>${d[u]}</strong><br/>${x}: ${w(m.avgTpotMs,t("common.units.msPerToken"),{maximumFractionDigits:2})}`:""}},grid:{left:80,right:50,top:60,bottom:100},xAxis:{type:"category",data:d,axisLabel:{rotate:30,color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}}},yAxis:{type:"value",name:t("dashboard.charts.tpotAxis"),axisLabel:{color:"#64748b"},axisLine:{lineStyle:{color:"#334155"}},splitLine:{lineStyle:{color:"#1e293b"}}},series:[{name:x,type:"bar",data:c.map(l=>l.avgTpotMs??0),itemStyle:{color:"#f59e0b",borderRadius:[4,4,0,0]}}]}},[c,t]);return v.isPending||S.isPending||f.isPending?e.jsx(re,{}):e.jsxs("div",{className:"flex flex-col gap-8",children:[e.jsx(de,{icon:e.jsx(B,{className:"h-7 w-7","aria-hidden":"true"}),title:t("nav.dashboard"),description:t("dashboard.description"),actions:e.jsxs("div",{className:"flex items-center gap-4 rounded-2xl bg-white/90 px-4 py-3 shadow-lg shadow-slate-200/30 ring-1 ring-slate-200/40 backdrop-blur-lg dark:bg-slate-900/90 dark:shadow-xl dark:shadow-slate-900/30 dark:ring-slate-700/40",children:[e.jsx("label",{htmlFor:"dashboard-endpoint-filter",className:"text-xs font-bold uppercase tracking-[0.15em] text-slate-600 dark:text-slate-300",children:t("dashboard.filters.endpoint")}),e.jsx("div",{className:"relative",children:e.jsx(ce,{id:"dashboard-endpoint-filter",value:s,onChange:d=>r(d.target.value),options:[{value:"all",label:t("dashboard.filters.endpointAll")},{value:"anthropic",label:t("dashboard.filters.endpointAnthropic")},{value:"openai",label:t("dashboard.filters.endpointOpenAI")}]})})]})}),A?e.jsxs("section",{className:o(z,"flex flex-wrap items-center gap-4 text-sm leading-relaxed animate-slide-up"),"aria-live":"polite",children:[e.jsxs("span",{className:o(le.success,"inline-flex items-center gap-2 rounded-full px-4 py-2 font-semibold"),children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-current shadow-lg","aria-hidden":"true"}),t("dashboard.status.listening",{host:A.host??"0.0.0.0",port:A.port})]}),e.jsx("span",{className:o(M.default,"font-semibold"),children:t("dashboard.status.providers",{value:A.providers.toLocaleString()})}),e.jsx("span",{className:o(M.primary,"font-semibold"),children:t("dashboard.status.todayRequests",{value:((i==null?void 0:i.today.requests)??0).toLocaleString()})}),e.jsx("span",{className:o(M.default,"font-semibold"),children:t("dashboard.status.active",{value:(A.activeRequests??0).toLocaleString()})}),e.jsx("span",{className:o(M.default,"font-semibold"),children:t("dashboard.status.dbSize",{value:J})}),e.jsx("span",{className:o(M.default,"font-semibold"),children:t("dashboard.status.memory",{value:W})}),e.jsx("button",{type:"button",onClick:K,disabled:n,className:o(ie,"h-9 rounded-full px-4 text-xs font-semibold",n?"cursor-wait opacity-70":""),children:t(n?"dashboard.actions.compacting":"dashboard.actions.compact")})]}):null,e.jsxs("section",{className:o(P.auto,"gap-4 sm:gap-6"),children:[e.jsx(E,{icon:e.jsx(D,{className:"h-5 w-5"}),title:t("dashboard.cards.todayRequests"),value:(i==null?void 0:i.today.requests)??0,suffix:t("common.units.request"),trend:"+12%",trendDirection:"up"}),e.jsx(E,{icon:e.jsx(he,{className:"h-5 w-5"}),title:t("dashboard.cards.todayInput"),value:(i==null?void 0:i.today.inputTokens)??0,suffix:t("common.units.token"),trend:"+8%",trendDirection:"up"}),e.jsx(E,{icon:e.jsx(D,{className:"h-5 w-5"}),title:t("dashboard.cards.todayCacheRead"),value:(i==null?void 0:i.today.cacheReadTokens)??0,suffix:t("common.units.token")}),e.jsx(E,{icon:e.jsx(D,{className:"h-5 w-5"}),title:t("dashboard.cards.todayCacheCreation"),value:(i==null?void 0:i.today.cacheCreationTokens)??0,suffix:t("common.units.token")}),e.jsx(E,{icon:e.jsx(B,{className:"h-5 w-5"}),title:t("dashboard.cards.todayOutput"),value:(i==null?void 0:i.today.outputTokens)??0,suffix:t("common.units.token"),trend:"+15%",trendDirection:"up"}),e.jsx(E,{icon:e.jsx(xe,{className:"h-5 w-5"}),title:t("dashboard.cards.avgLatency"),value:(i==null?void 0:i.today.avgLatencyMs)??0,suffix:t("common.units.token"),trend:"-5%",trendDirection:"down"})]}),e.jsxs("div",{className:o(P.fixed[2],"gap-6 sm:gap-8"),children:[e.jsx(R,{title:t("dashboard.charts.requestsTitle"),description:t("dashboard.charts.requestsDesc"),loading:k.isPending,option:X,empty:!j.length,emptyText:t("dashboard.charts.empty")}),e.jsx(R,{title:t("dashboard.charts.modelTitle"),description:t("dashboard.charts.modelDesc"),loading:y.isPending,option:Y,empty:!c.length,emptyText:t("dashboard.charts.empty")})]}),e.jsxs("div",{className:o(P.fixed[2],"gap-6 sm:gap-8"),children:[e.jsx(R,{title:t("dashboard.charts.ttftTitle"),description:t("dashboard.charts.ttftDesc"),loading:y.isPending,option:Z,empty:!c.some(d=>d.avgTtftMs!=null&&d.avgTtftMs>0),emptyText:t("dashboard.charts.ttftEmpty")}),e.jsx(R,{title:t("dashboard.charts.tpotTitle"),description:t("dashboard.charts.tpotDesc"),loading:y.isPending,option:ee,empty:!c.some(d=>d.avgTpotMs!=null&&d.avgTpotMs>0),emptyText:t("dashboard.charts.tpotEmpty")})]}),e.jsx(pe,{models:c,loading:y.isPending}),e.jsx(ue,{loading:T.isPending,records:V})]})}function E({icon:t,title:a,value:s,suffix:r,trend:n,trendDirection:L}){return e.jsxs("div",{className:o(z,"group hover-lift animate-slide-up"),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("div",{className:o(g,"text-xs font-bold uppercase tracking-[0.15em]"),children:a}),t&&e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-xl bg-gradient-to-br from-blue-600/15 to-indigo-600/10 text-blue-600 ring-1 ring-blue-500/20 dark:from-blue-500/25 dark:to-indigo-500/15 dark:text-blue-200 dark:ring-blue-400/20",children:t})]}),e.jsx("div",{className:"flex items-end justify-between",children:e.jsxs("div",{children:[e.jsxs("p",{className:"text-3xl font-bold text-slate-900 dark:text-slate-50",children:[s.toLocaleString(),r?e.jsx("span",{className:o(g,"ml-2 text-base sm:text-lg font-medium"),children:r}):null]}),n&&e.jsxs("div",{className:o("mt-2 flex items-center gap-1 text-xs font-semibold",L==="up"?"text-emerald-600 dark:text-emerald-400":"text-red-600 dark:text-red-400"),children:[e.jsx("span",{children:n}),e.jsx("span",{className:"text-slate-500",children:"vs last period"})]})]})})]})}function R({title:t,description:a,option:s,loading:r,empty:n,emptyText:L}){const{t:p}=q();return e.jsxs("div",{className:o(z,"space-y-4 sm:space-y-6 hover-lift animate-slide-up"),children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xl font-bold text-slate-900 dark:text-slate-50",children:t}),e.jsx("p",{className:o(g,"mt-2 text-xs sm:text-sm leading-relaxed"),children:a})]}),r?e.jsx("div",{className:$.container,children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:$.spinner}),e.jsx("span",{className:o($.text),children:p("common.loadingShort")})]})}):n?e.jsx("div",{className:G,children:e.jsxs("div",{className:"text-center",children:[e.jsx(B,{className:"mx-auto h-12 w-12 text-slate-300 dark:text-slate-600 mb-4"}),e.jsx("span",{className:o(g,"text-sm"),children:L??p("dashboard.charts.empty")})]})}):e.jsx(ne,{option:s,style:{height:320},notMerge:!0,lazyUpdate:!0,theme:void 0,className:oe})]})}function pe({models:t,loading:a}){const{t:s}=q(),r=t.length>0;return e.jsx(H,{title:e.jsx("span",{className:"text-sm font-semibold text-slate-900 dark:text-slate-50",children:s("dashboard.modelTable.title")}),description:s("dashboard.modelTable.description"),contentClassName:"gap-0 overflow-hidden p-0",children:a?e.jsx("div",{className:_,children:e.jsx("span",{className:o(g,"text-sm"),children:s("common.loadingShort")})}):r?e.jsx("div",{className:"max-h-80 overflow-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-slate-200/70 text-sm dark:divide-slate-700/60",children:[e.jsx("caption",{className:"sr-only",children:s("dashboard.modelTable.title")}),e.jsx("thead",{className:"bg-slate-100/70 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:bg-slate-800/60 dark:text-slate-400",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-5 py-3 font-semibold",children:s("dashboard.modelTable.columns.model")}),e.jsx("th",{className:"px-5 py-3 text-right font-semibold",children:s("dashboard.modelTable.columns.requests")}),e.jsx("th",{className:"px-5 py-3 text-right font-semibold",children:s("dashboard.modelTable.columns.latency")}),e.jsx("th",{className:"px-5 py-3 text-right font-semibold",children:s("dashboard.modelTable.columns.ttft")}),e.jsx("th",{className:"px-5 py-3 text-right font-semibold",children:s("dashboard.modelTable.columns.tpot")})]})}),e.jsx("tbody",{className:"divide-y divide-slate-200/60 dark:divide-slate-800/60",children:t.map(n=>e.jsxs("tr",{className:"transition hover:bg-slate-50/70 dark:hover:bg-slate-800/40",children:[e.jsx("td",{className:"px-5 py-3",children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"font-semibold text-slate-800 dark:text-slate-50",children:n.provider}),e.jsx("span",{className:o(g,"text-xs"),children:n.model})]})}),e.jsx("td",{className:"px-5 py-3 text-right font-medium text-slate-800 dark:text-slate-50",children:n.requests.toLocaleString()}),e.jsx("td",{className:"px-5 py-3 text-right",children:w(n.avgLatencyMs,s("common.units.ms"))}),e.jsx("td",{className:"px-5 py-3 text-right",children:w(n.avgTtftMs,s("common.units.ms"))}),e.jsx("td",{className:"px-5 py-3 text-right",children:w(n.avgTpotMs,s("common.units.msPerToken"),{maximumFractionDigits:2})})]},`${n.provider}/${n.model}`))})]})}):e.jsx("div",{className:G,children:e.jsx("span",{className:o(g,"text-sm"),children:s("dashboard.modelTable.empty")})})})}function ue({records:t,loading:a}){const{t:s}=q();return e.jsx(H,{title:e.jsx("span",{className:"text-sm font-semibold text-slate-900 dark:text-slate-50",children:s("dashboard.recent.title")}),description:s("dashboard.recent.subtitle",{count:5}),contentClassName:"gap-0 overflow-hidden p-0",children:a?e.jsx("div",{className:_,children:e.jsx("span",{className:o(g,"text-sm"),children:s("dashboard.recent.loading")})}):t.length===0?e.jsx("div",{className:G,children:e.jsx("span",{className:o(g,"text-sm"),children:s("dashboard.recent.empty")})}):e.jsx("div",{className:"max-h-80 overflow-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-slate-200/70 text-sm dark:divide-slate-700/60",children:[e.jsx("caption",{className:"sr-only",children:s("dashboard.recent.title")}),e.jsx("thead",{className:"bg-slate-100/70 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:bg-slate-800/60 dark:text-slate-400",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-5 py-3 font-semibold",children:s("dashboard.recent.columns.time")}),e.jsx("th",{className:"px-5 py-3 font-semibold",children:s("dashboard.recent.columns.endpoint")}),e.jsx("th",{className:"px-5 py-3 font-semibold",children:s("dashboard.recent.columns.provider")}),e.jsx("th",{className:"px-5 py-3 font-semibold",children:s("dashboard.recent.columns.route")}),e.jsx("th",{className:"px-5 py-3 text-right font-semibold",children:s("dashboard.recent.columns.latency")}),e.jsx("th",{className:"px-5 py-3 text-left font-semibold",children:s("dashboard.recent.columns.status")})]})}),e.jsx("tbody",{className:"divide-y divide-slate-200/60 dark:divide-slate-800/60",children:t.map(r=>e.jsxs("tr",{className:"transition hover:bg-slate-50/70 dark:hover:bg-slate-800/40",children:[e.jsx("td",{className:"px-5 py-3 text-xs font-medium text-slate-600 dark:text-slate-300",children:new Date(r.timestamp).toLocaleString()}),e.jsx("td",{className:"px-5 py-3 text-xs text-slate-500 dark:text-slate-400",children:r.endpoint==="anthropic"?s("logs.table.endpointAnthropic"):r.endpoint==="openai"?s("logs.table.endpointOpenAI"):r.endpoint}),e.jsx("td",{className:"px-5 py-3 text-sm font-medium text-slate-800 dark:text-slate-50",children:r.provider}),e.jsx("td",{className:"px-5 py-3",children:e.jsxs("div",{className:"flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400",children:[e.jsx("span",{children:r.client_model??s("dashboard.recent.routePlaceholder")}),e.jsx("span",{"aria-hidden":"true",className:"text-slate-400",children:"→"}),e.jsx("span",{className:"font-semibold text-slate-700 dark:text-slate-100",children:r.model})]})}),e.jsx("td",{className:"px-5 py-3 text-right text-sm font-medium text-slate-800 dark:text-slate-100",children:w(r.latency_ms,s("common.units.ms"))}),e.jsx("td",{className:"px-5 py-3",children:e.jsxs(me,{variant:r.error?"error":"success",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-current","aria-hidden":"true"}),(r.status_code??(r.error?500:200)).toString(),e.jsx("span",{children:r.error?s("common.status.error"):s("common.status.success")})]})})]},r.id))})]})})})}export{ve as default};
@@ -1 +1 @@
1
- import{j as s,d,P as m,Q as x}from"./index-CAbsGgAq.js";function i({label:a,children:l,className:t,required:r,error:e}){return s.jsxs("div",{className:d(x,t),children:[s.jsxs("label",{className:m,children:[a,r&&s.jsx("span",{className:"text-red-500 ml-1",children:"*"})]}),l,e&&s.jsx("p",{className:"text-xs text-red-600 dark:text-red-400 mt-1",children:e})]})}export{i as F};
1
+ import{j as s,d,P as m,Q as x}from"./index-BK1UNVMz.js";function i({label:a,children:l,className:t,required:r,error:e}){return s.jsxs("div",{className:d(x,t),children:[s.jsxs("label",{className:m,children:[a,r&&s.jsx("span",{className:"text-red-500 ml-1",children:"*"})]}),l,e&&s.jsx("p",{className:"text-xs text-red-600 dark:text-red-400 mt-1",children:e})]})}export{i as F};
@@ -1,4 +1,4 @@
1
- import{c as u,u as p,r as b,j as e,d as x,m}from"./index-CAbsGgAq.js";import{P as g,a as o}from"./PageSection-BfMkaweN.js";import{I as j}from"./info-CpmSkfUl.js";/**
1
+ import{c as u,u as p,r as b,j as e,d as x,m}from"./index-BK1UNVMz.js";import{P as g,a as o}from"./PageSection-B08EcVAN.js";import{I as j}from"./info-BTcWJb9B.js";/**
2
2
  * @license lucide-react v0.344.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as d,j as e,d as n,M as c,K as i}from"./index-CAbsGgAq.js";const f=d.forwardRef(({options:t,placeholder:s,className:r,...l},u)=>e.jsxs("select",{ref:u,className:n(c,r),...l,children:[s&&e.jsx("option",{value:"",disabled:!0,children:s}),t.map(a=>e.jsx("option",{value:a.value,disabled:a.disabled,children:a.label},a.value))]})),j=d.forwardRef(({variant:t="default",className:s,...r},l)=>e.jsx("input",{ref:l,className:n(i,s),...r}));export{j as I,f as S};
1
+ import{r as d,j as e,d as n,M as c,K as i}from"./index-BK1UNVMz.js";const f=d.forwardRef(({options:t,placeholder:s,className:r,...l},u)=>e.jsxs("select",{ref:u,className:n(c,r),...l,children:[s&&e.jsx("option",{value:"",disabled:!0,children:s}),t.map(a=>e.jsx("option",{value:a.value,disabled:a.disabled,children:a.label},a.value))]})),j=d.forwardRef(({variant:t="default",className:s,...r},l)=>e.jsx("input",{ref:l,className:n(i,s),...r}));export{j as I,f as S};