@jeffreycao/copilot-api 2.7.12 → 2.7.14
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.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{auth-K4YwtW2M.js → auth--x4CIFvT.js} +4 -4
- package/dist/{auth-K4YwtW2M.js.map → auth--x4CIFvT.js.map} +1 -1
- package/dist/auth-1hGXVwvW.js +2 -0
- package/dist/{config-Cs3Ol5sJ.js → config-BKA4Y1t8.js} +2 -2
- package/dist/{config-Cs3Ol5sJ.js.map → config-BKA4Y1t8.js.map} +1 -1
- package/dist/{config-store-C6GAtKLz.js → config-store-CC5TNG7V.js} +2 -2
- package/dist/{config-store-C6GAtKLz.js.map → config-store-CC5TNG7V.js.map} +1 -1
- package/dist/{copilot-runtime-DhtRP9zU.js → copilot-runtime-CW4zUahm.js} +3 -3
- package/dist/{copilot-runtime-DhtRP9zU.js.map → copilot-runtime-CW4zUahm.js.map} +1 -1
- package/dist/{debug-B7hUvJa4.js → debug-BPNjSHgl.js} +3 -3
- package/dist/{debug-B7hUvJa4.js.map → debug-BPNjSHgl.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{provider-CzziTLqX.js → provider-Dg-3-rrN.js} +2 -2
- package/dist/{provider-CzziTLqX.js.map → provider-Dg-3-rrN.js.map} +1 -1
- package/dist/{provider-management-DOfLC7WX.js → provider-management-CBrc2nDg.js} +2 -2
- package/dist/{provider-management-DOfLC7WX.js.map → provider-management-CBrc2nDg.js.map} +1 -1
- package/dist/{server-DBfAMzVE.js → server-CeyKV5sQ.js} +93 -22
- package/dist/server-CeyKV5sQ.js.map +1 -0
- package/dist/{start-BNzCkjva.js → start-COhhmcdU.js} +7 -7
- package/dist/{start-BNzCkjva.js.map → start-COhhmcdU.js.map} +1 -1
- package/dist/{token-C7R7Vd9b.js → token-BdwhXP3l.js} +3 -3
- package/dist/{token-C7R7Vd9b.js.map → token-BdwhXP3l.js.map} +1 -1
- package/package.json +1 -1
- package/pages/index.html +115 -10
- package/dist/auth-B_zdWSA1.js +0 -2
- package/dist/server-DBfAMzVE.js.map +0 -1
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.7.
|
|
4
|
+
"version": "2.7.14",
|
|
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
|
@@ -672,6 +672,7 @@
|
|
|
672
672
|
};
|
|
673
673
|
|
|
674
674
|
// --- State Management ---
|
|
675
|
+
const SESSION_PAGE_SIZE = 10;
|
|
675
676
|
const state = {
|
|
676
677
|
activeTab: "usage",
|
|
677
678
|
models: null,
|
|
@@ -687,6 +688,10 @@
|
|
|
687
688
|
data: null,
|
|
688
689
|
tokenUsageDailySummary: null,
|
|
689
690
|
tokenUsageSummary: null,
|
|
691
|
+
tokenUsageSessionsPage: null,
|
|
692
|
+
isSessionsLoading: false,
|
|
693
|
+
sessionsRequestId: 0,
|
|
694
|
+
tokenUsageSessionsError: null,
|
|
690
695
|
tokenUsageEventsPage: null,
|
|
691
696
|
tokenUsageDailyError: null,
|
|
692
697
|
tokenUsageSummaryError: null,
|
|
@@ -939,15 +944,24 @@
|
|
|
939
944
|
return url.toString();
|
|
940
945
|
}
|
|
941
946
|
|
|
942
|
-
function buildTokenUsageEventsUrl(
|
|
947
|
+
function buildTokenUsageEventsUrl(
|
|
948
|
+
usageEndpoint,
|
|
949
|
+
period,
|
|
950
|
+
page,
|
|
951
|
+
kind = "events"
|
|
952
|
+
) {
|
|
943
953
|
const url = new URL(
|
|
944
|
-
deriveEndpointUrl(usageEndpoint,
|
|
954
|
+
deriveEndpointUrl(usageEndpoint, `token-usage/${kind}`)
|
|
945
955
|
);
|
|
946
956
|
url.searchParams.set("period", period);
|
|
947
957
|
url.searchParams.set("page", String(page));
|
|
948
958
|
url.searchParams.set(
|
|
949
959
|
"page_size",
|
|
950
|
-
String(
|
|
960
|
+
String(
|
|
961
|
+
kind === "sessions"
|
|
962
|
+
? SESSION_PAGE_SIZE
|
|
963
|
+
: DEFAULT_TOKEN_USAGE_EVENTS_PAGE_SIZE
|
|
964
|
+
)
|
|
951
965
|
);
|
|
952
966
|
return url.toString();
|
|
953
967
|
}
|
|
@@ -1635,6 +1649,7 @@
|
|
|
1635
1649
|
const summary = state.tokenUsageSummary;
|
|
1636
1650
|
const dailySummary = state.tokenUsageDailySummary;
|
|
1637
1651
|
const eventsPage = state.tokenUsageEventsPage;
|
|
1652
|
+
const sessionsPage = state.tokenUsageSessionsPage;
|
|
1638
1653
|
const totals = summary?.totals || EMPTY_TOKEN_USAGE_TOTALS;
|
|
1639
1654
|
const activeRange =
|
|
1640
1655
|
summary?.range || dailySummary?.range || eventsPage?.range || null;
|
|
@@ -1783,6 +1798,28 @@
|
|
|
1783
1798
|
${renderTokenUsageModelBreakdown(summary)}
|
|
1784
1799
|
</div>
|
|
1785
1800
|
|
|
1801
|
+
<div class="panel">
|
|
1802
|
+
<div class="panel-header">
|
|
1803
|
+
<div>
|
|
1804
|
+
<p class="panel-title">Session Breakdown</p>
|
|
1805
|
+
<p class="panel-meta">${sessionsPage ? `Page ${sessionsPage.page} / ${sessionsPage.total_pages} - ${formatNumber(sessionsPage.total)} sessions` : "No session rows loaded."}</p>
|
|
1806
|
+
</div>
|
|
1807
|
+
<div class="flex items-center gap-2">
|
|
1808
|
+
<button type="button" data-session-page="-1" class="pill-button px-3 py-1.5 text-xs font-semibold" ${!sessionsPage || state.isSessionsLoading || sessionsPage.page <= 1 ? "disabled" : ""}>Previous</button>
|
|
1809
|
+
<button type="button" data-session-page="1" class="pill-button px-3 py-1.5 text-xs font-semibold" ${!sessionsPage || state.isSessionsLoading || sessionsPage.page >= sessionsPage.total_pages ? "disabled" : ""}>Next</button>
|
|
1810
|
+
</div>
|
|
1811
|
+
</div>
|
|
1812
|
+
${
|
|
1813
|
+
state.tokenUsageSessionsError
|
|
1814
|
+
? `<div class="p-4">${renderError(
|
|
1815
|
+
state.tokenUsageSessionsError,
|
|
1816
|
+
"Session breakdown failed"
|
|
1817
|
+
)}<button type="button" data-session-page="0" class="pill-button mt-2 px-3 py-1.5 text-xs font-semibold">Retry</button></div>`
|
|
1818
|
+
: ""
|
|
1819
|
+
}
|
|
1820
|
+
${renderTokenUsageModelBreakdown({ bySession: sessionsPage?.items }, "session")}
|
|
1821
|
+
</div>
|
|
1822
|
+
|
|
1786
1823
|
<div class="panel">
|
|
1787
1824
|
<div class="panel-header flex-col items-start sm:flex-row sm:items-center">
|
|
1788
1825
|
<div>
|
|
@@ -2248,20 +2285,22 @@
|
|
|
2248
2285
|
`;
|
|
2249
2286
|
}
|
|
2250
2287
|
|
|
2251
|
-
function renderTokenUsageModelBreakdown(summary) {
|
|
2252
|
-
|
|
2288
|
+
function renderTokenUsageModelBreakdown(summary, by = "model") {
|
|
2289
|
+
const items = by === "session" ? summary?.bySession : summary?.byModel;
|
|
2290
|
+
if (!items || items.length === 0) {
|
|
2253
2291
|
return renderEmptyState(
|
|
2254
2292
|
"No token usage recorded for the selected period."
|
|
2255
2293
|
);
|
|
2256
2294
|
}
|
|
2257
2295
|
|
|
2258
|
-
const rows =
|
|
2296
|
+
const rows = items
|
|
2259
2297
|
.map((model) => {
|
|
2298
|
+
const name = formatCellText(by === "session" ? model.session_id : model.model);
|
|
2260
2299
|
return `
|
|
2261
2300
|
<tr class="border-b last:border-b-0" style="border-color: var(--color-bg-light-1);">
|
|
2262
|
-
<td class="px-4 py-2 max-w-[280px] truncate" style="color: var(--color-fg-lightest);" title="${escapeHtml(
|
|
2263
|
-
|
|
2264
|
-
)}">${escapeHtml(
|
|
2301
|
+
<td class="px-4 py-2 max-w-[280px] truncate${by === "session" ? " font-mono" : ""}" style="color: var(--color-fg-lightest);" title="${escapeHtml(
|
|
2302
|
+
name
|
|
2303
|
+
)}">${escapeHtml(name)}</td>
|
|
2265
2304
|
<td class="px-4 py-2 text-right" style="color: var(--color-fg-dark);">${formatNumber(
|
|
2266
2305
|
model.request_count
|
|
2267
2306
|
)}</td>
|
|
@@ -2296,7 +2335,7 @@
|
|
|
2296
2335
|
<table class="data-table min-w-[960px] text-left">
|
|
2297
2336
|
<thead>
|
|
2298
2337
|
<tr>
|
|
2299
|
-
<th class="px-4 py-2 font-semibold"
|
|
2338
|
+
<th class="px-4 py-2 font-semibold">${by === "session" ? "Session" : "Model"}</th>
|
|
2300
2339
|
<th class="px-4 py-2 text-right font-semibold">Requests</th>
|
|
2301
2340
|
<th class="px-4 py-2 text-right font-semibold">Input</th>
|
|
2302
2341
|
<th class="px-4 py-2 text-right font-semibold">Output</th>
|
|
@@ -2473,6 +2512,7 @@
|
|
|
2473
2512
|
* Fetches usage data and token usage data from the specified API endpoint.
|
|
2474
2513
|
*/
|
|
2475
2514
|
async function fetchData(page = 1) {
|
|
2515
|
+
invalidateSessionsRequest();
|
|
2476
2516
|
const endpoint = endpointUrlInput.value.trim();
|
|
2477
2517
|
if (!endpoint) {
|
|
2478
2518
|
state.data = null;
|
|
@@ -2516,6 +2556,7 @@
|
|
|
2516
2556
|
|
|
2517
2557
|
if (summaryResult.status === "fulfilled") {
|
|
2518
2558
|
state.tokenUsageSummary = summaryResult.value;
|
|
2559
|
+
void fetchTokenUsageSessionsPage(1);
|
|
2519
2560
|
} else if (
|
|
2520
2561
|
isMissingTokenUsageEndpointError(summaryResult.reason)
|
|
2521
2562
|
) {
|
|
@@ -2572,6 +2613,7 @@
|
|
|
2572
2613
|
}
|
|
2573
2614
|
|
|
2574
2615
|
async function fetchTokenUsageSummaryAndEvents(page = 1) {
|
|
2616
|
+
invalidateSessionsRequest();
|
|
2575
2617
|
const endpoint = endpointUrlInput.value.trim();
|
|
2576
2618
|
if (!endpoint) {
|
|
2577
2619
|
state.tokenUsageDailySummary = null;
|
|
@@ -2607,6 +2649,7 @@
|
|
|
2607
2649
|
|
|
2608
2650
|
if (summaryResult.status === "fulfilled") {
|
|
2609
2651
|
state.tokenUsageSummary = summaryResult.value;
|
|
2652
|
+
void fetchTokenUsageSessionsPage(1);
|
|
2610
2653
|
} else if (
|
|
2611
2654
|
isMissingTokenUsageEndpointError(summaryResult.reason)
|
|
2612
2655
|
) {
|
|
@@ -2692,6 +2735,56 @@
|
|
|
2692
2735
|
}
|
|
2693
2736
|
}
|
|
2694
2737
|
|
|
2738
|
+
async function fetchTokenUsageSessionsPage(page) {
|
|
2739
|
+
const endpoint = endpointUrlInput.value.trim();
|
|
2740
|
+
if (!endpoint) {
|
|
2741
|
+
return;
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
const requestId = ++state.sessionsRequestId;
|
|
2745
|
+
state.isSessionsLoading = true;
|
|
2746
|
+
state.tokenUsageSessionsError = null;
|
|
2747
|
+
render();
|
|
2748
|
+
|
|
2749
|
+
try {
|
|
2750
|
+
const result = await fetchJson(
|
|
2751
|
+
buildTokenUsageEventsUrl(
|
|
2752
|
+
resolveUsageUrl(endpoint),
|
|
2753
|
+
getSelectedPeriod(),
|
|
2754
|
+
page,
|
|
2755
|
+
"sessions"
|
|
2756
|
+
)
|
|
2757
|
+
);
|
|
2758
|
+
if (requestId !== state.sessionsRequestId) {
|
|
2759
|
+
return;
|
|
2760
|
+
}
|
|
2761
|
+
state.tokenUsageSessionsPage = result;
|
|
2762
|
+
} catch (error) {
|
|
2763
|
+
if (requestId !== state.sessionsRequestId) {
|
|
2764
|
+
return;
|
|
2765
|
+
}
|
|
2766
|
+
// Older servers have no sessions endpoint; show the empty state.
|
|
2767
|
+
if (isMissingTokenUsageEndpointError(error)) {
|
|
2768
|
+
state.tokenUsageSessionsPage = null;
|
|
2769
|
+
} else {
|
|
2770
|
+
console.error("Token usage sessions fetch error:", error);
|
|
2771
|
+
state.tokenUsageSessionsError = getErrorMessage(error);
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
state.isSessionsLoading = false;
|
|
2776
|
+
render("usage");
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
// Clears sessions when refreshing the endpoint or period and ignores
|
|
2780
|
+
// late responses from the previous context.
|
|
2781
|
+
function invalidateSessionsRequest() {
|
|
2782
|
+
state.sessionsRequestId += 1;
|
|
2783
|
+
state.isSessionsLoading = false;
|
|
2784
|
+
state.tokenUsageSessionsPage = null;
|
|
2785
|
+
state.tokenUsageSessionsError = null;
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2695
2788
|
// --- Event Handlers & Initialization ---
|
|
2696
2789
|
|
|
2697
2790
|
/**
|
|
@@ -2753,6 +2846,18 @@
|
|
|
2753
2846
|
return;
|
|
2754
2847
|
}
|
|
2755
2848
|
|
|
2849
|
+
const sessionButton = event.target.closest("[data-session-page]");
|
|
2850
|
+
if (sessionButton) {
|
|
2851
|
+
if (!state.isSessionsLoading) {
|
|
2852
|
+
// Offset 0 is the error retry button: reload the current page.
|
|
2853
|
+
void fetchTokenUsageSessionsPage(
|
|
2854
|
+
(state.tokenUsageSessionsPage?.page ?? 1)
|
|
2855
|
+
+ Number(sessionButton.getAttribute("data-session-page"))
|
|
2856
|
+
);
|
|
2857
|
+
}
|
|
2858
|
+
return;
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2756
2861
|
const actionButton = event.target.closest("[data-page-action]");
|
|
2757
2862
|
if (!actionButton || !state.tokenUsageEventsPage || state.isEventsLoading) {
|
|
2758
2863
|
return;
|
package/dist/auth-B_zdWSA1.js
DELETED