@jeffreycao/copilot-api 2.6.31 → 2.6.33

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 (2) hide show
  1. package/package.json +1 -1
  2. package/pages/index.html +74 -14
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@jeffreycao/copilot-api",
4
- "version": "2.6.31",
4
+ "version": "2.6.33",
5
5
  "description": "GitHub Copilot, OpenAI Codex, OpenCode Go, and third-party AI provider gateway with OpenAI and Anthropic API compatibility.",
6
6
  "keywords": [
7
7
  "github-copilot",
package/pages/index.html CHANGED
@@ -349,7 +349,11 @@
349
349
  }
350
350
 
351
351
  .metric-grid-tight {
352
- grid-template-columns: repeat(7, minmax(0, 1fr));
352
+ grid-template-columns: repeat(6, minmax(0, 1fr));
353
+ }
354
+
355
+ .metric-grid-tight .metric-label {
356
+ white-space: nowrap;
353
357
  }
354
358
 
355
359
  .metric-card {
@@ -468,9 +472,9 @@
468
472
  gap: 10px;
469
473
  }
470
474
 
471
- @media (max-width: 1280px) {
475
+ @media (max-width: 899px) {
472
476
  .metric-grid-tight {
473
- grid-template-columns: repeat(4, minmax(0, 1fr));
477
+ grid-template-columns: repeat(3, minmax(0, 1fr));
474
478
  }
475
479
  }
476
480
 
@@ -488,7 +492,7 @@
488
492
  }
489
493
  }
490
494
 
491
- @media (max-width: 640px) {
495
+ @media (max-width: 639px) {
492
496
  .main-shell {
493
497
  padding: 12px 14px 18px;
494
498
  }
@@ -1035,6 +1039,16 @@
1035
1039
  return Number.isFinite(value) ? Number(value).toLocaleString() : "0";
1036
1040
  }
1037
1041
 
1042
+ function formatCacheHitRate(usage) {
1043
+ const inputTokens =
1044
+ usage.input_tokens +
1045
+ usage.cache_read_input_tokens +
1046
+ usage.cache_creation_input_tokens;
1047
+ return inputTokens > 0
1048
+ ? `${((usage.cache_read_input_tokens / inputTokens) * 100).toFixed(1)}%`
1049
+ : "—";
1050
+ }
1051
+
1038
1052
  function getMetricDisplayText(value) {
1039
1053
  return typeof value === "number" ? formatNumber(value) : value;
1040
1054
  }
@@ -1468,11 +1482,30 @@
1468
1482
  * @param {object} details - The details object for the quota.
1469
1483
  * @returns {string} HTML string for a single card.
1470
1484
  */
1485
+ function getCopilotQuotaRemaining(details) {
1486
+ if (Number.isFinite(details.remaining)) return details.remaining;
1487
+ if (Number.isFinite(details.quota_remaining)) {
1488
+ return details.quota_remaining;
1489
+ }
1490
+ return null;
1491
+ }
1492
+
1493
+ function getCopilotQuotaPercentRemaining(details) {
1494
+ if (details.unlimited) return 100;
1495
+ const percent = Number.isFinite(details.percent_remaining)
1496
+ ? details.percent_remaining
1497
+ : Number.isFinite(details.entitlement) && details.entitlement > 0
1498
+ ? ((getCopilotQuotaRemaining(details) ?? details.entitlement) /
1499
+ details.entitlement) * 100
1500
+ : 100;
1501
+ return Math.max(0, Math.min(100, percent));
1502
+ }
1503
+
1471
1504
  function renderQuotaCard(title, details) {
1472
- const { entitlement, remaining, percent_remaining, unlimited } =
1473
- details;
1505
+ const { entitlement, unlimited } = details;
1506
+ const remaining = getCopilotQuotaRemaining(details) ?? 0;
1474
1507
 
1475
- const percentUsed = unlimited ? 0 : 100 - percent_remaining;
1508
+ const percentUsed = 100 - getCopilotQuotaPercentRemaining(details);
1476
1509
  const used = unlimited
1477
1510
  ? "N/A"
1478
1511
  : (entitlement - remaining).toLocaleString();
@@ -1658,9 +1691,13 @@
1658
1691
  getMetricDisplayText(totals.output_tokens),
1659
1692
  getMetricDisplayText(totals.cache_read_input_tokens),
1660
1693
  getMetricDisplayText(totals.cache_creation_input_tokens),
1694
+ formatCacheHitRate(totals),
1661
1695
  getMetricDisplayText(totals.request_count),
1662
1696
  formatTokenUsageCosts(totals.costs),
1663
1697
  ]);
