@chenpu17/cc-gw 0.4.0 → 0.4.2

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 (23) hide show
  1. package/package.json +1 -1
  2. package/src/server/dist/index.js +189 -29
  3. package/src/web/dist/assets/{About-CH7-GnML.js → About-CfWemXks.js} +2 -2
  4. package/src/web/dist/assets/{ApiKeys-DbxeLLKa.js → ApiKeys-jGq-kKf8.js} +1 -1
  5. package/src/web/dist/assets/{Button-3qj8BOTb.js → Button-DdVyALkb.js} +1 -1
  6. package/src/web/dist/assets/Dashboard-uoI9oSjK.js +16 -0
  7. package/src/web/dist/assets/{FormField-DmKxUoqD.js → FormField-Dyi1Kr0k.js} +1 -1
  8. package/src/web/dist/assets/{Help-DLqRglMH.js → Help-iZXiqNPj.js} +1 -1
  9. package/src/web/dist/assets/{Input-AVaeYH0J.js → Input-DACzKnnk.js} +1 -1
  10. package/src/web/dist/assets/{Login-CQ-q3WoP.js → Login-mm-NJUOP.js} +1 -1
  11. package/src/web/dist/assets/{Logs-C5qWLb-O.js → Logs-DNxTsrk3.js} +1 -1
  12. package/src/web/dist/assets/{ModelManagement-DEwX4znU.js → ModelManagement-B4f8RUk8.js} +1 -1
  13. package/src/web/dist/assets/{PageSection-819eIHwY.js → PageSection-BfMkaweN.js} +1 -1
  14. package/src/web/dist/assets/{Settings-BghgyqoT.js → Settings-DRLUoVLq.js} +1 -1
  15. package/src/web/dist/assets/{StatusBadge-FIJj_rsA.js → StatusBadge-OH4R_aKr.js} +1 -1
  16. package/src/web/dist/assets/{copy-dJsIfcXG.js → copy-BVgnqUsP.js} +1 -1
  17. package/src/web/dist/assets/{index-But5PyJC.css → index-BFd07aus.css} +1 -1
  18. package/src/web/dist/assets/{index-D4f4GIYb.js → index-C2xoexDc.js} +1 -1
  19. package/src/web/dist/assets/{index-CMmlZ8am.js → index-CAbsGgAq.js} +5 -5
  20. package/src/web/dist/assets/{info-Cg4yNF4Z.js → info-CpmSkfUl.js} +1 -1
  21. package/src/web/dist/assets/{useApiQuery-qpXuOM9g.js → useApiQuery-CNbY7eTZ.js} +1 -1
  22. package/src/web/dist/index.html +2 -2
  23. package/src/web/dist/assets/Dashboard-Co1ZMGdJ.js +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenpu17/cc-gw",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11102,6 +11102,8 @@ async function migrateDailyMetricsTable(db) {
11102
11102
  const hasCompositePrimaryKey = primaryKeyColumns.length > 1;
