@jeffreycao/copilot-api 2.7.39 → 2.7.40
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/dist/auth-BVjOyO_F.js +1 -0
- package/dist/{auth-DBOz2FcU.js → auth-ByQjInU9.js} +2 -2
- package/dist/{auth-DBOz2FcU.js.map → auth-ByQjInU9.js.map} +1 -1
- package/dist/{copilot-runtime-0CujVONa.js → copilot-runtime-D6YjAamL.js} +2 -2
- package/dist/{copilot-runtime-0CujVONa.js.map → copilot-runtime-D6YjAamL.js.map} +1 -1
- package/dist/main.js +2 -2
- package/dist/{server-Jvc5DYJV.js → server-DhHL2SxL.js} +329 -7
- package/dist/{server-Jvc5DYJV.js.map → server-DhHL2SxL.js.map} +1 -1
- package/dist/{start-BQBvYKD-.js → start-CxJBWBbt.js} +5 -5
- package/dist/{start-BQBvYKD-.js.map → start-CxJBWBbt.js.map} +1 -1
- package/dist/{token-_1CBLbqH.js → token-CNWvfwYi.js} +7 -4
- package/dist/{token-_1CBLbqH.js.map → token-CNWvfwYi.js.map} +1 -1
- package/package.json +1 -1
- package/pages/index.html +304 -325
- package/dist/auth-IiEbOqcu.js +0 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { D as state, E as isGitHubCopilotEnabled, O as HTTPError, S as PATHS, a as getAnthropicApiKey, c as getConfig, d as getUpstreamTransportConfig, g as isResponsesApiWebSocketEnabled, h as isResponsesApiWebSearchEnabled, i as getAlphaSearchModel, j as forwardError, l as getMessageApiWebSearchModel, m as isMessagesApiEnabled, o as getClaudeAutoModel, p as isAlphaSearchCodexPriorityEnabled, s as getClaudeTokenMultiplier, u as getOpencodeModelContextWindow, w as GITHUB_COPILOT_PROVIDER, y as reloadConfig } from "./config-store-BsluQttR.js";
|
|
2
2
|
import { A as resolveMappedModel, C as getModelResponsesApiCompactThreshold$1, D as isContextManagementEnabledForMessages, E as getSmallModelForProvider, O as isContextManagementEnabledForResponses, S as getModelMappings, T as getSmallModel, _ as getModelsDevModelMaxOutputTokens, a as normalizeProviderBaseUrl, d as isProviderModelVisible, f as resolveProviderModelsDevId, g as getModelsDevModel, h as getBuiltinProviderModelRecords, i as listEnabledProviders, j as setModelMappings, k as isGpt56OrAbove, l as getLocalProviderModelRecords, m as builtinProviderModelRegistry, n as getRawProviderConfig, o as resolveEffectiveProviderType, p as usesModelsDevModelCatalog, s as resolveProviderConfigForModel, t as getProviderConfig, u as getProviderModelConfig, v as getModelsDevModelPricing, w as getReasoningEffortForModel, x as getExtraPromptForModel } from "./config-BqSuE5h5.js";
|
|
3
|
-
import { $ as
|
|
3
|
+
import { $ as buildCodexRequestHeaders, B as getXaiAccessToken, C as copilotHeaders, D as prepareForCompact, E as isOpencodeOauthApp, F as compactTextOnlyGuard, I as createAuthMiddleware, J as readGitHubTokenFromEnv, L as getConfiguredAdminApiKeys, M as compactMessageSections, O as prepareInteractionHeaders, P as compactSystemPromptStarts, Q as CODEX_API_BASE_URL, S as copilotBaseUrl, T as copilotWebSocketHeaders, U as readXaiCredentials, Y as XAI_API_BASE_URL, _ as isAsyncIterable, at as fetchUpstreamWithLifecycle, b as parseUserIdMetadata, ct as encodePoolKeyPart, d as generateRequestIdFromPayload, dt as createWebSocketUrl, et as forwardCodexResponses, f as getPromptCacheKey, g as getUUID, h as getSessionAffinityFromHeaders, it as setPluginRequestActualModel, j as compactAutoContinuePromptStarts, k as prepareMessageProxyHeaders, lt as getResponsesStreamTerminalDisposition, m as getRootSessionIdFromHeaders, n as invalidateCodexRuntime, nt as requestContext, ot as createResponsesHttpEventStream, p as getRootSessionId, pt as stripInternalRequestHeaders, q as readGitHubToken, rt as resolveTraceId$1, s as setupCodexToken, st as createResponsesSafeStream, tt as generateTraceId, u as stopCopilotRefreshLoop, ut as createPooledWebSocketStream, v as isNullish, x as getCopilotUsage, y as isResponsesStream } from "./token-CNWvfwYi.js";
|
|
4
4
|
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-DzipwtCX.js";
|
|
5
5
|
import { n as isProviderAgentModelVisible, t as getProviderAgentModels } from "./provider-management-vyEQj9RR.js";
|
|
6
|
-
import { i as registerProcessCleanup, n as stopModelsRefreshLoop, r as EventBus, t as setupCopilotRuntime } from "./copilot-runtime-
|
|
6
|
+
import { i as registerProcessCleanup, n as stopModelsRefreshLoop, r as EventBus, t as setupCopilotRuntime } from "./copilot-runtime-D6YjAamL.js";
|
|
7
7
|
import consola from "consola";
|
|
8
8
|
import { createHash, randomUUID } from "node:crypto";
|
|
9
9
|
import fs, { readFileSync } from "node:fs";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import fs$1 from "node:fs/promises";
|
|
12
|
+
import os from "node:os";
|
|
12
13
|
import { fetch as fetch$1, getGlobalDispatcher } from "undici";
|
|
13
14
|
import { events } from "fetch-event-stream";
|
|
14
15
|
import { z } from "zod";
|
|
@@ -9828,11 +9829,11 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
9828
9829
|
recordAnthropicFirstToken(parsedEvent);
|
|
9829
9830
|
if (parsedEvent?.type === "message_start") usage = mergeAnthropicUsage(usage, {
|
|
9830
9831
|
...normalizeAnthropicUsage(parsedEvent.message.usage),
|
|
9831
|
-
...normalizeCopilotUsage(parsedEvent.message.copilot_usage)
|
|
9832
|
+
...normalizeCopilotUsage$1(parsedEvent.message.copilot_usage)
|
|
9832
9833
|
});
|
|
9833
9834
|
else if (parsedEvent?.type === "message_delta") usage = mergeAnthropicUsage(usage, {
|
|
9834
9835
|
...normalizeAnthropicUsage(parsedEvent.usage),
|
|
9835
|
-
...normalizeCopilotUsage(parsedEvent.copilot_usage)
|
|
9836
|
+
...normalizeCopilotUsage$1(parsedEvent.copilot_usage)
|
|
9836
9837
|
});
|
|
9837
9838
|
if (parsedEvent?.type === "message_stop" || eventName === "message_stop") messageStopSeen = true;
|
|
9838
9839
|
else if (parsedEvent?.type === "error" || eventName === "error") errorSeen = true;
|
|
@@ -9861,7 +9862,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
9861
9862
|
});
|
|
9862
9863
|
recordUsage({
|
|
9863
9864
|
...normalizeAnthropicUsage(response.usage),
|
|
9864
|
-
...normalizeCopilotUsage(response.copilot_usage)
|
|
9865
|
+
...normalizeCopilotUsage$1(response.copilot_usage)
|
|
9865
9866
|
});
|
|
9866
9867
|
return c.json(response);
|
|
9867
9868
|
};
|
|
@@ -9893,7 +9894,7 @@ const createCopilotUsageRecorder = (options) => createCopilotTokenUsageRecorder(
|
|
|
9893
9894
|
sessionId: getMetadataSessionId(options.payload)
|
|
9894
9895
|
});
|
|
9895
9896
|
const getMetadataSessionId = (payload) => parseUserIdMetadata(payload.metadata?.user_id).sessionId;
|
|
9896
|
-
const normalizeCopilotUsage = (copilotUsage) => ({ total_nano_aiu: normalizeOptionalToken(copilotUsage?.total_nano_aiu) });
|
|
9897
|
+
const normalizeCopilotUsage$1 = (copilotUsage) => ({ total_nano_aiu: normalizeOptionalToken(copilotUsage?.total_nano_aiu) });
|
|
9897
9898
|
const parseAnthropicStreamEvent = (data) => {
|
|
9898
9899
|
try {
|
|
9899
9900
|
return JSON.parse(data);
|
|
@@ -13947,8 +13948,329 @@ function parsePageQuery(c) {
|
|
|
13947
13948
|
}
|
|
13948
13949
|
tokenUsageRoute.get("/events", async (c) => c.json(await getTokenUsageEventsPage(parsePageQuery(c))));
|
|
13949
13950
|
tokenUsageRoute.get("/sessions", async (c) => c.json(await getTokenUsageSessionsPage(parsePageQuery(c))));
|
|
13951
|
+
// src/services/subscription-usage.ts
|
|
13952
|
+
const CODEX_CLI_VERSION = "0.164.0";
|
|
13953
|
+
const amount = z.union([z.number().finite(), z.string().trim().min(1).refine((value) => Number.isFinite(Number(value)))]).transform(Number);
|
|
13954
|
+
const number = z.number().finite();
|
|
13955
|
+
const codexWindow = z.object({
|
|
13956
|
+
used_percent: number,
|
|
13957
|
+
limit_window_seconds: number.nullish(),
|
|
13958
|
+
reset_at: number.nullish(),
|
|
13959
|
+
reset_after_seconds: number.nullish()
|
|
13960
|
+
});
|
|
13961
|
+
const codexRateLimit = z.object({
|
|
13962
|
+
allowed: z.boolean().nullish(),
|
|
13963
|
+
limit_reached: z.boolean().nullish(),
|
|
13964
|
+
primary_window: codexWindow.nullish(),
|
|
13965
|
+
secondary_window: codexWindow.nullish()
|
|
13966
|
+
});
|
|
13967
|
+
const codexUsage = z.object({
|
|
13968
|
+
plan_type: z.string(),
|
|
13969
|
+
rate_limit: codexRateLimit.nullish(),
|
|
13970
|
+
additional_rate_limits: z.array(z.object({
|
|
13971
|
+
limit_name: z.string(),
|
|
13972
|
+
metered_feature: z.string(),
|
|
13973
|
+
rate_limit: codexRateLimit.nullish()
|
|
13974
|
+
})).nullish(),
|
|
13975
|
+
credits: z.object({
|
|
13976
|
+
has_credits: z.boolean(),
|
|
13977
|
+
unlimited: z.boolean(),
|
|
13978
|
+
balance: amount.nullish()
|
|
13979
|
+
}).nullish(),
|
|
13980
|
+
spend_control: z.object({
|
|
13981
|
+
reached: z.boolean(),
|
|
13982
|
+
individual_limit: z.object({
|
|
13983
|
+
limit: amount,
|
|
13984
|
+
used: amount,
|
|
13985
|
+
used_percent: number,
|
|
13986
|
+
reset_at: number.nullish(),
|
|
13987
|
+
reset_after_seconds: number.nullish()
|
|
13988
|
+
}).nullish()
|
|
13989
|
+
}).nullish(),
|
|
13990
|
+
rate_limit_reached_type: z.object({ type: z.string() }).nullish()
|
|
13991
|
+
});
|
|
13992
|
+
const cents = z.object({ val: amount.default(0) }).nullish();
|
|
13993
|
+
const xaiUsage = z.object({
|
|
13994
|
+
config: z.object({
|
|
13995
|
+
creditUsagePercent: number.nullish(),
|
|
13996
|
+
currentPeriod: z.object({
|
|
13997
|
+
type: z.string().nullish(),
|
|
13998
|
+
end: z.string().nullish()
|
|
13999
|
+
}).nullish(),
|
|
14000
|
+
monthlyLimit: cents,
|
|
14001
|
+
used: cents,
|
|
14002
|
+
onDemandCap: cents,
|
|
14003
|
+
onDemandUsed: cents,
|
|
14004
|
+
prepaidBalance: cents,
|
|
14005
|
+
billingPeriodEnd: z.string().nullish()
|
|
14006
|
+
}).nullish(),
|
|
14007
|
+
subscription_tier: z.string().nullish()
|
|
14008
|
+
});
|
|
14009
|
+
const copilotQuota = z.object({
|
|
14010
|
+
entitlement: number.nullish(),
|
|
14011
|
+
remaining: number.nullish(),
|
|
14012
|
+
quota_remaining: number.nullish(),
|
|
14013
|
+
percent_remaining: number.nullish(),
|
|
14014
|
+
unlimited: z.boolean().nullish()
|
|
14015
|
+
});
|
|
14016
|
+
const copilotUsage = z.object({
|
|
14017
|
+
copilot_plan: z.string().nullish(),
|
|
14018
|
+
quota_reset_date: z.string().nullish(),
|
|
14019
|
+
quota_snapshots: z.object({
|
|
14020
|
+
premium_interactions: copilotQuota.nullish(),
|
|
14021
|
+
chat: copilotQuota.nullish(),
|
|
14022
|
+
completions: copilotQuota.nullish()
|
|
14023
|
+
}).nullish()
|
|
14024
|
+
});
|
|
14025
|
+
const opencodeGoWindow = z.object({
|
|
14026
|
+
status: z.enum(["ok", "rate-limited"]),
|
|
14027
|
+
percent: number,
|
|
14028
|
+
resetsAt: z.string().nullish()
|
|
14029
|
+
});
|
|
14030
|
+
const opencodeGoUsage = z.object({ usage: z.object({
|
|
14031
|
+
rolling: opencodeGoWindow.nullish(),
|
|
14032
|
+
weekly: opencodeGoWindow.nullish(),
|
|
14033
|
+
monthly: opencodeGoWindow.nullish()
|
|
14034
|
+
}) });
|
|
14035
|
+
function normalizeOpencodeGoUsage(value) {
|
|
14036
|
+
const { usage } = opencodeGoUsage.parse(value);
|
|
14037
|
+
const windows = [];
|
|
14038
|
+
for (const scope of [
|
|
14039
|
+
"rolling",
|
|
14040
|
+
"weekly",
|
|
14041
|
+
"monthly"
|
|
14042
|
+
]) {
|
|
14043
|
+
const window = usage[scope];
|
|
14044
|
+
if (!window) continue;
|
|
14045
|
+
windows.push({
|
|
14046
|
+
id: `opencode-go:${scope}`,
|
|
14047
|
+
kind: "usage",
|
|
14048
|
+
windowSeconds: scope === "rolling" ? 18e3 : void 0,
|
|
14049
|
+
period: scope === "rolling" ? void 0 : scope,
|
|
14050
|
+
usedPercent: window.percent,
|
|
14051
|
+
resetAt: parseResetDate(window.resetsAt),
|
|
14052
|
+
limitReached: window.status === "rate-limited" || window.percent >= 100
|
|
14053
|
+
});
|
|
14054
|
+
}
|
|
14055
|
+
return {
|
|
14056
|
+
provider: "opencode-go",
|
|
14057
|
+
windows,
|
|
14058
|
+
limitReached: windows.some((window) => window.limitReached)
|
|
14059
|
+
};
|
|
14060
|
+
}
|
|
14061
|
+
function normalizeCopilotUsage(value) {
|
|
14062
|
+
const usage = copilotUsage.parse(value);
|
|
14063
|
+
const windows = [];
|
|
14064
|
+
const labels = {
|
|
14065
|
+
premium_interactions: "Premium",
|
|
14066
|
+
chat: "Chat",
|
|
14067
|
+
completions: "Completions"
|
|
14068
|
+
};
|
|
14069
|
+
for (const id of [
|
|
14070
|
+
"premium_interactions",
|
|
14071
|
+
"chat",
|
|
14072
|
+
"completions"
|
|
14073
|
+
]) {
|
|
14074
|
+
const quota = usage.quota_snapshots?.[id];
|
|
14075
|
+
if (!quota) continue;
|
|
14076
|
+
const remaining = quota.remaining ?? quota.quota_remaining;
|
|
14077
|
+
const limit = quota.entitlement ?? void 0;
|
|
14078
|
+
const remainingPercent = quota.percent_remaining ?? (limit !== void 0 && limit > 0 && remaining != null ? remaining / limit * 100 : void 0);
|
|
14079
|
+
if (!quota.unlimited && remainingPercent == null && remaining == null && limit === void 0) continue;
|
|
14080
|
+
windows.push({
|
|
14081
|
+
id: `copilot:${id}`,
|
|
14082
|
+
kind: "usage",
|
|
14083
|
+
name: labels[id],
|
|
14084
|
+
unlimited: quota.unlimited ?? false,
|
|
14085
|
+
usedPercent: quota.unlimited || remainingPercent == null ? void 0 : 100 - remainingPercent,
|
|
14086
|
+
used: limit !== void 0 && remaining != null ? Math.max(0, limit - remaining) : void 0,
|
|
14087
|
+
limit,
|
|
14088
|
+
unit: "requests",
|
|
14089
|
+
resetDate: usage.quota_reset_date ?? void 0,
|
|
14090
|
+
limitReached: !quota.unlimited && remainingPercent != null && remainingPercent <= 0
|
|
14091
|
+
});
|
|
14092
|
+
}
|
|
14093
|
+
return {
|
|
14094
|
+
provider: "github-copilot",
|
|
14095
|
+
planType: usage.copilot_plan ?? void 0,
|
|
14096
|
+
windows,
|
|
14097
|
+
limitReached: windows.some((window) => window.limitReached)
|
|
14098
|
+
};
|
|
14099
|
+
}
|
|
14100
|
+
function resetAt(window, now) {
|
|
14101
|
+
return window.reset_at ?? (window.reset_after_seconds == null ? void 0 : Math.floor(now / 1e3) + window.reset_after_seconds);
|
|
14102
|
+
}
|
|
14103
|
+
function normalizeCodexUsage(value, now = Date.now()) {
|
|
14104
|
+
const usage = codexUsage.parse(value);
|
|
14105
|
+
const windows = [];
|
|
14106
|
+
const addWindows = (id, limits, name) => {
|
|
14107
|
+
for (const scope of ["primary_window", "secondary_window"]) {
|
|
14108
|
+
const window = limits?.[scope];
|
|
14109
|
+
if (!window) continue;
|
|
14110
|
+
windows.push({
|
|
14111
|
+
id: `${id}:${scope}`,
|
|
14112
|
+
kind: "usage",
|
|
14113
|
+
name,
|
|
14114
|
+
usedPercent: window.used_percent,
|
|
14115
|
+
windowSeconds: window.limit_window_seconds ?? void 0,
|
|
14116
|
+
resetAt: resetAt(window, now),
|
|
14117
|
+
limitReached: limits?.limit_reached === true || limits?.allowed === false
|
|
14118
|
+
});
|
|
14119
|
+
}
|
|
14120
|
+
};
|
|
14121
|
+
addWindows("codex", usage.rate_limit);
|
|
14122
|
+
for (const [index, limit] of (usage.additional_rate_limits ?? []).entries()) addWindows(`${limit.metered_feature}:${index}`, limit.rate_limit, limit.limit_name);
|
|
14123
|
+
const spend = usage.spend_control?.individual_limit;
|
|
14124
|
+
if (spend) windows.push({
|
|
14125
|
+
id: "individual-limit",
|
|
14126
|
+
kind: "spend",
|
|
14127
|
+
period: "monthly",
|
|
14128
|
+
usedPercent: spend.used_percent,
|
|
14129
|
+
used: spend.used,
|
|
14130
|
+
limit: spend.limit,
|
|
14131
|
+
unit: "credits",
|
|
14132
|
+
resetAt: resetAt(spend, now),
|
|
14133
|
+
limitReached: usage.spend_control?.reached
|
|
14134
|
+
});
|
|
14135
|
+
return {
|
|
14136
|
+
provider: "codex",
|
|
14137
|
+
planType: usage.plan_type,
|
|
14138
|
+
windows,
|
|
14139
|
+
credits: usage.credits ? {
|
|
14140
|
+
balance: usage.credits.balance ?? void 0,
|
|
14141
|
+
unlimited: usage.credits.unlimited,
|
|
14142
|
+
hasCredits: usage.credits.has_credits,
|
|
14143
|
+
unit: "credits"
|
|
14144
|
+
} : void 0,
|
|
14145
|
+
limitReached: usage.rate_limit?.limit_reached === true || usage.rate_limit?.allowed === false || usage.spend_control?.reached === true || usage.rate_limit_reached_type != null && usage.rate_limit_reached_type.type !== "unknown",
|
|
14146
|
+
limitReason: usage.rate_limit_reached_type?.type
|
|
14147
|
+
};
|
|
14148
|
+
}
|
|
14149
|
+
function parseResetDate(value) {
|
|
14150
|
+
const milliseconds = value ? Date.parse(value) : NaN;
|
|
14151
|
+
return Number.isFinite(milliseconds) ? milliseconds / 1e3 : void 0;
|
|
14152
|
+
}
|
|
14153
|
+
function normalizeXaiUsage(value) {
|
|
14154
|
+
const usage = xaiUsage.parse(value);
|
|
14155
|
+
const config = usage.config;
|
|
14156
|
+
const windows = [];
|
|
14157
|
+
if (config) {
|
|
14158
|
+
const limit = config.monthlyLimit?.val;
|
|
14159
|
+
const used = config.used?.val;
|
|
14160
|
+
const usedPercent = config.creditUsagePercent ?? (limit !== void 0 && limit > 0 && used !== void 0 ? used / limit * 100 : void 0);
|
|
14161
|
+
if (usedPercent != null || limit !== void 0 || used !== void 0) windows.push({
|
|
14162
|
+
id: "included",
|
|
14163
|
+
kind: "usage",
|
|
14164
|
+
period: config.currentPeriod?.type === "USAGE_PERIOD_TYPE_WEEKLY" ? "weekly" : config.currentPeriod?.type === "USAGE_PERIOD_TYPE_MONTHLY" || config.monthlyLimit ? "monthly" : void 0,
|
|
14165
|
+
usedPercent,
|
|
14166
|
+
used: config.creditUsagePercent == null && used !== void 0 ? used / 100 : void 0,
|
|
14167
|
+
limit: config.creditUsagePercent == null && limit !== void 0 ? limit / 100 : void 0,
|
|
14168
|
+
unit: "USD",
|
|
14169
|
+
resetAt: parseResetDate(config.currentPeriod?.end ?? config.billingPeriodEnd)
|
|
14170
|
+
});
|
|
14171
|
+
if (config.onDemandCap || config.onDemandUsed) {
|
|
14172
|
+
const cap = Math.abs(config.onDemandCap?.val ?? 0);
|
|
14173
|
+
const spent = Math.abs(config.onDemandUsed?.val ?? 0);
|
|
14174
|
+
windows.push({
|
|
14175
|
+
id: "on-demand",
|
|
14176
|
+
kind: "on-demand",
|
|
14177
|
+
period: "monthly",
|
|
14178
|
+
unit: "USD",
|
|
14179
|
+
used: spent / 100,
|
|
14180
|
+
limit: cap / 100,
|
|
14181
|
+
usedPercent: cap > 0 ? spent / cap * 100 : void 0
|
|
14182
|
+
});
|
|
14183
|
+
}
|
|
14184
|
+
}
|
|
14185
|
+
return {
|
|
14186
|
+
provider: "xai",
|
|
14187
|
+
planType: usage.subscription_tier ?? void 0,
|
|
14188
|
+
windows,
|
|
14189
|
+
credits: config?.prepaidBalance ? {
|
|
14190
|
+
balance: Math.abs(config.prepaidBalance.val) / 100,
|
|
14191
|
+
unlimited: false,
|
|
14192
|
+
hasCredits: config.prepaidBalance.val !== 0,
|
|
14193
|
+
unit: "USD"
|
|
14194
|
+
} : void 0,
|
|
14195
|
+
limitReached: (windows.find((window) => window.id === "included")?.usedPercent ?? 0) >= 100
|
|
14196
|
+
};
|
|
14197
|
+
}
|
|
14198
|
+
async function getSubscriptionUsage(provider, signal) {
|
|
14199
|
+
if (provider === "github-copilot") {
|
|
14200
|
+
if (!isGitHubCopilotEnabled()) return null;
|
|
14201
|
+
const timeout = AbortSignal.timeout(15e3);
|
|
14202
|
+
const usage = await getCopilotUsage(void 0, signal ? AbortSignal.any([signal, timeout]) : timeout);
|
|
14203
|
+
return usage ? normalizeCopilotUsage(usage) : null;
|
|
14204
|
+
}
|
|
14205
|
+
const config = await resolveProviderConfig(provider);
|
|
14206
|
+
if (!config) return null;
|
|
14207
|
+
if (provider !== "opencode-go" && config.authType !== "oauth2") return null;
|
|
14208
|
+
let headers;
|
|
14209
|
+
let url;
|
|
14210
|
+
if (provider === "opencode-go") {
|
|
14211
|
+
url = resolveProviderEndpointUrl(config, "usage");
|
|
14212
|
+
headers = new Headers({
|
|
14213
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
14214
|
+
Accept: "application/json"
|
|
14215
|
+
});
|
|
14216
|
+
} else if (provider === "codex") {
|
|
14217
|
+
const platform = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "Mac OS" : os.type();
|
|
14218
|
+
const arch = process.arch === "x64" ? "x86_64" : process.arch === "arm64" ? "aarch64" : process.arch;
|
|
14219
|
+
headers = buildCodexRequestHeaders(new Headers({
|
|
14220
|
+
"user-agent": `codex_cli_rs/${CODEX_CLI_VERSION} (${platform} ${os.release()}; ${arch}) unknown`,
|
|
14221
|
+
originator: "codex_cli_rs",
|
|
14222
|
+
accept: "application/json"
|
|
14223
|
+
}));
|
|
14224
|
+
url = `${CODEX_API_BASE_URL}/wham/usage`;
|
|
14225
|
+
} else {
|
|
14226
|
+
const credentials = await readXaiCredentials();
|
|
14227
|
+
if (!credentials) return null;
|
|
14228
|
+
if (credentials.accessToken !== config.apiKey) throw new Error("Subscription account changed during the usage query");
|
|
14229
|
+
const version = await getGrokBuildVersion();
|
|
14230
|
+
const platform = process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : process.platform;
|
|
14231
|
+
const arch = process.arch === "x64" ? "x86_64" : process.arch === "arm64" ? "aarch64" : process.arch;
|
|
14232
|
+
headers = new Headers({
|
|
14233
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
14234
|
+
"X-XAI-Token-Auth": "xai-grok-cli",
|
|
14235
|
+
"x-userid": credentials.accountId,
|
|
14236
|
+
"x-grok-client-version": version,
|
|
14237
|
+
"x-grok-client-mode": "headless",
|
|
14238
|
+
"User-Agent": `grok-shell/${version} (${platform}; ${arch})`,
|
|
14239
|
+
Accept: "application/json"
|
|
14240
|
+
});
|
|
14241
|
+
url = `${XAI_API_BASE_URL}/v1/billing?format=credits`;
|
|
14242
|
+
}
|
|
14243
|
+
const timeout = AbortSignal.timeout(15e3);
|
|
14244
|
+
const response = await fetch(url, {
|
|
14245
|
+
headers,
|
|
14246
|
+
signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
|
|
14247
|
+
redirect: "error"
|
|
14248
|
+
});
|
|
14249
|
+
if (provider === "opencode-go" && response.status === 403) {
|
|
14250
|
+
await response.body?.cancel();
|
|
14251
|
+
return null;
|
|
14252
|
+
}
|
|
14253
|
+
if (!response.ok) {
|
|
14254
|
+
await response.body?.cancel();
|
|
14255
|
+
throw new Error(`Subscription usage request failed (HTTP ${response.status})`);
|
|
14256
|
+
}
|
|
14257
|
+
const value = await response.json();
|
|
14258
|
+
if (provider === "opencode-go") return normalizeOpencodeGoUsage(value);
|
|
14259
|
+
return provider === "codex" ? normalizeCodexUsage(value) : normalizeXaiUsage(value);
|
|
14260
|
+
}
|
|
13950
14261
|
// src/routes/usage/route.ts
|
|
13951
14262
|
const usageRoute = new Hono();
|
|
14263
|
+
usageRoute.get("/:provider", async (c) => {
|
|
14264
|
+
const provider = c.req.param("provider");
|
|
14265
|
+
c.header("Cache-Control", "no-store");
|
|
14266
|
+
if (provider !== "codex" && provider !== "xai" && provider !== "github-copilot" && provider !== "opencode-go") return c.json({ error: "Unsupported subscription provider" }, 404);
|
|
14267
|
+
try {
|
|
14268
|
+
const usage = await getSubscriptionUsage(provider, c.req.raw.signal);
|
|
14269
|
+
return usage ? c.json(usage) : c.json({ error: "Subscription account is not available" }, 404);
|
|
14270
|
+
} catch {
|
|
14271
|
+
return c.json({ error: "Failed to fetch subscription usage" }, 502);
|
|
14272
|
+
}
|
|
14273
|
+
});
|
|
13952
14274
|
usageRoute.get("/", async (c) => {
|
|
13953
14275
|
try {
|
|
13954
14276
|
const usage = await getCopilotUsage();
|
|
@@ -14109,4 +14431,4 @@ function createServer(options = {}) {
|
|
|
14109
14431
|
createServer();
|
|
14110
14432
|
export { createServer };
|
|
14111
14433
|
|
|
14112
|
-
//# sourceMappingURL=server-
|
|
14434
|
+
//# sourceMappingURL=server-DhHL2SxL.js.map
|