codex-multi-auth 2.16.0 → 2.17.0
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/.codex-plugin/plugin.json +1 -1
- package/README.md +22 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/lib/account-policy.d.ts +4 -0
- package/dist/lib/account-policy.d.ts.map +1 -1
- package/dist/lib/account-policy.js +8 -0
- package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
- package/dist/lib/accounts/rate-limits.js +2 -0
- package/dist/lib/accounts.d.ts +21 -3
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +229 -17
- package/dist/lib/api-route-store.d.ts +24 -0
- package/dist/lib/api-route-store.d.ts.map +1 -0
- package/dist/lib/api-route-store.js +145 -0
- package/dist/lib/auth/account-access.d.ts +115 -0
- package/dist/lib/auth/account-access.d.ts.map +1 -0
- package/dist/lib/auth/account-access.js +214 -0
- package/dist/lib/auth/token-utils.d.ts +54 -1
- package/dist/lib/auth/token-utils.d.ts.map +1 -1
- package/dist/lib/auth/token-utils.js +92 -7
- package/dist/lib/cli.d.ts +1 -1
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +4 -0
- package/dist/lib/codex-cli/state.d.ts +7 -0
- package/dist/lib/codex-cli/state.d.ts.map +1 -1
- package/dist/lib/codex-cli/state.js +18 -0
- package/dist/lib/codex-cli/writer.d.ts.map +1 -1
- package/dist/lib/codex-cli/writer.js +60 -8
- package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-manager-commands.js +1 -0
- package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-pool-write.js +4 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
- package/dist/lib/codex-manager/api-login-menu.js +224 -0
- package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/account.js +27 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +6 -2
- package/dist/lib/codex-manager/commands/check.d.ts +7 -1
- package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/check.js +24 -3
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +5 -1
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +5 -1
- package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
- package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/resets.js +67 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.js +63 -12
- package/dist/lib/codex-manager/commands/status.d.ts +12 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +166 -22
- package/dist/lib/codex-manager/commands/uninstall.js +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
- package/dist/lib/codex-manager/health-check.d.ts +3 -0
- package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
- package/dist/lib/codex-manager/health-check.js +56 -6
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +4 -2
- package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-flow.js +69 -7
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-data.js +14 -5
- package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +6 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
- package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
- package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
- package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
- package/dist/lib/codex-manager/persist-selected-account.js +2 -1
- package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/repair-commands.js +143 -8
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +25 -6
- package/dist/lib/concurrency.d.ts +3 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/concurrency.js +31 -0
- package/dist/lib/model-route-policy.d.ts +52 -0
- package/dist/lib/model-route-policy.d.ts.map +1 -0
- package/dist/lib/model-route-policy.js +159 -0
- package/dist/lib/policy/runtime-policy.d.ts +1 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +3 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +4 -0
- package/dist/lib/quota-probe.d.ts +5 -0
- package/dist/lib/quota-probe.d.ts.map +1 -1
- package/dist/lib/quota-probe.js +26 -2
- package/dist/lib/request/client-cancellation.d.ts +5 -0
- package/dist/lib/request/client-cancellation.d.ts.map +1 -0
- package/dist/lib/request/client-cancellation.js +7 -0
- package/dist/lib/request/response-outcome.d.ts +25 -0
- package/dist/lib/request/response-outcome.d.ts.map +1 -0
- package/dist/lib/request/response-outcome.js +49 -0
- package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +29 -10
- package/dist/lib/runtime/account-check.d.ts.map +1 -1
- package/dist/lib/runtime/account-check.js +2 -8
- package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
- package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
- package/dist/lib/runtime/account-model-catalog.js +154 -0
- package/dist/lib/runtime/account-pool.d.ts +3 -1
- package/dist/lib/runtime/account-pool.d.ts.map +1 -1
- package/dist/lib/runtime/account-pool.js +4 -0
- package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
- package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/account-reset-credits.js +82 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-capabilities.js +434 -0
- package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
- package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-runtime.js +358 -0
- package/dist/lib/runtime/app-bind.d.ts +19 -1
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +79 -9
- package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-account-checks.js +113 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/catalog-capabilities.js +61 -0
- package/dist/lib/runtime/inference-activity.d.ts +15 -0
- package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
- package/dist/lib/runtime/inference-activity.js +95 -0
- package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
- package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
- package/dist/lib/runtime/model-discovery-status.js +387 -0
- package/dist/lib/runtime/native-account-storage.d.ts +11 -0
- package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-storage.js +50 -0
- package/dist/lib/runtime/native-account-sync.d.ts +19 -0
- package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-sync.js +62 -0
- package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
- package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
- package/dist/lib/runtime/native-binding-lock.js +5 -0
- package/dist/lib/runtime/native-client-auth.d.ts +3 -0
- package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
- package/dist/lib/runtime/native-client-auth.js +42 -0
- package/dist/lib/runtime/native-provider-config.d.ts +4 -0
- package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
- package/dist/lib/runtime/native-provider-config.js +52 -0
- package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
- package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
- package/dist/lib/runtime/native-rate-limits.js +135 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credit-routing.js +66 -0
- package/dist/lib/runtime/reset-credits.d.ts +101 -0
- package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credits.js +162 -0
- package/dist/lib/runtime/response-output-history.d.ts +17 -0
- package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
- package/dist/lib/runtime/response-output-history.js +85 -0
- package/dist/lib/runtime/responses-websocket.d.ts +31 -0
- package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
- package/dist/lib/runtime/responses-websocket.js +636 -0
- package/dist/lib/runtime/resume-picker.d.ts +41 -0
- package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
- package/dist/lib/runtime/resume-picker.js +169 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +63 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
- package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-capability-failures.js +76 -0
- package/dist/lib/runtime/runtime-observability.d.ts +7 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +42 -2
- package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
- package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-first-use.js +64 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-event.js +31 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-order.js +31 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
- package/dist/lib/runtime/workspace-model-scopes.js +34 -0
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -1
- package/dist/lib/runtime-constants.js +5 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +4 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +852 -42
- package/dist/lib/schemas.d.ts +20 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +3 -0
- package/dist/lib/storage/credential-sidecars.d.ts +13 -0
- package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
- package/dist/lib/storage/credential-sidecars.js +52 -0
- package/dist/lib/storage/file-lock.d.ts +9 -0
- package/dist/lib/storage/file-lock.d.ts.map +1 -0
- package/dist/lib/storage/file-lock.js +186 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
- package/dist/lib/storage/flagged-storage.js +12 -0
- package/dist/lib/storage/path-state.d.ts +2 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -1
- package/dist/lib/storage/path-state.js +9 -0
- package/dist/lib/storage/paths.js +4 -4
- package/dist/lib/storage/pending-auth.d.ts +17 -0
- package/dist/lib/storage/pending-auth.d.ts.map +1 -0
- package/dist/lib/storage/pending-auth.js +153 -0
- package/dist/lib/storage/public-types.d.ts +13 -0
- package/dist/lib/storage/public-types.d.ts.map +1 -1
- package/dist/lib/storage/snapshot-merge.d.ts +16 -0
- package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
- package/dist/lib/storage/snapshot-merge.js +206 -0
- package/dist/lib/storage/transactions.d.ts.map +1 -1
- package/dist/lib/storage/transactions.js +5 -4
- package/dist/lib/storage.d.ts +6 -0
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +77 -7
- package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
- package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu-builder.js +1 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -0
- package/dist/lib/ui/check-progress.d.ts +8 -0
- package/dist/lib/ui/check-progress.d.ts.map +1 -0
- package/dist/lib/ui/check-progress.js +30 -0
- package/dist/lib/ui/format.d.ts +3 -1
- package/dist/lib/ui/format.d.ts.map +1 -1
- package/dist/lib/ui/format.js +8 -0
- package/dist/lib/ui/ui-copy.d.ts +2 -2
- package/dist/lib/ui/ui-copy.js +2 -2
- package/dist/lib/usage/pricing.js +2 -2
- package/dist/lib/usage/usage-extraction.d.ts +3 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
- package/dist/lib/usage/usage-extraction.js +46 -9
- package/package.json +7 -4
- package/scripts/codex-app-router.js +7 -0
- package/scripts/codex-bin-resolver.js +40 -8
- package/scripts/codex-routing.js +1 -0
- package/scripts/codex.js +100 -22
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resets.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/resets.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CAAC,IAAI,EAAC,MAAM,EAAE,GAAE,OAAO,CAAC,MAAM,CAAC,CA8BpE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AccountManager } from '../../accounts.js';
|
|
2
|
+
import { loadAccounts } from '../../storage.js';
|
|
3
|
+
import { runWithGlobalStoragePath } from '../../storage/path-state.js';
|
|
4
|
+
import { createResetCreditService, resetTargetForStoredAccount, resetAccountLabel } from '../../runtime/account-reset-credits.js';
|
|
5
|
+
import { withCheckProgress } from '../../ui/check-progress.js';
|
|
6
|
+
const usage = 'Usage: codex-multi-auth resets list [--refresh] | redeem <account-number> | auto manual|last-resort';
|
|
7
|
+
export async function runResetsCommand(args) {
|
|
8
|
+
const [command = 'list', value, ...extra] = args;
|
|
9
|
+
if (command === '--help' || command === '-h') {
|
|
10
|
+
console.log(usage);
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
if (extra.length || !['list', 'redeem', 'auto'].includes(command) || (command === 'list' && value !== undefined && value !== '--refresh') || (command === 'redeem' && !/^[1-9][0-9]*$/.test(value ?? '')) || (command === 'auto' && value !== 'manual' && value !== 'last-resort')) {
|
|
14
|
+
console.error(usage);
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
return runWithGlobalStoragePath(async () => {
|
|
18
|
+
const storage = await loadAccounts();
|
|
19
|
+
const manager = new AccountManager(undefined, storage);
|
|
20
|
+
const service = createResetCreditService(manager);
|
|
21
|
+
try {
|
|
22
|
+
if (command === 'auto') {
|
|
23
|
+
await service.setPolicy(value);
|
|
24
|
+
console.log(`Automatic reset redemption: ${value}`);
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
if (command === 'redeem') {
|
|
28
|
+
const index = Number(value) - 1;
|
|
29
|
+
const account = storage?.accounts[index];
|
|
30
|
+
const target = account && resetTargetForStoredAccount(account);
|
|
31
|
+
if (!target) {
|
|
32
|
+
console.error('Choose a configured, enabled subscription account/workspace.');
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
const outcome = await withCheckProgress(`Redeeming a reset for account ${index + 1}`, () => service.redeem(target));
|
|
36
|
+
console.log(`Account ${index + 1}: ${outcome}. Usage was re-read.`);
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
const targets = (storage?.accounts ?? []).map(resetTargetForStoredAccount).filter(t => t !== null);
|
|
40
|
+
const refreshed = value === '--refresh' ? await withCheckProgress('Refreshing reset-credit availability', () => service.refresh(targets)) : null;
|
|
41
|
+
const state = await service.status();
|
|
42
|
+
console.log(`Automatic redemption: ${state.policy}`);
|
|
43
|
+
if (state.lastRedemption) {
|
|
44
|
+
const index = (storage?.accounts ?? []).findIndex(a => resetTargetForStoredAccount(a)?.key === state.lastRedemption?.key);
|
|
45
|
+
console.log(`Last confirmed reset: ${index >= 0 ? `account ${index + 1}` : "removed account"}; ${state.lastRedemption.outcome}; ${state.lastRedemption.automatic ? "automatic" : "explicit"}`);
|
|
46
|
+
}
|
|
47
|
+
(storage?.accounts ?? []).forEach((a, i) => { const target = resetTargetForStoredAccount(a); const snapshot = target ? (refreshed ?? state.snapshots)[target.key] : undefined; console.log(`${resetAccountLabel(a, i)}: ${snapshot?.availableCount ?? 'unknown'} reset credits${snapshot ? ` (checked ${Math.max(0, Math.floor((Date.now() - snapshot.updatedAt) / 1000))}s ago)` : ''}${target?.key === state.pending?.key ? ' [redemption pending; retry this account]' : ''}`); });
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Only a consume whose result is unknown leaves a pending record; guard,
|
|
52
|
+
// pre-read and unknown-availability failures stop before spending anything.
|
|
53
|
+
const pending = command === 'redeem' ? await service.status().then(s => s.pending ?? null, () => ({ key: undefined })) : null;
|
|
54
|
+
// The pending record can belong to another account (a redeem is refused while
|
|
55
|
+
// any result is pending); point at the account that actually needs the retry.
|
|
56
|
+
const owner = pending?.key ? (storage?.accounts ?? []).findIndex(a => resetTargetForStoredAccount({ ...a, enabled: true, workspaces: undefined })?.key === pending.key) : -1;
|
|
57
|
+
const pendingAccount = owner >= 0 ? storage?.accounts[owner] : undefined;
|
|
58
|
+
const disabled = pendingAccount ? resetTargetForStoredAccount(pendingAccount) === null : false;
|
|
59
|
+
const retry = disabled ? `account ${owner + 1} or its workspace is disabled; re-enable it before retrying the pending result` : pending?.key && owner < 0 ? 'check it there (the pending account was removed)' : owner >= 0 && owner !== Number(value) - 1 ? `retry account ${owner + 1}, which holds the pending result` : 'retry the same account';
|
|
60
|
+
console.error(command === 'list' ? 'Reset-credit availability could not be refreshed. No credits were redeemed.' : command === 'auto' ? 'Reset-credit settings could not be updated.' : pending ? `Reset operation could not be confirmed. No new automatic redemption will be attempted while a result is pending; use resets list and ${retry}.` : 'No reset credit was redeemed. Availability could not be confirmed or a reset was just redeemed; run resets list --refresh and try again.');
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
await manager.flushPendingSave();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppBindResult, type AppBindStatus } from "../../runtime/app-bind.js";
|
|
1
|
+
import { type AppBindOptions, type AppBindResult, type AppBindStatus } from "../../runtime/app-bind.js";
|
|
2
2
|
import type { QuotaCacheData } from "../../quota-cache.js";
|
|
3
3
|
import { type RuntimeObservabilitySnapshot } from "../../runtime/runtime-observability.js";
|
|
4
4
|
import type { PluginConfig } from "../../types.js";
|
|
@@ -13,7 +13,7 @@ export interface RotationCommandDeps {
|
|
|
13
13
|
resolveActiveIndex: (storage: AccountStorageV3) => number;
|
|
14
14
|
getStoragePath: () => string | null;
|
|
15
15
|
setStoragePath: (path: string | null) => void;
|
|
16
|
-
bindCodexApp?: () => Promise<AppBindResult>;
|
|
16
|
+
bindCodexApp?: (options?: AppBindOptions) => Promise<AppBindResult>;
|
|
17
17
|
unbindCodexApp?: () => Promise<AppBindResult>;
|
|
18
18
|
getCodexAppBindStatus?: () => Promise<AppBindStatus>;
|
|
19
19
|
loadRuntimeObservabilitySnapshot?: () => Promise<RuntimeObservabilitySnapshot | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/rotation.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wCAAwC,CAAC;AAahD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAoB7C,MAAM,WAAW,mBAAmB;IACnC,gBAAgB,EAAE,MAAM,YAAY,CAAC;IACrC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,4BAA4B,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC1D,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/rotation.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wCAAwC,CAAC;AAahD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAoB7C,MAAM,WAAW,mBAAmB;IACnC,gBAAgB,EAAE,MAAM,YAAY,CAAC;IACrC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,4BAA4B,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC1D,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAkqBD,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAyHjB"}
|
|
@@ -30,7 +30,7 @@ function printRotationUsage(logInfo) {
|
|
|
30
30
|
" codex-multi-auth rotation enable",
|
|
31
31
|
" codex-multi-auth rotation disable",
|
|
32
32
|
" codex-multi-auth rotation status",
|
|
33
|
-
" codex-multi-auth rotation bind-app",
|
|
33
|
+
" codex-multi-auth rotation bind-app [--native [--catalog-account <idx>] | --custom-provider]",
|
|
34
34
|
" codex-multi-auth rotation unbind-app",
|
|
35
35
|
" codex-multi-auth rotation reset-rate-limits [--all | --account <idx>] [--dry-run] [--json]",
|
|
36
36
|
" codex-multi-auth rotation reset-runtime [--json]",
|
|
@@ -64,8 +64,14 @@ async function runResetRuntime(args, deps) {
|
|
|
64
64
|
let appBindRestarted = false;
|
|
65
65
|
if (deps.unbindCodexApp && deps.bindCodexApp) {
|
|
66
66
|
try {
|
|
67
|
+
const previous = await deps.getCodexAppBindStatus?.();
|
|
67
68
|
unbind = await deps.unbindCodexApp();
|
|
68
|
-
bind =
|
|
69
|
+
bind = previous?.state?.nativeOpenai
|
|
70
|
+
? await deps.bindCodexApp({
|
|
71
|
+
nativeOpenai: true,
|
|
72
|
+
catalogAccount: previous.state.catalogAccount,
|
|
73
|
+
})
|
|
74
|
+
: await deps.bindCodexApp(...(previous?.state ? [{ nativeOpenai: false }] : []));
|
|
69
75
|
appBindRestarted = true;
|
|
70
76
|
}
|
|
71
77
|
catch (error) {
|
|
@@ -630,6 +636,61 @@ export async function runRotationCommand(args, deps) {
|
|
|
630
636
|
if (subcommand === "reset-runtime") {
|
|
631
637
|
return runResetRuntime(rest, deps);
|
|
632
638
|
}
|
|
639
|
+
if (subcommand === "bind-app") {
|
|
640
|
+
if (!deps.bindCodexApp) {
|
|
641
|
+
logError("Codex app bind is unavailable in this build.");
|
|
642
|
+
return 1;
|
|
643
|
+
}
|
|
644
|
+
const options = {};
|
|
645
|
+
let catalogIndex;
|
|
646
|
+
for (let i = 0; i < rest.length; i += 1) {
|
|
647
|
+
const arg = rest[i];
|
|
648
|
+
if (arg === "--native" || arg === "--custom-provider") {
|
|
649
|
+
if (options.nativeOpenai !== undefined) {
|
|
650
|
+
logError("Choose one app bind mode.");
|
|
651
|
+
return 1;
|
|
652
|
+
}
|
|
653
|
+
options.nativeOpenai = arg === "--native";
|
|
654
|
+
}
|
|
655
|
+
else if (arg === "--catalog-account" && catalogIndex === undefined) {
|
|
656
|
+
const value = rest[++i] ?? "";
|
|
657
|
+
if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value))) {
|
|
658
|
+
logError("Catalog account must be a positive account index.");
|
|
659
|
+
return 1;
|
|
660
|
+
}
|
|
661
|
+
catalogIndex = Number(value) - 1;
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
logError(`Unknown app bind option: ${arg}`);
|
|
665
|
+
return 1;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (catalogIndex !== undefined) {
|
|
669
|
+
if (options.nativeOpenai !== true) {
|
|
670
|
+
logError("--catalog-account requires --native.");
|
|
671
|
+
return 1;
|
|
672
|
+
}
|
|
673
|
+
const previousStoragePath = deps.getStoragePath();
|
|
674
|
+
deps.setStoragePath(null);
|
|
675
|
+
let catalogStorage;
|
|
676
|
+
try {
|
|
677
|
+
catalogStorage = await deps.loadAccounts();
|
|
678
|
+
}
|
|
679
|
+
finally {
|
|
680
|
+
deps.setStoragePath(previousStoragePath);
|
|
681
|
+
}
|
|
682
|
+
const account = catalogStorage?.accounts[catalogIndex];
|
|
683
|
+
if (!account?.email || !account.accountId || account.enabled === false) {
|
|
684
|
+
logError("Catalog account must be an enabled account with an email and account ID.");
|
|
685
|
+
return 1;
|
|
686
|
+
}
|
|
687
|
+
options.catalogAccount = { email: account.email, accountId: account.accountId };
|
|
688
|
+
}
|
|
689
|
+
const result = rest.length ? await deps.bindCodexApp(options) : await deps.bindCodexApp();
|
|
690
|
+
logInfo(result.message);
|
|
691
|
+
logInfo(formatAppBindStatus(result.status));
|
|
692
|
+
return 0;
|
|
693
|
+
}
|
|
633
694
|
if (rest.length > 0) {
|
|
634
695
|
logError(`Unknown rotation option: ${rest[0]}`);
|
|
635
696
|
return 1;
|
|
@@ -669,16 +730,6 @@ export async function runRotationCommand(args, deps) {
|
|
|
669
730
|
}
|
|
670
731
|
return 0;
|
|
671
732
|
}
|
|
672
|
-
if (subcommand === "bind-app") {
|
|
673
|
-
if (!deps.bindCodexApp) {
|
|
674
|
-
logError("Codex app bind is unavailable in this build.");
|
|
675
|
-
return 1;
|
|
676
|
-
}
|
|
677
|
-
const result = await deps.bindCodexApp();
|
|
678
|
-
logInfo(result.message);
|
|
679
|
-
logInfo(formatAppBindStatus(result.status));
|
|
680
|
-
return 0;
|
|
681
|
-
}
|
|
682
733
|
if (subcommand === "unbind-app") {
|
|
683
734
|
if (!deps.unbindCodexApp) {
|
|
684
735
|
logError("Codex app bind is unavailable in this build.");
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { type loadResetCreditState } from "../../runtime/account-reset-credits.js";
|
|
2
|
+
import type { ApiRouteCredential } from "../../api-route-store.js";
|
|
3
|
+
import { loadAccountPolicyStore } from "../../account-policy.js";
|
|
4
|
+
import { type ModelInventory } from "../../runtime/model-discovery-status.js";
|
|
1
5
|
import type { ModelFamily } from "../../prompts/codex.js";
|
|
2
6
|
import type { QuotaCacheData } from "../../quota-cache.js";
|
|
3
7
|
import type { AppBindRouterStatus } from "../../runtime/app-bind.js";
|
|
@@ -6,14 +10,21 @@ import type { RuntimeObservabilitySnapshot } from "../../runtime/runtime-observa
|
|
|
6
10
|
import type { AccountStorageV3, StorageHealthSummary } from "../../storage.js";
|
|
7
11
|
type LoadedStorage = AccountStorageV3 | null;
|
|
8
12
|
export interface StatusCommandDeps {
|
|
13
|
+
loadResetCreditState?: typeof loadResetCreditState;
|
|
9
14
|
setStoragePath: (path: string | null) => void;
|
|
10
15
|
getStoragePath: () => string | null;
|
|
11
16
|
loadAccounts: () => Promise<LoadedStorage>;
|
|
12
17
|
resolveActiveIndex: (storage: AccountStorageV3, family?: ModelFamily) => number;
|
|
13
18
|
formatRateLimitEntry: (account: AccountStorageV3["accounts"][number], now: number, family: ModelFamily) => string | null;
|
|
14
19
|
loadRuntimeObservabilitySnapshot?: () => Promise<RuntimeObservabilitySnapshot | null>;
|
|
15
|
-
loadAppBindStatus?: () => Promise<AppBindRouterStatus
|
|
20
|
+
loadAppBindStatus?: () => Promise<(AppBindRouterStatus & {
|
|
21
|
+
nativeOpenai?: boolean;
|
|
22
|
+
}) | null>;
|
|
23
|
+
loadAccountPolicies?: typeof loadAccountPolicyStore;
|
|
16
24
|
loadAppHelperStatus?: () => RuntimeAccountSignal | null;
|
|
25
|
+
loadModelInventory?: () => Promise<ModelInventory | null>;
|
|
26
|
+
loadApiRoutes?: () => Promise<ApiRouteCredential[]>;
|
|
27
|
+
loadInferenceRequestTimes?: (keys: string[]) => Promise<Record<string, number>>;
|
|
17
28
|
loadQuotaCache?: () => Promise<QuotaCacheData | null>;
|
|
18
29
|
inspectStorageHealth?: () => Promise<StorageHealthSummary>;
|
|
19
30
|
getNow?: () => number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAIhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAuB,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAYpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1D,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAG7C,MAAM,WAAW,iBAAiB;IACjC,oBAAoB,CAAC,EAAE,OAAO,oBAAoB,CAAC;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,kBAAkB,EAAE,CACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,WAAW,KAChB,MAAM,CAAC;IACZ,oBAAoB,EAAE,CACrB,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,KACf,MAAM,GAAG,IAAI,CAAC;IACnB,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC,mBAAmB,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7F,mBAAmB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACpD,mBAAmB,CAAC,EAAE,MAAM,oBAAoB,GAAG,IAAI,CAAC;IACxD,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACpD,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAiFD,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,CAAC,CA2VjB;AAED,MAAM,WAAW,mBAAmB;IACnC,mBAAmB,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQpE"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import { resetSnapshotQuota } from "../../runtime/reset-credits.js";
|
|
2
|
+
import { resetTargetForStoredAccount } from "../../runtime/account-reset-credits.js";
|
|
3
|
+
import { subscriptionQuotaPreference, compareSubscriptionQuota, usesSubscriptionReserve, SUBSCRIPTION_RESERVE_PERCENT } from "../../runtime/subscription-quota-order.js";
|
|
4
|
+
import { styleReportText as paint } from "../../ui/format.js";
|
|
5
|
+
import { inferenceAccountKey } from "../../runtime/inference-activity.js";
|
|
6
|
+
import { modelScopeId } from "../../runtime/workspace-model-scopes.js";
|
|
7
|
+
import { loadAccountPolicyStore, getAccountPolicyKey } from "../../account-policy.js";
|
|
8
|
+
import { formatModelInventory } from "../../runtime/model-discovery-status.js";
|
|
1
9
|
import { AUTH_INVALIDATION_MARKER, formatAccountLabel, formatCooldown, formatWaitTime, formatWorkspaceLines, } from "../../accounts.js";
|
|
2
10
|
import { evaluateForecastAccounts, recommendForecastAccount, } from "../../forecast.js";
|
|
3
11
|
import { findQuotaCacheEntryForAccount, isQuotaCacheEntryExhausted, } from "../../quota-readiness.js";
|
|
@@ -60,13 +68,30 @@ function formatRuntimeLastAccount(runtimeSnapshot) {
|
|
|
60
68
|
}
|
|
61
69
|
return null;
|
|
62
70
|
}
|
|
71
|
+
/** Expired observations must not impose pressure after their window has reset. */
|
|
72
|
+
function forecastQuotaWindow(window, updatedAt, now) {
|
|
73
|
+
const expiresAt = window.resetAtMs ?? (window.windowMinutes && window.windowMinutes > 0 ? updatedAt + window.windowMinutes * 60_000 : null);
|
|
74
|
+
return expiresAt !== null && now >= expiresAt ? {} : window;
|
|
75
|
+
}
|
|
63
76
|
export async function runStatusCommand(deps) {
|
|
64
77
|
deps.setStoragePath(null);
|
|
65
|
-
|
|
78
|
+
let apiConfigurationUnavailable = false;
|
|
79
|
+
const apiRoutes = await deps.loadApiRoutes?.().catch(() => { apiConfigurationUnavailable = true; return []; }) ?? [];
|
|
80
|
+
const loadedStorage = await deps.loadAccounts();
|
|
81
|
+
const storage = loadedStorage ?? (apiRoutes.length ? { version: 3, activeIndex: 0, accounts: [] } : null);
|
|
66
82
|
const path = deps.getStoragePath();
|
|
67
83
|
const storageHealth = await deps.inspectStorageHealth?.();
|
|
68
84
|
const logInfo = deps.logInfo ?? console.log;
|
|
69
|
-
if (
|
|
85
|
+
if (apiConfigurationUnavailable && !deps.json)
|
|
86
|
+
logInfo("API configuration unavailable; subscription status remains available.");
|
|
87
|
+
const modelInventory = await deps.loadModelInventory?.();
|
|
88
|
+
const resetCredits = await deps.loadResetCreditState?.().catch(() => null);
|
|
89
|
+
const resetSnapshot = (account) => { const target = resetTargetForStoredAccount(account); return target ? resetCredits?.snapshots[target.key] : undefined; };
|
|
90
|
+
const accountPolicies = await (deps.loadAccountPolicies ?? loadAccountPolicyStore)().catch(() => ({ version: 1, accounts: {} }));
|
|
91
|
+
if (!deps.json && deps.loadModelInventory)
|
|
92
|
+
for (const line of formatModelInventory(modelInventory ?? null))
|
|
93
|
+
logInfo(line);
|
|
94
|
+
if (!storage || (storage.accounts.length === 0 && apiRoutes.length === 0)) {
|
|
70
95
|
const restoreReason = storage ? readRestoreReason(storage) : undefined;
|
|
71
96
|
const effectiveState = restoreReason === "intentional-reset"
|
|
72
97
|
? "intentional-reset"
|
|
@@ -78,8 +103,12 @@ export async function runStatusCommand(deps) {
|
|
|
78
103
|
if (deps.json) {
|
|
79
104
|
logInfo(JSON.stringify({
|
|
80
105
|
storagePath: path,
|
|
106
|
+
...(apiConfigurationUnavailable ? { warnings: ["api_configuration_unavailable"] } : {}),
|
|
81
107
|
storageHealth: effectiveState ?? null,
|
|
82
108
|
accountCount: 0,
|
|
109
|
+
totalAccountCount: 0,
|
|
110
|
+
apiAccounts: [],
|
|
111
|
+
modelInventory: modelInventory ?? null,
|
|
83
112
|
// Emit the same keys the populated branch does (as null) so a
|
|
84
113
|
// --json consumer sees one stable shape regardless of account count.
|
|
85
114
|
activeIndex: null,
|
|
@@ -98,37 +127,84 @@ export async function runStatusCommand(deps) {
|
|
|
98
127
|
: effectiveState === "corrupt"
|
|
99
128
|
? "No accounts configured. Storage appears corrupted."
|
|
100
129
|
: "No accounts configured.");
|
|
101
|
-
logInfo(`Storage: ${path}
|
|
130
|
+
logInfo(paint(`Storage: ${path}`, "muted"));
|
|
102
131
|
if (effectiveState) {
|
|
103
132
|
logInfo(`Storage health: ${effectiveState}`);
|
|
104
133
|
}
|
|
105
134
|
return 0;
|
|
106
135
|
}
|
|
107
136
|
const now = deps.getNow?.() ?? Date.now();
|
|
108
|
-
const activeIndex = deps.resolveActiveIndex(storage, "codex");
|
|
137
|
+
const activeIndex = storage.accounts.length ? deps.resolveActiveIndex(storage, "codex") : -1;
|
|
138
|
+
const quotaCache = await deps.loadQuotaCache?.() ?? null;
|
|
139
|
+
const forecastQuotas = storage.accounts.map(account => {
|
|
140
|
+
const cached = findQuotaCacheEntryForAccount(quotaCache, account, storage.accounts);
|
|
141
|
+
const reset = resetSnapshot(account);
|
|
142
|
+
const entry = reset && reset.updatedAt > (cached?.updatedAt ?? 0) && reset.updatedAt <= now && now - reset.updatedAt <= 60000 ? resetSnapshotQuota(reset) : cached;
|
|
143
|
+
if (!entry)
|
|
144
|
+
return null;
|
|
145
|
+
const primary = forecastQuotaWindow(entry.primary, entry.updatedAt, now);
|
|
146
|
+
const secondary = forecastQuotaWindow(entry.secondary, entry.updatedAt, now);
|
|
147
|
+
if (![primary, secondary].some(window => typeof window.usedPercent === "number" && Number.isFinite(window.usedPercent)))
|
|
148
|
+
return null;
|
|
149
|
+
return { ...entry, primary, secondary };
|
|
150
|
+
});
|
|
109
151
|
const forecastResults = evaluateForecastAccounts(storage.accounts.map((account, index) => ({
|
|
110
152
|
index,
|
|
111
153
|
account,
|
|
112
154
|
isCurrent: index === activeIndex,
|
|
113
155
|
now,
|
|
156
|
+
quotaCache,
|
|
157
|
+
allAccounts: storage.accounts,
|
|
158
|
+
liveQuota: forecastQuotas[index] ?? undefined,
|
|
114
159
|
})));
|
|
115
160
|
const recommendation = recommendForecastAccount(forecastResults);
|
|
116
161
|
if (!deps.json) {
|
|
117
|
-
logInfo(`Accounts (${storage.accounts.length})`);
|
|
118
|
-
logInfo(`Storage: ${path}
|
|
162
|
+
logInfo(paint(apiRoutes.length ? `Accounts (${storage.accounts.length + apiRoutes.length}: ${storage.accounts.length} subscription, ${apiRoutes.length} API/ZDR)` : `Accounts (${storage.accounts.length})`, "heading"));
|
|
163
|
+
logInfo(paint(`Storage: ${path}`, "muted"));
|
|
119
164
|
if (recommendation.recommendedIndex !== null) {
|
|
120
|
-
logInfo(`
|
|
165
|
+
logInfo(paint(`Forecast suggestion: account ${recommendation.recommendedIndex + 1} (${recommendation.reason})`, "accent"));
|
|
121
166
|
}
|
|
122
167
|
if (storageHealth) {
|
|
123
|
-
logInfo(`Storage health: ${storageHealth.state}
|
|
168
|
+
logInfo(paint(`Storage health: ${storageHealth.state}`, storageHealth.state === "healthy" ? "success" : "warning"));
|
|
124
169
|
}
|
|
125
170
|
}
|
|
126
171
|
const appHelperStatus = deps.loadAppHelperStatus?.() ?? null;
|
|
127
|
-
const [runtimeSnapshot, appBindStatus
|
|
172
|
+
const [runtimeSnapshot, appBindStatus] = await Promise.all([
|
|
128
173
|
deps.loadRuntimeObservabilitySnapshot?.() ?? Promise.resolve(null),
|
|
129
174
|
deps.loadAppBindStatus?.() ?? Promise.resolve(null),
|
|
130
|
-
deps.loadQuotaCache?.() ?? Promise.resolve(null),
|
|
131
175
|
]);
|
|
176
|
+
const quotaPreferences = forecastQuotas.map(quota => subscriptionQuotaPreference(quota, now));
|
|
177
|
+
const automaticOrder = new Map();
|
|
178
|
+
if (appBindStatus?.nativeOpenai) {
|
|
179
|
+
const candidates = storage.accounts.map((account, index) => ({ account, index, quota: quotaPreferences[index] ?? subscriptionQuotaPreference(null, now), tier: accountPolicies.accounts[getAccountPolicyKey(account, index)]?.priority ?? 1 }))
|
|
180
|
+
.filter(a => forecastResults[a.index]?.availability === "ready" && !a.quota.exhausted);
|
|
181
|
+
candidates.sort((a, b) => Number(usesSubscriptionReserve(a.quota)) - Number(usesSubscriptionReserve(b.quota)) ||
|
|
182
|
+
a.tier - b.tier || compareSubscriptionQuota(a.quota, b.quota) || Number(b.index === activeIndex) - Number(a.index === activeIndex) || a.index - b.index);
|
|
183
|
+
// A switch pin is strict in native mode too: no other account is tried, so none gets an order.
|
|
184
|
+
const pinned = typeof storage.pinnedAccountIndex === "number" ? candidates.filter(a => a.index === storage.pinnedAccountIndex) : candidates;
|
|
185
|
+
pinned.forEach((a, index) => { automaticOrder.set(a.index, index + 1); });
|
|
186
|
+
}
|
|
187
|
+
const activityKeys = [...storage.accounts.map(inferenceAccountKey), ...apiRoutes.map(route => `sha256:${modelScopeId(route.kind, route.id)}`)];
|
|
188
|
+
const persistedActivity = await deps.loadInferenceRequestTimes?.(activityKeys) ?? {};
|
|
189
|
+
const inferenceTimes = { ...runtimeSnapshot?.lastInferenceRequestAtByAccount };
|
|
190
|
+
for (const [key, at] of Object.entries(persistedActivity))
|
|
191
|
+
inferenceTimes[key] = Math.max(inferenceTimes[key] ?? 0, at);
|
|
192
|
+
const apiAccounts = apiRoutes.map((route, index) => ({
|
|
193
|
+
index, label: route.label, kind: route.kind, enabled: route.enabled, priority: route.priority,
|
|
194
|
+
visibleModelCount: route.visibleModels.length,
|
|
195
|
+
lastInferenceRequestAt: inferenceTimes[`sha256:${modelScopeId(route.kind, route.id)}`] ?? null,
|
|
196
|
+
}));
|
|
197
|
+
const printApiAccounts = () => {
|
|
198
|
+
if (!apiAccounts.length)
|
|
199
|
+
return;
|
|
200
|
+
logInfo("");
|
|
201
|
+
logInfo(paint(`API/ZDR accounts (${apiAccounts.length}; separate privacy pools, lower tier first):`, "heading"));
|
|
202
|
+
for (const account of apiAccounts) {
|
|
203
|
+
const last = account.lastInferenceRequestAt === null ? "inference not yet recorded" : `last inference request ${formatWaitTime(Math.max(0, now - account.lastInferenceRequestAt))} ago`;
|
|
204
|
+
logInfo(`${paint(`${account.kind.toUpperCase()} account ${account.index + 1}: ${account.label}`, "heading")}${account.enabled ? "" : paint(" [disabled]", "warning")} ${paint(last, "muted")}`);
|
|
205
|
+
logInfo(` ${paint(`priority tier: ${account.priority}`, "accent")}; visible models: ${account.visibleModelCount}`);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
132
208
|
const runtimeCurrent = resolveRuntimeCurrentAccount(storage, {
|
|
133
209
|
runtimeSnapshot,
|
|
134
210
|
appBindStatus,
|
|
@@ -141,10 +217,23 @@ export async function runStatusCommand(deps) {
|
|
|
141
217
|
const markers = buildAccountMarkers(account, i, activeIndex, runtimeCurrent, now, quotaCache, storage.accounts, deps.formatRateLimitEntry);
|
|
142
218
|
return {
|
|
143
219
|
index: i,
|
|
220
|
+
resetCreditsAvailable: resetSnapshot(account)?.availableCount ?? null,
|
|
221
|
+
resetCreditsCheckedAt: resetSnapshot(account)?.updatedAt ?? null,
|
|
144
222
|
label: formatAccountLabel(account, i),
|
|
145
223
|
enabled: account.enabled !== false,
|
|
146
224
|
current: i === activeIndex,
|
|
225
|
+
priority: accountPolicies.accounts[getAccountPolicyKey(account, i)]?.priority ?? 1,
|
|
226
|
+
autoPrime: accountPolicies.accounts[getAccountPolicyKey(account, i)]?.autoPrime ?? false,
|
|
147
227
|
markers,
|
|
228
|
+
selectionPreference: storage.pinnedAccountIndex === i ? "strict-pin" : null,
|
|
229
|
+
forecastRiskScore: forecastResults[i]?.riskScore ?? null,
|
|
230
|
+
forecastRiskLevel: forecastResults[i]?.riskLevel ?? null,
|
|
231
|
+
forecastQuotaUpdatedAt: forecastQuotas[i]?.updatedAt ?? null,
|
|
232
|
+
automaticOrder: automaticOrder.get(i) ?? null,
|
|
233
|
+
subscriptionReserve: usesSubscriptionReserve(quotaPreferences[i]),
|
|
234
|
+
quotaResetAt: quotaPreferences[i]?.resetAtMs ?? null,
|
|
235
|
+
quotaDrainPerHour: quotaPreferences[i]?.urgency ?? null,
|
|
236
|
+
lastInferenceRequestAt: inferenceTimes[inferenceAccountKey(account)] ?? null,
|
|
148
237
|
lastUsed: typeof account.lastUsed === "number" && account.lastUsed > 0
|
|
149
238
|
? account.lastUsed
|
|
150
239
|
: null,
|
|
@@ -153,8 +242,12 @@ export async function runStatusCommand(deps) {
|
|
|
153
242
|
});
|
|
154
243
|
logInfo(JSON.stringify({
|
|
155
244
|
storagePath: path,
|
|
245
|
+
...(apiConfigurationUnavailable ? { warnings: ["api_configuration_unavailable"] } : {}),
|
|
156
246
|
storageHealth: storageHealth?.state ?? null,
|
|
157
247
|
accountCount: storage.accounts.length,
|
|
248
|
+
apiAccounts,
|
|
249
|
+
totalAccountCount: storage.accounts.length + apiAccounts.length,
|
|
250
|
+
selectionMode: appBindStatus?.nativeOpenai ? "model-priority" : "legacy-pin",
|
|
158
251
|
activeIndex,
|
|
159
252
|
pinnedAccountIndex: typeof storage.pinnedAccountIndex === "number"
|
|
160
253
|
? storage.pinnedAccountIndex
|
|
@@ -162,7 +255,13 @@ export async function runStatusCommand(deps) {
|
|
|
162
255
|
recommendedIndex: recommendation.recommendedIndex,
|
|
163
256
|
recommendationReason: recommendation.reason,
|
|
164
257
|
runtimeInUseIndex: runtimeCurrent ? runtimeCurrent.index : null,
|
|
258
|
+
modelInventory: modelInventory ?? null,
|
|
165
259
|
accounts,
|
|
260
|
+
lastRequestedWorkspace: runtimeSnapshot?.lastRequestedWorkspaceId ? {
|
|
261
|
+
id: runtimeSnapshot.lastRequestedWorkspaceId,
|
|
262
|
+
accountIndex: runtimeSnapshot.lastAccountIndex ?? null,
|
|
263
|
+
requestedAt: runtimeSnapshot.lastAccountUpdatedAt ?? null,
|
|
264
|
+
} : null,
|
|
166
265
|
}, null, 2));
|
|
167
266
|
return 0;
|
|
168
267
|
}
|
|
@@ -179,8 +278,18 @@ export async function runStatusCommand(deps) {
|
|
|
179
278
|
logInfo(`Runtime: responses=${runtimeSnapshot.responsesRequests}, refresh=${runtimeSnapshot.authRefreshRequests}, probes=${runtimeSnapshot.diagnosticProbeRequests}, budgetExhaustions=${runtimeMetrics.requestAttemptBudgetExhaustions}`);
|
|
180
279
|
const lastRuntimeAccount = formatRuntimeLastAccount(runtimeSnapshot);
|
|
181
280
|
if (lastRuntimeAccount) {
|
|
182
|
-
logInfo(`Last runtime account: ${lastRuntimeAccount}
|
|
281
|
+
logInfo(paint(`Last runtime account: ${lastRuntimeAccount}`, "accent"));
|
|
282
|
+
if (typeof runtimeSnapshot.lastAccountUpdatedAt === "number" && runtimeSnapshot.lastAccountUpdatedAt > 0)
|
|
283
|
+
logInfo(`Last runtime request: ${formatWaitTime(Math.max(0, now - runtimeSnapshot.lastAccountUpdatedAt))} ago`);
|
|
183
284
|
}
|
|
285
|
+
const requestedId = runtimeSnapshot.lastRequestedWorkspaceId;
|
|
286
|
+
if (requestedId) {
|
|
287
|
+
const index = resolveRuntimeCurrentAccount(storage, { runtimeSnapshot }, { now })?.index;
|
|
288
|
+
const workspace = index === undefined ? undefined : storage.accounts[index]?.workspaces?.find(w => w.id === requestedId);
|
|
289
|
+
logInfo(`Last requested workspace: ${index === undefined ? "" : `account ${index + 1} / `}${workspace?.name?.trim() || "unlabelled"} (id:${requestedId.slice(-6)}; outgoing scope, billing plan not verified)`);
|
|
290
|
+
}
|
|
291
|
+
else
|
|
292
|
+
logInfo("Last requested workspace: not recorded");
|
|
184
293
|
if (poolCooldown || serverCooldown) {
|
|
185
294
|
logInfo(`Cooldowns: pool=${poolCooldown ?? "none"}, server-burst=${serverCooldown ?? "none"}`);
|
|
186
295
|
}
|
|
@@ -189,8 +298,11 @@ export async function runStatusCommand(deps) {
|
|
|
189
298
|
}
|
|
190
299
|
}
|
|
191
300
|
if (runtimeCurrent) {
|
|
192
|
-
logInfo(`Runtime in use: account ${runtimeCurrent.index + 1} (${runtimeCurrent.source})
|
|
301
|
+
logInfo(paint(`Runtime in use: account ${runtimeCurrent.index + 1} (${runtimeCurrent.source})`, "accent"));
|
|
193
302
|
}
|
|
303
|
+
if (appBindStatus?.nativeOpenai)
|
|
304
|
+
logInfo(paint("Automatic order estimates use the last check; requested model/workspace and live health can change the order.", "muted"));
|
|
305
|
+
logInfo(paint("Account/workspace labels below describe saved settings, not the last routed workspace.", "muted"));
|
|
194
306
|
const pinnedAccountIndex = storage.pinnedAccountIndex;
|
|
195
307
|
if (typeof pinnedAccountIndex === "number") {
|
|
196
308
|
if (!Number.isInteger(pinnedAccountIndex) ||
|
|
@@ -199,8 +311,8 @@ export async function runStatusCommand(deps) {
|
|
|
199
311
|
logInfo(`Pinned: invalid account index ${pinnedAccountIndex}; run codex-multi-auth unpin`);
|
|
200
312
|
}
|
|
201
313
|
else {
|
|
202
|
-
logInfo(`Pinned: account ${pinnedAccountIndex + 1} (set by switch)
|
|
203
|
-
if (runtimeCurrent && runtimeCurrent.index !== pinnedAccountIndex) {
|
|
314
|
+
logInfo(paint(`Pinned: account ${pinnedAccountIndex + 1} (strict; set by switch)`, "accent"));
|
|
315
|
+
if (!appBindStatus?.nativeOpenai && runtimeCurrent && runtimeCurrent.index !== pinnedAccountIndex) {
|
|
204
316
|
logInfo(` warning: runtime currently using account ${runtimeCurrent.index + 1} but pin requests account ${pinnedAccountIndex + 1}; the proxy will pick up the pin on the next request.`);
|
|
205
317
|
}
|
|
206
318
|
}
|
|
@@ -212,24 +324,56 @@ export async function runStatusCommand(deps) {
|
|
|
212
324
|
continue;
|
|
213
325
|
const label = formatAccountLabel(account, i);
|
|
214
326
|
const markers = buildAccountMarkers(account, i, activeIndex, runtimeCurrent, now, quotaCache, storage.accounts, deps.formatRateLimitEntry);
|
|
327
|
+
if (storage.pinnedAccountIndex === i)
|
|
328
|
+
markers.push("strict pin");
|
|
215
329
|
const markerLabel = markers.length > 0 ? ` [${markers.join(", ")}]` : "";
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
: "
|
|
219
|
-
|
|
330
|
+
const lastInferenceAt = inferenceTimes[inferenceAccountKey(account)];
|
|
331
|
+
const activity = typeof account.lastUsed === "number" && account.lastUsed > 0
|
|
332
|
+
? `account activity ${formatWaitTime(Math.max(0, now - account.lastUsed))} ago` : "no account activity recorded";
|
|
333
|
+
const lastUsed = typeof lastInferenceAt === "number" && lastInferenceAt > 0
|
|
334
|
+
? `last inference request ${formatWaitTime(Math.max(0, now - lastInferenceAt))} ago`
|
|
335
|
+
: `inference not yet recorded; ${activity}`;
|
|
336
|
+
logInfo(`${paint(`${i + 1}. ${label}`, "heading")}${paint(markerLabel, markers.some(m => /disabled|cooldown|exhausted|limited|invalid/.test(m)) ? "warning" : "success")} ${paint(lastUsed, "muted")}`);
|
|
337
|
+
logInfo(` ${paint(`priority tier: ${accountPolicies.accounts[getAccountPolicyKey(account, i)]?.priority ?? 1}`, "accent")}`);
|
|
338
|
+
if (accountPolicies.accounts[getAccountPolicyKey(account, i)]?.autoPrime)
|
|
339
|
+
logInfo(" automatic first-use priming: on (router checks every 15 minutes)");
|
|
340
|
+
if (appBindStatus?.nativeOpenai) {
|
|
341
|
+
const preference = quotaPreferences[i];
|
|
342
|
+
const order = automaticOrder.get(i);
|
|
343
|
+
const reset = preference?.resetAtMs ? `; limiting window resets in ${formatWaitTime(Math.max(0, preference.resetAtMs - now))}` : "; reset ordering unknown; run check";
|
|
344
|
+
const reserve = usesSubscriptionReserve(preference) ? `; ${SUBSCRIPTION_RESERVE_PERCENT}% reserve (last resort)` : "";
|
|
345
|
+
const pinnedElsewhere = typeof storage.pinnedAccountIndex === "number" && storage.pinnedAccountIndex !== i;
|
|
346
|
+
logInfo(paint(` automatic order: ${order ? `#${order}` : pinnedElsewhere ? `none (account ${(storage.pinnedAccountIndex ?? 0) + 1} is pinned)` : "unavailable"}${reset}${reserve}`, reserve ? "warning" : "accent"));
|
|
347
|
+
}
|
|
348
|
+
const quota = forecastQuotas[i];
|
|
349
|
+
if (quota) {
|
|
350
|
+
const windows = ["primary", "secondary"].flatMap(key => {
|
|
351
|
+
const used = quota[key].usedPercent;
|
|
352
|
+
return typeof used === "number" && Number.isFinite(used) ? [paint(`${key} ${Math.max(0, Math.min(100, Math.round(100 - used)))}% left`, used >= 95 ? "danger" : used >= 80 ? "warning" : "success")] : [];
|
|
353
|
+
});
|
|
354
|
+
logInfo(` quota: ${windows.join("; ")} (${paint(`cached quota ${formatWaitTime(Math.max(0, now - quota.updatedAt))} ago`, "muted")})`);
|
|
355
|
+
}
|
|
356
|
+
else
|
|
357
|
+
logInfo(paint(" quota unknown; run check (risk uses other known signals only)", "warning"));
|
|
358
|
+
const forecast = forecastResults[i];
|
|
359
|
+
const resets = resetSnapshot(account);
|
|
360
|
+
logInfo(` subscription resets: ${resets?.availableCount ?? "unknown"}${resets ? ` (cached ${formatWaitTime(Math.max(0, now - resets.updatedAt))} ago)` : "; run check"}`);
|
|
361
|
+
if (forecast)
|
|
362
|
+
logInfo(` ${paint(`forecast risk: ${forecast.riskScore}/100 (${forecast.riskLevel}; lower is better)`, forecast.riskLevel === "high" ? "danger" : forecast.riskLevel === "medium" ? "warning" : "success")}`);
|
|
220
363
|
const primaryReason = forecastResults[i]?.reasons[0];
|
|
221
364
|
if (primaryReason) {
|
|
222
|
-
logInfo(` reason: ${primaryReason}
|
|
365
|
+
logInfo(paint(` reason: ${primaryReason}`, "warning"));
|
|
223
366
|
}
|
|
224
367
|
// Surface every workspace a same-email account can rotate between, so
|
|
225
368
|
// personal Plus vs business/team stay visible at once (issue #491).
|
|
226
369
|
if ((account.workspaces?.length ?? 0) > 1) {
|
|
227
|
-
logInfo(" workspaces:");
|
|
228
|
-
for (const workspaceLine of formatWorkspaceLines(account, " ")) {
|
|
229
|
-
logInfo(workspaceLine);
|
|
370
|
+
logInfo(paint(" workspaces (saved selection; not live routing):", "muted"));
|
|
371
|
+
for (const workspaceLine of formatWorkspaceLines(account, " ", "saved selection")) {
|
|
372
|
+
logInfo(paint(workspaceLine, workspaceLine.includes("(saved selection)") ? "accent" : "muted"));
|
|
230
373
|
}
|
|
231
374
|
}
|
|
232
375
|
}
|
|
376
|
+
printApiAccounts();
|
|
233
377
|
return 0;
|
|
234
378
|
}
|
|
235
379
|
export function runFeaturesCommand(deps) {
|
|
@@ -44,7 +44,7 @@ function printUninstallUsage() {
|
|
|
44
44
|
"Options:",
|
|
45
45
|
" --dry-run Show what would be removed without making changes",
|
|
46
46
|
" --json Print machine-readable JSON output",
|
|
47
|
-
" --clear-accounts Also remove stored account credentials (irreversible)",
|
|
47
|
+
" --clear-accounts Also remove stored account credentials and API keys (irreversible)",
|
|
48
48
|
"",
|
|
49
49
|
"Behavior:",
|
|
50
50
|
" Reverses all first-run setup changes: unbinds Codex app, removes OS launchers,",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,EAGvB,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,EAC7D,QAAQ,EAAE,wBAAwB,EAClC,GAAG,SAAa,GACd,MAAM,
|
|
1
|
+
{"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,EAGvB,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,EAC7D,QAAQ,EAAE,wBAAwB,EAClC,GAAG,SAAa,GACd,MAAM,CAKR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,GACpB,kBAAkB,CAgBpB;AA8BD;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAgCD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,EACtB,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR"}
|
|
@@ -41,10 +41,11 @@ export function styleQuotaSummary(summary) {
|
|
|
41
41
|
* absolute reset clock for each quota window.
|
|
42
42
|
*/
|
|
43
43
|
export function formatQuotaSnapshotForDashboard(snapshot, settings, now = Date.now()) {
|
|
44
|
+
const status = snapshot.primingFailure ? `quota read OK; first-use probe unconfirmed (${snapshot.primingFailure})` : snapshot.primingCompleted ? "live session OK; first-use probe completed" : "live session OK";
|
|
44
45
|
if (!settings.showQuotaDetails)
|
|
45
|
-
return
|
|
46
|
+
return status;
|
|
46
47
|
const summary = formatCompactQuotaSnapshot(snapshot, now, { showReset: true });
|
|
47
|
-
return summary ?
|
|
48
|
+
return summary ? `${status} (${summary})` : status;
|
|
48
49
|
}
|
|
49
50
|
export function quotaCacheEntryToSnapshot(entry) {
|
|
50
51
|
return {
|
|
@@ -6,7 +6,10 @@ import { type DashboardDisplaySettings } from "../dashboard-settings.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export interface HealthCheckOptions {
|
|
8
8
|
forceRefresh?: boolean;
|
|
9
|
+
discoverModels?: boolean;
|
|
9
10
|
liveProbe?: boolean;
|
|
11
|
+
/** Explicit `check --prime` only: may start an unused subscription's quota windows. */
|
|
12
|
+
primeUnusedSubscription?: boolean;
|
|
10
13
|
model?: string;
|
|
11
14
|
display?: DashboardDisplaySettings;
|
|
12
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,KAAK,wBAAwB,EAE7B,MAAM,0BAA0B,CAAC;AA2ClC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,wBAAsB,cAAc,CACnC,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Wf"}
|