11103
11103
  if (!hasEndpointColumn || !hasCompositePrimaryKey) {
11104
11104
  const endpointSelector = hasEndpointColumn ? "COALESCE(endpoint, 'anthropic')" : "'anthropic'";
11105
+ const hasCachedTokensColumn = columns.some((column) => column.name === "total_cached_tokens");
11106
+ const cachedTokensSelector = hasCachedTokensColumn ? "COALESCE(total_cached_tokens, 0)" : "0";
11105
11107
  await exec(
11106
11108
  db,
11107
11109
  `ALTER TABLE daily_metrics RENAME TO daily_metrics_old;
@@ -11111,15 +11113,17 @@ async function migrateDailyMetricsTable(db) {
11111
11113
  request_count INTEGER DEFAULT 0,
11112
11114
  total_input_tokens INTEGER DEFAULT 0,
11113
11115
  total_output_tokens INTEGER DEFAULT 0,
11116
+ total_cached_tokens INTEGER DEFAULT 0,
11114
11117
  total_latency_ms INTEGER DEFAULT 0,
11115
11118
  PRIMARY KEY (date, endpoint)
11116
11119
  );
11117
- INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_latency_ms)
11120
+ INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_latency_ms)
11118
11121
  SELECT date,
11119
11122
  ${endpointSelector},
11120
11123
  request_count,
11121
11124
  total_input_tokens,
11122
11125
  total_output_tokens,
11126
+ ${cachedTokensSelector},
11123
11127
  total_latency_ms
11124
11128
  FROM daily_metrics_old;
11125
11129
  DROP TABLE daily_metrics_old;`
@@ -11176,6 +11180,7 @@ async function ensureSchema(db) {
11176
11180
  request_count INTEGER DEFAULT 0,
11177
11181
  total_input_tokens INTEGER DEFAULT 0,
11178
11182
  total_output_tokens INTEGER DEFAULT 0,
11183
+ total_cached_tokens INTEGER DEFAULT 0,
11179
11184
  total_latency_ms INTEGER DEFAULT 0,
11180
11185
  PRIMARY KEY (date, endpoint)
11181
11186
  );
@@ -11233,6 +11238,7 @@ async function ensureSchema(db) {
11233
11238
  await maybeAddColumn(db, "api_keys", "total_input_tokens", "INTEGER DEFAULT 0");
11234
11239
  await maybeAddColumn(db, "api_keys", "total_output_tokens", "INTEGER DEFAULT 0");
11235
11240
  await migrateDailyMetricsTable(db);
11241
+ await maybeAddColumn(db, "daily_metrics", "total_cached_tokens", "INTEGER DEFAULT 0");
11236
11242
  await run(db, "CREATE UNIQUE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash) WHERE key_hash IS NOT NULL");
11237
11243
  await run(db, "UPDATE api_keys SET key_hash = '*' WHERE is_wildcard = 1 AND (key_hash IS NULL OR key_hash = '')");
11238
11244
  await run(db, "UPDATE api_keys SET updated_at = created_at WHERE updated_at IS NULL");
@@ -11450,12 +11456,13 @@ async function upsertLogPayload(requestId, payload) {
11450
11456
  }
11451
11457
  async function updateMetrics(date, endpoint, delta) {
11452
11458
  await runQuery(
11453
- `INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_latency_ms)
11454
- VALUES (?, ?, ?, ?, ?, ?)
11459
+ `INSERT INTO daily_metrics (date, endpoint, request_count, total_input_tokens, total_output_tokens, total_cached_tokens, total_latency_ms)
11460
+ VALUES (?, ?, ?, ?, ?, ?, ?)
11455
11461
  ON CONFLICT(date, endpoint) DO UPDATE SET
11456
11462
  request_count = daily_metrics.request_count + excluded.request_count,
11457
11463
  total_input_tokens = daily_metrics.total_input_tokens + excluded.total_input_tokens,
11458
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,
11459
11466
  total_latency_ms = daily_metrics.total_latency_ms + excluded.total_latency_ms`,
11460
11467
  [
11461
11468
  date,
@@ -11463,6 +11470,7 @@ async function updateMetrics(date, endpoint, delta) {
11463
11470
  delta.requests,
11464
11471
  delta.inputTokens,
11465
11472
  delta.outputTokens,
11473
+ delta.cachedTokens ?? 0,
11466
11474
  delta.latencyMs
11467
11475
  ]
11468
11476
  );
@@ -12214,7 +12222,7 @@ async function registerMessagesRoute(app) {
12214
12222
  if (providerType === "anthropic") {
12215
12223
  let inputTokens2 = json.usage?.input_tokens ?? 0;
12216
12224
  let outputTokens2 = json.usage?.output_tokens ?? 0;
12217
- const cachedTokens2 = resolveCachedTokens(json.usage);
12225
+ const cachedTokens3 = resolveCachedTokens(json.usage);
12218
12226
  if (!inputTokens2) {
12219
12227
  inputTokens2 = target.tokenEstimate || estimateTokens(normalized, target.modelId);
12220
12228
  }
@@ -12225,13 +12233,13 @@ async function registerMessagesRoute(app) {
12225
12233
  logUsage("non_stream.anthropic", {
12226
12234
  input: inputTokens2,
12227
12235
  output: outputTokens2,
12228
- cached: cachedTokens2
12236
+ cached: cachedTokens3
12229
12237
  });
12230
12238
  const latencyMs2 = Date.now() - requestStart;
12231
12239
  await updateLogTokens(logId, {
12232
12240
  inputTokens: inputTokens2,
12233
12241
  outputTokens: outputTokens2,
12234
- cachedTokens: cachedTokens2,
12242
+ cachedTokens: cachedTokens3,
12235
12243
  ttftMs: latencyMs2,
12236
12244
  tpotMs: computeTpot(latencyMs2, outputTokens2, { streaming: false })
12237
12245
  });
@@ -12240,6 +12248,7 @@ async function registerMessagesRoute(app) {
12240
12248
  requests: 1,
12241
12249
  inputTokens: inputTokens2,
12242
12250
  outputTokens: outputTokens2,
12251
+ cachedTokens: cachedTokens3,
12243
12252
  latencyMs: latencyMs2
12244
12253
  });
12245
12254
  if (storeResponsePayloads) {
@@ -12260,7 +12269,7 @@ async function registerMessagesRoute(app) {
12260
12269
  const claudeResponse = buildClaudeResponse(json, target.modelId);
12261
12270
  let inputTokens = json.usage?.prompt_tokens ?? 0;
12262
12271
  let outputTokens = json.usage?.completion_tokens ?? 0;
12263
- const cachedTokens = resolveCachedTokens(json.usage);
12272
+ const cachedTokens2 = resolveCachedTokens(json.usage);
12264
12273
  if (!inputTokens) {
12265
12274
  inputTokens = target.tokenEstimate || estimateTokens(normalized, target.modelId);
12266
12275
  }
@@ -12271,13 +12280,13 @@ async function registerMessagesRoute(app) {
12271
12280
  logUsage("non_stream.openai", {
12272
12281
  input: inputTokens,
12273
12282
  output: outputTokens,
12274
- cached: cachedTokens
12283
+ cached: cachedTokens2
12275
12284
  });
12276
12285
  const latencyMs = Date.now() - requestStart;
12277
12286
  await updateLogTokens(logId, {
12278
12287
  inputTokens,
12279
12288
  outputTokens,
12280
- cachedTokens,
12289
+ cachedTokens: cachedTokens2,
12281
12290
  ttftMs: latencyMs,
12282
12291
  tpotMs: computeTpot(latencyMs, outputTokens, { streaming: false })
12283
12292
  });
@@ -12563,6 +12572,7 @@ async function registerMessagesRoute(app) {
12563
12572
  requests: 1,
12564
12573
  inputTokens: usagePrompt2,
12565
12574
  outputTokens: usageCompletion2,
12575
+ cachedTokens: usageCached2,
12566
12576
  latencyMs: totalLatencyMs
12567
12577
  });
12568
12578
  if (storeResponsePayloads) {
@@ -12733,6 +12743,7 @@ data: ${JSON.stringify(data)}
12733
12743
  requests: 1,
12734
12744
  inputTokens: finalPromptTokens,
12735
12745
  outputTokens: finalCompletionTokens,
12746
+ cachedTokens: usageCached,
12736
12747
  latencyMs: totalLatencyMs
12737
12748
  });
12738
12749
  if (storeResponsePayloads) {
@@ -12894,6 +12905,7 @@ data: ${JSON.stringify(data)}
12894
12905
  requests: 1,
12895
12906
  inputTokens: fallbackPrompt,
12896
12907
  outputTokens: fallbackCompletion,
12908
+ cachedTokens: usageCached,
12897
12909
  latencyMs: totalLatencyMs
12898
12910
  });
12899
12911
  if (storeResponsePayloads) {
@@ -13836,17 +13848,17 @@ async function registerOpenAiRoutes(app) {
13836
13848
  if (!Number.isFinite(inputTokens3) || inputTokens3 <= 0) {
13837
13849
  inputTokens3 = target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
13838
13850
  }
13839
- const cachedTokens2 = resolveCachedTokens2(usagePayload2);
13851
+ const cachedTokens3 = resolveCachedTokens2(usagePayload2);
13840
13852
  const latencyMs3 = Date.now() - requestStart;
13841
13853
  const openAIResponse = buildOpenAIResponseFromClaude(parsed, target.modelId, converted, {
13842
13854
  inputTokens: inputTokens3,
13843
13855
  outputTokens: outputTokens3,
13844
- cachedTokens: cachedTokens2
13856
+ cachedTokens: cachedTokens3
13845
13857
  });
13846
13858
  await updateLogTokens(logId, {
13847
13859
  inputTokens: inputTokens3,
13848
13860
  outputTokens: outputTokens3,
13849
- cachedTokens: cachedTokens2,
13861
+ cachedTokens: cachedTokens3,
13850
13862
  ttftMs: latencyMs3,
13851
13863
  tpotMs: computeTpot2(latencyMs3, outputTokens3, { streaming: false })
13852
13864
  });
@@ -13855,6 +13867,7 @@ async function registerOpenAiRoutes(app) {
13855
13867
  requests: 1,
13856
13868
  inputTokens: inputTokens3,
13857
13869
  outputTokens: outputTokens3,
13870
+ cachedTokens: cachedTokens3,
13858
13871
  latencyMs: latencyMs3
13859
13872
  });
13860
13873
  if (storeResponsePayloads) {
@@ -13889,12 +13902,12 @@ async function registerOpenAiRoutes(app) {
13889
13902
  return 0;
13890
13903
  })();
13891
13904
  const outputTokens2 = baseOutputTokens + reasoningTokens2;
13892
- const cachedTokens = resolveCachedTokens2(usagePayload);
13905
+ const cachedTokens2 = resolveCachedTokens2(usagePayload);
13893
13906
  const latencyMs2 = Date.now() - requestStart;
13894
13907
  await updateLogTokens(logId, {
13895
13908
  inputTokens: inputTokens2,
13896
13909
  outputTokens: outputTokens2,
13897
- cachedTokens,
13910
+ cachedTokens: cachedTokens2,
13898
13911
  ttftMs: usagePayload?.first_token_latency_ms ?? latencyMs2,
13899
13912
  tpotMs: usagePayload?.tokens_per_second ? computeTpot2(latencyMs2, outputTokens2, { streaming: false, reasoningTokens: reasoningTokens2 }) : null
13900
13913
  });
@@ -14292,6 +14305,7 @@ async function registerOpenAiRoutes(app) {
14292
14305
  requests: 1,
14293
14306
  inputTokens: finalPromptTokens,
14294
14307
  outputTokens: finalCompletionTokens,
14308
+ cachedTokens: usageCached2,
14295
14309
  latencyMs: totalLatencyMs
14296
14310
  });
14297
14311
  if (storeResponsePayloads && capturedResponseChunks2) {
@@ -14699,12 +14713,12 @@ async function registerOpenAiRoutes(app) {
14699
14713
  inputTokens: inputTokens3,
14700
14714
  outputTokens: outputTokens3
14701
14715
  });
14702
- const cachedTokens2 = resolveCachedTokens2(usagePayload2);
14716
+ const cachedTokens3 = resolveCachedTokens2(usagePayload2);
14703
14717
  const latencyMs3 = Date.now() - requestStart;
14704
14718
  await updateLogTokens(logId, {
14705
14719
  inputTokens: inputTokens3,
14706
14720
  outputTokens: outputTokens3,
14707
- cachedTokens: cachedTokens2,
14721
+ cachedTokens: cachedTokens3,
14708
14722
  ttftMs: latencyMs3,
14709
14723
  tpotMs: computeTpot2(latencyMs3, outputTokens3, { streaming: false })
14710
14724
  });
@@ -14713,6 +14727,7 @@ async function registerOpenAiRoutes(app) {
14713
14727
  requests: 1,
14714
14728
  inputTokens: inputTokens3,
14715
14729
  outputTokens: outputTokens3,
14730
+ cachedTokens: cachedTokens3,
14716
14731
  latencyMs: latencyMs3
14717
14732
  });
14718
14733
  if (storeResponsePayloads) {
@@ -14742,12 +14757,12 @@ async function registerOpenAiRoutes(app) {
14742
14757
  })(),
14743
14758
  target.modelId
14744
14759
  );
14745
- const cachedTokens = resolveCachedTokens2(usagePayload);
14760
+ const cachedTokens2 = resolveCachedTokens2(usagePayload);
14746
14761
  const latencyMs2 = Date.now() - requestStart;
14747
14762
  await updateLogTokens(logId, {
14748
14763
  inputTokens: inputTokens2,
14749
14764
  outputTokens: outputTokens2,
14750
- cachedTokens,
14765
+ cachedTokens: cachedTokens2,
14751
14766
  ttftMs: usagePayload?.first_token_latency_ms ?? latencyMs2,
14752
14767
  tpotMs: usagePayload?.tokens_per_second ? computeTpot2(latencyMs2, outputTokens2, { streaming: false }) : null
14753
14768
  });
@@ -15188,6 +15203,7 @@ async function registerOpenAiRoutes(app) {
15188
15203
  requests: 1,
15189
15204
  inputTokens: finalPromptTokens,
15190
15205
  outputTokens: finalCompletionTokens,
15206
+ cachedTokens: usageCached2,
15191
15207
  latencyMs: totalLatencyMs
15192
15208
  });
15193
15209
  if (storeResponsePayloads && capturedResponseChunks2) {
@@ -15597,6 +15613,7 @@ async function getDailyMetrics(days = 7, endpoint) {
15597
15613
  request_count AS requestCount,
15598
15614
  total_input_tokens AS inputTokens,
15599
15615
  total_output_tokens AS outputTokens,
15616
+ total_cached_tokens AS cachedTokens,
15600
15617
  total_latency_ms AS totalLatency
15601
15618
  FROM daily_metrics
15602
15619
  ${whereClause}
@@ -15609,6 +15626,7 @@ async function getDailyMetrics(days = 7, endpoint) {
15609
15626
  requestCount: row.requestCount ?? 0,
15610
15627
  inputTokens: row.inputTokens ?? 0,
15611
15628
  outputTokens: row.outputTokens ?? 0,
15629
+ cachedTokens: row.cachedTokens ?? 0,
15612
15630
  avgLatencyMs: row.requestCount ? Math.round((row.totalLatency ?? 0) / row.requestCount) : 0
15613
15631
  })).reverse();
15614
15632
  }
@@ -15619,6 +15637,7 @@ async function getMetricsOverview(endpoint) {
15619
15637
  COALESCE(SUM(request_count), 0) AS requests,
15620
15638
  COALESCE(SUM(total_input_tokens), 0) AS inputTokens,
15621
15639
  COALESCE(SUM(total_output_tokens), 0) AS outputTokens,
15640
+ COALESCE(SUM(total_cached_tokens), 0) AS cachedTokens,
15622
15641
  COALESCE(SUM(total_latency_ms), 0) AS totalLatency
15623
15642
  FROM daily_metrics
15624
15643
  ${totalsWhere}`,
@@ -15629,6 +15648,7 @@ async function getMetricsOverview(endpoint) {
15629
15648
  `SELECT request_count AS requests,
15630
15649
  total_input_tokens AS inputTokens,
15631
15650
  total_output_tokens AS outputTokens,
15651
+ total_cached_tokens AS cachedTokens,
15632
15652
  total_latency_ms AS totalLatency
15633
15653
  FROM daily_metrics
15634
15654
  WHERE date = ?
@@ -15645,12 +15665,14 @@ async function getMetricsOverview(endpoint) {
15645
15665
  requests: totalsRequests,
15646
15666
  inputTokens: totalsRow?.inputTokens ?? 0,
15647
15667
  outputTokens: totalsRow?.outputTokens ?? 0,
15668
+ cachedTokens: totalsRow?.cachedTokens ?? 0,
15648
15669
  avgLatencyMs: resolveAvg(totalsLatency, totalsRequests)
15649
15670
  },
15650
15671
  today: {
15651
15672
  requests: todayRequests,
15652
15673
  inputTokens: todayRow?.inputTokens ?? 0,
15653
15674
  outputTokens: todayRow?.outputTokens ?? 0,
15675
+ cachedTokens: todayRow?.cachedTokens ?? 0,
15654
15676
  avgLatencyMs: resolveAvg(todayLatency, todayRequests)
15655
15677
  }
15656
15678
  };
@@ -17094,6 +17116,13 @@ function resolveCachedTokens3(usage) {
17094
17116
  return null;
17095
17117
  }
17096
17118
  var roundTwoDecimals3 = (value) => Math.round(value * 100) / 100;
17119
+ function cloneOriginalPayload2(value) {
17120
+ const structuredCloneFn = globalThis.structuredClone;
17121
+ if (structuredCloneFn) {
17122
+ return structuredCloneFn(value);
17123
+ }
17124
+ return JSON.parse(JSON.stringify(value));
17125
+ }
17097
17126
  function computeTpot3(totalLatencyMs, outputTokens, options) {
17098
17127
  if (!Number.isFinite(outputTokens) || outputTokens <= 0) {
17099
17128
  return null;
@@ -17230,7 +17259,8 @@ async function registerUnifiedHandler(app, path5, endpointId) {
17230
17259
  if (endpoint.paths && Array.isArray(endpoint.paths) && endpoint.paths.length > 0) {
17231
17260
  const matchedPath = endpoint.paths.find((p) => {
17232
17261
  const normalizedPath = p.path.startsWith("/") ? p.path : `/${p.path}`;
17233
- return actualPath === normalizedPath;
17262
+ const expandedPaths = getPathsToRegister(normalizedPath, p.protocol);
17263
+ return expandedPaths.includes(actualPath);
17234
17264
  });
17235
17265
  protocol = matchedPath?.protocol;
17236
17266
  } else if (endpoint.protocol) {
@@ -17268,6 +17298,37 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17268
17298
  reply.code(400);
17269
17299
  return { error: "Invalid request body" };
17270
17300
  }
17301
+ const rawUrl = typeof request.raw?.url === "string" ? request.raw.url : request.url ?? "";
17302
+ let querySuffix = null;
17303
+ if (typeof rawUrl === "string") {
17304
+ const questionIndex = rawUrl.indexOf("?");
17305
+ if (questionIndex !== -1) {
17306
+ querySuffix = rawUrl.slice(questionIndex + 1);
17307
+ }
17308
+ }
17309
+ if (!querySuffix && typeof request.querystring === "string") {
17310
+ querySuffix = request.querystring || null;
17311
+ }
17312
+ const providerHeaders = {};
17313
+ const headersToForward = [
17314
+ "anthropic-version",
17315
+ "anthropic-beta",
17316
+ "x-stainless-arch",
17317
+ "x-stainless-async",
17318
+ "x-stainless-lang",
17319
+ "x-stainless-os",
17320
+ "x-stainless-package-version",
17321
+ "x-stainless-runtime",
17322
+ "x-stainless-runtime-version"
17323
+ ];
17324
+ for (const key of headersToForward) {
17325
+ const value = request.headers[key];
17326
+ if (typeof value === "string" && value.length > 0) {
17327
+ providerHeaders[key] = value;
17328
+ } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
17329
+ providerHeaders[key] = value[0];
17330
+ }
17331
+ }
17271
17332
  const providedApiKey = extractApiKeyFromRequest2(request);
17272
17333
  let apiKeyContext;
17273
17334
  try {
@@ -17351,9 +17412,36 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17351
17412
  const providerType = target.provider.type ?? "custom";
17352
17413
  const connector = getConnector(target.providerId);
17353
17414
  let providerBody;
17415
+ let finalHeaders = providerHeaders;
17354
17416
  if (providerType === "anthropic") {
17355
- providerBody = { ...payload };
17417
+ providerBody = cloneOriginalPayload2(payload);
17356
17418
  providerBody.model = target.modelId;
17419
+ if (normalized.stream !== void 0) {
17420
+ providerBody.stream = normalized.stream;
17421
+ }
17422
+ const collected = {};
17423
+ const skip = /* @__PURE__ */ new Set(["content-length", "host", "connection", "transfer-encoding"]);
17424
+ const sourceHeaders = request.raw?.headers ?? request.headers;
17425
+ for (const [headerKey, headerValue] of Object.entries(sourceHeaders)) {
17426
+ const lower = headerKey.toLowerCase();
17427
+ if (skip.has(lower))
17428
+ continue;
17429
+ let value;
17430
+ if (typeof headerValue === "string") {
17431
+ value = headerValue;
17432
+ } else if (Array.isArray(headerValue)) {
17433
+ value = headerValue.find((item) => typeof item === "string" && item.length > 0);
17434
+ }
17435
+ if (value && value.length > 0) {
17436
+ collected[lower] = value;
17437
+ }
17438
+ }
17439
+ if (!("content-type" in collected)) {
17440
+ collected["content-type"] = "application/json";
17441
+ }
17442
+ if (Object.keys(collected).length > 0) {
17443
+ finalHeaders = collected;
17444
+ }
17357
17445
  } else {
17358
17446
  providerBody = buildProviderBody(normalized, {
17359
17447
  maxTokens: payload.max_tokens,
@@ -17363,7 +17451,9 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17363
17451
  const upstream = await connector.send({
17364
17452
  model: target.modelId,
17365
17453
  body: providerBody,
17366
- stream: normalized.stream
17454
+ stream: normalized.stream,
17455
+ query: querySuffix,
17456
+ headers: finalHeaders
17367
17457
  });
17368
17458
  if (upstream.status >= 400) {
17369
17459
  reply.code(upstream.status);
@@ -17380,12 +17470,12 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17380
17470
  const json = await new Response(upstream.body).json();
17381
17471
  const inputTokens = json.usage?.input_tokens ?? estimateTokens(normalized, target.modelId);
17382
17472
  const outputTokens = json.usage?.output_tokens ?? 0;
17383
- const cachedTokens = resolveCachedTokens3(json.usage);
17473
+ const cachedTokens2 = resolveCachedTokens3(json.usage);
17384
17474
  const latencyMs = Date.now() - requestStart;
17385
17475
  await updateLogTokens(logId, {
17386
17476
  inputTokens,
17387
17477
  outputTokens,
17388
- cachedTokens,
17478
+ cachedTokens: cachedTokens2,
17389
17479
  ttftMs: latencyMs,
17390
17480
  tpotMs: computeTpot3(latencyMs, outputTokens, { streaming: false })
17391
17481
  });
@@ -17394,6 +17484,7 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17394
17484
  requests: 1,
17395
17485
  inputTokens,
17396
17486
  outputTokens,
17487
+ cachedTokens: cachedTokens2,
17397
17488
  latencyMs
17398
17489
  });
17399
17490
  if (storeResponsePayloads) {
@@ -17490,6 +17581,7 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
17490
17581
  requests: 1,
17491
17582
  inputTokens: usagePrompt,
17492
17583
  outputTokens: usageCompletion,
17584
+ cachedTokens: usageCached,
17493
17585
  latencyMs: totalLatencyMs
17494
17586
  });
17495
17587
  if (storeResponsePayloads && capturedChunks) {
@@ -17522,6 +17614,37 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
17522
17614
  reply.code(400);
17523
17615
  return { error: "Invalid request body" };
17524
17616
  }
17617
+ const rawUrl = typeof request.raw?.url === "string" ? request.raw.url : request.url ?? "";
17618
+ let querySuffix = null;
17619
+ if (typeof rawUrl === "string") {
17620
+ const questionIndex = rawUrl.indexOf("?");
17621
+ if (questionIndex !== -1) {
17622
+ querySuffix = rawUrl.slice(questionIndex + 1);
17623
+ }
17624
+ }
17625
+ if (!querySuffix && typeof request.querystring === "string") {
17626
+ querySuffix = request.querystring || null;
17627
+ }
17628
+ const providerHeaders = {};
17629
+ const headersToForward = [
17630
+ "anthropic-version",
17631
+ "anthropic-beta",
17632
+ "x-stainless-arch",
17633
+ "x-stainless-async",
17634
+ "x-stainless-lang",
17635
+ "x-stainless-os",
17636
+ "x-stainless-package-version",
17637
+ "x-stainless-runtime",
17638
+ "x-stainless-runtime-version"
17639
+ ];
17640
+ for (const key of headersToForward) {
17641
+ const value = request.headers[key];
17642
+ if (typeof value === "string" && value.length > 0) {
17643
+ providerHeaders[key] = value;
17644
+ } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
17645
+ providerHeaders[key] = value[0];
17646
+ }
17647
+ }
17525
17648
  const providedApiKey = extractApiKeyFromRequest2(request);
17526
17649
  let apiKeyContext;
17527
17650
  try {
@@ -17618,7 +17741,9 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
17618
17741
  const upstream = await connector.send({
17619
17742
  model: target.modelId,
17620
17743
  body: providerBody,
17621
- stream: normalized.stream
17744
+ stream: normalized.stream,
17745
+ query: querySuffix,
17746
+ headers: providerHeaders
17622
17747
  });
17623
17748
  if (upstream.status >= 400) {
17624
17749
  reply.code(upstream.status);
@@ -17636,12 +17761,12 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
17636
17761
  const usagePayload = json?.usage ?? null;
17637
17762
  const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
17638
17763
  const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(json?.choices?.[0]?.message?.content ?? "", target.modelId);
17639
- const cachedTokens = resolveCachedTokens3(usagePayload);
17764
+ const cachedTokens2 = resolveCachedTokens3(usagePayload);
17640
17765
  const latencyMs2 = Date.now() - requestStart;
17641
17766
  await updateLogTokens(logId, {
17642
17767
  inputTokens: inputTokens2,
17643
17768
  outputTokens: outputTokens2,
17644
- cachedTokens,
17769
+ cachedTokens: cachedTokens2,
17645
17770
  ttftMs: latencyMs2,
17646
17771
  tpotMs: computeTpot3(latencyMs2, outputTokens2, { streaming: false })
17647
17772
  });
@@ -17650,6 +17775,7 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
17650
17775
  requests: 1,
17651
17776
  inputTokens: inputTokens2,
17652
17777
  outputTokens: outputTokens2,
17778
+ cachedTokens: cachedTokens2,
17653
17779
  latencyMs: latencyMs2
17654
17780
  });
17655
17781
  if (storeResponsePayloads) {
@@ -17767,6 +17893,37 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
17767
17893
  reply.code(400);
17768
17894
  return { error: "Invalid request body" };
17769
17895
  }
17896
+ const rawUrl = typeof request.raw?.url === "string" ? request.raw.url : request.url ?? "";
17897
+ let querySuffix = null;
17898
+ if (typeof rawUrl === "string") {
17899
+ const questionIndex = rawUrl.indexOf("?");
17900
+ if (questionIndex !== -1) {
17901
+ querySuffix = rawUrl.slice(questionIndex + 1);
17902
+ }
17903
+ }
17904
+ if (!querySuffix && typeof request.querystring === "string") {
17905
+ querySuffix = request.querystring || null;
17906
+ }
17907
+ const providerHeaders = {};
17908
+ const headersToForward = [
17909
+ "anthropic-version",
17910
+ "anthropic-beta",
17911
+ "x-stainless-arch",
17912
+ "x-stainless-async",
17913
+ "x-stainless-lang",
17914
+ "x-stainless-os",
17915
+ "x-stainless-package-version",
17916
+ "x-stainless-runtime",
17917
+ "x-stainless-runtime-version"
17918
+ ];
17919
+ for (const key of headersToForward) {
17920
+ const value = request.headers[key];
17921
+ if (typeof value === "string" && value.length > 0) {
17922
+ providerHeaders[key] = value;
17923
+ } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
17924
+ providerHeaders[key] = value[0];
17925
+ }
17926
+ }
17770
17927
  const providedApiKey = extractApiKeyFromRequest2(request);
17771
17928
  let apiKeyContext;
17772
17929
  try {
@@ -17863,7 +18020,9 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
17863
18020
  const upstream = await connector.send({
17864
18021
  model: target.modelId,
17865
18022
  body: providerBody,
17866
- stream: normalized.stream
18023
+ stream: normalized.stream,
18024
+ query: querySuffix,
18025
+ headers: providerHeaders
17867
18026
  });
17868
18027
  if (upstream.status >= 400) {
17869
18028
  reply.code(upstream.status);
@@ -17882,12 +18041,12 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
17882
18041
  const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
17883
18042
  const content = json?.response?.body?.content ?? json?.choices?.[0]?.message?.content ?? "";
17884
18043
  const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(content, target.modelId);
17885
- const cachedTokens = resolveCachedTokens3(usagePayload);
18044
+ const cachedTokens2 = resolveCachedTokens3(usagePayload);
17886
18045
  const latencyMs2 = Date.now() - requestStart;
17887
18046
  await updateLogTokens(logId, {
17888
18047
  inputTokens: inputTokens2,
17889
18048
  outputTokens: outputTokens2,
17890
- cachedTokens,
18049
+ cachedTokens: cachedTokens2,
17891
18050
  ttftMs: latencyMs2,
17892
18051
  tpotMs: computeTpot3(latencyMs2, outputTokens2, { streaming: false })
17893
18052
  });
@@ -17896,6 +18055,7 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
17896
18055
  requests: 1,
17897
18056
  inputTokens: inputTokens2,
17898
18057
  outputTokens: outputTokens2,
18058
+ cachedTokens: cachedTokens2,
17899
18059
  latencyMs: latencyMs2
17900
18060
  });
17901
18061
  if (storeResponsePayloads) {
@@ -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-CMmlZ8am.js";import{u as N}from"./useApiQuery-qpXuOM9g.js";import{P as w,a as d}from"./PageSection-819eIHwY.js";import"./Input-AVaeYH0J.js";import{B as b}from"./Button-3qj8BOTb.js";import{I as y}from"./info-Cg4yNF4Z.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-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";/**
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-CMmlZ8am.
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.0",_={version:I},L={VITE_BUILD_TIME:"2025-10-25T06:44:24.223Z",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.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};
@@ -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-CMmlZ8am.js";import{E as le}from"./index-D4f4GIYb.js";import{u as w}from"./useApiQuery-qpXuOM9g.js";import{P as ie,a as q}from"./PageSection-819eIHwY.js";import{F as I}from"./FormField-DmKxUoqD.js";import{I as re}from"./Input-AVaeYH0J.js";import{B as C}from"./Button-3qj8BOTb.js";import{S as ne}from"./StatusBadge-FIJj_rsA.js";import{C as ce}from"./copy-dJsIfcXG.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-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";/**
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-CMmlZ8am.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-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};