@openai-oauth/core 2.0.0-beta.0 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auth.d.ts CHANGED
@@ -2,6 +2,7 @@ import { type FetchFunction, type OpenAIOAuthTokenResponse } from "./runtime.js"
2
2
  export type EffectiveAuth = {
3
3
  accessToken: string;
4
4
  accountId: string;
5
+ isFedRamp?: boolean;
5
6
  idToken?: string;
6
7
  refreshToken?: string;
7
8
  sourcePath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,OAAO,EAIN,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAG7B,MAAM,cAAc,CAAA;AAuBrB,MAAM,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,aAAa,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,KAAK,EAAE,wBAAwB,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,aAAa,CAAA;CACnB,CAAA;AAkDD,eAAO,MAAM,uBAAuB,GACnC,MAAM,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,CAAC,EACxD,MAAK,IAAiB,KACpB,OAA4E,CAAA;AAgB/E,eAAO,MAAM,yBAAyB,GAAI,eAAe,MAAM,KAAG,MAAM,EAmBvE,CAAA;AAgFD,eAAO,MAAM,wBAAwB,GAAI,eAAe,MAAM,KAAG,MAUhE,CAAA;AAED,eAAO,MAAM,cAAc,GAC1B,SAAS,qBAAqB,KAC5B,OAAO,CAAC,eAAe,CAsCzB,CAAA;AAyCD,eAAO,MAAM,cAAc,GAC1B,SAAS,iBAAiB,KACxB,OAAO,CAAC,aAAa,CAkFvB,CAAA"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAG7B,MAAM,cAAc,CAAA;AAwBrB,MAAM,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,aAAa,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,KAAK,EAAE,wBAAwB,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,aAAa,CAAA;CACnB,CAAA;AAmDD,eAAO,MAAM,uBAAuB,GACnC,MAAM,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,CAAC,EACxD,MAAK,IAAiB,KACpB,OAA4E,CAAA;AAgB/E,eAAO,MAAM,yBAAyB,GAAI,eAAe,MAAM,KAAG,MAAM,EAmBvE,CAAA;AAsFD,eAAO,MAAM,wBAAwB,GAAI,eAAe,MAAM,KAAG,MAUhE,CAAA;AAED,eAAO,MAAM,cAAc,GAC1B,SAAS,qBAAqB,KAC5B,OAAO,CAAC,eAAe,CAwCzB,CAAA;AAsCD,eAAO,MAAM,cAAc,GAC1B,SAAS,iBAAiB,KACxB,OAAO,CAAC,aAAa,CA0FvB,CAAA"}
package/dist/auth.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { promises as fs } from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { DEFAULT_OPENAI_OAUTH_CLIENT_ID, DEFAULT_OPENAI_OAUTH_ISSUER, deriveAccountId, parseJwtClaims, refreshOpenAIOAuthTokens, } from "./runtime.js";
4
+ import { DEFAULT_OPENAI_OAUTH_CLIENT_ID, DEFAULT_OPENAI_OAUTH_ISSUER, deriveAccountId, deriveChatGptAccountIsFedRamp, parseJwtClaims, refreshOpenAIOAuthTokens, } from "./runtime.js";
5
5
  const DEFAULT_AUTH_CLIENT_ID = process.env.CHATGPT_LOCAL_CLIENT_ID ?? DEFAULT_OPENAI_OAUTH_CLIENT_ID;
6
6
  const DEFAULT_AUTH_ISSUER = process.env.CHATGPT_LOCAL_ISSUER ?? DEFAULT_OPENAI_OAUTH_ISSUER;
7
7
  const AUTH_FILENAME = "auth.json";
@@ -70,11 +70,14 @@ const resolveWritePath = (preferred) => {
70
70
  return path.join(os.homedir(), ".chatgpt-local", AUTH_FILENAME);
71
71
  };
