@opengeni/codex 0.2.5 → 0.2.9

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.
@@ -0,0 +1,55 @@
1
+ import type { CodexFetch } from "./device-code";
2
+ import { type CodexRateLimitResetConsumeResponse, type CodexRateLimitResetCreditsDetails } from "./reset-credits";
3
+ export type CodexAuthHeaders = {
4
+ accessToken: string;
5
+ chatgptAccountId: string | null;
6
+ isFedramp: boolean;
7
+ clientVersion: string;
8
+ };
9
+ export type ResetCreditFetchFailureReason = "http_error" | "invalid_response" | "network_error" | "timeout";
10
+ /** GET /codex/models — login-check + live catalog. A 200 means the token is accepted. spec §1.4/§F */
11
+ export declare function fetchCodexModels(a: CodexAuthHeaders, fetchImpl?: CodexFetch, timeoutMs?: number): Promise<{
12
+ ok: boolean;
13
+ status: number;
14
+ slugs: string[];
15
+ }>;
16
+ /** GET /wham/usage — authoritative limits. NB the WHAM base is /backend-api, NOT /codex (spec §1.8a). */
17
+ export declare function fetchCodexUsage(a: CodexAuthHeaders, fetchImpl?: CodexFetch, timeoutMs?: number): Promise<{
18
+ status: number;
19
+ payload: unknown;
20
+ }>;
21
+ /**
22
+ * GET /wham/rate-limit-reset-credits — detailed earned reset credits.
23
+ *
24
+ * A non-2xx or malformed body returns an explicit non-ok result. The caller may
25
+ * fall back to the count-only summary embedded in /wham/usage, but must never
26
+ * invent actionable rows from that count.
27
+ */
28
+ export declare function fetchCodexRateLimitResetCredits(a: CodexAuthHeaders, fetchImpl?: CodexFetch, timeoutMs?: number): Promise<{
29
+ ok: true;
30
+ status: number;
31
+ details: CodexRateLimitResetCreditsDetails;
32
+ } | {
33
+ ok: false;
34
+ status: number;
35
+ reason: ResetCreditFetchFailureReason;
36
+ }>;
37
+ /**
38
+ * POST /wham/rate-limit-reset-credits/consume with the exact v0.144.6 body.
39
+ * `idempotencyKey` identifies one logical human redemption and MUST be reused
40
+ * by the server on retries. Supplying `creditId` is preferred; omission leaves
41
+ * provider selection in control and is therefore not used by OpenGeni's
42
+ * human-only flow.
43
+ */
44
+ export declare function consumeCodexRateLimitResetCredit(a: CodexAuthHeaders, input: {
45
+ idempotencyKey: string;
46
+ creditId?: string | undefined;
47
+ }, fetchImpl?: CodexFetch, timeoutMs?: number): Promise<{
48
+ ok: true;
49
+ status: number;
50
+ result: CodexRateLimitResetConsumeResponse;
51
+ } | {
52
+ ok: false;
53
+ status: number;
54
+ reason: ResetCreditFetchFailureReason | "invalid_request";
55
+ }>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Pure NECESSARY condition for a Codex-billed turn: the model id is namespaced
3
+ * for the Codex subscription provider (`codex/<slug>`).
4
+ *
5
+ * This is NOT sufficient to bypass billing — an active, connected workspace
6
+ * credential and the deployment flag (`settings.codexSubscriptionEnabled`) are
7
+ * ALSO required (see `isCodexBilledTurn`/`workspaceCodexSubscriptionActive` in
8
+ * `@opengeni/db`). Used only as a cheap, synchronous short-circuit so the common
9
+ * non-codex path never issues a credential read.
10
+ */
11
+ export declare function isCodexBilledModel(model: string | null | undefined): boolean;
@@ -0,0 +1,16 @@
1
+ export type CodexOperationFailureReason = "network_error" | "timeout";
2
+ /**
3
+ * Bound the complete provider operation, including response-body consumption.
4
+ *
5
+ * AbortController makes native fetch release its socket, while Promise.race is
6
+ * the backstop for injected/custom fetch implementations that ignore `signal`.
7
+ * The losing operation is rejection-handled and can never become an unhandled
8
+ * promise after the caller has received the timeout result.
9
+ */
10
+ export declare function runBoundedCodexOperation<T>(operation: (signal: AbortSignal) => Promise<T>, timeoutMs: number): Promise<{
11
+ ok: true;
12
+ value: T;
13
+ } | {
14
+ ok: false;
15
+ reason: CodexOperationFailureReason;
16
+ }>;
@@ -25,6 +25,12 @@ var CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT = Math.floor(
25
25
  var CODEX_CLIENT_VERSION = "0.144.6";
26
26
  var CODEX_REFRESH_WINDOW_MS = 5 * 60 * 1e3;
27
27
  var CODEX_REFRESH_FALLBACK_MS = 8 * 24 * 60 * 60 * 1e3;
28
+ var CODEX_RESPONSE_HEADERS_TIMEOUT_MS = 4 * 6e4;
29
+ var CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS = 5 * 6e4;
30
+ var CODEX_RESPONSE_WHOLE_TIMEOUT_MS = 30 * 6e4;
31
+ var CODEX_RESPONSE_NO_BYTE_RETRIES = 0;
32
+ var CODEX_RESPONSE_RETRY_BACKOFF_MS = 1e3;
33
+ var CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS = 35 * 6e4;
28
34
  var CODEX_APPS_MCP_SERVER_ID = "codex_apps";
29
35
  var CODEX_APPS_MCP_SERVER_NAME = "codex_apps";
30
36
  var CODEX_APPS_MCP_URL = "https://chatgpt.com/backend-api/ps/mcp";
@@ -54,10 +60,16 @@ export {
54
60
  CODEX_CLIENT_VERSION,
55
61
  CODEX_REFRESH_WINDOW_MS,
56
62
  CODEX_REFRESH_FALLBACK_MS,
63
+ CODEX_RESPONSE_HEADERS_TIMEOUT_MS,
64
+ CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS,
65
+ CODEX_RESPONSE_WHOLE_TIMEOUT_MS,
66
+ CODEX_RESPONSE_NO_BYTE_RETRIES,
67
+ CODEX_RESPONSE_RETRY_BACKOFF_MS,
68
+ CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS,
57
69
  CODEX_APPS_MCP_SERVER_ID,
58
70
  CODEX_APPS_MCP_SERVER_NAME,
59
71
  CODEX_APPS_MCP_URL,
60
72
  CODEX_APPS_STARTUP_TIMEOUT_MS,
61
73
  CODEX_APPS_REQUIRED_SCOPES
62
74
  };
63
- //# sourceMappingURL=chunk-AMRVHBCD.js.map
75
+ //# sourceMappingURL=chunk-YGKQDUY7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["// Wire constants for the ChatGPT/Codex subscription backend.\n// Source: CODEX-SUBSCRIPTION-SPEC.md (verified against openai/codex codex-rs).\n\nexport const CODEX_ISSUER = \"https://auth.openai.com\";\nexport const CODEX_CLIENT_ID = \"app_EMoamEEZ73f0CkXaXp7hrann\"; // spec §1.1 (manager.rs:1444)\nexport const CODEX_AUTH_BASE = `${CODEX_ISSUER}/api/accounts`; // device endpoints (device_code_auth.rs:164)\nexport const CODEX_TOKEN_URL = `${CODEX_ISSUER}/oauth/token`; // exchange (form) + refresh (json)\nexport const CODEX_DEVICE_VERIFICATION_URL = `${CODEX_ISSUER}/codex/device`;\nexport const CODEX_DEVICE_REDIRECT_URI = `${CODEX_ISSUER}/deviceauth/callback`;\n\n// Model requests: base already includes /codex; client appends /responses, /models.\nexport const CODEX_RESPONSES_BASE = \"https://chatgpt.com/backend-api/codex\";\n// Usage lives on the WHAM base — NOT under /codex (verified, spec §1.8a).\nexport const CODEX_WHAM_BASE = \"https://chatgpt.com/backend-api\";\n\nexport const CODEX_ORIGINATOR = \"codex_cli_rs\"; // whitelisted originator (spec §1.2)\nexport const CODEX_ID_TOKEN_AUTH_CLAIM = \"https://api.openai.com/auth\";\n\n// Synthetic registry-provider identity. The provider's baseURL is the bare\n// /backend-api (NOT /codex) — codexSubscriptionFetch rewrites /responses ->\n// /codex/responses. Codex model ids are namespaced `codex/<slug>` so they never\n// collide with the built-in OpenAI provider's model ids; the fetch's resolveModel\n// strips the prefix before the slug reaches the backend.\nexport const CODEX_PROVIDER_ID = \"codex-subscription\";\nexport const CODEX_PROVIDER_BASE_URL = \"https://chatgpt.com/backend-api\";\nexport const CODEX_MODEL_ID_PREFIX = \"codex/\";\n\n// The only Codex subscription models OpenGeni exposes. The live GET /models\n// catalog must contain every exact slug; older or internal models never broaden\n// this product allowlist.\nexport const CODEX_FALLBACK_MODEL_SLUGS = [\"gpt-5.6-sol\", \"gpt-5.6-terra\", \"gpt-5.6-luna\"] as const;\n\n// Live Codex model-catalog values for every exposed gpt-5.6 subscription slug.\n// Verified 2026-07-18 against Codex CLI 0.144.6's freshly fetched\n// ~/.codex/models_cache.json and the matching openai/codex core derivations:\n// raw context window = 272,000\n// effective input window (95%) = 258,400\n// automatic compaction limit (90%) = 244,800\n// Keep all three explicit: the effective ceiling is a hard input guard while\n// the lower auto-compact limit is the proactive checkpoint trigger.\nexport const CODEX_MODEL_CONTEXT_WINDOW_TOKENS = 272_000;\nexport const CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT = 95;\nexport const CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS = Math.floor(\n (CODEX_MODEL_CONTEXT_WINDOW_TOKENS * CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT) / 100,\n);\nexport const CODEX_AUTO_COMPACTION_PERCENT = 90;\nexport const CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT = Math.floor(\n (CODEX_MODEL_CONTEXT_WINDOW_TOKENS * CODEX_AUTO_COMPACTION_PERCENT) / 100,\n);\n\n// Sent as the `version` header and inside the User-Agent. Staging-proven on\n// 2026-07-09: 0.142.4 filtered every GPT-5.6 slug out of GET /models, while the\n// official Codex 0.144.0+ releases return all three exact slugs above. Keep\n// this pinned to the latest stable Codex release we have verified end-to-end.\nexport const CODEX_CLIENT_VERSION = \"0.144.6\";\n\nexport const CODEX_REFRESH_WINDOW_MS = 5 * 60 * 1000; // proactive refresh when within 5 min of exp (spec §1.1)\nexport const CODEX_REFRESH_FALLBACK_MS = 8 * 24 * 60 * 60 * 1000; // 8 days when exp is unparseable\n\n// ── Apps / connectors MCP (spec §1.10, §E) ───────────────────────────────────\n// One server-side MCP exposes ALL the user's ChatGPT/Codex connectors\n// (gmail/github/linear/slack/sentry/drive/calendar/…). Streamable HTTP, always.\nexport const CODEX_APPS_MCP_SERVER_ID = \"codex_apps\"; // tools surface as mcp__codex_apps__<tool>\nexport const CODEX_APPS_MCP_SERVER_NAME = \"codex_apps\"; // MCP `name` — MUST equal the id so the SDK namespaces tools as mcp__codex_apps__*\nexport const CODEX_APPS_MCP_URL = \"https://chatgpt.com/backend-api/ps/mcp\"; // live URL (NOT /codex, NOT the legacy /wham/apps)\nexport const CODEX_APPS_STARTUP_TIMEOUT_MS = 30_000; // startup_timeout 30s (spec §1.10) — maps to timeoutMs on this server only\n// Connector scopes that the apps MCP requires. Present ONLY when granted at\n// browser-authorize time; the device-code path CANNOT be confirmed to grant\n// them, so treat connector availability as runtime-discovered (spec §1.10 / §E).\nexport const CODEX_APPS_REQUIRED_SCOPES = [\"api.connectors.read\", \"api.connectors.invoke\"] as const;\n"],"mappings":";AAGO,IAAM,eAAe;AACrB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB,GAAG,YAAY;AACvC,IAAM,kBAAkB,GAAG,YAAY;AACvC,IAAM,gCAAgC,GAAG,YAAY;AACrD,IAAM,4BAA4B,GAAG,YAAY;AAGjD,IAAM,uBAAuB;AAE7B,IAAM,kBAAkB;AAExB,IAAM,mBAAmB;AACzB,IAAM,4BAA4B;AAOlC,IAAM,oBAAoB;AAC1B,IAAM,0BAA0B;AAChC,IAAM,wBAAwB;AAK9B,IAAM,6BAA6B,CAAC,eAAe,iBAAiB,cAAc;AAUlF,IAAM,oCAAoC;AAC1C,IAAM,yCAAyC;AAC/C,IAAM,8CAA8C,KAAK;AAAA,EAC7D,oCAAoC,yCAA0C;AACjF;AACO,IAAM,gCAAgC;AACtC,IAAM,uCAAuC,KAAK;AAAA,EACtD,oCAAoC,gCAAiC;AACxE;AAMO,IAAM,uBAAuB;AAE7B,IAAM,0BAA0B,IAAI,KAAK;AACzC,IAAM,4BAA4B,IAAI,KAAK,KAAK,KAAK;AAKrD,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AACnC,IAAM,qBAAqB;AAC3B,IAAM,gCAAgC;AAItC,IAAM,6BAA6B,CAAC,uBAAuB,uBAAuB;","names":[]}
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["// Wire constants for the ChatGPT/Codex subscription backend.\n// Source: CODEX-SUBSCRIPTION-SPEC.md (verified against openai/codex codex-rs).\n\nexport const CODEX_ISSUER = \"https://auth.openai.com\";\nexport const CODEX_CLIENT_ID = \"app_EMoamEEZ73f0CkXaXp7hrann\"; // spec §1.1 (manager.rs:1444)\nexport const CODEX_AUTH_BASE = `${CODEX_ISSUER}/api/accounts`; // device endpoints (device_code_auth.rs:164)\nexport const CODEX_TOKEN_URL = `${CODEX_ISSUER}/oauth/token`; // exchange (form) + refresh (json)\nexport const CODEX_DEVICE_VERIFICATION_URL = `${CODEX_ISSUER}/codex/device`;\nexport const CODEX_DEVICE_REDIRECT_URI = `${CODEX_ISSUER}/deviceauth/callback`;\n\n// Model requests: base already includes /codex; client appends /responses, /models.\nexport const CODEX_RESPONSES_BASE = \"https://chatgpt.com/backend-api/codex\";\n// Usage lives on the WHAM base — NOT under /codex (verified, spec §1.8a).\nexport const CODEX_WHAM_BASE = \"https://chatgpt.com/backend-api\";\n\nexport const CODEX_ORIGINATOR = \"codex_cli_rs\"; // whitelisted originator (spec §1.2)\nexport const CODEX_ID_TOKEN_AUTH_CLAIM = \"https://api.openai.com/auth\";\n\n// Synthetic registry-provider identity. The provider's baseURL is the bare\n// /backend-api (NOT /codex) — codexSubscriptionFetch rewrites /responses ->\n// /codex/responses. Codex model ids are namespaced `codex/<slug>` so they never\n// collide with the built-in OpenAI provider's model ids; the fetch's resolveModel\n// strips the prefix before the slug reaches the backend.\nexport const CODEX_PROVIDER_ID = \"codex-subscription\";\nexport const CODEX_PROVIDER_BASE_URL = \"https://chatgpt.com/backend-api\";\nexport const CODEX_MODEL_ID_PREFIX = \"codex/\";\n\n// The only Codex subscription models OpenGeni exposes. The live GET /models\n// catalog must contain every exact slug; older or internal models never broaden\n// this product allowlist.\nexport const CODEX_FALLBACK_MODEL_SLUGS = [\"gpt-5.6-sol\", \"gpt-5.6-terra\", \"gpt-5.6-luna\"] as const;\n\n// Live Codex model-catalog values for every exposed gpt-5.6 subscription slug.\n// Verified 2026-07-18 against Codex CLI 0.144.6's freshly fetched\n// ~/.codex/models_cache.json and the matching openai/codex core derivations:\n// raw context window = 272,000\n// effective input window (95%) = 258,400\n// automatic compaction limit (90%) = 244,800\n// Keep all three explicit: the effective ceiling is a hard input guard while\n// the lower auto-compact limit is the proactive checkpoint trigger.\nexport const CODEX_MODEL_CONTEXT_WINDOW_TOKENS = 272_000;\nexport const CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT = 95;\nexport const CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS = Math.floor(\n (CODEX_MODEL_CONTEXT_WINDOW_TOKENS * CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT) / 100,\n);\nexport const CODEX_AUTO_COMPACTION_PERCENT = 90;\nexport const CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT = Math.floor(\n (CODEX_MODEL_CONTEXT_WINDOW_TOKENS * CODEX_AUTO_COMPACTION_PERCENT) / 100,\n);\n\n// Sent as the `version` header and inside the User-Agent. Staging-proven on\n// 2026-07-09: 0.142.4 filtered every GPT-5.6 slug out of GET /models, while the\n// official Codex 0.144.0+ releases return all three exact slugs above. Keep\n// this pinned to the latest stable Codex release we have verified end-to-end.\nexport const CODEX_CLIENT_VERSION = \"0.144.6\";\n\nexport const CODEX_REFRESH_WINDOW_MS = 5 * 60 * 1000; // proactive refresh when within 5 min of exp (spec §1.1)\nexport const CODEX_REFRESH_FALLBACK_MS = 8 * 24 * 60 * 60 * 1000; // 8 days when exp is unparseable\n\n// Codex Responses transport deadlines. The OpenAI SDK's own timeout only covers\n// the wait for response headers and erases the underlying timeout class into the\n// bare `Request timed out.` error. Keep the provider-specific budgets here so\n// the transport can enforce and durably report them without enabling the SDK's\n// blind request replay.\nexport const CODEX_RESPONSE_HEADERS_TIMEOUT_MS = 4 * 60_000;\nexport const CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS = 5 * 60_000;\nexport const CODEX_RESPONSE_WHOLE_TIMEOUT_MS = 30 * 60_000;\n// Kept as a compatibility-shaped policy field, but automatic replay is disabled\n// until a provider-specific operation receipt can prove non-acceptance or resume\n// the same operation identity. An absent response does not prove that the\n// provider never accepted the request.\nexport const CODEX_RESPONSE_NO_BYTE_RETRIES = 0;\nexport const CODEX_RESPONSE_RETRY_BACKOFF_MS = 1_000;\n// Must exceed the transport-owned whole-response deadline. This SDK guard is a\n// last-resort envelope; the inner transport emits the typed/durable failure.\nexport const CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS = 35 * 60_000;\n\n// ── Apps / connectors MCP (spec §1.10, §E) ───────────────────────────────────\n// One server-side MCP exposes ALL the user's ChatGPT/Codex connectors\n// (gmail/github/linear/slack/sentry/drive/calendar/…). Streamable HTTP, always.\nexport const CODEX_APPS_MCP_SERVER_ID = \"codex_apps\"; // tools surface as mcp__codex_apps__<tool>\nexport const CODEX_APPS_MCP_SERVER_NAME = \"codex_apps\"; // MCP `name` — MUST equal the id so the SDK namespaces tools as mcp__codex_apps__*\nexport const CODEX_APPS_MCP_URL = \"https://chatgpt.com/backend-api/ps/mcp\"; // live URL (NOT /codex, NOT the legacy /wham/apps)\nexport const CODEX_APPS_STARTUP_TIMEOUT_MS = 30_000; // startup_timeout 30s (spec §1.10) — maps to timeoutMs on this server only\n// Connector scopes that the apps MCP requires. Present ONLY when granted at\n// browser-authorize time; the device-code path CANNOT be confirmed to grant\n// them, so treat connector availability as runtime-discovered (spec §1.10 / §E).\nexport const CODEX_APPS_REQUIRED_SCOPES = [\"api.connectors.read\", \"api.connectors.invoke\"] as const;\n"],"mappings":";AAGO,IAAM,eAAe;AACrB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB,GAAG,YAAY;AACvC,IAAM,kBAAkB,GAAG,YAAY;AACvC,IAAM,gCAAgC,GAAG,YAAY;AACrD,IAAM,4BAA4B,GAAG,YAAY;AAGjD,IAAM,uBAAuB;AAE7B,IAAM,kBAAkB;AAExB,IAAM,mBAAmB;AACzB,IAAM,4BAA4B;AAOlC,IAAM,oBAAoB;AAC1B,IAAM,0BAA0B;AAChC,IAAM,wBAAwB;AAK9B,IAAM,6BAA6B,CAAC,eAAe,iBAAiB,cAAc;AAUlF,IAAM,oCAAoC;AAC1C,IAAM,yCAAyC;AAC/C,IAAM,8CAA8C,KAAK;AAAA,EAC7D,oCAAoC,yCAA0C;AACjF;AACO,IAAM,gCAAgC;AACtC,IAAM,uCAAuC,KAAK;AAAA,EACtD,oCAAoC,gCAAiC;AACxE;AAMO,IAAM,uBAAuB;AAE7B,IAAM,0BAA0B,IAAI,KAAK;AACzC,IAAM,4BAA4B,IAAI,KAAK,KAAK,KAAK;AAOrD,IAAM,oCAAoC,IAAI;AAC9C,IAAM,wCAAwC,IAAI;AAClD,IAAM,kCAAkC,KAAK;AAK7C,IAAM,iCAAiC;AACvC,IAAM,kCAAkC;AAGxC,IAAM,sCAAsC,KAAK;AAKjD,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AACnC,IAAM,qBAAqB;AAC3B,IAAM,gCAAgC;AAItC,IAAM,6BAA6B,CAAC,uBAAuB,uBAAuB;","names":[]}
@@ -1,29 +1,33 @@
1
- declare const CODEX_ISSUER = "https://auth.openai.com";
2
- declare const CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
3
- declare const CODEX_AUTH_BASE = "https://auth.openai.com/api/accounts";
4
- declare const CODEX_TOKEN_URL = "https://auth.openai.com/oauth/token";
5
- declare const CODEX_DEVICE_VERIFICATION_URL = "https://auth.openai.com/codex/device";
6
- declare const CODEX_DEVICE_REDIRECT_URI = "https://auth.openai.com/deviceauth/callback";
7
- declare const CODEX_RESPONSES_BASE = "https://chatgpt.com/backend-api/codex";
8
- declare const CODEX_WHAM_BASE = "https://chatgpt.com/backend-api";
9
- declare const CODEX_ORIGINATOR = "codex_cli_rs";
10
- declare const CODEX_ID_TOKEN_AUTH_CLAIM = "https://api.openai.com/auth";
11
- declare const CODEX_PROVIDER_ID = "codex-subscription";
12
- declare const CODEX_PROVIDER_BASE_URL = "https://chatgpt.com/backend-api";
13
- declare const CODEX_MODEL_ID_PREFIX = "codex/";
14
- declare const CODEX_FALLBACK_MODEL_SLUGS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"];
15
- declare const CODEX_MODEL_CONTEXT_WINDOW_TOKENS = 272000;
16
- declare const CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT = 95;
17
- declare const CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS: number;
18
- declare const CODEX_AUTO_COMPACTION_PERCENT = 90;
19
- declare const CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT: number;
20
- declare const CODEX_CLIENT_VERSION = "0.144.6";
21
- declare const CODEX_REFRESH_WINDOW_MS: number;
22
- declare const CODEX_REFRESH_FALLBACK_MS: number;
23
- declare const CODEX_APPS_MCP_SERVER_ID = "codex_apps";
24
- declare const CODEX_APPS_MCP_SERVER_NAME = "codex_apps";
25
- declare const CODEX_APPS_MCP_URL = "https://chatgpt.com/backend-api/ps/mcp";
26
- declare const CODEX_APPS_STARTUP_TIMEOUT_MS = 30000;
27
- declare const CODEX_APPS_REQUIRED_SCOPES: readonly ["api.connectors.read", "api.connectors.invoke"];
28
-
29
- export { CODEX_APPS_MCP_SERVER_ID, CODEX_APPS_MCP_SERVER_NAME, CODEX_APPS_MCP_URL, CODEX_APPS_REQUIRED_SCOPES, CODEX_APPS_STARTUP_TIMEOUT_MS, CODEX_AUTH_BASE, CODEX_AUTO_COMPACTION_PERCENT, CODEX_CLIENT_ID, CODEX_CLIENT_VERSION, CODEX_DEVICE_REDIRECT_URI, CODEX_DEVICE_VERIFICATION_URL, CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT, CODEX_FALLBACK_MODEL_SLUGS, CODEX_ID_TOKEN_AUTH_CLAIM, CODEX_ISSUER, CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT, CODEX_MODEL_CONTEXT_WINDOW_TOKENS, CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS, CODEX_MODEL_ID_PREFIX, CODEX_ORIGINATOR, CODEX_PROVIDER_BASE_URL, CODEX_PROVIDER_ID, CODEX_REFRESH_FALLBACK_MS, CODEX_REFRESH_WINDOW_MS, CODEX_RESPONSES_BASE, CODEX_TOKEN_URL, CODEX_WHAM_BASE };
1
+ export declare const CODEX_ISSUER = "https://auth.openai.com";
2
+ export declare const CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
3
+ export declare const CODEX_AUTH_BASE = "https://auth.openai.com/api/accounts";
4
+ export declare const CODEX_TOKEN_URL = "https://auth.openai.com/oauth/token";
5
+ export declare const CODEX_DEVICE_VERIFICATION_URL = "https://auth.openai.com/codex/device";
6
+ export declare const CODEX_DEVICE_REDIRECT_URI = "https://auth.openai.com/deviceauth/callback";
7
+ export declare const CODEX_RESPONSES_BASE = "https://chatgpt.com/backend-api/codex";
8
+ export declare const CODEX_WHAM_BASE = "https://chatgpt.com/backend-api";
9
+ export declare const CODEX_ORIGINATOR = "codex_cli_rs";
10
+ export declare const CODEX_ID_TOKEN_AUTH_CLAIM = "https://api.openai.com/auth";
11
+ export declare const CODEX_PROVIDER_ID = "codex-subscription";
12
+ export declare const CODEX_PROVIDER_BASE_URL = "https://chatgpt.com/backend-api";
13
+ export declare const CODEX_MODEL_ID_PREFIX = "codex/";
14
+ export declare const CODEX_FALLBACK_MODEL_SLUGS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"];
15
+ export declare const CODEX_MODEL_CONTEXT_WINDOW_TOKENS = 272000;
16
+ export declare const CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT = 95;
17
+ export declare const CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS: number;
18
+ export declare const CODEX_AUTO_COMPACTION_PERCENT = 90;
19
+ export declare const CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT: number;
20
+ export declare const CODEX_CLIENT_VERSION = "0.144.6";
21
+ export declare const CODEX_REFRESH_WINDOW_MS: number;
22
+ export declare const CODEX_REFRESH_FALLBACK_MS: number;
23
+ export declare const CODEX_RESPONSE_HEADERS_TIMEOUT_MS: number;
24
+ export declare const CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS: number;
25
+ export declare const CODEX_RESPONSE_WHOLE_TIMEOUT_MS: number;
26
+ export declare const CODEX_RESPONSE_NO_BYTE_RETRIES = 0;
27
+ export declare const CODEX_RESPONSE_RETRY_BACKOFF_MS = 1000;
28
+ export declare const CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS: number;
29
+ export declare const CODEX_APPS_MCP_SERVER_ID = "codex_apps";
30
+ export declare const CODEX_APPS_MCP_SERVER_NAME = "codex_apps";
31
+ export declare const CODEX_APPS_MCP_URL = "https://chatgpt.com/backend-api/ps/mcp";
32
+ export declare const CODEX_APPS_STARTUP_TIMEOUT_MS = 30000;
33
+ export declare const CODEX_APPS_REQUIRED_SCOPES: readonly ["api.connectors.read", "api.connectors.invoke"];
package/dist/constants.js CHANGED
@@ -24,9 +24,15 @@ import {
24
24
  CODEX_REFRESH_FALLBACK_MS,
25
25
  CODEX_REFRESH_WINDOW_MS,
26
26
  CODEX_RESPONSES_BASE,
27
+ CODEX_RESPONSE_HEADERS_TIMEOUT_MS,
28
+ CODEX_RESPONSE_NO_BYTE_RETRIES,
29
+ CODEX_RESPONSE_RETRY_BACKOFF_MS,
30
+ CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS,
31
+ CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS,
32
+ CODEX_RESPONSE_WHOLE_TIMEOUT_MS,
27
33
  CODEX_TOKEN_URL,
28
34
  CODEX_WHAM_BASE
29
- } from "./chunk-AMRVHBCD.js";
35
+ } from "./chunk-YGKQDUY7.js";
30
36
  export {
31
37
  CODEX_APPS_MCP_SERVER_ID,
32
38
  CODEX_APPS_MCP_SERVER_NAME,
@@ -53,6 +59,12 @@ export {
53
59
  CODEX_REFRESH_FALLBACK_MS,
54
60
  CODEX_REFRESH_WINDOW_MS,
55
61
  CODEX_RESPONSES_BASE,
62
+ CODEX_RESPONSE_HEADERS_TIMEOUT_MS,
63
+ CODEX_RESPONSE_NO_BYTE_RETRIES,
64
+ CODEX_RESPONSE_RETRY_BACKOFF_MS,
65
+ CODEX_RESPONSE_SDK_OUTER_TIMEOUT_MS,
66
+ CODEX_RESPONSE_STREAM_IDLE_TIMEOUT_MS,
67
+ CODEX_RESPONSE_WHOLE_TIMEOUT_MS,
56
68
  CODEX_TOKEN_URL,
57
69
  CODEX_WHAM_BASE
58
70
  };
@@ -0,0 +1,36 @@
1
+ export type CodexFetch = (input: string | URL, init?: RequestInit) => Promise<Response>;
2
+ export type CodexDeviceStart = {
3
+ deviceAuthId: string;
4
+ userCode: string;
5
+ verificationUri: string;
6
+ intervalSeconds: number;
7
+ };
8
+ export type CodexTokens = {
9
+ idToken: string;
10
+ accessToken: string;
11
+ refreshToken: string;
12
+ };
13
+ export type CodexPollResult = {
14
+ status: "pending";
15
+ } | {
16
+ status: "expired";
17
+ } | {
18
+ status: "authorized";
19
+ authorizationCode: string;
20
+ codeVerifier: string;
21
+ };
22
+ export declare class CodexDeviceError extends Error {
23
+ constructor(message: string);
24
+ }
25
+ /** Step 1: POST {auth}/deviceauth/usercode {client_id}. device_code_auth.rs:67-95 */
26
+ export declare function startDeviceCode(fetchImpl?: CodexFetch): Promise<CodexDeviceStart>;
27
+ /** Step 3 (single, non-blocking): POST {auth}/deviceauth/token. 403/404 => pending. device_code_auth.rs:106-145 */
28
+ export declare function pollDeviceCode(input: {
29
+ deviceAuthId: string;
30
+ userCode: string;
31
+ }, fetchImpl?: CodexFetch): Promise<CodexPollResult>;
32
+ /** Step 4: POST {issuer}/oauth/token form-encoded grant_type=authorization_code. server.rs:732-766 */
33
+ export declare function exchangeDeviceCode(input: {
34
+ authorizationCode: string;
35
+ codeVerifier: string;
36
+ }, fetchImpl?: CodexFetch): Promise<CodexTokens>;
@@ -0,0 +1,84 @@
1
+ import { type CodexUsageHeaderSnapshot } from "./request-context";
2
+ export type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
3
+ /**
4
+ * Internal provenance marker copied onto buffered non-OK Codex responses.
5
+ * OpenAI's APIError preserves response headers, which lets the worker
6
+ * distinguish a model-provider refusal from an unrelated sandbox/MCP HTTP
7
+ * error that happened during the same Codex turn.
8
+ */
9
+ export declare const CODEX_TRANSPORT_ERROR_HEADER = "x-opengeni-codex-transport-error";
10
+ /** True only for an error produced from this Codex transport's non-OK response. */
11
+ export declare function isCodexTransportError(error: unknown): boolean;
12
+ export type CodexEncryptedArtifactRejection = {
13
+ status: 400;
14
+ kind: "encrypted_content_rejected";
15
+ };
16
+ /**
17
+ * Classify only the provider's definitive request rejection for an opaque
18
+ * reasoning artifact that it can no longer decrypt/parse. A Codex transport
19
+ * marker plus HTTP 400 proves this request was rejected before inference; the
20
+ * semantic match prevents unrelated malformed prompts from entering recovery.
21
+ */
22
+ export declare function classifyCodexEncryptedArtifactRejection(error: unknown): CodexEncryptedArtifactRejection | null;
23
+ /**
24
+ * Multi-account P4 (Part A): scrape the full usage snapshot the codex backend
25
+ * stamps on every `/codex/responses` response in `x-codex-primary-*` /
26
+ * `x-codex-secondary-*` headers (integer-identical to GET /wham/usage, for free).
27
+ *
28
+ * CRITICAL clobber-fix: return null unless BOTH windows expose a valid used-percent
29
+ * integer. recordCodexAccountUsage writes all five columns unconditionally, so a
30
+ * primary-only snapshot would null the weekly column. Both windows are always
31
+ * emitted together on `/codex/responses`; gating on both makes every write a full
32
+ * 5-column snapshot byte-identical to the poll path, and a malformed/absent header
33
+ * set simply no-ops (the /wham/usage poll fallback still covers it).
34
+ */
35
+ export declare function parseCodexUsageHeaders(headers: Headers): CodexUsageHeaderSnapshot | null;
36
+ export declare function codexSubscriptionFetch(base?: FetchLike): FetchLike;
37
+ /** The codex backend's hard-cap error type (ChatGPT/Codex usage limit reached). */
38
+ export declare const CODEX_USAGE_LIMIT_ERROR_TYPE = "usage_limit_reached";
39
+ export type CodexUsageLimitInfo = {
40
+ /** Seconds until the usage cap resets, when the backend reported it. */
41
+ resetsInSeconds: number | null;
42
+ };
43
+ /**
44
+ * Classify a thrown error as a ChatGPT/Codex usage-cap (429 usage_limit_reached)
45
+ * and extract the reset window. The SDK surfaces the codex backend's 429 as an
46
+ * OpenAI APIError whose `.type` (and `.error.type`) is `usage_limit_reached` and
47
+ * whose `.error.resets_in_seconds` carries the cap reset. Walks the cause chain
48
+ * and tolerates the message-only shape so it survives any SDK re-wrapping.
49
+ * Returns null for anything that is not a usage cap.
50
+ */
51
+ export declare function classifyCodexUsageLimitError(error: unknown): CodexUsageLimitInfo | null;
52
+ export type CodexSseFailureProjection = {
53
+ status: number;
54
+ error: {
55
+ type: string;
56
+ code: string;
57
+ message: string;
58
+ param?: string;
59
+ event_type?: string;
60
+ response_id?: string;
61
+ response_status?: string;
62
+ diagnostic_truncated?: true;
63
+ };
64
+ headers: Headers;
65
+ };
66
+ /**
67
+ * A provider terminal carried inside an accepted HTTP-200 stream. The OpenAI
68
+ * SDK cannot turn that late terminal into a non-2xx APIError because headers
69
+ * have already been accepted, so the body transform throws this equivalent
70
+ * bounded shape. Provider-supplied message/param text is intentionally absent:
71
+ * the worker may persist Error.message, while identifiers/classifications are
72
+ * sufficient for retry, compaction, and incident diagnostics.
73
+ */
74
+ export declare class CodexStreamingTerminalError extends Error {
75
+ readonly status: number;
76
+ readonly code: string;
77
+ readonly type: string;
78
+ readonly eventType?: string;
79
+ readonly responseId?: string;
80
+ readonly responseStatus?: string;
81
+ readonly headers: Headers;
82
+ readonly error: Record<string, unknown>;
83
+ constructor(projection: CodexSseFailureProjection, publicMessage: string);
84
+ }