@cortexkit/opencode-openai-auth 0.11.1 → 1.0.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 +15 -26
- package/dist/index-766sfrh5.js +1 -0
- package/dist/index-8kj7sa1p.js +12 -0
- package/dist/index-b3q3j39x.js +2 -0
- package/dist/index-bmd7x5aq.js +2 -0
- package/dist/index-eqh53k8v.js +2 -0
- package/dist/{index-sdt2d2ra.js → index-hy9030jh.js} +1 -1
- package/dist/index-jyr8y8k4.js +7 -0
- package/dist/index-rv08jmd4.js +2 -0
- package/dist/index-ww91hyzr.js +221 -0
- package/dist/index.d.ts +578 -145
- package/dist/index.js +1 -110
- package/dist/pool-lifecycle-DbDmgabd.d.ts +2430 -0
- package/dist/port-file-Do3lQIEk.d.ts +29 -0
- package/dist/protocol-BOBdkqqm.d.ts +198 -0
- package/dist/rpc/port-file.d.ts +4 -17
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +2 -2
- package/dist/rpc/protocol.js +1 -0
- package/dist/rpc/rpc-client.d.ts +5 -4
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.d.ts +2 -0
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state-D6cUKgkm.d.ts +385 -0
- package/dist/sidebar-state.d.ts +2 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-wdza526f.js +1 -0
- package/dist/{token-9823y0pc.js → token-ypk61xj0.js} +1 -1
- package/dist/tui-preferences.js +5 -2
- package/dist/tui.d.ts +9 -4
- package/dist/v2/server.d.ts +54 -0
- package/dist/v2/server.js +4 -0
- package/package.json +21 -9
- package/src/tui/entry.mjs +26 -25
- package/src/tui-compiled/raw/logger.js +24 -0
- package/src/tui-compiled/raw/rpc/protocol.js +3 -0
- package/src/tui-compiled/raw/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/raw/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/raw/selector.js +21 -0
- package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/raw/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/raw/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/raw/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/raw/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/raw/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/raw/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/raw/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/raw/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/raw/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/raw/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/raw/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/raw/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/raw/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/raw/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/raw/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/raw/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/raw/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/raw/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/raw/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/raw/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/raw/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/raw/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/raw/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/raw/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/raw/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/raw/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/raw/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/raw/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/raw/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/raw/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/raw/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/raw/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/raw/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/raw/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/raw/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/raw/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/raw/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/raw/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/raw/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/raw/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/raw/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/raw/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/raw/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/raw/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/raw/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/raw/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/raw/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/raw/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/raw/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/raw/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/raw/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/raw/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/raw/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/raw/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/raw/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/raw/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/raw/sidebar-state.js +960 -0
- package/src/tui-compiled/raw/tui/command-dialogs.tsx +424 -0
- package/src/tui-compiled/raw/tui-preferences.js +135 -0
- package/src/tui-compiled/raw/tui.tsx +135 -143
- package/src/tui-compiled/runtime/logger.js +24 -0
- package/src/tui-compiled/runtime/rpc/protocol.js +3 -0
- package/src/tui-compiled/runtime/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/runtime/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/runtime/selector.js +21 -0
- package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/runtime/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/runtime/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/runtime/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/runtime/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/runtime/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/runtime/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/runtime/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/runtime/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/runtime/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/runtime/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/runtime/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/runtime/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/runtime/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/runtime/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/runtime/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/runtime/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/runtime/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/runtime/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/runtime/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/runtime/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/runtime/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/runtime/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/runtime/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/runtime/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/runtime/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/runtime/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/runtime/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/runtime/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/runtime/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/runtime/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/runtime/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/runtime/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/runtime/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/runtime/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/runtime/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/runtime/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/runtime/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/runtime/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/runtime/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/runtime/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/runtime/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/runtime/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/runtime/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/runtime/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/runtime/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/runtime/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/runtime/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/runtime/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/runtime/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/runtime/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/runtime/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/runtime/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/runtime/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/runtime/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/runtime/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/runtime/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/runtime/sidebar-state.js +960 -0
- package/src/tui-compiled/runtime/tui/command-dialogs.js +378 -0
- package/src/tui-compiled/runtime/tui-preferences.js +135 -0
- package/src/tui-compiled/runtime/{tui.tsx → tui.js} +288 -316
- package/dist/index-4effjmr6.js +0 -2
- package/dist/index-9ehhb051.js +0 -2
- package/dist/index-g3hsdjh4.js +0 -2
- package/dist/index-hh52v8sb.js +0 -2
- package/dist/index-jwn4r3sw.js +0 -1
- package/dist/index-sq36b120.js +0 -211
- package/dist/internal-BTndPmW2.d.ts +0 -914
- package/dist/quota-normalize-08hpp51v.js +0 -1
- package/dist/sidebar-state-CoKYKcLn.d.ts +0 -220
- package/dist/token-util-ypgz7rge.js +0 -1
- package/src/tui-compiled/raw/core-account-paths.ts +0 -114
- package/src/tui-compiled/raw/core-custody-state.ts +0 -243
- package/src/tui-compiled/raw/logger.ts +0 -53
- package/src/tui-compiled/raw/rpc-port-file.ts +0 -177
- package/src/tui-compiled/raw/rpc-protocol.ts +0 -12
- package/src/tui-compiled/raw/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/raw/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/raw/sidebar-state.ts +0 -1659
- package/src/tui-compiled/raw/tui-command-dialogs.tsx +0 -1096
- package/src/tui-compiled/raw/tui-preferences.ts +0 -328
- package/src/tui-compiled/runtime/core-account-paths.ts +0 -114
- package/src/tui-compiled/runtime/core-custody-state.ts +0 -243
- package/src/tui-compiled/runtime/logger.ts +0 -53
- package/src/tui-compiled/runtime/rpc-port-file.ts +0 -177
- package/src/tui-compiled/runtime/rpc-protocol.ts +0 -12
- package/src/tui-compiled/runtime/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/runtime/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/runtime/sidebar-state.ts +0 -1659
- package/src/tui-compiled/runtime/tui-command-dialogs.tsx +0 -855
- package/src/tui-compiled/runtime/tui-preferences.ts +0 -328
- package/src/tui-compiled/shared/internal.ts +0 -6
- package/src/tui-compiled/shared/logger.ts +0 -264
- package/src/tui-compiled/shared/paths.ts +0 -33
- package/src/tui-compiled/shared/refresh-file-lock.ts +0 -384
- package/src/tui-compiled/shared/util/error.ts +0 -9
- package/src/tui-compiled/shared/util/open-url.ts +0 -30
package/dist/index.d.ts
CHANGED
|
@@ -1,136 +1,529 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as TokenResponse, d as parseJwtClaims, f as AccountPaths, l as beginAccountLogin, p as PoolStore, r as OpenAiVault, s as IdTokenClaims, t as PoolLifecycleDeps, u as extractAccountIdFromClaims } from "./pool-lifecycle-DbDmgabd.js";
|
|
2
|
+
import { _ as SidebarMachineState, b as SidebarState } from "./sidebar-state-D6cUKgkm.js";
|
|
3
3
|
import { Hooks, Plugin, PluginInput } from "@opencode-ai/plugin";
|
|
4
|
-
//#region
|
|
5
|
-
|
|
4
|
+
//#region ../core/dist/provider.d.ts
|
|
5
|
+
type QuotaWindowName = string;
|
|
6
|
+
type ProviderQuotaFn = (input: {
|
|
7
|
+
accessToken: string;
|
|
8
|
+
fetchImpl: typeof fetch;
|
|
9
|
+
now: () => number;
|
|
10
|
+
}) => Promise<OAuthQuotaSnapshot>;
|
|
6
11
|
//#endregion
|
|
7
|
-
//#region
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
//#region ../core/dist/quota-manager.d.ts
|
|
13
|
+
type QuotaEntry = {
|
|
14
|
+
quota: OAuthQuotaSnapshot;
|
|
15
|
+
refreshAfter: number;
|
|
16
|
+
checkedAt: number;
|
|
17
|
+
accountId?: string;
|
|
13
18
|
};
|
|
14
|
-
type
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
type QuotaManagerOptions = {
|
|
20
|
+
storage: AccountStorage | null;
|
|
21
|
+
fetchImpl?: typeof fetch;
|
|
22
|
+
/**
|
|
23
|
+
* Account config file this manager's cross-process refresh locks are named
|
|
24
|
+
* after. Host-resolved and required, so two hosts pointing at different
|
|
25
|
+
* stores never contend on one another's lock.
|
|
26
|
+
*/
|
|
27
|
+
configPath: string;
|
|
28
|
+
now?: () => number;
|
|
29
|
+
/** Injected quota-fetch function — replaces the hard-imported Anthropic fetchOAuthQuotaSnapshot */
|
|
30
|
+
fetchQuotaFn?: ProviderQuotaFn;
|
|
31
|
+
onMainQuotaFetched?: (quota: OAuthQuotaSnapshot, checkedAt: number, fingerprint: string, fetchStartedAt: number) => void;
|
|
32
|
+
onApiError?: (error: AccountOperationError) => void;
|
|
17
33
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
declare class QuotaManager {
|
|
35
|
+
private main;
|
|
36
|
+
private mainTokenFp;
|
|
37
|
+
private mainQuotaAccountId;
|
|
38
|
+
private fallbacks;
|
|
39
|
+
private fallbackTokenFps;
|
|
40
|
+
private inflightMain;
|
|
41
|
+
private inflightMainFp;
|
|
42
|
+
private inflightFallbacks;
|
|
43
|
+
private mainLastApiError;
|
|
44
|
+
private fallbackApiErrors;
|
|
45
|
+
private fallbackErrorTokenFps;
|
|
46
|
+
private rateLimitedUntilMap;
|
|
47
|
+
private apiGate;
|
|
48
|
+
private lastApiCallAt;
|
|
49
|
+
private storage;
|
|
50
|
+
private readonly fetchImpl;
|
|
51
|
+
private readonly now;
|
|
52
|
+
private readonly fetchQuotaFn;
|
|
53
|
+
private readonly onMainQuotaFetched;
|
|
54
|
+
private readonly onApiError;
|
|
55
|
+
private readonly configPath;
|
|
56
|
+
constructor(opts: QuotaManagerOptions);
|
|
57
|
+
/**
|
|
58
|
+
* Cached main quota entry. Pass the live access token to enforce token
|
|
59
|
+
* binding: if the cached entry was produced by a different token (main
|
|
60
|
+
* account switched), it is dropped and null is returned so the caller
|
|
61
|
+
* refetches for the current account. Called without a token (e.g. for
|
|
62
|
+
* display) it returns whatever is cached.
|
|
63
|
+
*/
|
|
64
|
+
getMain(accessToken?: string): QuotaEntry | null;
|
|
65
|
+
/**
|
|
66
|
+
* Cached fallback quota entry. Pass the live access token to enforce token
|
|
67
|
+
* binding: if the entry was produced by a different token (account re-login),
|
|
68
|
+
* it is dropped and null is returned so the caller refetches.
|
|
69
|
+
*/
|
|
70
|
+
getFallback(accountId: string, accessToken?: string): QuotaEntry | null;
|
|
71
|
+
getAllFallbacks(): Map<string, QuotaEntry>;
|
|
72
|
+
setMain(accessToken: string, entry: QuotaEntry, accountId?: string, completeSnapshot?: boolean): void;
|
|
73
|
+
/**
|
|
74
|
+
* Non-invalidating read of the cached main quota for POLICY decisions
|
|
75
|
+
* (killswitch). Unlike getMain(token), a token mismatch does NOT drop the
|
|
76
|
+
* cache — an access-token refresh is a same-account event and must not turn a
|
|
77
|
+
* known-exhausted account into "unknown" (which would fail open and spend).
|
|
78
|
+
*
|
|
79
|
+
* Pass the live ChatGPT accountId to still drop on a genuine account SWITCH:
|
|
80
|
+
* if the cached entry's account identity is known and differs, return null so
|
|
81
|
+
* the killswitch treats it as unknown rather than judging account A by account
|
|
82
|
+
* B's quota. When identity is unknown on either side, the cached snapshot is
|
|
83
|
+
* returned (best-effort) — the same fail-open-on-unknown stance as elsewhere.
|
|
84
|
+
*/
|
|
85
|
+
peekMainForPolicy(accountId?: string): QuotaEntry | null;
|
|
86
|
+
/**
|
|
87
|
+
* Non-invalidating read of a cached fallback quota for POLICY decisions
|
|
88
|
+
* (killswitch, admission). Keyed by the stable internal account id, so a
|
|
89
|
+
* token refresh for the same account does not drop it (getFallback(id, token)
|
|
90
|
+
* would).
|
|
91
|
+
*
|
|
92
|
+
* Pass the live ChatGPT identity to still drop on a genuine re-login: if the
|
|
93
|
+
* cached entry's identity is known and differs, return null so the previous
|
|
94
|
+
* identity's (possibly exhausted) quota is never judged against its
|
|
95
|
+
* replacement. Unknown on either side fails open, matching peekMainForPolicy.
|
|
96
|
+
*/
|
|
97
|
+
peekFallbackForPolicy(accountId: string, identity?: string): QuotaEntry | null;
|
|
98
|
+
setFallback(accountId: string, entry: QuotaEntry, accessToken?: string, completeSnapshot?: boolean, identity?: string): void;
|
|
99
|
+
/**
|
|
100
|
+
* Mark accountId ('main' or a fallback id) rate-limited until resetAtMs.
|
|
101
|
+
* Keeps the LATER reset: skips only when an existing mark is strictly
|
|
102
|
+
* later than resetAtMs, so an equal-reset re-mark still applies (idempotent)
|
|
103
|
+
* instead of being silently dropped by a stale `>=` comparison.
|
|
104
|
+
*/
|
|
105
|
+
markRateLimited(accountId: string, resetAtMs: number): void;
|
|
106
|
+
/** True iff accountId has a mark whose reset has not yet passed. */
|
|
107
|
+
isRateLimited(accountId: string): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Raw stored reset for accountId's mark, or undefined if none. Unlike
|
|
110
|
+
* isRateLimited, this does NOT apply read-time expiry — callers on the
|
|
111
|
+
* block path already know the mark is live (isRateLimited just returned
|
|
112
|
+
* true) and want its exact reset estimate for a Retry-After computation.
|
|
113
|
+
*/
|
|
114
|
+
rateLimitedUntil(accountId: string): number | undefined;
|
|
115
|
+
/** Explicit early clear — read-time expiry in isRateLimited is primary. */
|
|
116
|
+
clearRateLimited(accountId: string): void;
|
|
117
|
+
refreshMain(accessToken: string): Promise<OAuthQuotaSnapshot>;
|
|
118
|
+
refreshFallback(accountId: string, accessToken: string): Promise<OAuthQuotaSnapshot>;
|
|
119
|
+
refreshAllFallbacks(accounts: OAuthAccount[]): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Fire-and-forget refresh. Does not await, swallows errors.
|
|
122
|
+
*/
|
|
123
|
+
refreshMainInBackground(accessToken: string): void;
|
|
124
|
+
isMainStale(): boolean;
|
|
125
|
+
isFallbackStale(accountId: string, accessToken?: string): boolean;
|
|
126
|
+
shouldRefreshOnRequestCount(requestCount: number): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Combined check: should a refresh happen right now?
|
|
129
|
+
* True if main is stale by time OR triggered by request count.
|
|
130
|
+
*/
|
|
131
|
+
needsRefresh(requestCount: number): boolean;
|
|
132
|
+
updateStorage(storage: AccountStorage | null): void;
|
|
133
|
+
/**
|
|
134
|
+
* Seed/update the main quota cache from persisted state. This is deliberately
|
|
135
|
+
* callable after every disk load so another plugin process's fresh quota write
|
|
136
|
+
* can stop this process from showing "checking…" or making a redundant quota
|
|
137
|
+
* API call.
|
|
138
|
+
*/
|
|
139
|
+
seedMainFromStorage(storage: AccountStorage | null, accessToken?: string): void;
|
|
140
|
+
private seedMainBackoffFromStorage;
|
|
141
|
+
/**
|
|
142
|
+
* Seed fallback cache entries from persisted account.quota data.
|
|
143
|
+
* Updates older in-memory entries so a fresh quota write from another plugin
|
|
144
|
+
* process prevents redundant checks and stale sidebar writes.
|
|
145
|
+
*/
|
|
146
|
+
seedFallbacksFromAccounts(accounts: OAuthAccount[]): void;
|
|
147
|
+
/**
|
|
148
|
+
* Whether the MAIN quota API is currently in backoff. Scoped to the main
|
|
149
|
+
* account — a fallback account's 429 never reports here.
|
|
150
|
+
*/
|
|
151
|
+
isBackedOff(): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Whether a specific fallback account's quota API is in backoff.
|
|
154
|
+
*/
|
|
155
|
+
isFallbackBackedOff(accountId: string, accessToken?: string): boolean;
|
|
156
|
+
getLastApiError(): AccountOperationError | undefined;
|
|
157
|
+
/** Minimum gap between consecutive quota API calls (ms). */
|
|
158
|
+
private static readonly API_CALL_GAP_MS;
|
|
159
|
+
private static fallbackInflightKey;
|
|
160
|
+
private static quotaLockName;
|
|
161
|
+
/**
|
|
162
|
+
* Serialize API calls through a shared gate so only one
|
|
163
|
+
* quota API request runs at a time, with a minimum gap
|
|
164
|
+
* between calls. Prevents concurrent and rapid-fire calls
|
|
165
|
+
* from triggering rate limits.
|
|
166
|
+
*/
|
|
167
|
+
private _enqueueApiFetch;
|
|
168
|
+
private _fetchMain;
|
|
169
|
+
private _fetchFallback;
|
|
170
|
+
/** Route through injected fetchQuotaFn, or throw if unset. */
|
|
171
|
+
private _fetchQuota;
|
|
172
|
+
private static isAuthError;
|
|
173
|
+
/** Main quota failure: arms main-only backoff and persists via onApiError. */
|
|
174
|
+
private _handleMainFetchError;
|
|
175
|
+
/**
|
|
176
|
+
* Fallback quota failure: arms backoff for THIS account only. Never touches
|
|
177
|
+
* main backoff state and never calls onApiError (which persists the main
|
|
178
|
+
* quota error) — the per-account error is recorded by the caller via the
|
|
179
|
+
* account's lastQuotaRefreshError.
|
|
180
|
+
*/
|
|
181
|
+
private _handleFallbackFetchError;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region ../core/dist/accounts.d.ts
|
|
185
|
+
type AccountQuotaWindow = {
|
|
186
|
+
usedPercent: number;
|
|
187
|
+
remainingPercent: number;
|
|
188
|
+
resetsAt?: string;
|
|
189
|
+
checkedAt: number;
|
|
190
|
+
windowMinutes?: number;
|
|
191
|
+
};
|
|
192
|
+
interface OAuthQuotaSnapshot {
|
|
193
|
+
primary?: AccountQuotaWindow;
|
|
194
|
+
secondary?: AccountQuotaWindow;
|
|
195
|
+
resetCreditsAvailable?: number;
|
|
196
|
+
resetCreditsApplicable?: number;
|
|
197
|
+
spendControl?: OAuthSpendControlReading;
|
|
198
|
+
/**
|
|
199
|
+
* Set when the source explicitly reported that the account has no credit
|
|
200
|
+
* budget (wham's `spend_control` or `individual_limit` is null). An absent
|
|
201
|
+
* `spendControl` alone only means the source did not carry the field: header
|
|
202
|
+
* and WebSocket pushes never do, so merges keep the previous budget for them.
|
|
203
|
+
* This marker is what lets a merge drop a budget that no longer exists.
|
|
204
|
+
*/
|
|
205
|
+
spendControlCleared?: true;
|
|
206
|
+
credits?: OAuthCredits;
|
|
207
|
+
}
|
|
208
|
+
interface OAuthSpendControlReading {
|
|
209
|
+
limit: number;
|
|
210
|
+
used: number;
|
|
211
|
+
remaining: number;
|
|
212
|
+
usedPercent: number;
|
|
213
|
+
remainingPercent: number;
|
|
214
|
+
resetsAt?: string;
|
|
215
|
+
unit?: string;
|
|
216
|
+
source?: string;
|
|
217
|
+
reached: boolean;
|
|
218
|
+
}
|
|
219
|
+
interface OAuthCredits {
|
|
220
|
+
hasCredits: boolean;
|
|
221
|
+
unlimited: boolean;
|
|
222
|
+
overageLimitReached: boolean;
|
|
223
|
+
balance?: number;
|
|
224
|
+
}
|
|
225
|
+
type AccountBase = {
|
|
226
|
+
id: string;
|
|
227
|
+
label?: string;
|
|
228
|
+
enabled?: boolean;
|
|
229
|
+
addedAt?: number;
|
|
230
|
+
lastUsed?: number;
|
|
231
|
+
/** Stable ChatGPT account identifier extracted from the OAuth token claims. */
|
|
232
|
+
accountId?: string;
|
|
233
|
+
};
|
|
234
|
+
type AccountOperationError = {
|
|
235
|
+
message: string;
|
|
236
|
+
checkedAt: number;
|
|
237
|
+
nextRetryAt?: number;
|
|
238
|
+
retryCount?: number;
|
|
239
|
+
tokenHash?: string;
|
|
240
|
+
};
|
|
241
|
+
type OAuthAccount = AccountBase & {
|
|
242
|
+
type: 'oauth';
|
|
243
|
+
corrupt?: false;
|
|
244
|
+
access?: string;
|
|
245
|
+
refresh: string;
|
|
246
|
+
expires?: number;
|
|
247
|
+
lastRefreshedAt?: number;
|
|
248
|
+
lastRefreshError?: AccountOperationError;
|
|
249
|
+
lastQuotaRefreshError?: AccountOperationError;
|
|
250
|
+
quota?: OAuthQuotaSnapshot;
|
|
251
|
+
};
|
|
252
|
+
type CorruptOAuthAccount = AccountBase & {
|
|
253
|
+
type: 'oauth';
|
|
254
|
+
corrupt: true;
|
|
255
|
+
access?: undefined;
|
|
256
|
+
refresh?: undefined;
|
|
257
|
+
expires?: undefined;
|
|
258
|
+
lastRefreshedAt?: undefined;
|
|
259
|
+
lastRefreshError?: undefined;
|
|
260
|
+
lastQuotaRefreshError?: undefined;
|
|
261
|
+
quota?: undefined;
|
|
262
|
+
};
|
|
263
|
+
type ApiKeyAccount = AccountBase & {
|
|
264
|
+
type: 'api';
|
|
265
|
+
apiKey?: string;
|
|
266
|
+
baseURL: string;
|
|
267
|
+
authHeader?: 'authorization-bearer' | 'x-api-key';
|
|
268
|
+
};
|
|
269
|
+
type FallbackAccount = OAuthAccount | CorruptOAuthAccount | ApiKeyAccount;
|
|
270
|
+
/**
|
|
271
|
+
* `ordered` is the shared command menu's name for plain roster order; it is
|
|
272
|
+
* written only from that menu, which needs a migrated install.
|
|
273
|
+
*/
|
|
274
|
+
type RoutingMode = 'ordered' | 'main-first' | 'fallback-first' | 'sticky-balanced';
|
|
275
|
+
type KillswitchThresholds = Partial<Record<QuotaWindowName | '5h' | '1w', number>>;
|
|
276
|
+
type KillswitchConfig = {
|
|
277
|
+
enabled?: boolean;
|
|
278
|
+
main?: KillswitchThresholds;
|
|
279
|
+
accounts?: Record<string, KillswitchThresholds>;
|
|
280
|
+
/**
|
|
281
|
+
* In a `KILLSWITCH_FLOORS_SCHEMA` block, the floors of every account the
|
|
282
|
+
* block has no entry for, so an account added after the block was written
|
|
283
|
+
* is protected without anything writing floors for it.
|
|
284
|
+
*/
|
|
285
|
+
defaults?: KillswitchThresholds;
|
|
286
|
+
/**
|
|
287
|
+
* `KILLSWITCH_FLOORS_SCHEMA` once the block holds explicit per-account
|
|
288
|
+
* floors; see that constant for how the two formats differ.
|
|
289
|
+
*/
|
|
290
|
+
schema?: string;
|
|
291
|
+
};
|
|
292
|
+
/** The cache keep-warm settings; see `cacheKeepSettings`. */
|
|
293
|
+
type CacheKeepSettings = {
|
|
294
|
+
enabled?: boolean;
|
|
295
|
+
subagents?: boolean;
|
|
296
|
+
sustain?: boolean;
|
|
297
|
+
/** Clock-hour window start (0-23, inclusive) — keeps cachekeep idle warming
|
|
298
|
+
* inside `[startHour, endHour)` local hours. Omit to warm unconditionally. */
|
|
299
|
+
startHour?: number;
|
|
300
|
+
/** Clock-hour window end (0-23, exclusive) — must differ from startHour
|
|
301
|
+
* to be honored; an unset or equal hour falls back to "always warm". */
|
|
302
|
+
endHour?: number;
|
|
303
|
+
};
|
|
304
|
+
interface ResetInFlight {
|
|
305
|
+
redeemRequestId: string;
|
|
306
|
+
creditId: string;
|
|
307
|
+
startedAt: number;
|
|
308
|
+
}
|
|
309
|
+
interface ResetLastOutcome {
|
|
310
|
+
code: string;
|
|
311
|
+
at: number;
|
|
312
|
+
previousOutcome?: {
|
|
313
|
+
code: string;
|
|
314
|
+
at: number;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
interface ResetAccountState {
|
|
318
|
+
inFlight?: ResetInFlight | Record<string, unknown>;
|
|
319
|
+
lastOutcome?: ResetLastOutcome;
|
|
320
|
+
cooldownUntil?: number;
|
|
321
|
+
}
|
|
322
|
+
type ResetStateByAccount = Record<string, ResetAccountState>;
|
|
323
|
+
type AccountStorage = {
|
|
324
|
+
version: 1;
|
|
325
|
+
main?: {
|
|
326
|
+
type: 'opencode';
|
|
327
|
+
provider: 'openai';
|
|
328
|
+
};
|
|
329
|
+
routing?: {
|
|
330
|
+
mode?: RoutingMode;
|
|
331
|
+
};
|
|
332
|
+
fallbackOn?: number[];
|
|
333
|
+
refresh?: {
|
|
334
|
+
enabled?: boolean;
|
|
335
|
+
refreshBeforeExpiryMinutes?: number;
|
|
336
|
+
mainLastRefreshError?: AccountOperationError;
|
|
337
|
+
mainRefreshLeaseId?: string;
|
|
338
|
+
mainRefreshLeaseUntil?: number;
|
|
339
|
+
mainRefreshLeaseTokenHash?: string;
|
|
340
|
+
};
|
|
341
|
+
quota?: {
|
|
342
|
+
enabled?: boolean;
|
|
343
|
+
checkIntervalMinutes?: number;
|
|
344
|
+
refreshEveryNRequests?: number;
|
|
345
|
+
minimumRemaining?: Partial<Record<QuotaWindowName | '5h' | '1w', number>>;
|
|
346
|
+
failClosedOnUnknownQuota?: boolean;
|
|
347
|
+
mainQuota?: OAuthQuotaSnapshot;
|
|
348
|
+
mainQuotaCheckedAt?: number;
|
|
349
|
+
mainQuotaToken?: string;
|
|
350
|
+
mainLastQuotaApiError?: AccountOperationError;
|
|
49
351
|
};
|
|
50
|
-
|
|
51
|
-
|
|
352
|
+
reset?: ResetStateByAccount;
|
|
353
|
+
dump?: {
|
|
354
|
+
enabled?: boolean;
|
|
355
|
+
};
|
|
356
|
+
costZeroing?: {
|
|
357
|
+
enabled?: boolean;
|
|
358
|
+
};
|
|
359
|
+
killswitch?: KillswitchConfig;
|
|
360
|
+
logging?: {
|
|
361
|
+
level?: string;
|
|
362
|
+
};
|
|
363
|
+
/** The older name of `cacheKeep`; read only until a settings write renames it. */
|
|
364
|
+
cachekeep?: CacheKeepSettings;
|
|
365
|
+
cacheKeep?: CacheKeepSettings;
|
|
366
|
+
/** Stable ChatGPT account identifier of the main account (extracted from OAuth token). */
|
|
367
|
+
mainAccountId?: string;
|
|
368
|
+
accounts: FallbackAccount[];
|
|
52
369
|
};
|
|
370
|
+
declare function loadAccounts(paths: AccountPaths): Promise<AccountStorage | null>;
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region ../core/dist/refresh-all-quota.d.ts
|
|
373
|
+
interface RefreshAllQuotaResult {
|
|
374
|
+
account: string;
|
|
375
|
+
ok: boolean;
|
|
376
|
+
error?: string;
|
|
377
|
+
/**
|
|
378
|
+
* The account cannot recover on its own: the provider has rejected its
|
|
379
|
+
* credentials, so no amount of retrying will help until the operator re-adds
|
|
380
|
+
* it.
|
|
381
|
+
*
|
|
382
|
+
* Carried as a flag rather than left for the caller to infer from `error`,
|
|
383
|
+
* because sniffing an error string for a user-facing decision breaks the
|
|
384
|
+
* moment the wording changes.
|
|
385
|
+
*/
|
|
386
|
+
permanent?: boolean;
|
|
387
|
+
}
|
|
53
388
|
//#endregion
|
|
54
|
-
//#region
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
389
|
+
//#region ../core/dist/commands.d.ts
|
|
390
|
+
/**
|
|
391
|
+
* The prompt-cache manager, as the Cache section uses it.
|
|
392
|
+
*
|
|
393
|
+
* Declared structurally rather than imported: the manager itself is tied to
|
|
394
|
+
* one host's live request loader and stays there. Only the members the Cache
|
|
395
|
+
* section and the host's session cleanup reach appear here.
|
|
396
|
+
*/
|
|
397
|
+
interface CacheKeepManager {
|
|
398
|
+
status(): {
|
|
399
|
+
running: boolean;
|
|
400
|
+
sustain: boolean;
|
|
401
|
+
window?: {
|
|
402
|
+
startHour: number;
|
|
403
|
+
endHour: number;
|
|
404
|
+
} | undefined;
|
|
405
|
+
tracked: number;
|
|
406
|
+
generatedAt: number;
|
|
407
|
+
ttlMs: number;
|
|
408
|
+
leadMs: number;
|
|
409
|
+
maxIdleWarmMs: number;
|
|
410
|
+
maxSubagentIdleMs: number;
|
|
411
|
+
targets: ReadonlyArray<{
|
|
412
|
+
sessionKey: string;
|
|
413
|
+
accountId?: string;
|
|
414
|
+
cacheExpiresAt: number;
|
|
415
|
+
lastWarmedAt?: number;
|
|
416
|
+
backoffUntil?: number;
|
|
417
|
+
}>;
|
|
418
|
+
};
|
|
419
|
+
start(): void;
|
|
420
|
+
stop(): void;
|
|
421
|
+
remove(sessionKey: string): void;
|
|
422
|
+
}
|
|
423
|
+
interface ResetTargetIdentity {
|
|
424
|
+
accountKey: string;
|
|
425
|
+
label: string;
|
|
426
|
+
accessToken: string;
|
|
427
|
+
chatgptAccountId?: string;
|
|
428
|
+
onAuthFailure?: (status: number) => Promise<void>;
|
|
429
|
+
}
|
|
430
|
+
/** One live process, on an older version, that keeps the accounts from moving to the account pool. */
|
|
431
|
+
interface MigrationBlocker {
|
|
432
|
+
/** `'unknown'` when the directory of process heartbeats could not be read. */
|
|
433
|
+
pid: number | 'unknown';
|
|
434
|
+
version: string;
|
|
435
|
+
}
|
|
436
|
+
type MenuMigrationState = {
|
|
437
|
+
migrated: true;
|
|
438
|
+
} | {
|
|
439
|
+
migrated: false;
|
|
440
|
+
blockers: readonly MigrationBlocker[];
|
|
60
441
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
handshakeTimeoutMs?: number;
|
|
72
|
-
}) => Promise<ClaustrumCacheTransportLike>;
|
|
442
|
+
//#endregion
|
|
443
|
+
//#region src/commands.d.ts
|
|
444
|
+
/** What the `/openai` menu reads and changes in this process. */
|
|
445
|
+
interface OpenCodeMenuContext {
|
|
446
|
+
accountStoragePath: string;
|
|
447
|
+
/** Runtime-state file that goes with `accountStoragePath`. */
|
|
448
|
+
accountStatePath: string;
|
|
449
|
+
/** Host package version, sent as the version half of the OAuth `User-Agent`. */
|
|
450
|
+
packageVersion: string;
|
|
451
|
+
quotaManager: QuotaManager;
|
|
73
452
|
loadAccounts: typeof loadAccounts;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
453
|
+
/** The pool store the accounts live in. */
|
|
454
|
+
store: () => PoolStore;
|
|
455
|
+
/** Whether the install is migrated, and what holds it back when not. */
|
|
456
|
+
migration: () => Promise<MenuMigrationState>;
|
|
457
|
+
/** Starts an OAuth account-add flow; injected by the runtime boundary. */
|
|
458
|
+
beginAccountLogin?: typeof beginAccountLogin;
|
|
459
|
+
/** Actively poll quota for every account. */
|
|
460
|
+
refreshAllQuota?: () => Promise<RefreshAllQuotaResult[]>;
|
|
461
|
+
/** Refresh the sidebar-state file after a change. */
|
|
462
|
+
refreshSidebar?: () => Promise<void>;
|
|
463
|
+
/** Re-read the pool so requests route across the changed rows at once. */
|
|
464
|
+
afterWrite?: () => unknown;
|
|
465
|
+
cacheKeepManager?: CacheKeepManager | null;
|
|
466
|
+
setCacheKeepEnabled?: (enabled: boolean) => void;
|
|
467
|
+
setCacheKeepSubagents?: (enabled: boolean) => void;
|
|
468
|
+
setCacheKeepSustain?: (enabled: boolean) => void;
|
|
469
|
+
setCacheKeepWindow?: (window: {
|
|
470
|
+
startHour: number;
|
|
471
|
+
endHour: number;
|
|
472
|
+
} | undefined) => void;
|
|
473
|
+
clearStickyRouting?: (sessionId: string) => Promise<boolean>;
|
|
474
|
+
getStickyRouting?: (sessionId: string) => Promise<string | undefined>;
|
|
475
|
+
resolveResetTarget?: (accountKey: string) => Promise<ResetTargetIdentity>;
|
|
476
|
+
refreshResetTargetQuota?: (accountKey: string) => Promise<RefreshAllQuotaResult>;
|
|
477
|
+
fetchImpl?: typeof fetch;
|
|
83
478
|
now?: () => number;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
/** Run the initial completion sweep. Resolves BEFORE the background refresh is armed. */
|
|
112
|
-
boot(): Promise<void>;
|
|
113
|
-
/** Clear the timer and close the cache + transport. Idempotent. */
|
|
114
|
-
dispose(): void;
|
|
115
|
-
/** Force one tick pass (used by the timer and tests). */
|
|
116
|
-
runTick(): Promise<void>;
|
|
117
|
-
/** Sync projection read for the sidebar writer. */
|
|
118
|
-
getCustodyProjection(account: OAuthAccount, now: number): SidebarAccountCustody | undefined;
|
|
119
|
-
/** Whether the custody runtime is enabled for this process. */
|
|
120
|
-
isEnabled(): boolean;
|
|
121
|
-
/** Cache handle (undefined when custody is disabled). */
|
|
122
|
-
getCache(): ClaustrumCredentialCache | undefined;
|
|
123
|
-
/** Connect the cache on demand and return it. */
|
|
124
|
-
ensureCache(): Promise<ClaustrumCredentialCache | undefined>;
|
|
125
|
-
/** Transport handle (undefined when custody is disabled). */
|
|
126
|
-
getTransport(): ClaustrumCacheTransportLike | undefined;
|
|
127
|
-
/** True if the detection step produced an `available` connection file. */
|
|
128
|
-
wasDetected(): boolean;
|
|
129
|
-
};
|
|
130
|
-
export declare function __createCustodyRuntimeForTest(options: CustodyRuntimeOptions): CustodyRuntime;
|
|
131
|
-
export declare function __resetSweepFailureLogDedupeForTest(): void;
|
|
479
|
+
randomUUID?: () => string;
|
|
480
|
+
/** This host's connection to the Claustrum vault (the Vault section). */
|
|
481
|
+
vault?: OpenAiVault;
|
|
482
|
+
}
|
|
483
|
+
//#endregion
|
|
484
|
+
//#region src/core/background-quota-refresh.d.ts
|
|
485
|
+
type TimerHandle = ReturnType<typeof setInterval>;
|
|
486
|
+
interface BackgroundQuotaRefreshOptions {
|
|
487
|
+
setIntervalFn?: (callback: () => void, intervalMs: number) => TimerHandle;
|
|
488
|
+
clearIntervalFn?: (timer: TimerHandle) => void;
|
|
489
|
+
random?: () => number;
|
|
490
|
+
onError?: (error: unknown) => void;
|
|
491
|
+
}
|
|
492
|
+
declare class BackgroundQuotaRefresh {
|
|
493
|
+
private readonly setIntervalFn;
|
|
494
|
+
private readonly clearIntervalFn;
|
|
495
|
+
private readonly random;
|
|
496
|
+
private onError;
|
|
497
|
+
private run;
|
|
498
|
+
private timer;
|
|
499
|
+
private tickPromise;
|
|
500
|
+
private stopped;
|
|
501
|
+
constructor(options?: BackgroundQuotaRefreshOptions);
|
|
502
|
+
start(run: () => Promise<void>, onError?: ((error: unknown) => void) | undefined): void;
|
|
503
|
+
stop(): void;
|
|
504
|
+
isStopped(): boolean;
|
|
505
|
+
}
|
|
132
506
|
//#endregion
|
|
133
507
|
//#region src/index.d.ts
|
|
508
|
+
export declare const ALLOWED_MODELS: Set<string>;
|
|
509
|
+
export declare const DISALLOWED_MODELS: Set<string>;
|
|
510
|
+
/**
|
|
511
|
+
* Whether a model (by its API id) is offered on a ChatGPT login: the allow
|
|
512
|
+
* list, else not the deny list and a GPT version above 5.4. The caller drops
|
|
513
|
+
* `pro` reasoning variants itself. Shared by the OpenCode 1 models hook and
|
|
514
|
+
* the OpenCode 2 model transform.
|
|
515
|
+
*/
|
|
516
|
+
export declare function codexOAuthModelListed(apiId: string): boolean;
|
|
517
|
+
/**
|
|
518
|
+
* The context window a ChatGPT login gets for a model (by its id), or
|
|
519
|
+
* undefined to keep the model's own. Shared by the OpenCode 1 models hook and
|
|
520
|
+
* the OpenCode 2 model transform.
|
|
521
|
+
*/
|
|
522
|
+
export declare function codexOAuthModelLimit(modelId: string): {
|
|
523
|
+
context: number;
|
|
524
|
+
input: number;
|
|
525
|
+
output: number;
|
|
526
|
+
} | undefined;
|
|
134
527
|
/**
|
|
135
528
|
* Surfaced when a request would go to the wire with no credential.
|
|
136
529
|
*
|
|
@@ -141,9 +534,13 @@ export declare function __resetSweepFailureLogDedupeForTest(): void;
|
|
|
141
534
|
* transport log.
|
|
142
535
|
*/
|
|
143
536
|
export declare const EMPTY_BEARER_MESSAGE = "Refusing to send a request with no access token. This is a defect in the plugin, not a problem with the provider or the account; the transport log names the account and the path that produced it.";
|
|
537
|
+
export declare const RESPONSES_LITE_MODELS: ReadonlySet<string>;
|
|
538
|
+
export declare const CODEX_VERSION = "0.159.0";
|
|
539
|
+
export declare const CODEX_USER_AGENT = "codex_exec/0.159.0 (Debian 12.0.0; aarch64) unknown (codex_exec; 0.159.0)";
|
|
144
540
|
export declare const getMainRefreshLockName: () => string;
|
|
145
541
|
export declare const MAIN_REFRESH_LOCK_TTL_MS: number;
|
|
146
542
|
export declare const MAIN_REFRESH_LEASE_TTL_MS = 90000;
|
|
543
|
+
export declare function __bootQuotaSeedPromiseForTest(): Promise<unknown> | undefined;
|
|
147
544
|
export declare function __resetBootQuotaSeedForTest(): void;
|
|
148
545
|
export declare class AuthPersistError extends Error {
|
|
149
546
|
readonly code = "OPENAI_AUTH_PERSIST_FAILED";
|
|
@@ -167,17 +564,32 @@ interface ResetTargetResolverDeps {
|
|
|
167
564
|
expires: number;
|
|
168
565
|
}>;
|
|
169
566
|
refreshFallbackAccount: (account: OAuthAccount, storage: AccountStorage) => Promise<OAuthAccount>;
|
|
567
|
+
/**
|
|
568
|
+
* Refresh the pool row `main` while it serves as the main account. Defaults
|
|
569
|
+
* to refreshFallbackAccount.
|
|
570
|
+
*/
|
|
571
|
+
refreshPoolMainRow?: (account: OAuthAccount, storage: AccountStorage) => Promise<OAuthAccount>;
|
|
572
|
+
/**
|
|
573
|
+
* On a migrated install, the pool row behind an account key (`main` is row
|
|
574
|
+
* `main`) and its usable bearer, refreshed through the pool. Undefined when
|
|
575
|
+
* the install is not migrated; the legacy slot and roster then apply.
|
|
576
|
+
*/
|
|
577
|
+
poolAccess?: (accountKey: string) => Promise<PoolResetAccess | undefined>;
|
|
170
578
|
loadAccounts: typeof loadAccounts;
|
|
171
579
|
accountStoragePath: string;
|
|
172
580
|
accountStatePath: string;
|
|
173
581
|
now: () => number;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
582
|
+
}
|
|
583
|
+
/** A pool row as the reset-credit resolver sees it; `row` is absent when no row has the id. */
|
|
584
|
+
export interface PoolResetAccess {
|
|
585
|
+
row?: {
|
|
586
|
+
id: string;
|
|
587
|
+
type: 'oauth' | 'api';
|
|
588
|
+
enabled: boolean;
|
|
589
|
+
label?: string;
|
|
590
|
+
identity?: string;
|
|
591
|
+
};
|
|
592
|
+
token?: string;
|
|
181
593
|
}
|
|
182
594
|
export declare function createResetTargetResolver(deps: ResetTargetResolverDeps): (accountKey: string) => Promise<ResetTargetIdentity>;
|
|
183
595
|
export declare function buildResetRedemptionDeps(): {
|
|
@@ -185,27 +597,46 @@ export declare function buildResetRedemptionDeps(): {
|
|
|
185
597
|
now: () => number;
|
|
186
598
|
randomUUID: () => `${string}-${string}-${string}-${string}-${string}`;
|
|
187
599
|
};
|
|
600
|
+
/**
|
|
601
|
+
* Test seam: the context the latest loader run gave the `/openai` menu, so a
|
|
602
|
+
* test of the loader's live gates (keep-warm, sticky pins) can drive them on
|
|
603
|
+
* an install the menu itself would not open on.
|
|
604
|
+
*/
|
|
605
|
+
export declare function __menuContextForTest(): OpenCodeMenuContext | null;
|
|
606
|
+
export declare const POOL_MIGRATION_ENABLED = true;
|
|
188
607
|
interface CodexAuthPluginOptions {
|
|
608
|
+
/**
|
|
609
|
+
* Test seams for the background account-pool migration and adoption
|
|
610
|
+
* (`core/pool-lifecycle.ts`): its fence, timers, run functions and
|
|
611
|
+
* per-run dependencies.
|
|
612
|
+
*/
|
|
613
|
+
poolMigration?: Partial<Pick<PoolLifecycleDeps, 'fence' | 'migrate' | 'adopt' | 'timers' | 'random' | 'runDeps' | 'log'>> & {
|
|
614
|
+
/** Overrides POOL_MIGRATION_ENABLED, so tests can run the migration. */
|
|
615
|
+
enabled?: boolean;
|
|
616
|
+
};
|
|
617
|
+
/** Test seam: timer functions for the background quota poller, so a test can fire its tick. */
|
|
618
|
+
backgroundQuota?: ConstructorParameters<typeof BackgroundQuotaRefresh>[0];
|
|
189
619
|
issuer?: string;
|
|
190
620
|
codexApiEndpoint?: string;
|
|
191
621
|
experimentalWebSockets?: boolean;
|
|
192
622
|
responsesLite?: boolean;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
623
|
+
/**
|
|
624
|
+
* Test seams for the Claustrum vault: its connections and the directory its
|
|
625
|
+
* token and roster live in.
|
|
626
|
+
*/
|
|
627
|
+
vault?: Partial<Pick<ConstructorParameters<typeof OpenAiVault>[0], 'stateDir' | 'connectionFile' | 'connectScoped' | 'connectEnrollment' | 'pollIntervalMs'>> & {
|
|
628
|
+
/**
|
|
629
|
+
* Longest an adoption or the pool source's first quota polls wait for
|
|
630
|
+
* the vault's first roster; `VAULT_FIRST_ROSTER_BACKGROUND_WAIT_MS` by
|
|
631
|
+
* default.
|
|
632
|
+
*/
|
|
633
|
+
firstRosterWaitMs?: number;
|
|
634
|
+
};
|
|
635
|
+
/** Test seams for the OAuth logins of the auth methods. */
|
|
636
|
+
login?: {
|
|
637
|
+
/** Controls the wait for the host's slot write without real timers. */
|
|
203
638
|
sleep?: (ms: number) => Promise<void>;
|
|
204
|
-
/**
|
|
205
|
-
warn?: (message: string) => void;
|
|
206
|
-
/** Test seam: observes the account lock around custody binding checks. */
|
|
207
|
-
withFallbackAccountLock?: CommandContext['withFallbackAccountLock'];
|
|
208
|
-
/** Test seam: replaces external OAuth I/O while preserving the hook callback. */
|
|
639
|
+
/** Replaces external OAuth I/O while preserving the hook callback. */
|
|
209
640
|
authorize?: {
|
|
210
641
|
browser?: () => Promise<{
|
|
211
642
|
url: string;
|
|
@@ -222,9 +653,11 @@ interface CodexAuthPluginOptions {
|
|
|
222
653
|
}
|
|
223
654
|
export declare function findCachekeepFallbackAccount(accounts: FallbackAccount[], accountId: string): OAuthAccount | undefined;
|
|
224
655
|
export declare function mergePushedQuotaMetadata(incoming: OAuthQuotaSnapshot, previous: OAuthQuotaSnapshot | undefined): OAuthQuotaSnapshot;
|
|
225
|
-
export declare function buildSidebarMachineState(qm: QuotaManager, store: AccountStorage, now?: number, mainAccountIdentity?: string | undefined
|
|
656
|
+
export declare function buildSidebarMachineState(qm: QuotaManager, store: AccountStorage, now?: number, mainAccountIdentity?: string | undefined): SidebarMachineState;
|
|
226
657
|
export declare function buildSidebarState(qm: QuotaManager, store: AccountStorage, activeId: string, now?: number): SidebarState;
|
|
227
658
|
export declare function resolveSidebarSessionId(headers: Headers): string | undefined;
|
|
659
|
+
export declare const MID_CONVERSATION_EFFORT_MODELS: ReadonlySet<string>;
|
|
660
|
+
export declare function rewriteResponsesLiteBody(parsed: Record<string, unknown>): void;
|
|
228
661
|
export declare function CodexAuthPlugin(input: PluginInput, options?: CodexAuthPluginOptions): Promise<Hooks>;
|
|
229
662
|
export declare const OpenAIAuthPlugin: Plugin;
|
|
230
663
|
declare const _default: {
|
|
@@ -232,4 +665,4 @@ declare const _default: {
|
|
|
232
665
|
server: Plugin;
|
|
233
666
|
};
|
|
234
667
|
//#endregion
|
|
235
|
-
export { type
|
|
668
|
+
export { type IdTokenClaims, _default as default, extractAccountIdFromClaims, parseJwtClaims };
|