@slkiser/opencode-quota 3.0.2 → 3.1.1
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 +207 -143
- package/dist/lib/anthropic.d.ts +4 -5
- package/dist/lib/anthropic.d.ts.map +1 -1
- package/dist/lib/anthropic.js +230 -18
- package/dist/lib/anthropic.js.map +1 -1
- package/dist/lib/api-key-resolver.d.ts +1 -1
- package/dist/lib/api-key-resolver.d.ts.map +1 -1
- package/dist/lib/api-key-resolver.js +11 -13
- package/dist/lib/api-key-resolver.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +6 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts.map +1 -1
- package/dist/lib/cursor-detection.js +14 -5
- package/dist/lib/cursor-detection.js.map +1 -1
- package/dist/lib/cursor-usage.d.ts.map +1 -1
- package/dist/lib/cursor-usage.js +18 -14
- package/dist/lib/cursor-usage.js.map +1 -1
- package/dist/lib/entries.d.ts +1 -1
- package/dist/lib/entries.d.ts.map +1 -1
- package/dist/lib/entries.js.map +1 -1
- package/dist/lib/format-utils.d.ts +8 -0
- package/dist/lib/format-utils.d.ts.map +1 -1
- package/dist/lib/format-utils.js +13 -0
- package/dist/lib/format-utils.js.map +1 -1
- package/dist/lib/format.d.ts +2 -0
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +14 -9
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/grouped-entry-normalization.d.ts +5 -0
- package/dist/lib/grouped-entry-normalization.d.ts.map +1 -1
- package/dist/lib/grouped-entry-normalization.js +7 -3
- package/dist/lib/grouped-entry-normalization.js.map +1 -1
- package/dist/lib/init-installer.d.ts +1 -0
- package/dist/lib/init-installer.d.ts.map +1 -1
- package/dist/lib/init-installer.js +15 -0
- package/dist/lib/init-installer.js.map +1 -1
- package/dist/lib/kimi-auth.d.ts +38 -0
- package/dist/lib/kimi-auth.d.ts.map +1 -0
- package/dist/lib/kimi-auth.js +104 -0
- package/dist/lib/kimi-auth.js.map +1 -0
- package/dist/lib/kimi.d.ts +3 -0
- package/dist/lib/kimi.d.ts.map +1 -0
- package/dist/lib/kimi.js +206 -0
- package/dist/lib/kimi.js.map +1 -0
- package/dist/lib/opencode-sqlite.d.ts.map +1 -1
- package/dist/lib/opencode-sqlite.js +9 -12
- package/dist/lib/opencode-sqlite.js.map +1 -1
- package/dist/lib/opencode-storage.d.ts.map +1 -1
- package/dist/lib/opencode-storage.js +9 -5
- package/dist/lib/opencode-storage.js.map +1 -1
- package/dist/lib/provider-metadata.d.ts +1 -1
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +17 -4
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/quota-command-format.d.ts.map +1 -1
- package/dist/lib/quota-command-format.js +41 -42
- package/dist/lib/quota-command-format.js.map +1 -1
- package/dist/lib/quota-render-data.d.ts.map +1 -1
- package/dist/lib/quota-render-data.js +1 -4
- package/dist/lib/quota-render-data.js.map +1 -1
- package/dist/lib/quota-stats-format.d.ts.map +1 -1
- package/dist/lib/quota-stats-format.js +164 -121
- package/dist/lib/quota-stats-format.js.map +1 -1
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +590 -265
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/report-document.d.ts +36 -0
- package/dist/lib/report-document.d.ts.map +1 -0
- package/dist/lib/report-document.js +109 -0
- package/dist/lib/report-document.js.map +1 -0
- package/dist/lib/session-tokens-format.d.ts +8 -0
- package/dist/lib/session-tokens-format.d.ts.map +1 -1
- package/dist/lib/session-tokens-format.js +36 -20
- package/dist/lib/session-tokens-format.js.map +1 -1
- package/dist/lib/synthetic-config.d.ts +41 -0
- package/dist/lib/synthetic-config.d.ts.map +1 -0
- package/dist/lib/synthetic-config.js +57 -0
- package/dist/lib/synthetic-config.js.map +1 -0
- package/dist/lib/synthetic.d.ts +17 -0
- package/dist/lib/synthetic.d.ts.map +1 -0
- package/dist/lib/synthetic.js +94 -0
- package/dist/lib/synthetic.js.map +1 -0
- package/dist/lib/toast-format-grouped.d.ts +2 -0
- package/dist/lib/toast-format-grouped.d.ts.map +1 -1
- package/dist/lib/toast-format-grouped.js +9 -6
- package/dist/lib/toast-format-grouped.js.map +1 -1
- package/dist/lib/tui-config-diagnostics.d.ts.map +1 -1
- package/dist/lib/tui-config-diagnostics.js +13 -9
- package/dist/lib/tui-config-diagnostics.js.map +1 -1
- package/dist/lib/tui-panel-state.d.ts.map +1 -1
- package/dist/lib/tui-panel-state.js +10 -5
- package/dist/lib/tui-panel-state.js.map +1 -1
- package/dist/lib/tui-sidebar-format.d.ts +1 -1
- package/dist/lib/tui-sidebar-format.d.ts.map +1 -1
- package/dist/lib/tui-sidebar-format.js +1 -0
- package/dist/lib/tui-sidebar-format.js.map +1 -1
- package/dist/lib/types.d.ts +42 -4
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +1 -0
- package/dist/lib/types.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -0
- package/dist/plugin.js.map +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/copilot.js +2 -1
- package/dist/providers/copilot.js.map +1 -1
- package/dist/providers/cursor.d.ts.map +1 -1
- package/dist/providers/cursor.js +2 -1
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/google-antigravity.d.ts.map +1 -1
- package/dist/providers/google-antigravity.js +2 -1
- package/dist/providers/google-antigravity.js.map +1 -1
- package/dist/providers/kimi-code.d.ts +3 -0
- package/dist/providers/kimi-code.d.ts.map +1 -0
- package/dist/providers/kimi-code.js +71 -0
- package/dist/providers/kimi-code.js.map +1 -0
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +4 -2
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/synthetic.d.ts +6 -0
- package/dist/providers/synthetic.d.ts.map +1 -0
- package/dist/providers/synthetic.js +57 -0
- package/dist/providers/synthetic.js.map +1 -0
- package/package.json +2 -2
- package/dist/lib/firmware-config.d.ts +0 -41
- package/dist/lib/firmware-config.d.ts.map +0 -1
- package/dist/lib/firmware-config.js +0 -60
- package/dist/lib/firmware-config.js.map +0 -1
- package/dist/lib/firmware.d.ts +0 -22
- package/dist/lib/firmware.d.ts.map +0 -1
- package/dist/lib/firmware.js +0 -62
- package/dist/lib/firmware.js.map +0 -1
- package/dist/providers/firmware.d.ts +0 -6
- package/dist/providers/firmware.d.ts.map +0 -1
- package/dist/providers/firmware.js +0 -45
- package/dist/providers/firmware.js.map +0 -1
package/dist/lib/quota-status.js
CHANGED
|
@@ -5,9 +5,9 @@ import { getGoogleTokenCachePath } from "./google-token-cache.js";
|
|
|
5
5
|
import { inspectAntigravityCompanionPresence } from "./google-antigravity-companion.js";
|
|
6
6
|
import { inspectAntigravityAccountsPresence } from "./google.js";
|
|
7
7
|
import { getAnthropicDiagnostics } from "./anthropic.js";
|
|
8
|
-
import { getFirmwareKeyDiagnostics } from "./firmware.js";
|
|
9
8
|
import { getChutesKeyDiagnostics } from "./chutes.js";
|
|
10
9
|
import { getNanoGptKeyDiagnostics, queryNanoGptQuota } from "./nanogpt.js";
|
|
10
|
+
import { getSyntheticKeyDiagnostics } from "./synthetic.js";
|
|
11
11
|
import { getCopilotQuotaAuthDiagnostics } from "./copilot.js";
|
|
12
12
|
import { computeAlibabaCodingPlanQuota, computeQwenQuota, getAlibabaCodingPlanQuotaPath, getQwenLocalQuotaPath, readAlibabaCodingPlanQuotaState, readQwenLocalQuotaState, } from "./qwen-local-quota.js";
|
|
13
13
|
import { DEFAULT_ALIBABA_AUTH_CACHE_MAX_AGE_MS, getAlibabaCodingPlanAuthDiagnostics, resolveAlibabaCodingPlanAuthCached, } from "./alibaba-auth.js";
|
|
@@ -15,12 +15,15 @@ import { hasQwenOAuthAuth, resolveQwenLocalPlan } from "./qwen-auth.js";
|
|
|
15
15
|
import { resolveOpenAIOAuth } from "./openai.js";
|
|
16
16
|
import { DEFAULT_MINIMAX_AUTH_CACHE_MAX_AGE_MS, getMiniMaxAuthDiagnostics, resolveMiniMaxAuthCached, } from "./minimax-auth.js";
|
|
17
17
|
import { DEFAULT_ZAI_AUTH_CACHE_MAX_AGE_MS, getZaiAuthDiagnostics } from "./zai-auth.js";
|
|
18
|
+
import { DEFAULT_KIMI_AUTH_CACHE_MAX_AGE_MS, getKimiAuthDiagnostics, } from "./kimi-auth.js";
|
|
19
|
+
import { queryKimiQuota } from "./kimi.js";
|
|
18
20
|
import { getPricingSnapshotHealth, getPricingRefreshPolicy, getPricingSnapshotMeta, getPricingSnapshotSource, getRuntimePricingRefreshStatePath, getRuntimePricingSnapshotPath, listProviders, getProviderModelCount, hasProvider as snapshotHasProvider, readPricingRefreshState, } from "./modelsdev-pricing.js";
|
|
19
21
|
import { getProviders } from "../providers/registry.js";
|
|
20
22
|
import { getPackageVersion } from "./version.js";
|
|
21
23
|
import { getOpenCodeDbPath, getOpenCodeDbPathCandidates, getOpenCodeDbStats, } from "./opencode-storage.js";
|
|
22
24
|
import { aggregateUsage } from "./quota-stats.js";
|
|
23
|
-
import { fmtUsdAmount
|
|
25
|
+
import { fmtUsdAmount } from "./format-utils.js";
|
|
26
|
+
import { renderPlainTextReport } from "./report-document.js";
|
|
24
27
|
import { totalTokenBuckets } from "./token-buckets.js";
|
|
25
28
|
import { CURSOR_CANONICAL_PLUGIN_PACKAGE, inspectCursorAuthPresence, inspectCursorOpenCodeIntegration, } from "./cursor-detection.js";
|
|
26
29
|
import { getCurrentCursorUsageSummary } from "./cursor-usage.js";
|
|
@@ -80,13 +83,30 @@ async function readBasicApiKeyDiagnostics(read) {
|
|
|
80
83
|
return getDefaultBasicApiKeyDiagnostics();
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
|
-
function
|
|
84
|
-
return
|
|
86
|
+
function formatInlineApiKeyDiagnosticsValue(diagnostics) {
|
|
87
|
+
return `configured=${diagnostics.configured ? "true" : "false"}${diagnostics.source ? ` source=${diagnostics.source}` : ""}${diagnostics.checkedPaths.length > 0 ? ` checked=${diagnostics.checkedPaths.join(" | ")}` : ""}`;
|
|
85
88
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
function createKvSection(id, title, rows) {
|
|
90
|
+
return {
|
|
91
|
+
id,
|
|
92
|
+
title,
|
|
93
|
+
blocks: [{ kind: "kv", rows }],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function createLinesSection(id, title, lines) {
|
|
97
|
+
return {
|
|
98
|
+
id,
|
|
99
|
+
title,
|
|
100
|
+
blocks: [{ kind: "lines", lines }],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function buildBasicApiKeySection(params) {
|
|
104
|
+
return createKvSection(params.id, params.section, [
|
|
105
|
+
{
|
|
106
|
+
key: params.label,
|
|
107
|
+
value: formatInlineApiKeyDiagnosticsValue(params.diagnostics),
|
|
108
|
+
},
|
|
109
|
+
]);
|
|
90
110
|
}
|
|
91
111
|
function getDefaultNanoGptApiKeyDiagnostics() {
|
|
92
112
|
return {
|
|
@@ -102,14 +122,6 @@ async function readNanoGptApiKeyDiagnostics(read) {
|
|
|
102
122
|
return getDefaultNanoGptApiKeyDiagnostics();
|
|
103
123
|
}
|
|
104
124
|
}
|
|
105
|
-
function appendNanoGptApiKeySection(lines, diagnostics) {
|
|
106
|
-
lines.push("");
|
|
107
|
-
lines.push("nanogpt:");
|
|
108
|
-
lines.push(`- api_key_configured: ${diagnostics.configured ? "true" : "false"}`);
|
|
109
|
-
lines.push(`- api_key_source: ${diagnostics.source ?? "(none)"}`);
|
|
110
|
-
lines.push(`- api_key_checked_paths: ${joinOrNone(diagnostics.checkedPaths)}`);
|
|
111
|
-
lines.push(`- api_key_auth_paths: ${joinOrNone(diagnostics.authPaths)}`);
|
|
112
|
-
}
|
|
113
125
|
function fmtNanoGptMetric(value) {
|
|
114
126
|
if (!Number.isFinite(value))
|
|
115
127
|
return "0";
|
|
@@ -164,11 +176,11 @@ function computePricingCoverageFromAgg(agg) {
|
|
|
164
176
|
}
|
|
165
177
|
function supportedProviderPricingRow(params) {
|
|
166
178
|
const id = params.id;
|
|
167
|
-
if (id === "
|
|
179
|
+
if (id === "synthetic") {
|
|
168
180
|
return {
|
|
169
181
|
id,
|
|
170
182
|
pricing: "no",
|
|
171
|
-
notes: "
|
|
183
|
+
notes: "subscription request quota (not token-priced)",
|
|
172
184
|
};
|
|
173
185
|
}
|
|
174
186
|
if (id === "qwen-code") {
|
|
@@ -206,6 +218,13 @@ function supportedProviderPricingRow(params) {
|
|
|
206
218
|
notes: "subscription percentage quota via dashboard scraping (not token-priced)",
|
|
207
219
|
};
|
|
208
220
|
}
|
|
221
|
+
if (id === "kimi-code") {
|
|
222
|
+
return {
|
|
223
|
+
id,
|
|
224
|
+
pricing: "no",
|
|
225
|
+
notes: "request quota via Kimi Code API (not token-priced)",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
209
228
|
// Providers that correspond directly to models.dev providers.
|
|
210
229
|
if (params.snapshotProviders.includes(id)) {
|
|
211
230
|
return { id, pricing: "yes", notes: "models.dev snapshot provider" };
|
|
@@ -247,20 +266,8 @@ function supportedProviderPricingRow(params) {
|
|
|
247
266
|
};
|
|
248
267
|
}
|
|
249
268
|
export async function buildQuotaStatusReport(params) {
|
|
250
|
-
const lines = [];
|
|
251
269
|
const version = await getPackageVersion();
|
|
252
270
|
const v = version ?? "unknown";
|
|
253
|
-
lines.push(renderCommandHeading({
|
|
254
|
-
title: `Quota Status (opencode-quota v${v}) (/quota_status)`,
|
|
255
|
-
generatedAtMs: params.generatedAtMs,
|
|
256
|
-
}));
|
|
257
|
-
lines.push("");
|
|
258
|
-
// === toast diagnostics ===
|
|
259
|
-
lines.push("toast:");
|
|
260
|
-
lines.push(`- configSource: ${params.configSource}${params.configPaths.length ? ` (${params.configPaths.join(" | ")})` : ""}`);
|
|
261
|
-
lines.push(`- network_setting_sources: ${formatNetworkSettingSources(params.networkSettingSources)}`);
|
|
262
|
-
lines.push(`- enabledProviders: ${params.enabledProviders === "auto" ? "(auto)" : params.enabledProviders.length ? params.enabledProviders.join(",") : "(none)"}`);
|
|
263
|
-
lines.push(`- onlyCurrentModel: ${params.onlyCurrentModel ? "true" : "false"}`);
|
|
264
271
|
const modelDisplay = params.currentModel
|
|
265
272
|
? params.currentModel
|
|
266
273
|
: params.sessionModelLookup === "not_found"
|
|
@@ -268,18 +275,26 @@ export async function buildQuotaStatusReport(params) {
|
|
|
268
275
|
: params.sessionModelLookup === "no_session"
|
|
269
276
|
? "(no session available)"
|
|
270
277
|
: "(unknown)";
|
|
271
|
-
|
|
278
|
+
const sections = [];
|
|
279
|
+
// === toast diagnostics ===
|
|
280
|
+
const toastLines = [
|
|
281
|
+
`- configSource: ${params.configSource}${params.configPaths.length ? ` (${params.configPaths.join(" | ")})` : ""}`,
|
|
282
|
+
`- network_setting_sources: ${formatNetworkSettingSources(params.networkSettingSources)}`,
|
|
283
|
+
`- enabledProviders: ${params.enabledProviders === "auto" ? "(auto)" : params.enabledProviders.length ? params.enabledProviders.join(",") : "(none)"}`,
|
|
284
|
+
`- onlyCurrentModel: ${params.onlyCurrentModel ? "true" : "false"}`,
|
|
285
|
+
`- currentModel: ${modelDisplay}`,
|
|
286
|
+
];
|
|
272
287
|
if (params.tuiDiagnostics) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
288
|
+
toastLines.push("");
|
|
289
|
+
toastLines.push("tui:");
|
|
290
|
+
toastLines.push(`- config_configured: ${params.tuiDiagnostics.configured ? "true" : "false"}`);
|
|
291
|
+
toastLines.push(`- inferred_selected_config_path: ${params.tuiDiagnostics.inferredSelectedPath ?? "(none)"}`);
|
|
292
|
+
toastLines.push(`- present_config_paths: ${joinOrNone(params.tuiDiagnostics.presentPaths)}`);
|
|
293
|
+
toastLines.push(`- candidate_config_paths: ${joinOrNone(params.tuiDiagnostics.candidatePaths)}`);
|
|
294
|
+
toastLines.push(`- quota_plugin_configured: ${params.tuiDiagnostics.quotaPluginConfigured ? "true" : "false"}`);
|
|
295
|
+
toastLines.push(`- quota_plugin_paths: ${joinOrNone(params.tuiDiagnostics.quotaPluginConfigPaths)}`);
|
|
296
|
+
}
|
|
297
|
+
toastLines.push("- providers:");
|
|
283
298
|
for (const p of params.providerAvailability) {
|
|
284
299
|
const bits = [];
|
|
285
300
|
bits.push(p.enabled ? "enabled" : "disabled");
|
|
@@ -287,12 +302,16 @@ export async function buildQuotaStatusReport(params) {
|
|
|
287
302
|
if (p.matchesCurrentModel !== undefined) {
|
|
288
303
|
bits.push(`matchesCurrentModel=${p.matchesCurrentModel ? "yes" : "no"}`);
|
|
289
304
|
}
|
|
290
|
-
|
|
305
|
+
toastLines.push(` - ${p.id}: ${bits.join(" ")}`);
|
|
291
306
|
}
|
|
292
|
-
|
|
293
|
-
|
|
307
|
+
sections.push(createLinesSection("toast", "toast:", toastLines));
|
|
308
|
+
// === paths ===
|
|
309
|
+
const pathsRows = [];
|
|
294
310
|
const runtime = getOpencodeRuntimeDirs();
|
|
295
|
-
|
|
311
|
+
pathsRows.push({
|
|
312
|
+
key: "opencode_dirs",
|
|
313
|
+
value: `data=${runtime.dataDir} config=${runtime.configDir} cache=${runtime.cacheDir} state=${runtime.stateDir}`,
|
|
314
|
+
});
|
|
296
315
|
const authCandidates = getAuthPaths();
|
|
297
316
|
const authPresent = [];
|
|
298
317
|
await Promise.all(authCandidates.map(async (p) => {
|
|
@@ -304,7 +323,10 @@ export async function buildQuotaStatusReport(params) {
|
|
|
304
323
|
// ignore missing/unreadable
|
|
305
324
|
}
|
|
306
325
|
}));
|
|
307
|
-
|
|
326
|
+
pathsRows.push({
|
|
327
|
+
key: "auth.json",
|
|
328
|
+
value: `preferred=${getAuthPath()} present=${joinOrNone(authPresent)} candidates=${joinOrNone(authCandidates)}`,
|
|
329
|
+
});
|
|
308
330
|
const authData = await readAuthFileCached({ maxAgeMs: 5_000 });
|
|
309
331
|
const qwenAuthConfigured = hasQwenOAuthAuth(authData);
|
|
310
332
|
const qwenLocalPlan = resolveQwenLocalPlan(authData);
|
|
@@ -317,55 +339,129 @@ export async function buildQuotaStatusReport(params) {
|
|
|
317
339
|
maxAgeMs: DEFAULT_ALIBABA_AUTH_CACHE_MAX_AGE_MS,
|
|
318
340
|
fallbackTier: params.alibabaCodingPlanTier,
|
|
319
341
|
});
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
342
|
+
pathsRows.push({ key: "qwen oauth auth configured", value: qwenAuthConfigured ? "true" : "false" });
|
|
343
|
+
pathsRows.push({
|
|
344
|
+
key: "qwen_oauth_source",
|
|
345
|
+
value: qwenLocalPlan.state === "qwen_free" ? qwenLocalPlan.sourceKey : "(none)",
|
|
346
|
+
});
|
|
347
|
+
pathsRows.push({
|
|
348
|
+
key: "qwen_local_plan",
|
|
349
|
+
value: qwenLocalPlan.state === "qwen_free" ? "qwen-code/free" : "(none)",
|
|
350
|
+
});
|
|
351
|
+
pathsRows.push({
|
|
352
|
+
key: "alibaba auth configured",
|
|
353
|
+
value: alibabaAuthDiagnostics.state === "none" ? "false" : "true",
|
|
354
|
+
});
|
|
355
|
+
pathsRows.push({ key: "alibaba_api_key_source", value: alibabaAuthDiagnostics.source ?? "(none)" });
|
|
356
|
+
pathsRows.push({
|
|
357
|
+
key: "alibaba_api_key_checked_paths",
|
|
358
|
+
value: joinOrNone(alibabaAuthDiagnostics.checkedPaths),
|
|
359
|
+
});
|
|
360
|
+
pathsRows.push({
|
|
361
|
+
key: "alibaba_api_key_auth_paths",
|
|
362
|
+
value: joinOrNone(alibabaAuthDiagnostics.authPaths),
|
|
363
|
+
});
|
|
364
|
+
pathsRows.push({
|
|
365
|
+
key: "alibaba coding plan fallback tier",
|
|
366
|
+
value: params.alibabaCodingPlanTier,
|
|
367
|
+
});
|
|
368
|
+
pathsRows.push({
|
|
369
|
+
key: "alibaba_coding_plan",
|
|
370
|
+
value: alibabaAuthDiagnostics.state === "configured"
|
|
371
|
+
? alibabaAuthDiagnostics.tier
|
|
372
|
+
: alibabaAuthDiagnostics.state === "invalid"
|
|
373
|
+
? "invalid"
|
|
374
|
+
: "(none)",
|
|
375
|
+
});
|
|
329
376
|
if (alibabaAuthDiagnostics.state === "invalid") {
|
|
330
|
-
|
|
377
|
+
pathsRows.push({
|
|
378
|
+
key: "alibaba_auth_error",
|
|
379
|
+
value: sanitizeDisplayText(alibabaAuthDiagnostics.error),
|
|
380
|
+
});
|
|
331
381
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
382
|
+
sections.push(createKvSection("paths", "paths:", pathsRows));
|
|
383
|
+
// === openai ===
|
|
384
|
+
const openaiRows = [
|
|
385
|
+
{ key: "auth_configured", value: openaiAuth.state === "configured" ? "true" : "false" },
|
|
386
|
+
{
|
|
387
|
+
key: "auth_source",
|
|
388
|
+
value: openaiAuth.state === "configured" ? openaiAuth.sourceKey : "(none)",
|
|
389
|
+
},
|
|
390
|
+
];
|
|
336
391
|
const openaiTokenStatus = openaiAuth.state !== "configured"
|
|
337
392
|
? "(none)"
|
|
338
393
|
: openaiAuth.expiresAt && openaiAuth.expiresAt < Date.now()
|
|
339
394
|
? "expired"
|
|
340
395
|
: "valid";
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
396
|
+
openaiRows.push({ key: "token_status", value: openaiTokenStatus });
|
|
397
|
+
openaiRows.push({
|
|
398
|
+
key: "token_expires_at",
|
|
399
|
+
value: openaiAuth.state === "configured" && openaiAuth.expiresAt
|
|
400
|
+
? new Date(openaiAuth.expiresAt).toISOString()
|
|
401
|
+
: "(none)",
|
|
402
|
+
});
|
|
403
|
+
openaiRows.push({
|
|
404
|
+
key: "account_email",
|
|
405
|
+
value: openaiAuth.state === "configured" && openaiAuth.email
|
|
406
|
+
? sanitizeDisplayText(openaiAuth.email)
|
|
407
|
+
: "(none)",
|
|
408
|
+
});
|
|
409
|
+
openaiRows.push({
|
|
410
|
+
key: "account_id",
|
|
411
|
+
value: openaiAuth.state === "configured" && openaiAuth.accountId
|
|
412
|
+
? sanitizeDisplayText(openaiAuth.accountId)
|
|
413
|
+
: "(none)",
|
|
414
|
+
});
|
|
415
|
+
sections.push(createKvSection("openai", "openai:", openaiRows));
|
|
416
|
+
// === anthropic ===
|
|
417
|
+
const anthropicRows = [];
|
|
347
418
|
try {
|
|
348
419
|
const anthropicDiagnostics = await getAnthropicDiagnostics({
|
|
349
420
|
binaryPath: params.anthropicBinaryPath,
|
|
350
421
|
});
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
422
|
+
anthropicRows.push({
|
|
423
|
+
key: "cli_installed",
|
|
424
|
+
value: anthropicDiagnostics.installed ? "true" : "false",
|
|
425
|
+
});
|
|
426
|
+
anthropicRows.push({ key: "cli_version", value: anthropicDiagnostics.version ?? "(none)" });
|
|
427
|
+
anthropicRows.push({ key: "auth_status", value: anthropicDiagnostics.authStatus });
|
|
428
|
+
anthropicRows.push({
|
|
429
|
+
key: "quota_supported",
|
|
430
|
+
value: anthropicDiagnostics.quotaSupported ? "true" : "false",
|
|
431
|
+
});
|
|
432
|
+
anthropicRows.push({
|
|
433
|
+
key: "quota_source",
|
|
434
|
+
value: anthropicDiagnostics.quotaSource === "none" ? "(none)" : anthropicDiagnostics.quotaSource,
|
|
435
|
+
});
|
|
436
|
+
anthropicRows.push({
|
|
437
|
+
key: "checked_commands",
|
|
438
|
+
value: anthropicDiagnostics.checkedCommands.length > 0
|
|
439
|
+
? anthropicDiagnostics.checkedCommands.join(" | ")
|
|
440
|
+
: "(none)",
|
|
441
|
+
});
|
|
357
442
|
if (anthropicDiagnostics.message) {
|
|
358
|
-
|
|
443
|
+
anthropicRows.push({ key: "message", value: anthropicDiagnostics.message });
|
|
359
444
|
}
|
|
360
445
|
if (anthropicDiagnostics.quotaSupported && anthropicDiagnostics.quota) {
|
|
361
|
-
|
|
362
|
-
|
|
446
|
+
anthropicRows.push({
|
|
447
|
+
key: "five_hour_remaining",
|
|
448
|
+
value: `${anthropicDiagnostics.quota.five_hour.percentRemaining}% reset_at=${anthropicDiagnostics.quota.five_hour.resetTimeIso ?? "(none)"}`,
|
|
449
|
+
});
|
|
450
|
+
anthropicRows.push({
|
|
451
|
+
key: "seven_day_remaining",
|
|
452
|
+
value: `${anthropicDiagnostics.quota.seven_day.percentRemaining}% reset_at=${anthropicDiagnostics.quota.seven_day.resetTimeIso ?? "(none)"}`,
|
|
453
|
+
});
|
|
363
454
|
}
|
|
364
455
|
}
|
|
365
456
|
catch (err) {
|
|
366
|
-
|
|
367
|
-
|
|
457
|
+
anthropicRows.push({ key: "cli_installed", value: "false" });
|
|
458
|
+
anthropicRows.push({
|
|
459
|
+
key: "message",
|
|
460
|
+
value: `failed to probe Claude CLI${err ? `: ${sanitizeDisplayText(err instanceof Error ? err.message : String(err))}` : ""}`,
|
|
461
|
+
});
|
|
368
462
|
}
|
|
463
|
+
sections.push(createKvSection("anthropic", "anthropic:", anthropicRows));
|
|
464
|
+
// === cursor ===
|
|
369
465
|
const cursorPlanLabel = getCursorPlanDisplayName(params.cursorPlan);
|
|
370
466
|
const cursorIncludedApiUsd = getEffectiveCursorIncludedApiUsd({
|
|
371
467
|
plan: params.cursorPlan,
|
|
@@ -373,54 +469,83 @@ export async function buildQuotaStatusReport(params) {
|
|
|
373
469
|
});
|
|
374
470
|
const cursorAuth = await inspectCursorAuthPresence();
|
|
375
471
|
const cursorIntegration = await inspectCursorOpenCodeIntegration();
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
472
|
+
const cursorRows = [
|
|
473
|
+
{ key: "plan", value: cursorPlanLabel ?? "none" },
|
|
474
|
+
{
|
|
475
|
+
key: "included_api_usd",
|
|
476
|
+
value: typeof cursorIncludedApiUsd === "number" ? fmtUsdAmount(cursorIncludedApiUsd) : "(none)",
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
key: "billing_cycle_start_day",
|
|
480
|
+
value: typeof params.cursorBillingCycleStartDay === "number"
|
|
481
|
+
? String(params.cursorBillingCycleStartDay)
|
|
482
|
+
: "(calendar month)",
|
|
483
|
+
},
|
|
484
|
+
{ key: "auth_state", value: cursorAuth.state },
|
|
485
|
+
{ key: "auth_selected_path", value: cursorAuth.selectedPath ?? "(none)" },
|
|
486
|
+
{ key: "auth_present_paths", value: joinOrNone(cursorAuth.presentPaths) },
|
|
487
|
+
{ key: "auth_candidate_paths", value: joinOrNone(cursorAuth.candidatePaths) },
|
|
488
|
+
];
|
|
385
489
|
if (cursorAuth.error) {
|
|
386
|
-
|
|
490
|
+
cursorRows.push({ key: "auth_error", value: cursorAuth.error });
|
|
387
491
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
492
|
+
cursorRows.push({ key: "plugin_enabled", value: cursorIntegration.pluginEnabled ? "true" : "false" });
|
|
493
|
+
cursorRows.push({ key: "canonical_plugin_package", value: CURSOR_CANONICAL_PLUGIN_PACKAGE });
|
|
494
|
+
cursorRows.push({
|
|
495
|
+
key: "provider_configured",
|
|
496
|
+
value: cursorIntegration.providerConfigured ? "true" : "false",
|
|
497
|
+
});
|
|
498
|
+
cursorRows.push({ key: "config_matches", value: joinOrNone(cursorIntegration.matchedPaths) });
|
|
499
|
+
cursorRows.push({ key: "config_checked_paths", value: joinOrNone(cursorIntegration.checkedPaths) });
|
|
393
500
|
try {
|
|
394
501
|
const cursorUsage = await getCurrentCursorUsageSummary({
|
|
395
502
|
billingCycleStartDay: params.cursorBillingCycleStartDay,
|
|
396
503
|
});
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
504
|
+
cursorRows.push({ key: "cycle_source", value: cursorUsage.window.source });
|
|
505
|
+
cursorRows.push({ key: "cycle_reset_at", value: cursorUsage.window.resetTimeIso });
|
|
506
|
+
cursorRows.push({
|
|
507
|
+
key: "api_usage",
|
|
508
|
+
value: `${fmtUsdAmount(cursorUsage.api.costUsd)} across ${fmtInt(cursorUsage.api.messageCount)} messages`,
|
|
509
|
+
});
|
|
510
|
+
cursorRows.push({
|
|
511
|
+
key: "auto_composer_usage",
|
|
512
|
+
value: `${fmtUsdAmount(cursorUsage.autoComposer.costUsd)} across ${fmtInt(cursorUsage.autoComposer.messageCount)} messages`,
|
|
513
|
+
});
|
|
514
|
+
cursorRows.push({
|
|
515
|
+
key: "total_cursor_usage",
|
|
516
|
+
value: `${fmtUsdAmount(cursorUsage.total.costUsd)} across ${fmtInt(cursorUsage.total.messageCount)} messages`,
|
|
517
|
+
});
|
|
518
|
+
cursorRows.push({ key: "unknown_cursor_models", value: fmtInt(cursorUsage.unknownModels.length) });
|
|
403
519
|
}
|
|
404
520
|
catch (err) {
|
|
405
521
|
const msg = err instanceof Error ? err.message : String(err);
|
|
406
|
-
|
|
522
|
+
cursorRows.push({ key: "usage_error", value: msg });
|
|
407
523
|
}
|
|
408
524
|
const qwenLocalQuotaPath = getQwenLocalQuotaPath();
|
|
409
525
|
const qwenLocalQuotaExists = await pathExists(qwenLocalQuotaPath);
|
|
410
|
-
|
|
526
|
+
cursorRows.push({
|
|
527
|
+
key: "qwen free local quota",
|
|
528
|
+
value: `path=${qwenLocalQuotaPath} exists=${qwenLocalQuotaExists ? "true" : "false"}`,
|
|
529
|
+
});
|
|
411
530
|
try {
|
|
412
531
|
const qwenState = await readQwenLocalQuotaState();
|
|
413
532
|
const qwenQuota = computeQwenQuota({ state: qwenState });
|
|
414
533
|
const qwenUsageSuffix = qwenLocalQuotaExists ? "" : " (default state)";
|
|
415
|
-
|
|
534
|
+
cursorRows.push({
|
|
535
|
+
key: "qwen free local usage",
|
|
536
|
+
value: `daily=${qwenQuota.day.used}/${qwenQuota.day.limit} rpm=${qwenQuota.rpm.used}/${qwenQuota.rpm.limit}${qwenUsageSuffix}`,
|
|
537
|
+
});
|
|
416
538
|
}
|
|
417
539
|
catch (err) {
|
|
418
540
|
const msg = err instanceof Error ? err.message : String(err);
|
|
419
|
-
|
|
541
|
+
cursorRows.push({ key: "qwen free local usage", value: `error (${msg})` });
|
|
420
542
|
}
|
|
421
543
|
const alibabaLocalQuotaPath = getAlibabaCodingPlanQuotaPath();
|
|
422
544
|
const alibabaLocalQuotaExists = await pathExists(alibabaLocalQuotaPath);
|
|
423
|
-
|
|
545
|
+
cursorRows.push({
|
|
546
|
+
key: "alibaba coding plan local quota",
|
|
547
|
+
value: `path=${alibabaLocalQuotaPath} exists=${alibabaLocalQuotaExists ? "true" : "false"}`,
|
|
548
|
+
});
|
|
424
549
|
if (alibabaCodingPlanAuth.state === "configured") {
|
|
425
550
|
try {
|
|
426
551
|
const alibabaState = await readAlibabaCodingPlanQuotaState();
|
|
@@ -429,250 +554,366 @@ export async function buildQuotaStatusReport(params) {
|
|
|
429
554
|
tier: alibabaCodingPlanAuth.tier,
|
|
430
555
|
});
|
|
431
556
|
const alibabaUsageSuffix = alibabaLocalQuotaExists ? "" : " (default state)";
|
|
432
|
-
|
|
557
|
+
cursorRows.push({
|
|
558
|
+
key: "alibaba coding plan usage",
|
|
559
|
+
value: `tier=${alibabaCodingPlanAuth.tier} 5h=${alibabaQuota.fiveHour.used}/${alibabaQuota.fiveHour.limit} weekly=${alibabaQuota.weekly.used}/${alibabaQuota.weekly.limit} monthly=${alibabaQuota.monthly.used}/${alibabaQuota.monthly.limit}${alibabaUsageSuffix}`,
|
|
560
|
+
});
|
|
433
561
|
}
|
|
434
562
|
catch (err) {
|
|
435
563
|
const msg = err instanceof Error ? err.message : String(err);
|
|
436
|
-
|
|
564
|
+
cursorRows.push({ key: "alibaba coding plan usage", value: `error (${msg})` });
|
|
437
565
|
}
|
|
438
566
|
}
|
|
439
567
|
else if (alibabaCodingPlanAuth.state === "invalid") {
|
|
440
|
-
|
|
568
|
+
cursorRows.push({ key: "alibaba coding plan error", value: alibabaCodingPlanAuth.error });
|
|
441
569
|
}
|
|
442
|
-
|
|
443
|
-
|
|
570
|
+
sections.push(createKvSection("cursor", "cursor:", cursorRows));
|
|
571
|
+
// === minimax ===
|
|
572
|
+
const minimaxRows = [];
|
|
444
573
|
const minimaxAuth = await getMiniMaxAuthDiagnostics({
|
|
445
574
|
maxAgeMs: DEFAULT_MINIMAX_AUTH_CACHE_MAX_AGE_MS,
|
|
446
575
|
});
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
576
|
+
minimaxRows.push({ key: "auth_state", value: minimaxAuth.state });
|
|
577
|
+
minimaxRows.push({
|
|
578
|
+
key: "api_key_configured",
|
|
579
|
+
value: minimaxAuth.state === "configured" ? "true" : "false",
|
|
580
|
+
});
|
|
581
|
+
minimaxRows.push({ key: "api_key_source", value: minimaxAuth.source ?? "(none)" });
|
|
582
|
+
minimaxRows.push({ key: "api_key_checked_paths", value: joinOrNone(minimaxAuth.checkedPaths) });
|
|
583
|
+
minimaxRows.push({ key: "api_key_auth_paths", value: joinOrNone(minimaxAuth.authPaths) });
|
|
452
584
|
if (minimaxAuth.state === "invalid") {
|
|
453
|
-
|
|
585
|
+
minimaxRows.push({ key: "auth_error", value: sanitizeDisplayText(minimaxAuth.error) });
|
|
454
586
|
}
|
|
455
587
|
if (minimaxAuth.state === "configured") {
|
|
456
588
|
const resolvedMiniMaxAuth = await resolveMiniMaxAuthCached({
|
|
457
589
|
maxAgeMs: DEFAULT_MINIMAX_AUTH_CACHE_MAX_AGE_MS,
|
|
458
590
|
});
|
|
459
591
|
if (resolvedMiniMaxAuth.state !== "configured") {
|
|
460
|
-
|
|
592
|
+
minimaxRows.push({
|
|
593
|
+
key: "live_fetch_error",
|
|
594
|
+
value: "MiniMax API key became unavailable before fetch",
|
|
595
|
+
});
|
|
461
596
|
}
|
|
462
597
|
else {
|
|
463
598
|
const minimaxQuota = await queryMiniMaxQuota(resolvedMiniMaxAuth.apiKey);
|
|
464
599
|
if (!minimaxQuota.success) {
|
|
465
|
-
|
|
600
|
+
minimaxRows.push({ key: "live_fetch_error", value: minimaxQuota.error });
|
|
466
601
|
}
|
|
467
602
|
else {
|
|
468
603
|
const fiveHourEntry = minimaxQuota.entries.find((entry) => entry.window === "five_hour");
|
|
469
604
|
const weeklyEntry = minimaxQuota.entries.find((entry) => entry.window === "weekly");
|
|
470
605
|
if (fiveHourEntry) {
|
|
471
|
-
|
|
606
|
+
minimaxRows.push({
|
|
607
|
+
key: "five_hour_usage",
|
|
608
|
+
value: `${fiveHourEntry.right ?? "(none)"} percent_remaining=${fiveHourEntry.percentRemaining} reset_at=${fiveHourEntry.resetTimeIso ?? "(none)"}`,
|
|
609
|
+
});
|
|
472
610
|
}
|
|
473
611
|
if (weeklyEntry) {
|
|
474
|
-
|
|
612
|
+
minimaxRows.push({
|
|
613
|
+
key: "weekly_usage",
|
|
614
|
+
value: `${weeklyEntry.right ?? "(none)"} percent_remaining=${weeklyEntry.percentRemaining} reset_at=${weeklyEntry.resetTimeIso ?? "(none)"}`,
|
|
615
|
+
});
|
|
475
616
|
}
|
|
476
617
|
if (!fiveHourEntry && !weeklyEntry) {
|
|
477
|
-
|
|
618
|
+
minimaxRows.push({ key: "live_state", value: "no reportable MiniMax Coding Plan quota" });
|
|
478
619
|
}
|
|
479
620
|
}
|
|
480
621
|
}
|
|
481
622
|
}
|
|
482
|
-
|
|
483
|
-
|
|
623
|
+
sections.push(createKvSection("minimax", "minimax:", minimaxRows));
|
|
624
|
+
// === kimi ===
|
|
625
|
+
const kimiRows = [];
|
|
626
|
+
const kimiAuth = await getKimiAuthDiagnostics({
|
|
627
|
+
maxAgeMs: DEFAULT_KIMI_AUTH_CACHE_MAX_AGE_MS,
|
|
628
|
+
});
|
|
629
|
+
kimiRows.push({ key: "auth_state", value: kimiAuth.state });
|
|
630
|
+
kimiRows.push({
|
|
631
|
+
key: "api_key_configured",
|
|
632
|
+
value: kimiAuth.state === "configured" ? "true" : "false",
|
|
633
|
+
});
|
|
634
|
+
kimiRows.push({ key: "api_key_source", value: kimiAuth.source ?? "(none)" });
|
|
635
|
+
kimiRows.push({ key: "api_key_checked_paths", value: joinOrNone(kimiAuth.checkedPaths) });
|
|
636
|
+
kimiRows.push({ key: "api_key_auth_paths", value: joinOrNone(kimiAuth.authPaths) });
|
|
637
|
+
if (kimiAuth.state === "invalid") {
|
|
638
|
+
kimiRows.push({ key: "auth_error", value: sanitizeDisplayText(kimiAuth.error) });
|
|
639
|
+
}
|
|
640
|
+
if (kimiAuth.state === "configured") {
|
|
641
|
+
const kimiQuota = await queryKimiQuota();
|
|
642
|
+
if (!kimiQuota) {
|
|
643
|
+
kimiRows.push({
|
|
644
|
+
key: "live_fetch_error",
|
|
645
|
+
value: "Kimi API key became unavailable before fetch",
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
else if (!kimiQuota.success) {
|
|
649
|
+
kimiRows.push({ key: "live_fetch_error", value: kimiQuota.error });
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
for (const window of kimiQuota.windows) {
|
|
653
|
+
kimiRows.push({
|
|
654
|
+
key: window.label.toLowerCase().replace(/\s+/g, "_"),
|
|
655
|
+
value: `used=${window.used}/${window.limit} percent_remaining=${window.percentRemaining} reset_at=${window.resetTimeIso ?? "(none)"}`,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
if (kimiQuota.windows.length === 0) {
|
|
659
|
+
kimiRows.push({ key: "live_state", value: "no reportable Kimi quota" });
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
sections.push(createKvSection("kimi", "kimi:", kimiRows));
|
|
664
|
+
// === opencode_go ===
|
|
665
|
+
const openCodeGoRows = [];
|
|
484
666
|
const openCodeGoDiag = await getOpenCodeGoConfigDiagnostics();
|
|
485
|
-
|
|
486
|
-
|
|
667
|
+
openCodeGoRows.push({ key: "config_state", value: openCodeGoDiag.state });
|
|
668
|
+
openCodeGoRows.push({ key: "config_source", value: openCodeGoDiag.source ?? "(none)" });
|
|
487
669
|
if (openCodeGoDiag.missing) {
|
|
488
|
-
|
|
670
|
+
openCodeGoRows.push({ key: "config_missing", value: openCodeGoDiag.missing });
|
|
489
671
|
}
|
|
490
672
|
if (openCodeGoDiag.error) {
|
|
491
|
-
|
|
673
|
+
openCodeGoRows.push({ key: "config_error", value: sanitizeDisplayText(openCodeGoDiag.error) });
|
|
492
674
|
}
|
|
493
|
-
|
|
675
|
+
openCodeGoRows.push({ key: "config_checked_paths", value: joinOrNone(openCodeGoDiag.checkedPaths) });
|
|
494
676
|
if (openCodeGoDiag.state === "configured") {
|
|
495
677
|
const openCodeGoConfig = await resolveOpenCodeGoConfigCached({
|
|
496
678
|
maxAgeMs: DEFAULT_OPENCODE_GO_CONFIG_CACHE_MAX_AGE_MS,
|
|
497
679
|
});
|
|
498
680
|
if (openCodeGoConfig.state !== "configured") {
|
|
499
|
-
|
|
681
|
+
openCodeGoRows.push({
|
|
682
|
+
key: "live_fetch_error",
|
|
683
|
+
value: "OpenCode Go config became unavailable before fetch",
|
|
684
|
+
});
|
|
500
685
|
}
|
|
501
686
|
else {
|
|
502
687
|
const openCodeGoQuota = await queryOpenCodeGoQuota(openCodeGoConfig.config.workspaceId, openCodeGoConfig.config.authCookie);
|
|
503
688
|
if (!openCodeGoQuota) {
|
|
504
|
-
|
|
689
|
+
openCodeGoRows.push({ key: "live_fetch_error", value: "OpenCode Go returned null" });
|
|
505
690
|
}
|
|
506
691
|
else if (!openCodeGoQuota.success) {
|
|
507
|
-
|
|
692
|
+
openCodeGoRows.push({ key: "live_fetch_error", value: openCodeGoQuota.error });
|
|
508
693
|
}
|
|
509
694
|
else {
|
|
510
|
-
|
|
695
|
+
openCodeGoRows.push({
|
|
696
|
+
key: "monthly_usage",
|
|
697
|
+
value: `percent_used=${openCodeGoQuota.usagePercent} percent_remaining=${openCodeGoQuota.percentRemaining} reset_in_sec=${openCodeGoQuota.resetInSec} reset_at=${openCodeGoQuota.resetTimeIso}`,
|
|
698
|
+
});
|
|
511
699
|
}
|
|
512
700
|
}
|
|
513
701
|
}
|
|
514
|
-
|
|
515
|
-
|
|
702
|
+
sections.push(createKvSection("opencode_go", "opencode_go:", openCodeGoRows));
|
|
703
|
+
// === zai ===
|
|
704
|
+
const zaiRows = [];
|
|
516
705
|
const zaiAuth = await getZaiAuthDiagnostics({
|
|
517
706
|
maxAgeMs: DEFAULT_ZAI_AUTH_CACHE_MAX_AGE_MS,
|
|
518
707
|
});
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
708
|
+
zaiRows.push({ key: "auth_state", value: zaiAuth.state });
|
|
709
|
+
zaiRows.push({
|
|
710
|
+
key: "api_key_configured",
|
|
711
|
+
value: zaiAuth.state === "configured" ? "true" : "false",
|
|
712
|
+
});
|
|
713
|
+
zaiRows.push({ key: "api_key_source", value: zaiAuth.source ?? "(none)" });
|
|
714
|
+
zaiRows.push({ key: "api_key_checked_paths", value: joinOrNone(zaiAuth.checkedPaths) });
|
|
715
|
+
zaiRows.push({ key: "api_key_auth_paths", value: joinOrNone(zaiAuth.authPaths) });
|
|
524
716
|
if (zaiAuth.state === "invalid") {
|
|
525
|
-
|
|
717
|
+
zaiRows.push({ key: "auth_error", value: sanitizeDisplayText(zaiAuth.error) });
|
|
526
718
|
}
|
|
527
719
|
if (zaiAuth.state === "configured") {
|
|
528
720
|
const zaiQuota = await queryZaiQuota();
|
|
529
721
|
if (!zaiQuota) {
|
|
530
|
-
|
|
722
|
+
zaiRows.push({ key: "live_fetch_error", value: "Z.ai API key became unavailable before fetch" });
|
|
531
723
|
}
|
|
532
724
|
else if (!zaiQuota.success) {
|
|
533
|
-
|
|
725
|
+
zaiRows.push({ key: "live_fetch_error", value: zaiQuota.error });
|
|
534
726
|
}
|
|
535
727
|
else {
|
|
536
728
|
if (zaiQuota.windows.fiveHour) {
|
|
537
|
-
|
|
729
|
+
zaiRows.push({
|
|
730
|
+
key: "five_hour_remaining",
|
|
731
|
+
value: `${zaiQuota.windows.fiveHour.percentRemaining}% reset_at=${zaiQuota.windows.fiveHour.resetTimeIso ?? "(none)"}`,
|
|
732
|
+
});
|
|
538
733
|
}
|
|
539
734
|
if (zaiQuota.windows.weekly) {
|
|
540
|
-
|
|
735
|
+
zaiRows.push({
|
|
736
|
+
key: "weekly_remaining",
|
|
737
|
+
value: `${zaiQuota.windows.weekly.percentRemaining}% reset_at=${zaiQuota.windows.weekly.resetTimeIso ?? "(none)"}`,
|
|
738
|
+
});
|
|
541
739
|
}
|
|
542
740
|
if (zaiQuota.windows.mcp) {
|
|
543
|
-
|
|
741
|
+
zaiRows.push({
|
|
742
|
+
key: "mcp_remaining",
|
|
743
|
+
value: `${zaiQuota.windows.mcp.percentRemaining}% reset_at=${zaiQuota.windows.mcp.resetTimeIso ?? "(none)"}`,
|
|
744
|
+
});
|
|
544
745
|
}
|
|
545
746
|
if (!zaiQuota.windows.fiveHour && !zaiQuota.windows.weekly && !zaiQuota.windows.mcp) {
|
|
546
|
-
|
|
747
|
+
zaiRows.push({ key: "live_state", value: "no reportable Z.ai quota windows" });
|
|
547
748
|
}
|
|
548
749
|
}
|
|
549
750
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
751
|
+
sections.push(createKvSection("zai", "zai:", zaiRows));
|
|
752
|
+
// === simple API key sections ===
|
|
753
|
+
const syntheticDiag = await readBasicApiKeyDiagnostics(getSyntheticKeyDiagnostics);
|
|
754
|
+
sections.push(buildBasicApiKeySection({
|
|
755
|
+
id: "synthetic",
|
|
756
|
+
section: "synthetic:",
|
|
757
|
+
label: "synthetic api key",
|
|
758
|
+
diagnostics: syntheticDiag,
|
|
759
|
+
}));
|
|
557
760
|
const chutesDiag = await readBasicApiKeyDiagnostics(getChutesKeyDiagnostics);
|
|
558
|
-
|
|
559
|
-
|
|
761
|
+
sections.push(buildBasicApiKeySection({
|
|
762
|
+
id: "chutes",
|
|
560
763
|
section: "chutes:",
|
|
561
764
|
label: "chutes api key",
|
|
562
765
|
diagnostics: chutesDiag,
|
|
563
|
-
});
|
|
766
|
+
}));
|
|
767
|
+
// === nanogpt ===
|
|
564
768
|
const nanoGptDiag = await readNanoGptApiKeyDiagnostics(getNanoGptKeyDiagnostics);
|
|
565
|
-
|
|
769
|
+
const nanoGptRows = [
|
|
770
|
+
{ key: "api_key_configured", value: nanoGptDiag.configured ? "true" : "false" },
|
|
771
|
+
{ key: "api_key_source", value: nanoGptDiag.source ?? "(none)" },
|
|
772
|
+
{ key: "api_key_checked_paths", value: joinOrNone(nanoGptDiag.checkedPaths) },
|
|
773
|
+
{ key: "api_key_auth_paths", value: joinOrNone(nanoGptDiag.authPaths) },
|
|
774
|
+
];
|
|
566
775
|
if (nanoGptDiag.configured) {
|
|
567
776
|
try {
|
|
568
777
|
const nanoGptQuota = await queryNanoGptQuota();
|
|
569
778
|
if (!nanoGptQuota) {
|
|
570
|
-
|
|
779
|
+
nanoGptRows.push({
|
|
780
|
+
key: "live_fetch_error",
|
|
781
|
+
value: "NanoGPT API key became unavailable before fetch",
|
|
782
|
+
});
|
|
571
783
|
}
|
|
572
784
|
else if (!nanoGptQuota.success) {
|
|
573
|
-
|
|
785
|
+
nanoGptRows.push({ key: "live_fetch_error", value: nanoGptQuota.error });
|
|
574
786
|
}
|
|
575
787
|
else {
|
|
576
788
|
if (nanoGptQuota.subscription) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
789
|
+
nanoGptRows.push({
|
|
790
|
+
key: "subscription_active",
|
|
791
|
+
value: nanoGptQuota.subscription.active ? "true" : "false",
|
|
792
|
+
});
|
|
793
|
+
nanoGptRows.push({ key: "subscription_state", value: nanoGptQuota.subscription.state });
|
|
794
|
+
nanoGptRows.push({
|
|
795
|
+
key: "enforce_daily_limit",
|
|
796
|
+
value: nanoGptQuota.subscription.enforceDailyLimit ? "true" : "false",
|
|
797
|
+
});
|
|
580
798
|
if (nanoGptQuota.subscription.daily) {
|
|
581
799
|
const daily = nanoGptQuota.subscription.daily;
|
|
582
|
-
|
|
800
|
+
nanoGptRows.push({
|
|
801
|
+
key: "daily_usage",
|
|
802
|
+
value: `${fmtNanoGptMetric(daily.used)}/${fmtNanoGptMetric(daily.limit)} remaining=${fmtNanoGptMetric(daily.remaining)} percent_remaining=${daily.percentRemaining} reset_at=${daily.resetTimeIso ?? "(none)"}`,
|
|
803
|
+
});
|
|
583
804
|
}
|
|
584
805
|
if (nanoGptQuota.subscription.monthly) {
|
|
585
806
|
const monthly = nanoGptQuota.subscription.monthly;
|
|
586
|
-
|
|
807
|
+
nanoGptRows.push({
|
|
808
|
+
key: "monthly_usage",
|
|
809
|
+
value: `${fmtNanoGptMetric(monthly.used)}/${fmtNanoGptMetric(monthly.limit)} remaining=${fmtNanoGptMetric(monthly.remaining)} percent_remaining=${monthly.percentRemaining} reset_at=${monthly.resetTimeIso ?? "(none)"}`,
|
|
810
|
+
});
|
|
587
811
|
}
|
|
588
|
-
|
|
812
|
+
nanoGptRows.push({
|
|
813
|
+
key: "billing_period_end",
|
|
814
|
+
value: nanoGptQuota.subscription.currentPeriodEndIso ?? "(none)",
|
|
815
|
+
});
|
|
589
816
|
if (nanoGptQuota.subscription.graceUntilIso) {
|
|
590
|
-
|
|
817
|
+
nanoGptRows.push({ key: "grace_until", value: nanoGptQuota.subscription.graceUntilIso });
|
|
591
818
|
}
|
|
592
819
|
}
|
|
593
|
-
|
|
594
|
-
|
|
820
|
+
nanoGptRows.push({
|
|
821
|
+
key: "balance_usd",
|
|
822
|
+
value: typeof nanoGptQuota.balance?.usdBalance === "number"
|
|
823
|
+
? fmtUsdAmount(nanoGptQuota.balance.usdBalance)
|
|
824
|
+
: "(none)",
|
|
825
|
+
});
|
|
826
|
+
nanoGptRows.push({ key: "balance_nano", value: nanoGptQuota.balance?.nanoBalanceRaw ?? "(none)" });
|
|
595
827
|
for (const entry of nanoGptQuota.endpointErrors ?? []) {
|
|
596
|
-
|
|
828
|
+
nanoGptRows.push({ key: `live_error_${entry.endpoint}`, value: entry.message });
|
|
597
829
|
}
|
|
598
830
|
}
|
|
599
831
|
}
|
|
600
832
|
catch (err) {
|
|
601
833
|
const msg = err instanceof Error ? err.message : String(err);
|
|
602
|
-
|
|
834
|
+
nanoGptRows.push({ key: "live_fetch_error", value: msg });
|
|
603
835
|
}
|
|
604
836
|
}
|
|
837
|
+
sections.push(createKvSection("nanogpt", "nanogpt:", nanoGptRows));
|
|
838
|
+
// === copilot auth ===
|
|
605
839
|
const copilotDiag = getCopilotQuotaAuthDiagnostics(authData);
|
|
606
|
-
|
|
607
|
-
lines.push("copilot_quota_auth:");
|
|
608
|
-
lines.push(`- pat_state: ${copilotDiag.pat.state}`);
|
|
840
|
+
const copilotRows = [{ key: "pat_state", value: copilotDiag.pat.state }];
|
|
609
841
|
if (copilotDiag.pat.selectedPath) {
|
|
610
|
-
|
|
842
|
+
copilotRows.push({ key: "pat_path", value: copilotDiag.pat.selectedPath });
|
|
611
843
|
}
|
|
612
844
|
if (copilotDiag.pat.tokenKind) {
|
|
613
|
-
|
|
845
|
+
copilotRows.push({ key: "pat_token_kind", value: copilotDiag.pat.tokenKind });
|
|
614
846
|
}
|
|
615
847
|
if (copilotDiag.pat.config?.tier) {
|
|
616
|
-
|
|
848
|
+
copilotRows.push({ key: "pat_tier", value: copilotDiag.pat.config.tier });
|
|
617
849
|
}
|
|
618
850
|
if (copilotDiag.pat.config?.organization) {
|
|
619
|
-
|
|
851
|
+
copilotRows.push({ key: "pat_organization", value: copilotDiag.pat.config.organization });
|
|
620
852
|
}
|
|
621
853
|
if (copilotDiag.pat.config?.enterprise) {
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
854
|
+
copilotRows.push({ key: "pat_enterprise", value: copilotDiag.pat.config.enterprise });
|
|
855
|
+
}
|
|
856
|
+
copilotRows.push({ key: "billing_mode", value: copilotDiag.billingMode });
|
|
857
|
+
copilotRows.push({ key: "billing_scope", value: copilotDiag.billingScope });
|
|
858
|
+
copilotRows.push({ key: "quota_api", value: copilotDiag.quotaApi });
|
|
859
|
+
copilotRows.push({
|
|
860
|
+
key: "billing_api_access_likely",
|
|
861
|
+
value: copilotDiag.billingApiAccessLikely ? "true" : "false",
|
|
862
|
+
});
|
|
863
|
+
copilotRows.push({ key: "remaining_totals_state", value: copilotDiag.remainingTotalsState });
|
|
629
864
|
if (copilotDiag.queryPeriod) {
|
|
630
|
-
|
|
865
|
+
copilotRows.push({
|
|
866
|
+
key: "billing_period",
|
|
867
|
+
value: `${copilotDiag.queryPeriod.year}-${String(copilotDiag.queryPeriod.month).padStart(2, "0")}`,
|
|
868
|
+
});
|
|
631
869
|
}
|
|
632
870
|
if (copilotDiag.usernameFilter) {
|
|
633
|
-
|
|
871
|
+
copilotRows.push({ key: "username_filter", value: copilotDiag.usernameFilter });
|
|
634
872
|
}
|
|
635
873
|
if (copilotDiag.billingMode === "organization_usage") {
|
|
636
|
-
|
|
637
|
-
|
|
874
|
+
copilotRows.push({
|
|
875
|
+
key: "billing_usage_note",
|
|
876
|
+
value: "organization premium usage for the current billing period",
|
|
877
|
+
});
|
|
878
|
+
copilotRows.push({
|
|
879
|
+
key: "remaining_quota_note",
|
|
880
|
+
value: "valid PAT access can query billing usage, but pooled org usage does not provide a true per-user remaining quota",
|
|
881
|
+
});
|
|
638
882
|
}
|
|
639
883
|
if (copilotDiag.billingMode === "enterprise_usage") {
|
|
640
|
-
|
|
641
|
-
|
|
884
|
+
copilotRows.push({
|
|
885
|
+
key: "billing_usage_note",
|
|
886
|
+
value: "enterprise premium usage for the current billing period",
|
|
887
|
+
});
|
|
888
|
+
copilotRows.push({
|
|
889
|
+
key: "remaining_quota_note",
|
|
890
|
+
value: "valid enterprise billing access can query pooled enterprise usage, but it does not provide a true per-user remaining quota",
|
|
891
|
+
});
|
|
642
892
|
}
|
|
643
893
|
if (copilotDiag.billingTargetError) {
|
|
644
|
-
|
|
894
|
+
copilotRows.push({ key: "billing_target_error", value: copilotDiag.billingTargetError });
|
|
645
895
|
}
|
|
646
896
|
if (copilotDiag.tokenCompatibilityError) {
|
|
647
|
-
|
|
897
|
+
copilotRows.push({ key: "token_compatibility_error", value: copilotDiag.tokenCompatibilityError });
|
|
648
898
|
}
|
|
649
899
|
if (copilotDiag.pat.error) {
|
|
650
|
-
|
|
900
|
+
copilotRows.push({ key: "pat_error", value: copilotDiag.pat.error });
|
|
651
901
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
902
|
+
copilotRows.push({
|
|
903
|
+
key: "pat_checked_paths",
|
|
904
|
+
value: copilotDiag.pat.checkedPaths.length ? copilotDiag.pat.checkedPaths.join(" | ") : "(none)",
|
|
905
|
+
});
|
|
906
|
+
copilotRows.push({
|
|
907
|
+
key: "oauth_configured",
|
|
908
|
+
value: `${copilotDiag.oauth.configured ? "true" : "false"} key=${copilotDiag.oauth.keyName ?? "(none)"} refresh=${copilotDiag.oauth.hasRefreshToken ? "true" : "false"} access=${copilotDiag.oauth.hasAccessToken ? "true" : "false"}`,
|
|
909
|
+
});
|
|
910
|
+
copilotRows.push({ key: "effective_source", value: copilotDiag.effectiveSource });
|
|
911
|
+
copilotRows.push({ key: "override", value: copilotDiag.override });
|
|
912
|
+
sections.push(createKvSection("copilot_quota_auth", "copilot_quota_auth:", copilotRows));
|
|
913
|
+
// === google antigravity + db path ===
|
|
656
914
|
const googleTokenCachePath = getGoogleTokenCachePath();
|
|
657
915
|
const googleAuthPresence = await inspectAntigravityAccountsPresence();
|
|
658
916
|
const googleCompanionPresence = await inspectAntigravityCompanionPresence();
|
|
659
|
-
lines.push("");
|
|
660
|
-
lines.push("google_antigravity:");
|
|
661
|
-
lines.push(`- auth_state: ${googleAuthPresence.state}`);
|
|
662
|
-
lines.push(`- selected_accounts_path: ${googleAuthPresence.selectedPath ?? "(none)"}`);
|
|
663
|
-
lines.push(`- present_accounts_paths: ${joinOrNone(googleAuthPresence.presentPaths)}`);
|
|
664
|
-
lines.push(`- candidate_accounts_paths: ${joinOrNone(googleAuthPresence.candidatePaths)}`);
|
|
665
|
-
lines.push(`- account_count: ${googleAuthPresence.accountCount}`);
|
|
666
|
-
lines.push(`- valid_account_count: ${googleAuthPresence.validAccountCount}`);
|
|
667
|
-
lines.push(`- companion_package_state: ${googleCompanionPresence.state}`);
|
|
668
|
-
lines.push(`- companion_package_path: ${googleCompanionPresence.state === "present" || googleCompanionPresence.state === "invalid" ? googleCompanionPresence.resolvedPath ?? "(none)" : "(none)"}`);
|
|
669
|
-
if (googleCompanionPresence.state !== "present") {
|
|
670
|
-
lines.push(`- companion_error: ${sanitizeDisplayText(googleCompanionPresence.error)}`);
|
|
671
|
-
}
|
|
672
|
-
lines.push(`- token_cache_path: ${googleTokenCachePath} exists=${(await pathExists(googleTokenCachePath)) ? "true" : "false"}`);
|
|
673
|
-
if (googleAuthPresence.state === "invalid" && googleAuthPresence.error) {
|
|
674
|
-
lines.push(`- auth_error: ${sanitizeDisplayText(googleAuthPresence.error)}`);
|
|
675
|
-
}
|
|
676
917
|
const dbCandidates = getOpenCodeDbPathCandidates();
|
|
677
918
|
const dbSelected = getOpenCodeDbPath();
|
|
678
919
|
const dbPresent = [];
|
|
@@ -680,41 +921,75 @@ export async function buildQuotaStatusReport(params) {
|
|
|
680
921
|
if (await pathExists(p))
|
|
681
922
|
dbPresent.push(p);
|
|
682
923
|
}));
|
|
683
|
-
|
|
924
|
+
const googleRows = [
|
|
925
|
+
{ key: "auth_state", value: googleAuthPresence.state },
|
|
926
|
+
{ key: "selected_accounts_path", value: googleAuthPresence.selectedPath ?? "(none)" },
|
|
927
|
+
{ key: "present_accounts_paths", value: joinOrNone(googleAuthPresence.presentPaths) },
|
|
928
|
+
{ key: "candidate_accounts_paths", value: joinOrNone(googleAuthPresence.candidatePaths) },
|
|
929
|
+
{ key: "account_count", value: String(googleAuthPresence.accountCount) },
|
|
930
|
+
{ key: "valid_account_count", value: String(googleAuthPresence.validAccountCount) },
|
|
931
|
+
{ key: "companion_package_state", value: googleCompanionPresence.state },
|
|
932
|
+
{
|
|
933
|
+
key: "companion_package_path",
|
|
934
|
+
value: googleCompanionPresence.state === "present" || googleCompanionPresence.state === "invalid"
|
|
935
|
+
? googleCompanionPresence.resolvedPath ?? "(none)"
|
|
936
|
+
: "(none)",
|
|
937
|
+
},
|
|
938
|
+
];
|
|
939
|
+
if (googleCompanionPresence.state !== "present") {
|
|
940
|
+
googleRows.push({
|
|
941
|
+
key: "companion_error",
|
|
942
|
+
value: sanitizeDisplayText(googleCompanionPresence.error),
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
googleRows.push({
|
|
946
|
+
key: "token_cache_path",
|
|
947
|
+
value: `${googleTokenCachePath} exists=${(await pathExists(googleTokenCachePath)) ? "true" : "false"}`,
|
|
948
|
+
});
|
|
949
|
+
if (googleAuthPresence.state === "invalid" && googleAuthPresence.error) {
|
|
950
|
+
googleRows.push({ key: "auth_error", value: sanitizeDisplayText(googleAuthPresence.error) });
|
|
951
|
+
}
|
|
952
|
+
googleRows.push({
|
|
953
|
+
key: "opencode db",
|
|
954
|
+
value: `preferred=${dbSelected} present=${joinOrNone(dbPresent)} candidates=${joinOrNone(dbCandidates)}`,
|
|
955
|
+
});
|
|
956
|
+
sections.push(createKvSection("google_antigravity", "google_antigravity:", googleRows));
|
|
684
957
|
if (params.googleRefresh?.attempted) {
|
|
685
|
-
|
|
686
|
-
lines.push("google_token_refresh:");
|
|
958
|
+
const googleRefreshRows = [];
|
|
687
959
|
if (typeof params.googleRefresh.total === "number" &&
|
|
688
960
|
typeof params.googleRefresh.successCount === "number") {
|
|
689
|
-
|
|
961
|
+
googleRefreshRows.push({
|
|
962
|
+
key: "refreshed",
|
|
963
|
+
value: `${params.googleRefresh.successCount}/${params.googleRefresh.total}`,
|
|
964
|
+
});
|
|
690
965
|
}
|
|
691
966
|
else {
|
|
692
|
-
|
|
967
|
+
googleRefreshRows.push({ key: "attempted" });
|
|
693
968
|
}
|
|
694
969
|
for (const f of params.googleRefresh.failures ?? []) {
|
|
695
|
-
|
|
970
|
+
googleRefreshRows.push({ key: f.email ?? "Unknown", value: f.error });
|
|
696
971
|
}
|
|
972
|
+
sections.push(createKvSection("google_token_refresh", "google_token_refresh:", googleRefreshRows));
|
|
697
973
|
}
|
|
698
974
|
// === session token errors ===
|
|
699
975
|
if (params.sessionTokenError) {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
976
|
+
const sessionTokenErrorRows = [
|
|
977
|
+
{ key: "session_id", value: params.sessionTokenError.sessionID },
|
|
978
|
+
{ key: "error", value: params.sessionTokenError.error },
|
|
979
|
+
];
|
|
704
980
|
if (params.sessionTokenError.checkedPath) {
|
|
705
|
-
|
|
981
|
+
sessionTokenErrorRows.push({ key: "checked_path", value: params.sessionTokenError.checkedPath });
|
|
706
982
|
}
|
|
983
|
+
sections.push(createKvSection("session_tokens_error", "session_tokens_error:", sessionTokenErrorRows));
|
|
707
984
|
}
|
|
708
985
|
// === storage scan ===
|
|
709
986
|
const dbStats = await getOpenCodeDbStats();
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
987
|
+
sections.push(createKvSection("storage", "storage:", [
|
|
988
|
+
{ key: "sessions_in_db", value: fmtInt(dbStats.sessionCount) },
|
|
989
|
+
{ key: "messages_in_db", value: fmtInt(dbStats.messageCount) },
|
|
990
|
+
{ key: "assistant_messages_in_db", value: fmtInt(dbStats.assistantMessageCount) },
|
|
991
|
+
]));
|
|
715
992
|
// === pricing snapshot ===
|
|
716
|
-
// We intentionally compute all-time usage once so that pricing coverage and unknown_pricing
|
|
717
|
-
// are consistent and do not require multiple storage scans.
|
|
718
993
|
const agg = await aggregateUsage({});
|
|
719
994
|
const meta = getPricingSnapshotMeta();
|
|
720
995
|
const providers = listProviders();
|
|
@@ -728,73 +1003,113 @@ export async function buildQuotaStatusReport(params) {
|
|
|
728
1003
|
const runtimeSnapshotPath = getRuntimePricingSnapshotPath();
|
|
729
1004
|
const refreshStatePath = getRuntimePricingRefreshStatePath();
|
|
730
1005
|
const pricingRefreshState = await readPricingRefreshState();
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1006
|
+
const pricingRows = [
|
|
1007
|
+
{
|
|
1008
|
+
key: "pricing",
|
|
1009
|
+
value: `source=${meta.source} active_source=${snapshotSource} generated_at=${new Date(meta.generatedAt).toISOString()} units=${meta.units}`,
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
key: "selection",
|
|
1013
|
+
value: `configured=${params.pricingSnapshotSource} active=${snapshotSource}`,
|
|
1014
|
+
},
|
|
1015
|
+
];
|
|
735
1016
|
if (params.pricingSnapshotSource === "bundled") {
|
|
736
|
-
|
|
1017
|
+
pricingRows.push({
|
|
1018
|
+
key: "selection_note",
|
|
1019
|
+
value: "bundled config pins the packaged snapshot and ignores runtime refresh for active pricing",
|
|
1020
|
+
});
|
|
737
1021
|
}
|
|
738
1022
|
else if (params.pricingSnapshotSource === "runtime" && snapshotSource !== "runtime") {
|
|
739
|
-
|
|
1023
|
+
pricingRows.push({
|
|
1024
|
+
key: "selection_note",
|
|
1025
|
+
value: "runtime config requested the local runtime snapshot, but bundled fallback is active because no valid runtime snapshot is available",
|
|
1026
|
+
});
|
|
740
1027
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
1028
|
+
pricingRows.push({
|
|
1029
|
+
key: "runtime_paths",
|
|
1030
|
+
value: `snapshot=${runtimeSnapshotPath} refresh_state=${refreshStatePath}`,
|
|
1031
|
+
});
|
|
1032
|
+
pricingRows.push({
|
|
1033
|
+
key: "staleness",
|
|
1034
|
+
value: `age_ms=${fmtInt(health.ageMs)} max_age_ms=${fmtInt(health.maxAgeMs)} stale=${health.stale ? "true" : "false"}`,
|
|
1035
|
+
});
|
|
1036
|
+
pricingRows.push({
|
|
1037
|
+
key: "refresh_policy",
|
|
1038
|
+
value: `auto_refresh_days=${fmtInt(autoRefreshDays)}`,
|
|
1039
|
+
});
|
|
744
1040
|
if (pricingRefreshState) {
|
|
745
|
-
|
|
1041
|
+
pricingRows.push({
|
|
1042
|
+
key: "refresh",
|
|
1043
|
+
value: `last_attempt_at=${pricingRefreshState.lastAttemptAt ? new Date(pricingRefreshState.lastAttemptAt).toISOString() : "(none)"} last_success_at=${pricingRefreshState.lastSuccessAt ? new Date(pricingRefreshState.lastSuccessAt).toISOString() : "(none)"} last_failure_at=${pricingRefreshState.lastFailureAt ? new Date(pricingRefreshState.lastFailureAt).toISOString() : "(none)"} last_result=${pricingRefreshState.lastResult ?? "(none)"}`,
|
|
1044
|
+
});
|
|
746
1045
|
if (pricingRefreshState.lastError) {
|
|
747
|
-
|
|
1046
|
+
pricingRows.push({ key: "refresh_error", value: pricingRefreshState.lastError });
|
|
748
1047
|
}
|
|
749
1048
|
}
|
|
750
1049
|
else {
|
|
751
|
-
|
|
1050
|
+
pricingRows.push({ key: "refresh", value: "(no runtime refresh state yet)" });
|
|
752
1051
|
}
|
|
753
|
-
|
|
754
|
-
|
|
1052
|
+
pricingRows.push({ key: "providers", value: providers.join(",") });
|
|
1053
|
+
pricingRows.push({
|
|
1054
|
+
key: "coverage_seen",
|
|
1055
|
+
value: `priced_keys=${fmtInt(coverage.totals.pricedKeysSeen)} mapped_but_missing=${fmtInt(coverage.totals.mappedMissingKeysSeen)} unpriced_keys=${fmtInt(coverage.totals.unpricedKeysSeen)}`,
|
|
1056
|
+
});
|
|
755
1057
|
for (const p of providers) {
|
|
756
1058
|
const c = coverage.byProvider.get(p) ?? {
|
|
757
1059
|
pricedKeysSeen: 0,
|
|
758
1060
|
mappedMissingKeysSeen: 0,
|
|
759
1061
|
unpricedKeysSeen: 0,
|
|
760
1062
|
};
|
|
761
|
-
|
|
1063
|
+
pricingRows.push({
|
|
1064
|
+
key: p,
|
|
1065
|
+
value: `models=${fmtInt(getProviderModelCount(p))} priced_models_seen=${fmtInt(c.pricedKeysSeen)} mapped_but_missing_models_seen=${fmtInt(c.mappedMissingKeysSeen)} unpriced_models_seen=${fmtInt(c.unpricedKeysSeen)}`,
|
|
1066
|
+
indent: 1,
|
|
1067
|
+
});
|
|
762
1068
|
}
|
|
1069
|
+
sections.push(createKvSection("pricing_snapshot", "pricing_snapshot:", pricingRows));
|
|
763
1070
|
// === supported providers pricing ===
|
|
764
1071
|
const supported = getProviders().map((p) => p.id);
|
|
765
|
-
|
|
766
|
-
lines.push("supported_providers_pricing:");
|
|
767
|
-
for (const id of supported) {
|
|
1072
|
+
const supportedRows = supported.map((id) => {
|
|
768
1073
|
const row = supportedProviderPricingRow({ id, agg, snapshotProviders: providers });
|
|
769
|
-
|
|
770
|
-
|
|
1074
|
+
return {
|
|
1075
|
+
key: row.id,
|
|
1076
|
+
value: `pricing=${row.pricing} (${row.notes})`,
|
|
1077
|
+
};
|
|
1078
|
+
});
|
|
1079
|
+
sections.push(createKvSection("supported_providers_pricing", "supported_providers_pricing:", supportedRows));
|
|
771
1080
|
// === unpriced models ===
|
|
772
|
-
|
|
773
|
-
lines.push("");
|
|
774
|
-
lines.push("unpriced_models:");
|
|
1081
|
+
const unpricedRows = [];
|
|
775
1082
|
if (agg.unpriced.length === 0) {
|
|
776
|
-
|
|
1083
|
+
unpricedRows.push({ key: "none" });
|
|
777
1084
|
}
|
|
778
1085
|
else {
|
|
779
|
-
|
|
1086
|
+
unpricedRows.push({
|
|
1087
|
+
key: "keys",
|
|
1088
|
+
value: `${fmtInt(agg.unpriced.length)} tokens_total=${fmtInt(totalTokenBuckets(agg.totals.unpriced))}`,
|
|
1089
|
+
});
|
|
780
1090
|
for (const row of agg.unpriced.slice(0, STATUS_SAMPLE_LIMIT)) {
|
|
781
1091
|
const src = `${row.key.sourceProviderID}/${row.key.sourceModelID}`;
|
|
782
1092
|
const mapped = `${row.key.mappedProvider}/${row.key.mappedModel}`;
|
|
783
|
-
|
|
1093
|
+
unpricedRows.push({
|
|
1094
|
+
key: src,
|
|
1095
|
+
value: `mapped=${mapped} tokens=${fmtInt(totalTokenBuckets(row.tokens))} msgs=${fmtInt(row.messageCount)} reason=${row.key.reason}`,
|
|
1096
|
+
});
|
|
784
1097
|
}
|
|
785
1098
|
if (agg.unpriced.length > STATUS_SAMPLE_LIMIT) {
|
|
786
|
-
|
|
1099
|
+
unpricedRows.push({ key: `... (${fmtInt(agg.unpriced.length - STATUS_SAMPLE_LIMIT)} more)` });
|
|
787
1100
|
}
|
|
788
1101
|
}
|
|
1102
|
+
sections.push(createKvSection("unpriced_models", "unpriced_models:", unpricedRows));
|
|
789
1103
|
// === unknown pricing ===
|
|
790
|
-
|
|
791
|
-
lines.push("");
|
|
792
|
-
lines.push("unknown_pricing:");
|
|
1104
|
+
const unknownRows = [];
|
|
793
1105
|
if (agg.unknown.length === 0) {
|
|
794
|
-
|
|
1106
|
+
unknownRows.push({ key: "none" });
|
|
795
1107
|
}
|
|
796
1108
|
else {
|
|
797
|
-
|
|
1109
|
+
unknownRows.push({
|
|
1110
|
+
key: "keys",
|
|
1111
|
+
value: `${fmtInt(agg.unknown.length)} tokens_total=${fmtInt(totalTokenBuckets(agg.totals.unknown))}`,
|
|
1112
|
+
});
|
|
798
1113
|
for (const row of agg.unknown.slice(0, STATUS_SAMPLE_LIMIT)) {
|
|
799
1114
|
const src = `${row.key.sourceProviderID}/${row.key.sourceModelID}`;
|
|
800
1115
|
const mappedBase = row.key.mappedProvider && row.key.mappedModel
|
|
@@ -803,12 +1118,22 @@ export async function buildQuotaStatusReport(params) {
|
|
|
803
1118
|
const candidates = row.key.providerCandidates && row.key.providerCandidates.length > 0
|
|
804
1119
|
? ` candidates=${row.key.providerCandidates.join(",")}`
|
|
805
1120
|
: "";
|
|
806
|
-
|
|
1121
|
+
unknownRows.push({
|
|
1122
|
+
key: src,
|
|
1123
|
+
value: `mapped=${mappedBase}${candidates} tokens=${fmtInt(totalTokenBuckets(row.tokens))} msgs=${fmtInt(row.messageCount)}`,
|
|
1124
|
+
});
|
|
807
1125
|
}
|
|
808
1126
|
if (agg.unknown.length > STATUS_SAMPLE_LIMIT) {
|
|
809
|
-
|
|
1127
|
+
unknownRows.push({ key: `... (${fmtInt(agg.unknown.length - STATUS_SAMPLE_LIMIT)} more)` });
|
|
810
1128
|
}
|
|
811
1129
|
}
|
|
812
|
-
|
|
1130
|
+
sections.push(createKvSection("unknown_pricing", "unknown_pricing:", unknownRows));
|
|
1131
|
+
return renderPlainTextReport({
|
|
1132
|
+
heading: {
|
|
1133
|
+
title: `Quota Status (opencode-quota v${v}) (/quota_status)`,
|
|
1134
|
+
generatedAtMs: params.generatedAtMs,
|
|
1135
|
+
},
|
|
1136
|
+
sections,
|
|
1137
|
+
});
|
|
813
1138
|
}
|
|
814
1139
|
//# sourceMappingURL=quota-status.js.map
|