1698
+ const costCurrencies = [
1699
+ ...new Set(totals.costs.map((cost) => cost.currency)),
1700
+ ];
1664
1701
  return [
1665
1702
  renderTokenUsageMetric(
1666
1703
  "Total",
@@ -1692,18 +1729,39 @@
1692
1729
  "var(--color-yellow-accent)",
1693
1730
  metricFontSize
1694
1731
  ),
1732
+ renderTokenUsageMetric(
1733
+ "Cache Hit Rate",
1734
+ formatCacheHitRate(totals),
1735
+ "var(--color-aqua-accent)",
1736
+ metricFontSize
1737
+ ),
1695
1738
  renderTokenUsageMetric(
1696
1739
  "Requests",
1697
1740
  totals.request_count,
1698
1741
  "var(--color-purple-accent)",
1699
1742
  metricFontSize
1700
1743
  ),
1701
- renderTokenUsageCostMetric(
1702
- "Cost",
1703
- formatTokenUsageCosts(totals.costs),
1704
- "var(--color-yellow-accent)",
1705
- metricFontSize
1706
- ),
1744
+ ...(costCurrencies.length > 0
1745
+ ? costCurrencies.map((currency) =>
1746
+ renderTokenUsageCostMetric(
1747
+ `Cost (${currency})`,
1748
+ formatTokenUsageCost(
1749
+ totals.costs.find(
1750
+ (cost) => cost.currency === currency
1751
+ )
1752
+ ),
1753
+ "var(--color-yellow-accent)",
1754
+ metricFontSize
1755
+ )
1756
+ )
1757
+ : [
1758
+ renderTokenUsageCostMetric(
1759
+ "Cost",
1760
+ formatTokenUsageCosts(totals.costs),
1761
+ "var(--color-yellow-accent)",
1762
+ metricFontSize
1763
+ ),
1764
+ ]),
1707
1765
  ].join("");
1708
1766
  })()
1709
1767
  }
@@ -2219,6 +2277,7 @@
2219
2277
  <td class="px-4 py-2 text-right" style="color: var(--color-fg-dark);">${formatNumber(
2220
2278
  model.cache_creation_input_tokens
2221
2279
  )}</td>
2280
+ <td class="px-4 py-2 text-right" style="color: var(--color-fg-dark);">${formatCacheHitRate(model)}</td>
2222
2281
  <td class="px-4 py-2 text-right font-semibold" style="color: var(--color-yellow-accent);">${formatNumber(
2223
2282
  model.total_tokens
2224
2283
  )}</td>
@@ -2234,7 +2293,7 @@
2234
2293
 
2235
2294
  return `
2236
2295
  <div class="overflow-auto ${state.isTokenUsageLoading ? "opacity-60" : ""}">
2237
- <table class="data-table min-w-[860px] text-left">
2296
+ <table class="data-table min-w-[960px] text-left">
2238
2297
  <thead>
2239
2298
  <tr>
2240
2299
  <th class="px-4 py-2 font-semibold">Model</th>
@@ -2243,6 +2302,7 @@
2243
2302
  <th class="px-4 py-2 text-right font-semibold">Output</th>
2244
2303
  <th class="px-4 py-2 text-right font-semibold">Cache Read</th>
2245
2304
  <th class="px-4 py-2 text-right font-semibold">Cache Write</th>
2305
+ <th class="px-4 py-2 text-right font-semibold">Cache Hit Rate</th>
2246
2306
  <th class="px-4 py-2 text-right font-semibold">Total Tokens</th>
2247
2307
  <th class="px-4 py-2 text-right font-semibold">Total Cost</th>
2248
2308
  </tr>