72
72
  const toAuthFile = (input) => {
73
- const auth = {};
73
+ const auth = { ...input };
74
74
  const tokensValue = input.tokens;
75
75
  if (typeof input.OPENAI_API_KEY === "string" && input.OPENAI_API_KEY) {
76
76
  auth.OPENAI_API_KEY = input.OPENAI_API_KEY;
77
77
  }
78
+ else {
79
+ delete auth.OPENAI_API_KEY;
80
+ }
78
81
  if (isRecord(tokensValue) && Object.keys(tokensValue).length > 0) {
79
82
  auth.tokens = {
80
83
  id_token: typeof tokensValue.id_token === "string"
@@ -91,9 +94,15 @@ const toAuthFile = (input) => {
91
94
  : undefined,
92
95
  };
93
96
  }
97
+ else {
98
+ delete auth.tokens;
99
+ }
94
100
  if (typeof input.last_refresh === "string" && input.last_refresh) {
95
101
  auth.last_refresh = input.last_refresh;
96
102
  }
103
+ else {
104
+ delete auth.last_refresh;
105
+ }
97
106
  return auth;
98
107
  };
99
108
  const readAuthFile = async (candidates) => {
@@ -139,6 +148,7 @@ export const saveAuthTokens = async (options) => {
139
148
  }
140
149
  await writeAuthFile(filePath, {
141
150
  ...existing,
151
+ auth_mode: "chatgpt",
142
152
  tokens: {
143
153
  id_token: options.token.idToken,
144
154
  access_token: options.token.accessToken,
@@ -152,6 +162,7 @@ export const saveAuthTokens = async (options) => {
152
162
  auth: {
153
163
  accessToken: options.token.accessToken,
154
164
  accountId,
165
+ isFedRamp: options.token.isFedRamp,
155
166
  idToken: options.token.idToken,
156
167
  refreshToken: options.token.refreshToken,
157
168
  sourcePath: filePath,
@@ -160,24 +171,20 @@ export const saveAuthTokens = async (options) => {
160
171
  };
161
172
  };
162
173
  const refreshChatGptTokens = async (refreshToken, clientId, issuer, tokenUrl, fetchFn) => {
163
- try {
164
- const refreshed = await refreshOpenAIOAuthTokens({
165
- refreshToken,
166
- clientId,
167
- issuer,
168
- tokenUrl,
169
- fetch: fetchFn,
170
- });
171
- return {
172
- accessToken: refreshed.accessToken,
173
- idToken: refreshed.idToken,
174
- refreshToken: refreshed.refreshToken ?? refreshToken,
175
- accountId: refreshed.accountId,
176
- };
177
- }
178
- catch {
179
- return undefined;
180
- }
174
+ const refreshed = await refreshOpenAIOAuthTokens({
175
+ refreshToken,
176
+ clientId,
177
+ issuer,
178
+ tokenUrl,
179
+ fetch: fetchFn,
180
+ });
181
+ return {
182
+ accessToken: refreshed.accessToken,
183
+ idToken: refreshed.idToken,
184
+ refreshToken: refreshed.refreshToken ?? refreshToken,
185
+ accountId: refreshed.accountId,
186
+ isFedRamp: refreshed.isFedRamp,
187
+ };
181
188
  };
182
189
  const normalizeTokens = (tokens) => {
183
190
  const maybeString = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
@@ -200,30 +207,36 @@ export const loadAuthTokens = async (options) => {
200
207
  let idToken = tokens.id_token;
201
208
  let refreshToken = tokens.refresh_token;
202
209
  let accountId = tokens.account_id ?? deriveAccountId(idToken);
210
+ let isFedRamp = deriveChatGptAccountIsFedRamp(idToken) ||
211
+ deriveChatGptAccountIsFedRamp(accessToken);
203
212
  let lastRefresh = authData.last_refresh;
204
213
  const needsRefresh = ensureFresh &&
205
214
  typeof refreshToken === "string" &&
206
215
  shouldRefreshAccessToken(accessToken, lastRefresh, now());
207
216
  if (needsRefresh && typeof refreshToken === "string") {
208
217
  const refreshed = await refreshChatGptTokens(refreshToken, clientId, issuer, tokenUrl, fetch);
209
- if (refreshed) {
210
- accessToken = refreshed.accessToken;
211
- idToken = refreshed.idToken ?? idToken;
212
- refreshToken = refreshed.refreshToken ?? refreshToken;
213
- accountId = refreshed.accountId ?? accountId;
214
- lastRefresh = now().toISOString();
215
- const writePath = resolveWritePath(readResult.path ?? authFilePath);
216
- await writeAuthFile(writePath, {
217
- ...authData,
218
- tokens: {
219
- id_token: idToken,
220
- access_token: accessToken,
221
- refresh_token: refreshToken,
222
- account_id: accountId,
223
- },
224
- last_refresh: lastRefresh,
225
- });
226
- }
218
+ accessToken = refreshed.accessToken;
219
+ idToken = refreshed.idToken ?? idToken;
220
+ refreshToken = refreshed.refreshToken ?? refreshToken;
221
+ accountId = refreshed.accountId ?? accountId;
222
+ isFedRamp =
223
+ isFedRamp ||
224
+ refreshed.isFedRamp === true ||
225
+ deriveChatGptAccountIsFedRamp(idToken) ||
226
+ deriveChatGptAccountIsFedRamp(accessToken);
227
+ lastRefresh = now().toISOString();
228
+ const writePath = resolveWritePath(readResult.path ?? authFilePath);
229
+ await writeAuthFile(writePath, {
230
+ ...authData,
231
+ auth_mode: "chatgpt",
232
+ tokens: {
233
+ id_token: idToken,
234
+ access_token: accessToken,
235
+ refresh_token: refreshToken,
236
+ account_id: accountId,
237
+ },
238
+ last_refresh: lastRefresh,
239
+ });
227
240
  }
228
241
  if (typeof accessToken !== "string" || accessToken.length === 0) {
229
242
  throw new Error("ChatGPT access token not found. Run `codex login` to create auth.json.");
@@ -234,6 +247,7 @@ export const loadAuthTokens = async (options) => {
234
247
  return {
235
248
  accessToken,
236
249
  accountId,
250
+ isFedRamp,
237
251
  idToken,
238
252
  refreshToken,
239
253
  sourcePath: readResult.path ?? resolveWritePath(authFilePath),
@@ -0,0 +1,32 @@
1
+ export declare const DEFAULT_CODEX_CLIENT_VERSION = "0.144.1";
2
+ type FetchLike = typeof fetch;
3
+ export type CodexModelInfo = {
4
+ slug: string;
5
+ visibility?: string;
6
+ supportedInApi?: boolean;
7
+ minimalClientVersion?: string;
8
+ useResponsesLite?: boolean;
9
+ preferWebsockets?: boolean;
10
+ supportVerbosity?: boolean;
11
+ defaultVerbosity?: string;
12
+ defaultReasoningLevel?: string;
13
+ defaultReasoningSummary?: string;
14
+ supportsParallelToolCalls?: boolean;
15
+ availableInPlans?: string[];
16
+ raw: Record<string, unknown>;
17
+ };
18
+ export type ResolveCodexClientVersionOptions = {
19
+ codexVersion?: string;
20
+ fetchImpl?: FetchLike;
21
+ onWarning?: (message: string) => void;
22
+ };
23
+ export type FetchCodexModelCatalogOptions = ResolveCodexClientVersionOptions;
24
+ export type CodexModelCatalogClient = {
25
+ request(path: string, init?: RequestInit): Promise<Response>;
26
+ };
27
+ export declare const resolveCodexClientVersion: (options?: ResolveCodexClientVersionOptions) => Promise<string>;
28
+ export declare const resetCodexClientVersionCache: () => void;
29
+ export declare const fetchCodexModelCatalog: (client: CodexModelCatalogClient, options?: FetchCodexModelCatalogOptions) => Promise<CodexModelInfo[]>;
30
+ export declare const isPublicCodexModel: (model: CodexModelInfo) => boolean;
31
+ export {};
32
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,YAAY,CAAA;AAKrD,KAAK,SAAS,GAAG,OAAO,KAAK,CAAA;AAE7B,MAAM,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,gCAAgC,GAAG;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG,gCAAgC,CAAA;AAE5E,MAAM,MAAM,uBAAuB,GAAG;IACrC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC5D,CAAA;AAiFD,eAAO,MAAM,yBAAyB,GACrC,UAAS,gCAAqC,KAC5C,OAAO,CAAC,MAAM,CA4ChB,CAAA;AAED,eAAO,MAAM,4BAA4B,QAAO,IAI/C,CAAA;AAED,eAAO,MAAM,sBAAsB,GAClC,QAAQ,uBAAuB,EAC/B,UAAS,6BAAkC,KACzC,OAAO,CAAC,cAAc,EAAE,CA8B1B,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,cAAc,KAAG,OAEK,CAAA"}
package/dist/models.js ADDED
@@ -0,0 +1,131 @@
1
+ export const DEFAULT_CODEX_CLIENT_VERSION = "0.144.1";
2
+ const CODEX_VERSION_CACHE_TTL_MS = 60 * 60 * 1000;
3
+ const CODEX_REGISTRY_URL = "https://registry.npmjs.org/@openai/codex/latest";
4
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5
+ const normalizeVersion = (value) => {
6
+ if (typeof value !== "string") {
7
+ return undefined;
8
+ }
9
+ return value.trim().match(/\b\d+\.\d+\.\d+\b/)?.[0];
10
+ };
11
+ const optionalString = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
12
+ const optionalBoolean = (value) => typeof value === "boolean" ? value : undefined;
13
+ const optionalStrings = (value) => Array.isArray(value)
14
+ ? value.filter((item) => typeof item === "string")
15
+ : undefined;
16
+ const toCodexModelInfo = (value) => {
17
+ if (!isRecord(value)) {
18
+ return undefined;
19
+ }
20
+ const slug = optionalString(value.slug);
21
+ if (!slug) {
22
+ return undefined;
23
+ }
24
+ return {
25
+ slug,
26
+ visibility: optionalString(value.visibility),
27
+ supportedInApi: optionalBoolean(value.supported_in_api),
28
+ minimalClientVersion: optionalString(value.minimal_client_version),
29
+ useResponsesLite: optionalBoolean(value.use_responses_lite),
30
+ preferWebsockets: optionalBoolean(value.prefer_websockets),
31
+ supportVerbosity: optionalBoolean(value.support_verbosity),
32
+ defaultVerbosity: optionalString(value.default_verbosity),
33
+ defaultReasoningLevel: optionalString(value.default_reasoning_level),
34
+ defaultReasoningSummary: optionalString(value.default_reasoning_summary),
35
+ supportsParallelToolCalls: optionalBoolean(value.supports_parallel_tool_calls),
36
+ availableInPlans: optionalStrings(value.available_in_plans),
37
+ raw: value,
38
+ };
39
+ };
40
+ const toUpstreamErrorMessage = (bodyText) => {
41
+ if (!bodyText) {
42
+ return "Failed to load models from Codex.";
43
+ }
44
+ try {
45
+ const parsed = JSON.parse(bodyText);
46
+ if (isRecord(parsed)) {
47
+ if (typeof parsed.detail === "string" && parsed.detail.length > 0) {
48
+ return parsed.detail;
49
+ }
50
+ if (isRecord(parsed.error) && typeof parsed.error.message === "string") {
51
+ return parsed.error.message;
52
+ }
53
+ }
54
+ }
55
+ catch { }
56
+ return bodyText;
57
+ };
58
+ let cachedCodexClientVersion;
59
+ let codexClientVersionCacheExpiresAt = 0;
60
+ let inflightCodexClientVersion;
61
+ export const resolveCodexClientVersion = async (options = {}) => {
62
+ const explicitVersion = normalizeVersion(options.codexVersion);
63
+ if (explicitVersion) {
64
+ return explicitVersion;
65
+ }
66
+ const now = Date.now();
67
+ if (cachedCodexClientVersion && now < codexClientVersionCacheExpiresAt) {
68
+ return cachedCodexClientVersion;
69
+ }
70
+ if (inflightCodexClientVersion) {
71
+ return inflightCodexClientVersion;
72
+ }
73
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
74
+ inflightCodexClientVersion = (async () => {
75
+ try {
76
+ const response = await fetchImpl(CODEX_REGISTRY_URL, {
77
+ headers: { accept: "application/json" },
78
+ });
79
+ if (response.ok) {
80
+ const parsed = (await response.json());
81
+ const version = normalizeVersion(parsed.version);
82
+ if (version) {
83
+ cachedCodexClientVersion = version;
84
+ codexClientVersionCacheExpiresAt =
85
+ Date.now() + CODEX_VERSION_CACHE_TTL_MS;
86
+ return version;
87
+ }
88
+ }
89
+ }
90
+ catch { }
91
+ options.onWarning?.(`Could not determine the latest Codex version. Falling back to ${DEFAULT_CODEX_CLIENT_VERSION}. Pass a version explicitly if you need to override it.`);
92
+ cachedCodexClientVersion = DEFAULT_CODEX_CLIENT_VERSION;
93
+ codexClientVersionCacheExpiresAt = Date.now() + CODEX_VERSION_CACHE_TTL_MS;
94
+ return DEFAULT_CODEX_CLIENT_VERSION;
95
+ })().finally(() => {
96
+ inflightCodexClientVersion = undefined;
97
+ });
98
+ return inflightCodexClientVersion;
99
+ };
100
+ export const resetCodexClientVersionCache = () => {
101
+ cachedCodexClientVersion = undefined;
102
+ codexClientVersionCacheExpiresAt = 0;
103
+ inflightCodexClientVersion = undefined;
104
+ };
105
+ export const fetchCodexModelCatalog = async (client, options = {}) => {
106
+ const clientVersion = await resolveCodexClientVersion(options);
107
+ const response = await client.request(`/models?client_version=${encodeURIComponent(clientVersion)}`);
108
+ const bodyText = await response.text();
109
+ if (!response.ok) {
110
+ throw new Error(toUpstreamErrorMessage(bodyText));
111
+ }
112
+ let parsed;
113
+ try {
114
+ parsed = JSON.parse(bodyText);
115
+ }
116
+ catch {
117
+ throw new Error("Codex returned an invalid models response.");
118
+ }
119
+ if (!isRecord(parsed) || !Array.isArray(parsed.models)) {
120
+ throw new Error("Codex returned a malformed models response.");
121
+ }
122
+ const models = parsed.models
123
+ .map(toCodexModelInfo)
124
+ .filter((model) => model !== undefined);
125
+ if (models.length === 0) {
126
+ throw new Error("Codex returned an empty models list.");
127
+ }
128
+ return models;
129
+ };
130
+ export const isPublicCodexModel = (model) => model.supportedInApi !== false &&
131
+ (model.visibility === undefined || model.visibility === "list");
package/dist/runtime.d.ts CHANGED
@@ -10,6 +10,7 @@ export type FetchFunction = typeof fetch;
10
10
  export type OpenAIOAuthSession = {
11
11
  accessToken: string;
12
12
  accountId: string;
13
+ isFedRamp?: boolean;
13
14
  idToken?: string;
14
15
  refreshToken?: string;
15
16
  expiresAt?: string;
@@ -25,7 +26,6 @@ export type OpenAIOAuth = {
25
26
  headers?: Record<string, string>;
26
27
  instructions?: string;
27
28
  openAIBaseURL?: string;
28
- storeResponses?: boolean;
29
29
  };
30
30
  export type SessionStore = {
31
31
  get(): Promise<OpenAIOAuthSession | null>;
@@ -56,6 +56,7 @@ export type OpenAIOAuthTokenResponse = {
56
56
  idToken?: string;
57
57
  expiresIn?: number;
58
58
  accountId?: string;
59
+ isFedRamp?: boolean;
59
60
  raw: unknown;
60
61
  };
61
62
  export type ExchangeOpenAIOAuthCodeOptions = {
@@ -79,10 +80,10 @@ export type RefreshOpenAIOAuthTokensOptions = {
79
80
  export type CodexOAuthRuntimeSettings = {
80
81
  auth: OpenAIOAuthSessionInput;
81
82
  baseURL?: string;
83
+ codexVersion?: string;
82
84
  fetch?: FetchFunction;
83
85
  headers?: Record<string, string>;
84
86
  instructions?: string;
85
- storeResponses?: boolean;
86
87
  responsesState?: CodexResponsesState | false;
87
88
  };
88
89
  export type OpenAIOAuthTransportOptions = CodexOAuthRuntimeSettings & {
@@ -109,11 +110,11 @@ export type CodexOAuthClient = {
109
110
  export type NormalizeCodexResponsesBodyOptions = {
110
111
  instructions?: string;
111
112
  forceStream?: boolean;
112
- storeResponses?: boolean;
113
113
  };
114
114
  export declare const usesServerReplayState: (value: Record<string, unknown>) => boolean;
115
115
  export declare const parseJwtClaims: (token: string | undefined) => Record<string, unknown> | undefined;
116
116
  export declare const deriveAccountId: (idToken: string | undefined) => string | undefined;
117
+ export declare const deriveChatGptAccountIsFedRamp: (token: string | undefined) => boolean;
117
118
  export declare const createOpenAIOAuthRequest: (options: OpenAIOAuthRequestOptions) => Promise<OpenAIOAuthRequest>;
118
119
  export declare const exchangeOpenAIOAuthCode: (options: ExchangeOpenAIOAuthCodeOptions) => Promise<OpenAIOAuthTokenResponse>;
119
120
  export declare const refreshOpenAIOAuthTokens: (options: RefreshOpenAIOAuthTokensOptions) => Promise<OpenAIOAuthTokenResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
package/dist/runtime.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { withoutTrailingSlash } from "@ai-sdk/provider-utils";
2
+ import { fetchCodexModelCatalog, isPublicCodexModel, } from "./models.js";
2
3
  import { CodexResponsesState } from "./state.js";
3
4
  export { collectCompletedResponseFromSse, iterateServerSentEvents, } from "./sse.js";
4
5
  export { CodexResponsesState, } from "./state.js";
@@ -9,6 +10,9 @@ export const DEFAULT_OPENAI_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
9
10
  export const DEFAULT_OPENAI_OAUTH_ISSUER = "https://auth.openai.com";
10
11
  export const DEFAULT_OPENAI_OAUTH_SCOPE = "openid profile email offline_access";
11
12
  const DEFAULT_CODEX_INSTRUCTIONS = "";
13
+ const MODEL_CATALOG_TTL_MS = 5 * 60 * 1000;
14
+ const MODEL_CATALOG_FAILURE_TTL_MS = 60 * 1000;
15
+ const RESPONSES_LITE_HEADER = "x-openai-internal-codex-responses-lite";
12
16
  const textEncoder = new TextEncoder();
13
17
  const bytesToBase64Url = (bytes) => {
14
18
  let binary = "";
@@ -100,6 +104,14 @@ export const deriveAccountId = (idToken) => {
100
104
  }
101
105
  return undefined;
102
106
  };
107
+ export const deriveChatGptAccountIsFedRamp = (token) => {
108
+ const claims = parseJwtClaims(token);
109
+ if (!claims) {
110
+ return false;
111
+ }
112
+ const authClaim = claims["https://api.openai.com/auth"];
113
+ return isRecord(authClaim) && authClaim.chatgpt_account_is_fedramp === true;
114
+ };
103
115
  const resolveTokenUrl = (issuer, tokenUrl) => tokenUrl ?? `${trimTrailingSlash(issuer)}/oauth/token`;
104
116
  const toTokenResponse = (payload) => {
105
117
  if (!isRecord(payload)) {
@@ -120,23 +132,50 @@ const toTokenResponse = (payload) => {
120
132
  idToken,
121
133
  expiresIn,
122
134
  accountId: deriveAccountId(idToken) ?? deriveAccountId(accessToken),
135
+ isFedRamp: deriveChatGptAccountIsFedRamp(idToken) ||
136
+ deriveChatGptAccountIsFedRamp(accessToken),
123
137
  raw: payload,
124
138
  };
125
139
  };
126
140
  const requestOpenAIOAuthTokens = async (options) => {
127
141
  const issuer = options.issuer ?? DEFAULT_OPENAI_OAUTH_ISSUER;
142
+ const isForm = options.encoding === "form";
128
143
  const response = await pickFetch(options.fetch)(resolveTokenUrl(issuer, options.tokenUrl), {
129
144
  method: "POST",
130
145
  headers: {
131
- "Content-Type": "application/json",
146
+ "Content-Type": isForm
147
+ ? "application/x-www-form-urlencoded"
148
+ : "application/json",
132
149
  },
133
- body: JSON.stringify(options.body),
150
+ body: isForm
151
+ ? new URLSearchParams(options.body).toString()
152
+ : JSON.stringify(options.body),
134
153
  signal: options.signal,
135
154
  });
155
+ const bodyText = await response.text();
136
156
  if (!response.ok) {
137
- throw new Error(`OpenAI OAuth token request failed with HTTP ${response.status}.`);
157
+ let detail = "";
158
+ try {
159
+ const parsed = JSON.parse(bodyText);
160
+ if (isRecord(parsed)) {
161
+ const message = parsed.error_description ?? parsed.message ?? parsed.detail;
162
+ if (typeof message === "string") {
163
+ detail = ` ${message}`;
164
+ }
165
+ }
166
+ }
167
+ catch { }
168
+ throw new Error(`OpenAI OAuth token request failed with HTTP ${response.status}.${detail}`);
169
+ }
170
+ try {
171
+ return toTokenResponse(JSON.parse(bodyText));
172
+ }
173
+ catch (error) {
174
+ if (error instanceof SyntaxError) {
175
+ throw new Error("OpenAI OAuth token response was not valid JSON.");
176
+ }
177
+ throw error;
138
178
  }
139
- return toTokenResponse(await response.json());
140
179
  };
141
180
  export const createOpenAIOAuthRequest = async (options) => {
142
181
  const state = options.state ?? randomURLSafeString(24);
@@ -175,6 +214,7 @@ export const exchangeOpenAIOAuthCode = (options) => requestOpenAIOAuthTokens({
175
214
  tokenUrl: options.tokenUrl,
176
215
  fetch: options.fetch,
177
216
  signal: options.signal,
217
+ encoding: "form",
178
218
  body: {
179
219
  grant_type: "authorization_code",
180
220
  code: options.code,
@@ -188,11 +228,11 @@ export const refreshOpenAIOAuthTokens = (options) => requestOpenAIOAuthTokens({
188
228
  tokenUrl: options.tokenUrl,
189
229
  fetch: options.fetch,
190
230
  signal: options.signal,
231
+ encoding: "json",
191
232
  body: {
192
233
  grant_type: "refresh_token",
193
234
  refresh_token: options.refreshToken,
194
235
  client_id: options.clientId ?? DEFAULT_OPENAI_OAUTH_CLIENT_ID,
195
- scope: DEFAULT_OPENAI_OAUTH_SCOPE,
196
236
  },
197
237
  });
198
238
  const pickFetch = (customFetch) => {
@@ -277,22 +317,90 @@ const decodeBody = async (body) => {
277
317
  return undefined;
278
318
  };
279
319
  export const getDefaultCodexInstructions = () => DEFAULT_CODEX_INSTRUCTIONS;
280
- export const normalizeCodexResponsesBody = (body, options = {}) => {
320
+ const normalizeResponsesInput = (input) => typeof input === "string"
321
+ ? [
322
+ {
323
+ role: "user",
324
+ content: [{ type: "input_text", text: input }],
325
+ },
326
+ ]
327
+ : input;
328
+ const addEncryptedReasoningContent = (include) => {
329
+ const values = Array.isArray(include)
330
+ ? include.filter((value) => typeof value === "string")
331
+ : [];
332
+ if (!values.includes("reasoning.encrypted_content")) {
333
+ values.push("reasoning.encrypted_content");
334
+ }
335
+ return values;
336
+ };
337
+ const applyModelDefaults = (normalized, modelInfo) => {
338
+ if (!modelInfo) {
339
+ return;
340
+ }
341
+ const reasoning = isRecord(normalized.reasoning)
342
+ ? { ...normalized.reasoning }
343
+ : {};
344
+ if (reasoning.effort === undefined &&
345
+ modelInfo.defaultReasoningLevel !== undefined) {
346
+ reasoning.effort = modelInfo.defaultReasoningLevel;
347
+ }
348
+ if (modelInfo.useResponsesLite) {
349
+ reasoning.context = "all_turns";
350
+ }
351
+ if (Object.keys(reasoning).length > 0) {
352
+ normalized.reasoning = reasoning;
353
+ }
354
+ if (modelInfo.supportVerbosity && modelInfo.defaultVerbosity !== undefined) {
355
+ const text = isRecord(normalized.text) ? { ...normalized.text } : {};
356
+ if (text.verbosity === undefined) {
357
+ text.verbosity = modelInfo.defaultVerbosity;
358
+ }
359
+ normalized.text = text;
360
+ }
361
+ if (!modelInfo.useResponsesLite) {
362
+ return;
363
+ }
364
+ const input = Array.isArray(normalized.input) ? [...normalized.input] : [];
365
+ const prefix = [];
366
+ const tools = Array.isArray(normalized.tools) ? normalized.tools : [];
367
+ if (tools.length > 0 &&
368
+ !input.some((item) => isRecord(item) && item.type === "additional_tools")) {
369
+ prefix.push({
370
+ type: "additional_tools",
371
+ role: "developer",
372
+ tools,
373
+ });
374
+ }
375
+ if (typeof normalized.instructions === "string" && normalized.instructions) {
376
+ prefix.push({
377
+ role: "developer",
378
+ content: [{ type: "input_text", text: normalized.instructions }],
379
+ });
380
+ }
381
+ normalized.input = [...prefix, ...input];
382
+ normalized.instructions = "";
383
+ normalized.parallel_tool_calls = false;
384
+ delete normalized.tools;
385
+ };
386
+ const normalizeCodexResponsesBodyInternal = (body, options = {}) => {
281
387
  const normalized = { ...body };
282
388
  const instructions = typeof normalized.instructions === "string"
283
389
  ? normalized.instructions
284
390
  : (options.instructions ?? getDefaultCodexInstructions());
285
391
  normalized.instructions = instructions;
286
- if (normalized.store === undefined) {
287
- normalized.store = options.storeResponses ?? false;
288
- }
392
+ normalized.input = normalizeResponsesInput(normalized.input);
393
+ normalized.store = false;
394
+ normalized.include = addEncryptedReasoningContent(normalized.include);
395
+ applyModelDefaults(normalized, options.modelInfo);
289
396
  if (options.forceStream) {
290
397
  normalized.stream = true;
291
398
  }
292
399
  delete normalized.max_output_tokens;
293
400
  return normalized;
294
401
  };
295
- const prepareResponsesRequestBody = async (pathname, headers, body, settings, state) => {
402
+ export const normalizeCodexResponsesBody = (body, options = {}) => normalizeCodexResponsesBodyInternal(body, options);
403
+ const prepareResponsesRequestBody = async (pathname, headers, body, settings, state, auth, resolveModelInfo) => {
296
404
  if (!pathname.endsWith("/responses")) {
297
405
  return { body };
298
406
  }
@@ -311,10 +419,18 @@ const prepareResponsesRequestBody = async (pathname, headers, body, settings, st
311
419
  Array.isArray(parsed)) {
312
420
  return { body };
313
421
  }
314
- const normalized = normalizeCodexResponsesBody(parsed, {
422
+ const wantsStream = parsed.stream === true;
423
+ const modelInfo = typeof parsed.model === "string"
424
+ ? await resolveModelInfo(auth, parsed.model)
425
+ : undefined;
426
+ const normalized = normalizeCodexResponsesBodyInternal(parsed, {
427
+ forceStream: true,
315
428
  instructions: settings.instructions,
316
- storeResponses: settings.storeResponses,
429
+ modelInfo,
317
430
  });
431
+ if (modelInfo?.useResponsesLite) {
432
+ headers.set(RESPONSES_LITE_HEADER, "true");
433
+ }
318
434
  if (state?.requiresCachedState(normalized)) {
319
435
  await state.waitForPendingCaptures();
320
436
  }
@@ -322,6 +438,7 @@ const prepareResponsesRequestBody = async (pathname, headers, body, settings, st
322
438
  return {
323
439
  body: JSON.stringify(expanded),
324
440
  requestBody: expanded,
441
+ wantsStream,
325
442
  };
326
443
  }
327
444
  catch {
@@ -348,6 +465,101 @@ const captureResponsesState = (response, requestBody, state) => {
348
465
  headers: new Headers(response.headers),
349
466
  });
350
467
  };
468
+ const finalizeResponsesResponse = async (response, prepared, state) => {
469
+ if (prepared.requestBody == null ||
470
+ prepared.wantsStream == null ||
471
+ !response.ok ||
472
+ response.body == null) {
473
+ return response;
474
+ }
475
+ if (prepared.wantsStream) {
476
+ return captureResponsesState(response, prepared.requestBody, state);
477
+ }
478
+ const completed = await collectCompletedResponseFromSse(response.body);
479
+ state?.rememberResponse(completed, prepared.requestBody);
480
+ const headers = new Headers(response.headers);
481
+ headers.delete("content-encoding");
482
+ headers.delete("content-length");
483
+ headers.set("content-type", "application/json");
484
+ return new Response(JSON.stringify(completed), {
485
+ status: response.status,
486
+ statusText: response.statusText,
487
+ headers,
488
+ });
489
+ };
490
+ const applyAuthHeaders = (headers, auth) => {
491
+ headers.delete("authorization");
492
+ headers.delete("chatgpt-account-id");
493
+ headers.delete("openai-beta");
494
+ headers.delete(RESPONSES_LITE_HEADER);
495
+ headers.delete("x-openai-fedramp");
496
+ headers.set("Authorization", `Bearer ${auth.accessToken}`);
497
+ headers.set("chatgpt-account-id", auth.accountId);
498
+ const isFedRamp = auth.isFedRamp ??
499
+ (deriveChatGptAccountIsFedRamp(auth.idToken) ||
500
+ deriveChatGptAccountIsFedRamp(auth.accessToken));
501
+ if (isFedRamp) {
502
+ headers.set("X-OpenAI-Fedramp", "true");
503
+ }
504
+ };
505
+ const createModelCatalogResolver = (fetch, baseURL, settings) => {
506
+ const cache = new Map();
507
+ const inflight = new Map();
508
+ return async (auth) => {
509
+ const cacheKey = `${auth.accountId}:${auth.isFedRamp === true}`;
510
+ const cached = cache.get(cacheKey);
511
+ if (cached && cached.expiresAt > Date.now()) {
512
+ return cached.result;
513
+ }
514
+ let loading = inflight.get(cacheKey);
515
+ if (!loading) {
516
+ loading = (async () => {
517
+ try {
518
+ const models = await fetchCodexModelCatalog({
519
+ request: async (path, init) => {
520
+ const headers = new Headers(settings.headers);
521
+ new Headers(init?.headers).forEach((value, key) => {
522
+ headers.set(key, value);
523
+ });
524
+ applyAuthHeaders(headers, auth);
525
+ return fetch(new URL(path.replace(/^\//, ""), `${baseURL}/`).toString(), {
526
+ ...init,
527
+ method: init?.method ?? "GET",
528
+ headers,
529
+ });
530
+ },
531
+ }, {
532
+ codexVersion: settings.codexVersion,
533
+ fetchImpl: fetch,
534
+ });
535
+ const result = { models };
536
+ cache.set(cacheKey, {
537
+ expiresAt: Date.now() + MODEL_CATALOG_TTL_MS,
538
+ result,
539
+ });
540
+ return result;
541
+ }
542
+ catch (error) {
543
+ const result = {
544
+ models: [],
545
+ error: error instanceof Error
546
+ ? error
547
+ : new Error("Failed to load models from Codex."),
548
+ };
549
+ cache.set(cacheKey, {
550
+ expiresAt: Date.now() + MODEL_CATALOG_FAILURE_TTL_MS,
551
+ result,
552
+ });
553
+ return result;
554
+ }
555
+ })().finally(() => {
556
+ inflight.delete(cacheKey);
557
+ });
558
+ inflight.set(cacheKey, loading);
559
+ }
560
+ return loading;
561
+ };
562
+ };
351
563
  const resolveAuth = async (source) => {
352
564
  const auth = typeof source === "function" ? await source() : source;
353
565
  if (!auth) {
@@ -361,29 +573,48 @@ export const createCodexOAuthFetch = (settings) => {
361
573
  const responsesState = settings.responsesState === false
362
574
  ? undefined
363
575
  : (settings.responsesState ?? new CodexResponsesState());
576
+ const resolveModelCatalog = createModelCatalogResolver(fetch, baseURL, settings);
577
+ const resolveModelInfo = async (auth, model) => (await resolveModelCatalog(auth)).models.find((entry) => entry.slug === model);
364
578
  return async (input, init) => {
365
579
  const request = await readRequestParts(input, init);
366
580
  const targetUrl = resolveTargetUrl(request.url, baseURL);
367
581
  const target = new URL(targetUrl);
368
582
  const auth = await resolveAuth(settings.auth);
583
+ if ((request.method ?? "GET").toUpperCase() === "GET" &&
584
+ target.pathname.endsWith("/models") &&
585
+ !target.searchParams.has("client_version")) {
586
+ const catalog = await resolveModelCatalog(auth);
587
+ const models = catalog.models.filter(isPublicCodexModel);
588
+ if (models.length === 0) {
589
+ return Response.json({
590
+ error: {
591
+ message: catalog.error?.message ?? "Failed to load models from Codex.",
592
+ },
593
+ }, { status: 502 });
594
+ }
595
+ return Response.json({
596
+ object: "list",
597
+ data: models.map((model) => ({
598
+ id: model.slug,
599
+ object: "model",
600
+ created: 0,
601
+ owned_by: "codex-oauth",
602
+ })),
603
+ });
604
+ }
369
605
  const headers = new Headers(settings.headers);
370
606
  request.headers.forEach((value, key) => {
371
607
  headers.set(key, value);
372
608
  });
373
- headers.delete("authorization");
374
- headers.delete("chatgpt-account-id");
375
- headers.delete("openai-beta");
376
- headers.set("Authorization", `Bearer ${auth.accessToken}`);
377
- headers.set("chatgpt-account-id", auth.accountId);
378
- headers.set("OpenAI-Beta", "responses=experimental");
379
- const preparedBody = await prepareResponsesRequestBody(target.pathname, headers, request.body, settings, responsesState);
609
+ applyAuthHeaders(headers, auth);
610
+ const preparedBody = await prepareResponsesRequestBody(target.pathname, headers, request.body, settings, responsesState, auth, resolveModelInfo);
380
611
  const response = await fetch(target.toString(), {
381
612
  method: request.method ?? init?.method,
382
613
  headers,
383
614
  body: preparedBody.body,
384
615
  signal: request.signal ?? undefined,
385
616
  });
386
- return captureResponsesState(response, preparedBody.requestBody, responsesState);
617
+ return finalizeResponsesResponse(response, preparedBody, responsesState);
387
618
  };
388
619
  };
389
620
  const resolveOpenAICompatibleUrl = (path, baseURL) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openai-oauth/core",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.2",
4
4
  "description": "Core auth and in-memory OpenAI-compatible transport for openai-oauth.",
5
5
  "keywords": [
6
6
  "openai",