@codeworksh/aikit 0.7.2-dev.20260825090340 → 0.8.0-dev.20260905193244
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/cli.mjs +5 -5
- package/cli.mjs.map +1 -1
- package/{codex-DyQHzQmn.mjs → codex-MtP1574D.mjs} +63 -50
- package/codex-MtP1574D.mjs.map +1 -0
- package/{failure-C0lCOdFE.d.mts → failure-5Wjd-qFH.d.mts} +6 -2
- package/{failure-xra3YPdY.mjs → failure-SAPyG-w2.mjs} +8 -77
- package/failure-SAPyG-w2.mjs.map +1 -0
- package/index.d.mts +120 -3898
- package/index.mjs +490 -559
- package/index.mjs.map +1 -1
- package/llm/failure.d.mts +1 -1
- package/llm/failure.mjs +2 -1
- package/model-CBnredXj.mjs +453 -0
- package/model-CBnredXj.mjs.map +1 -0
- package/{model-CKKq3s4y.d.mts → model-CpX11Oob.d.mts} +126 -46
- package/{modelgen-xolcfdfT.mjs → modelgen-BjSsusLQ.mjs} +78 -5
- package/modelgen-BjSsusLQ.mjs.map +1 -0
- package/modelgen.d.mts +1 -1
- package/modelgen.mjs +1 -1
- package/oauth/openai/codex.mjs +1 -1
- package/openai-codex-BRH4Qa7l.mjs +2 -0
- package/{openai-codex-_3XkJ4bs.mjs → openai-codex-t4B7g-gv.mjs} +542 -105
- package/openai-codex-t4B7g-gv.mjs.map +1 -0
- package/package.json +2 -2
- package/registry-DYdYTwFt.mjs +65 -0
- package/registry-DYdYTwFt.mjs.map +1 -0
- package/schema-rXSoWhic.mjs +80 -0
- package/schema-rXSoWhic.mjs.map +1 -0
- package/codex-DyQHzQmn.mjs.map +0 -1
- package/failure-xra3YPdY.mjs.map +0 -1
- package/modelgen-xolcfdfT.mjs.map +0 -1
- package/openai-codex-FcyE8vxh.mjs +0 -2
- package/openai-codex-_3XkJ4bs.mjs.map +0 -1
- package/registry-DHskX4NP.mjs +0 -5266
- package/registry-DHskX4NP.mjs.map +0 -1
package/cli.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as openAICodexHeaders, r as OpenAICodexOAuthClient, t as JsonOpenAICodexAuthStorage } from "./codex-
|
|
3
|
-
import { t as ModelgenCommand } from "./modelgen-
|
|
2
|
+
import { c as openAICodexHeaders, r as OpenAICodexOAuthClient, t as JsonOpenAICodexAuthStorage } from "./codex-MtP1574D.mjs";
|
|
3
|
+
import { t as ModelgenCommand } from "./modelgen-BjSsusLQ.mjs";
|
|
4
4
|
import yargs from "yargs";
|
|
5
5
|
import { hideBin } from "yargs/helpers";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.8.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/cli/oauth.ts
|
|
10
10
|
async function promptLine(message) {
|
|
@@ -140,12 +140,12 @@ const cli = yargs(hideBin(process.argv)).scriptName("aikit").wrap(100).help("hel
|
|
|
140
140
|
type: "boolean",
|
|
141
141
|
describe: "print request headers for Codex API calls"
|
|
142
142
|
}).check((args) => {
|
|
143
|
-
if (!args.openaiCodex) throw new Error("
|
|
143
|
+
if (!args.openaiCodex) throw new Error("choose an auth provider, for example: auth --openai-codex");
|
|
144
144
|
if ([
|
|
145
145
|
args.status,
|
|
146
146
|
args.refresh,
|
|
147
147
|
args.logout
|
|
148
|
-
].filter(Boolean).length > 1) throw new Error("
|
|
148
|
+
].filter(Boolean).length > 1) throw new Error("choose only one of --status, --refresh, or --logout");
|
|
149
149
|
return true;
|
|
150
150
|
}),
|
|
151
151
|
handler: async (args) => {
|
package/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["pkg.version"],"sources":["../../package.json","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import type { CommandModule } from \"yargs\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n\topenAICodexHeaders,\n} from \"../oauth/openai/codex.ts\";\n\n// `?: T | undefined` rather than plain `?: T`: yargs hands these through as explicit `undefined`,\n// which a bare optional property no longer accepts under `exactOptionalPropertyTypes`.\ntype AuthArgs = {\n\topenaiCodex?: boolean | undefined;\n\tauthFile?: string | undefined;\n\tbrowser?: boolean | undefined;\n\tmanual?: boolean | undefined;\n\tstatus?: boolean | undefined;\n\trefresh?: boolean | undefined;\n\tlogout?: boolean | undefined;\n\tjson?: boolean | undefined;\n\tprintHeaders?: boolean | undefined;\n\toriginator?: string | undefined;\n};\n\nasync function promptLine(message: string): Promise<string> {\n\tconst readline = await import(\"node:readline/promises\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t});\n\n\ttry {\n\t\treturn await rl.question(`${message} `);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst { spawn } = await import(\"node:child_process\");\n\tconst command =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? { file: \"open\", args: [url] }\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? { file: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n\t\t\t\t: { file: \"xdg-open\", args: [url] };\n\n\tconst child = spawn(command.file, command.args, {\n\t\tdetached: true,\n\t\tstdio: \"ignore\",\n\t});\n\tchild.unref();\n}\n\nfunction printCredentials(\n\tcredentials: OpenAICodexOAuthCredentials,\n\toptions: { json?: boolean | undefined; printHeaders?: boolean | undefined },\n) {\n\tif (options.json) {\n\t\tconsole.log(\n\t\t\tJSON.stringify(\n\t\t\t\t{\n\t\t\t\t\taccountId: credentials.accountId,\n\t\t\t\t\texpires: credentials.expires,\n\t\t\t\t\texpiresAt: new Date(credentials.expires).toISOString(),\n\t\t\t\t\theaders: options.printHeaders ? openAICodexHeaders(credentials) : undefined,\n\t\t\t\t},\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t),\n\t\t);\n\t\treturn;\n\t}\n\n\tconsole.log(`Account: ${credentials.accountId}`);\n\tconsole.log(`Expires: ${new Date(credentials.expires).toLocaleString()}`);\n\tif (options.printHeaders) {\n\t\tconsole.log(\"Headers:\");\n\t\tfor (const [name, value] of Object.entries(openAICodexHeaders(credentials))) {\n\t\t\tconsole.log(`${name}: ${value}`);\n\t\t}\n\t}\n}\n\nasync function runOpenAICodexAuth(args: AuthArgs): Promise<void> {\n\tconst storage = new JsonOpenAICodexAuthStorage({\n\t\t...(args.authFile !== undefined && { path: args.authFile }),\n\t});\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\n\tif (args.logout) {\n\t\tawait client.logout();\n\t\tconsole.log(`Cleared OpenAI Codex credentials from ${storage.path}`);\n\t\treturn;\n\t}\n\n\tif (args.status) {\n\t\tconst credentials = await storage.get();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tif (args.refresh) {\n\t\tconst credentials = await client.getCredentials();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(`Refreshed OpenAI Codex credentials in ${storage.path}`);\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tconst credentials = await client.login({\n\t\t...(args.originator !== undefined && { originator: args.originator }),\n\t\t...(args.manual && {\n\t\t\tonManualCodeInput: async () =>\n\t\t\t\tpromptLine(\"Paste the redirect URL or authorization code, or wait for browser callback:\"),\n\t\t}),\n\t\tonAuth: (info) => {\n\t\t\tconsole.log(info.instructions ?? \"Complete OpenAI Codex authentication in your browser.\");\n\t\t\tconsole.log(info.url);\n\t\t\tif (args.browser !== false) {\n\t\t\t\tvoid openBrowser(info.url).catch((error) => {\n\t\t\t\t\tconsole.warn(`Failed to open browser: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonPrompt: async (prompt) => promptLine(prompt.message),\n\t});\n\n\tconsole.log(`Saved OpenAI Codex credentials to ${storage.path}`);\n\tprintCredentials(credentials, args);\n}\n\nexport const OAuthCommand: CommandModule<object, AuthArgs> = {\n\tcommand: \"auth\",\n\tdescribe: \"manage OAuth credentials\",\n\tbuilder: (yargs) =>\n\t\tyargs\n\t\t\t.option(\"openai-codex\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"use OpenAI Codex OAuth\",\n\t\t\t})\n\t\t\t.option(\"auth-file\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescribe: \"path to auth.json (defaults to CODEWORK_CREDENTIALS or ~/.codework/aikit/auth.json)\",\n\t\t\t})\n\t\t\t.option(\"browser\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: true,\n\t\t\t\tdescribe: \"open the authorization URL in the default browser\",\n\t\t\t})\n\t\t\t.option(\"manual\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: false,\n\t\t\t\tdescribe: \"also prompt for a pasted redirect URL or authorization code\",\n\t\t\t})\n\t\t\t.option(\"originator\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdefault: \"codework\",\n\t\t\t\tdescribe: \"OAuth originator value\",\n\t\t\t})\n\t\t\t.option(\"status\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"show stored credential status without refreshing\",\n\t\t\t})\n\t\t\t.option(\"refresh\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"refresh stored credentials if expired\",\n\t\t\t})\n\t\t\t.option(\"logout\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"clear stored credentials\",\n\t\t\t})\n\t\t\t.option(\"json\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print machine-readable output\",\n\t\t\t})\n\t\t\t.option(\"print-headers\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print request headers for Codex API calls\",\n\t\t\t})\n\t\t\t.check((args) => {\n\t\t\t\tif (!args.openaiCodex) throw new Error(\"Choose an auth provider, for example: auth --openai-codex\");\n\t\t\t\tconst actions = [args.status, args.refresh, args.logout].filter(Boolean).length;\n\t\t\t\tif (actions > 1) throw new Error(\"Choose only one of --status, --refresh, or --logout\");\n\t\t\t\treturn true;\n\t\t\t}),\n\thandler: async (args) => {\n\t\tawait runOpenAICodexAuth(args);\n\t},\n};\n","#!/usr/bin/env node\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { ModelgenCommand } from \"./cli/modelgen.ts\";\nimport { OAuthCommand } from \"./cli/oauth.ts\";\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"aikit\")\n\t.wrap(100)\n\t.help(\"help\", \"show help\")\n\t.alias(\"help\", \"h\")\n\t.version(\"version\", \"show version number\", pkg.version)\n\t.alias(\"version\", \"v\")\n\t.command(ModelgenCommand)\n\t.command(OAuthCommand)\n\t.demandCommand(1, \"Choose a command\")\n\t.strict()\n\t.fail((message, error) => {\n\t\tif (error) throw error;\n\t\tif (message) throw new Error(message);\n\t});\n\ntry {\n\tawait cli.parse();\n} catch (error) {\n\tprocess.exitCode = 1;\n\tconsole.error(error instanceof Error ? error.message : String(error));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["pkg.version"],"sources":["../../package.json","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import type { CommandModule } from \"yargs\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n\topenAICodexHeaders,\n} from \"../oauth/openai/codex.ts\";\n\n// `?: T | undefined` rather than plain `?: T`: yargs hands these through as explicit `undefined`,\n// which a bare optional property no longer accepts under `exactOptionalPropertyTypes`.\ntype AuthArgs = {\n\topenaiCodex?: boolean | undefined;\n\tauthFile?: string | undefined;\n\tbrowser?: boolean | undefined;\n\tmanual?: boolean | undefined;\n\tstatus?: boolean | undefined;\n\trefresh?: boolean | undefined;\n\tlogout?: boolean | undefined;\n\tjson?: boolean | undefined;\n\tprintHeaders?: boolean | undefined;\n\toriginator?: string | undefined;\n};\n\nasync function promptLine(message: string): Promise<string> {\n\tconst readline = await import(\"node:readline/promises\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t});\n\n\ttry {\n\t\treturn await rl.question(`${message} `);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst { spawn } = await import(\"node:child_process\");\n\tconst command =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? { file: \"open\", args: [url] }\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? { file: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n\t\t\t\t: { file: \"xdg-open\", args: [url] };\n\n\tconst child = spawn(command.file, command.args, {\n\t\tdetached: true,\n\t\tstdio: \"ignore\",\n\t});\n\tchild.unref();\n}\n\nfunction printCredentials(\n\tcredentials: OpenAICodexOAuthCredentials,\n\toptions: { json?: boolean | undefined; printHeaders?: boolean | undefined },\n) {\n\tif (options.json) {\n\t\tconsole.log(\n\t\t\tJSON.stringify(\n\t\t\t\t{\n\t\t\t\t\taccountId: credentials.accountId,\n\t\t\t\t\texpires: credentials.expires,\n\t\t\t\t\texpiresAt: new Date(credentials.expires).toISOString(),\n\t\t\t\t\theaders: options.printHeaders ? openAICodexHeaders(credentials) : undefined,\n\t\t\t\t},\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t),\n\t\t);\n\t\treturn;\n\t}\n\n\tconsole.log(`Account: ${credentials.accountId}`);\n\tconsole.log(`Expires: ${new Date(credentials.expires).toLocaleString()}`);\n\tif (options.printHeaders) {\n\t\tconsole.log(\"Headers:\");\n\t\tfor (const [name, value] of Object.entries(openAICodexHeaders(credentials))) {\n\t\t\tconsole.log(`${name}: ${value}`);\n\t\t}\n\t}\n}\n\nasync function runOpenAICodexAuth(args: AuthArgs): Promise<void> {\n\tconst storage = new JsonOpenAICodexAuthStorage({\n\t\t...(args.authFile !== undefined && { path: args.authFile }),\n\t});\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\n\tif (args.logout) {\n\t\tawait client.logout();\n\t\tconsole.log(`Cleared OpenAI Codex credentials from ${storage.path}`);\n\t\treturn;\n\t}\n\n\tif (args.status) {\n\t\tconst credentials = await storage.get();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tif (args.refresh) {\n\t\tconst credentials = await client.getCredentials();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(`Refreshed OpenAI Codex credentials in ${storage.path}`);\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tconst credentials = await client.login({\n\t\t...(args.originator !== undefined && { originator: args.originator }),\n\t\t...(args.manual && {\n\t\t\tonManualCodeInput: async () =>\n\t\t\t\tpromptLine(\"Paste the redirect URL or authorization code, or wait for browser callback:\"),\n\t\t}),\n\t\tonAuth: (info) => {\n\t\t\tconsole.log(info.instructions ?? \"Complete OpenAI Codex authentication in your browser.\");\n\t\t\tconsole.log(info.url);\n\t\t\tif (args.browser !== false) {\n\t\t\t\tvoid openBrowser(info.url).catch((error) => {\n\t\t\t\t\tconsole.warn(`Failed to open browser: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonPrompt: async (prompt) => promptLine(prompt.message),\n\t});\n\n\tconsole.log(`Saved OpenAI Codex credentials to ${storage.path}`);\n\tprintCredentials(credentials, args);\n}\n\nexport const OAuthCommand: CommandModule<object, AuthArgs> = {\n\tcommand: \"auth\",\n\tdescribe: \"manage OAuth credentials\",\n\tbuilder: (yargs) =>\n\t\tyargs\n\t\t\t.option(\"openai-codex\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"use OpenAI Codex OAuth\",\n\t\t\t})\n\t\t\t.option(\"auth-file\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescribe: \"path to auth.json (defaults to CODEWORK_CREDENTIALS or ~/.codework/aikit/auth.json)\",\n\t\t\t})\n\t\t\t.option(\"browser\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: true,\n\t\t\t\tdescribe: \"open the authorization URL in the default browser\",\n\t\t\t})\n\t\t\t.option(\"manual\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: false,\n\t\t\t\tdescribe: \"also prompt for a pasted redirect URL or authorization code\",\n\t\t\t})\n\t\t\t.option(\"originator\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdefault: \"codework\",\n\t\t\t\tdescribe: \"OAuth originator value\",\n\t\t\t})\n\t\t\t.option(\"status\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"show stored credential status without refreshing\",\n\t\t\t})\n\t\t\t.option(\"refresh\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"refresh stored credentials if expired\",\n\t\t\t})\n\t\t\t.option(\"logout\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"clear stored credentials\",\n\t\t\t})\n\t\t\t.option(\"json\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print machine-readable output\",\n\t\t\t})\n\t\t\t.option(\"print-headers\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print request headers for Codex API calls\",\n\t\t\t})\n\t\t\t.check((args) => {\n\t\t\t\tif (!args.openaiCodex) throw new Error(\"choose an auth provider, for example: auth --openai-codex\");\n\t\t\t\tconst actions = [args.status, args.refresh, args.logout].filter(Boolean).length;\n\t\t\t\tif (actions > 1) throw new Error(\"choose only one of --status, --refresh, or --logout\");\n\t\t\t\treturn true;\n\t\t\t}),\n\thandler: async (args) => {\n\t\tawait runOpenAICodexAuth(args);\n\t},\n};\n","#!/usr/bin/env node\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { ModelgenCommand } from \"./cli/modelgen.ts\";\nimport { OAuthCommand } from \"./cli/oauth.ts\";\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"aikit\")\n\t.wrap(100)\n\t.help(\"help\", \"show help\")\n\t.alias(\"help\", \"h\")\n\t.version(\"version\", \"show version number\", pkg.version)\n\t.alias(\"version\", \"v\")\n\t.command(ModelgenCommand)\n\t.command(OAuthCommand)\n\t.demandCommand(1, \"Choose a command\")\n\t.strict()\n\t.fail((message, error) => {\n\t\tif (error) throw error;\n\t\tif (message) throw new Error(message);\n\t});\n\ntry {\n\tawait cli.parse();\n} catch (error) {\n\tprocess.exitCode = 1;\n\tconsole.error(error instanceof Error ? error.message : String(error));\n}\n"],"mappings":"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"}
|
|
@@ -43,7 +43,7 @@ function expandHome(path) {
|
|
|
43
43
|
}
|
|
44
44
|
function homeDirectory() {
|
|
45
45
|
const home = readEnv("HOME") ?? readEnv("USERPROFILE");
|
|
46
|
-
if (!home) throw new Error("
|
|
46
|
+
if (!home) throw new Error("unable to resolve home directory for OpenAI Codex auth storage");
|
|
47
47
|
return home;
|
|
48
48
|
}
|
|
49
49
|
function codeworkHomeDirectory() {
|
|
@@ -63,6 +63,28 @@ function isOpenAICodexCredentials(value) {
|
|
|
63
63
|
if (!isObject(value)) return false;
|
|
64
64
|
return typeof value.access === "string" && typeof value.refresh === "string" && typeof value.expires === "number" && typeof value.accountId === "string";
|
|
65
65
|
}
|
|
66
|
+
function redactOAuthSecrets(value, secrets = []) {
|
|
67
|
+
let redacted = value;
|
|
68
|
+
for (const secret of secrets.filter(Boolean).sort((left, right) => right.length - left.length)) redacted = redacted.replaceAll(secret, "[REDACTED]");
|
|
69
|
+
return redacted.replace(/((?:"?(?:access_token|refresh_token|id_token|code|code_verifier)"?)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^&\s,}]+)/gi, "$1\"[REDACTED]\"").replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]");
|
|
70
|
+
}
|
|
71
|
+
function tokenEndpointResult(payload, operation) {
|
|
72
|
+
const missing = [
|
|
73
|
+
!payload.access_token && "access_token",
|
|
74
|
+
!payload.refresh_token && "refresh_token",
|
|
75
|
+
typeof payload.expires_in !== "number" && "expires_in"
|
|
76
|
+
].filter((field) => Boolean(field));
|
|
77
|
+
if (missing.length > 0) return {
|
|
78
|
+
type: "failed",
|
|
79
|
+
message: `OpenAI Codex token ${operation} response missing fields: ${missing.join(", ")}`
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
type: "success",
|
|
83
|
+
access: payload.access_token,
|
|
84
|
+
refresh: payload.refresh_token,
|
|
85
|
+
expires: Date.now() + payload.expires_in * 1e3
|
|
86
|
+
};
|
|
87
|
+
}
|
|
66
88
|
function base64UrlEncode(bytes) {
|
|
67
89
|
let binary = "";
|
|
68
90
|
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
@@ -74,7 +96,7 @@ function base64UrlDecode(value) {
|
|
|
74
96
|
return atob(padded);
|
|
75
97
|
}
|
|
76
98
|
function getCrypto() {
|
|
77
|
-
if (!globalThis.crypto?.getRandomValues || !globalThis.crypto.subtle) throw new Error("
|
|
99
|
+
if (!globalThis.crypto?.getRandomValues || !globalThis.crypto.subtle) throw new Error("openAI codex OAuth requires web crypto support");
|
|
78
100
|
return globalThis.crypto;
|
|
79
101
|
}
|
|
80
102
|
function createState() {
|
|
@@ -152,36 +174,33 @@ async function createOpenAICodexAuthorizationFlow(options = {}) {
|
|
|
152
174
|
};
|
|
153
175
|
}
|
|
154
176
|
async function exchangeOpenAICodexAuthorizationCode(code, verifier, redirectUri = DEFAULT_REDIRECT_URI) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
177
|
+
try {
|
|
178
|
+
const response = await fetch(TOKEN_URL, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
181
|
+
body: new URLSearchParams({
|
|
182
|
+
grant_type: "authorization_code",
|
|
183
|
+
client_id: CLIENT_ID,
|
|
184
|
+
code,
|
|
185
|
+
code_verifier: verifier,
|
|
186
|
+
redirect_uri: redirectUri
|
|
187
|
+
})
|
|
188
|
+
});
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
const text = await response.text().catch(() => "");
|
|
191
|
+
return {
|
|
192
|
+
type: "failed",
|
|
193
|
+
status: response.status,
|
|
194
|
+
message: `OpenAI Codex token exchange failed (${response.status}): ${redactOAuthSecrets(text || response.statusText, [code, verifier])}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return tokenEndpointResult(await response.json(), "exchange");
|
|
198
|
+
} catch (error) {
|
|
168
199
|
return {
|
|
169
200
|
type: "failed",
|
|
170
|
-
|
|
171
|
-
message: `OpenAI Codex token exchange failed (${response.status}): ${text || response.statusText}`
|
|
201
|
+
message: `OpenAI Codex token exchange error: ${redactOAuthSecrets(error instanceof Error ? error.message : String(error), [code, verifier])}`
|
|
172
202
|
};
|
|
173
203
|
}
|
|
174
|
-
const json = await response.json();
|
|
175
|
-
if (!json.access_token || !json.refresh_token || typeof json.expires_in !== "number") return {
|
|
176
|
-
type: "failed",
|
|
177
|
-
message: `OpenAI Codex token exchange response missing fields: ${JSON.stringify(json)}`
|
|
178
|
-
};
|
|
179
|
-
return {
|
|
180
|
-
type: "success",
|
|
181
|
-
access: json.access_token,
|
|
182
|
-
refresh: json.refresh_token,
|
|
183
|
-
expires: Date.now() + json.expires_in * 1e3
|
|
184
|
-
};
|
|
185
204
|
}
|
|
186
205
|
async function refreshAccessToken(refreshToken) {
|
|
187
206
|
try {
|
|
@@ -199,24 +218,14 @@ async function refreshAccessToken(refreshToken) {
|
|
|
199
218
|
return {
|
|
200
219
|
type: "failed",
|
|
201
220
|
status: response.status,
|
|
202
|
-
message: `OpenAI Codex token refresh failed (${response.status}): ${text || response.statusText}`
|
|
221
|
+
message: `OpenAI Codex token refresh failed (${response.status}): ${redactOAuthSecrets(text || response.statusText, [refreshToken])}`
|
|
203
222
|
};
|
|
204
223
|
}
|
|
205
|
-
|
|
206
|
-
if (!json.access_token || !json.refresh_token || typeof json.expires_in !== "number") return {
|
|
207
|
-
type: "failed",
|
|
208
|
-
message: `OpenAI Codex token refresh response missing fields: ${JSON.stringify(json)}`
|
|
209
|
-
};
|
|
210
|
-
return {
|
|
211
|
-
type: "success",
|
|
212
|
-
access: json.access_token,
|
|
213
|
-
refresh: json.refresh_token,
|
|
214
|
-
expires: Date.now() + json.expires_in * 1e3
|
|
215
|
-
};
|
|
224
|
+
return tokenEndpointResult(await response.json(), "refresh");
|
|
216
225
|
} catch (error) {
|
|
217
226
|
return {
|
|
218
227
|
type: "failed",
|
|
219
|
-
message: `OpenAI Codex token refresh error: ${error instanceof Error ? error.message : String(error)}`
|
|
228
|
+
message: `OpenAI Codex token refresh error: ${redactOAuthSecrets(error instanceof Error ? error.message : String(error), [refreshToken])}`
|
|
220
229
|
};
|
|
221
230
|
}
|
|
222
231
|
}
|
|
@@ -276,7 +285,7 @@ function oauthErrorHtml(message, details) {
|
|
|
276
285
|
}
|
|
277
286
|
async function startLocalOAuthServer(state) {
|
|
278
287
|
const http = await import("node:http").catch(() => void 0);
|
|
279
|
-
if (!http) throw new Error("
|
|
288
|
+
if (!http) throw new Error("openAI codex OAuth callback server is only available in Node.js environments");
|
|
280
289
|
let settleWait;
|
|
281
290
|
const waitForCodePromise = new Promise((resolve) => {
|
|
282
291
|
let settled = false;
|
|
@@ -368,7 +377,7 @@ async function loginOpenAICodex(options) {
|
|
|
368
377
|
if (result?.code) code = result.code;
|
|
369
378
|
else if (manualCode) {
|
|
370
379
|
const parsed = parseOpenAICodexAuthorizationInput(manualCode);
|
|
371
|
-
if (parsed.state && parsed.state !== flow.state) throw new Error("
|
|
380
|
+
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
372
381
|
code = parsed.code;
|
|
373
382
|
}
|
|
374
383
|
if (!code) {
|
|
@@ -376,7 +385,7 @@ async function loginOpenAICodex(options) {
|
|
|
376
385
|
if (manualError) throw manualError;
|
|
377
386
|
if (manualCode) {
|
|
378
387
|
const parsed = parseOpenAICodexAuthorizationInput(manualCode);
|
|
379
|
-
if (parsed.state && parsed.state !== flow.state) throw new Error("
|
|
388
|
+
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
380
389
|
code = parsed.code;
|
|
381
390
|
}
|
|
382
391
|
}
|
|
@@ -386,14 +395,14 @@ async function loginOpenAICodex(options) {
|
|
|
386
395
|
}
|
|
387
396
|
if (!code) {
|
|
388
397
|
const parsed = parseOpenAICodexAuthorizationInput(await options.onPrompt({ message: "Paste the authorization code or full redirect URL:" }));
|
|
389
|
-
if (parsed.state && parsed.state !== flow.state) throw new Error("
|
|
398
|
+
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
390
399
|
code = parsed.code;
|
|
391
400
|
}
|
|
392
|
-
if (!code) throw new Error("
|
|
401
|
+
if (!code) throw new Error("missing authorization code");
|
|
393
402
|
const tokenResult = await exchangeOpenAICodexAuthorizationCode(code, flow.verifier, flow.redirectUri);
|
|
394
403
|
if (tokenResult.type !== "success") throw new Error(tokenResult.message);
|
|
395
404
|
const accountId = getOpenAICodexAccountId(tokenResult.access);
|
|
396
|
-
if (!accountId) throw new Error("
|
|
405
|
+
if (!accountId) throw new Error("failed to extract accountId from token");
|
|
397
406
|
return {
|
|
398
407
|
access: tokenResult.access,
|
|
399
408
|
refresh: tokenResult.refresh,
|
|
@@ -408,7 +417,7 @@ async function refreshOpenAICodexToken(refreshToken) {
|
|
|
408
417
|
const result = await refreshAccessToken(refreshToken);
|
|
409
418
|
if (result.type !== "success") throw new Error(result.message);
|
|
410
419
|
const accountId = getOpenAICodexAccountId(result.access);
|
|
411
|
-
if (!accountId) throw new Error("
|
|
420
|
+
if (!accountId) throw new Error("failed to extract accountId from token");
|
|
412
421
|
return {
|
|
413
422
|
access: result.access,
|
|
414
423
|
refresh: result.refresh,
|
|
@@ -473,7 +482,11 @@ var JsonOpenAICodexAuthStorage = class {
|
|
|
473
482
|
const path = await import("node:path");
|
|
474
483
|
await fs.mkdir(path.dirname(this.path), { recursive: true });
|
|
475
484
|
const tempPath = `${this.path}.${process.pid}.${Date.now()}.tmp`;
|
|
476
|
-
await fs.writeFile(tempPath, `${JSON.stringify(value, null, " ")}\n`,
|
|
485
|
+
await fs.writeFile(tempPath, `${JSON.stringify(value, null, " ")}\n`, {
|
|
486
|
+
encoding: "utf8",
|
|
487
|
+
mode: 384
|
|
488
|
+
});
|
|
489
|
+
await fs.chmod(tempPath, 384);
|
|
477
490
|
await fs.rename(tempPath, this.path);
|
|
478
491
|
}
|
|
479
492
|
};
|
|
@@ -525,4 +538,4 @@ async function getOpenAICodexApiKey(options = {}) {
|
|
|
525
538
|
//#endregion
|
|
526
539
|
export { exchangeOpenAICodexAuthorizationCode as a, openAICodexHeaders as c, createOpenAICodexAuthorizationFlow as i, parseOpenAICodexAuthorizationInput as l, OPENAI_CODEX_API_KEY_ENV as n, getOpenAICodexAccountId as o, OpenAICodexOAuthClient as r, getOpenAICodexApiKey as s, JsonOpenAICodexAuthStorage as t, refreshOpenAICodexToken as u };
|
|
527
540
|
|
|
528
|
-
//# sourceMappingURL=codex-
|
|
541
|
+
//# sourceMappingURL=codex-MtP1574D.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-MtP1574D.mjs","names":[],"sources":["../../src/oauth/openai/codex.ts"],"sourcesContent":["/**\n * OpenAI Codex OAuth.\n *\n * Public interface, by use case:\n *\n * 1. Server OAuth integration (storage-free, bring your own routes):\n * `createOpenAICodexAuthorizationFlow`, `exchangeOpenAICodexAuthorizationCode`,\n * `parseOpenAICodexAuthorizationInput`, `refreshOpenAICodexToken`, `getOpenAICodexAccountId`.\n * 2. CLI / interactive login (localhost callback server, persisted credentials):\n * `OpenAICodexOAuthClient`, `JsonOpenAICodexAuthStorage`, `OpenAICodexAuthStorage`.\n * 3. Application credential access (get key, auto-refresh, request headers):\n * `getOpenAICodexApiKey`, `OpenAICodexOAuthClient.getCredentials/getApiKey/getHeaders`,\n * `openAICodexHeaders`, `OPENAI_CODEX_API_KEY_ENV`.\n *\n * Everything else in this module is an implementation detail and intentionally\n * not exported.\n */\n\nimport dedent from \"dedent\";\n\nconst CODEWORK_OAUTH_CALLBACK_HOST = \"CODEWORK_OAUTH_CALLBACK_HOST\";\nconst CODEWORK_CREDENTIALS = \"CODEWORK_CREDENTIALS\";\nconst CODEWORK_HOME_DIR = \"CODEWORK_HOME_DIR\";\n\nconst CLIENT_ID = \"app_EMoamEEZ73f0CkXaXp7hrann\";\nconst AUTHORIZE_URL = \"https://auth.openai.com/oauth/authorize\";\nconst TOKEN_URL = \"https://auth.openai.com/oauth/token\";\nconst DEFAULT_REDIRECT_URI = \"http://localhost:1455/auth/callback\";\nconst DEFAULT_SCOPE = \"openid profile email offline_access\";\nconst DEFAULT_ORIGINATOR = \"codework\";\nconst DEFAULT_PROVIDER_ID = \"openai-codex\";\nconst JWT_CLAIM_PATH = \"https://api.openai.com/auth\";\nconst REFRESH_SKEW_MS = 60 * 1000;\n\nexport type OpenAICodexOAuthCredentials = {\n\taccess: string;\n\trefresh: string;\n\texpires: number;\n\taccountId: string;\n};\n\nexport type OpenAICodexTokenSuccess = {\n\ttype: \"success\";\n\taccess: string;\n\trefresh: string;\n\texpires: number;\n};\n\nexport type OpenAICodexTokenFailure = {\n\ttype: \"failed\";\n\tmessage: string;\n\tstatus?: number;\n};\n\nexport type OpenAICodexTokenResult = OpenAICodexTokenSuccess | OpenAICodexTokenFailure;\n\nexport type OpenAICodexAuthorizationFlow = {\n\turl: string;\n\tverifier: string;\n\tstate: string;\n\tredirectUri: string;\n};\n\nexport type OpenAICodexAuthorizationOptions = {\n\toriginator?: string;\n\tredirectUri?: string;\n\tscope?: string;\n};\n\nexport type OpenAICodexLoginPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OpenAICodexLoginOptions = OpenAICodexAuthorizationOptions & {\n\tonAuth: (info: { url: string; instructions?: string }) => void;\n\tonPrompt: (prompt: OpenAICodexLoginPrompt) => Promise<string>;\n\tonProgress?: (message: string) => void;\n\tonManualCodeInput?: () => Promise<string>;\n};\n\nexport interface OpenAICodexAuthStorage {\n\tget(): Promise<OpenAICodexOAuthCredentials | undefined>;\n\tset(credentials: OpenAICodexOAuthCredentials): Promise<void>;\n\tclear(): Promise<void>;\n}\n\nexport type JsonOpenAICodexAuthStorageOptions = {\n\tpath?: string;\n\tproviderId?: string;\n};\n\ntype JwtPayload = {\n\t[JWT_CLAIM_PATH]?: {\n\t\tchatgpt_account_id?: string;\n\t};\n\t[key: string]: unknown;\n};\n\ntype OAuthServerInfo = {\n\tclose: () => Promise<void>;\n\tcancelWait: () => void;\n\twaitForCode: () => Promise<{ code: string } | null>;\n};\n\ntype AuthFile = Record<string, unknown>;\n\ntype TokenEndpointPayload = {\n\taccess_token?: string;\n\trefresh_token?: string;\n\texpires_in?: number;\n};\n\nfunction readEnv(name: string): string | undefined {\n\tif (typeof process === \"undefined\") return undefined;\n\treturn process.env[name];\n}\n\nfunction joinPath(...parts: string[]): string {\n\treturn parts.filter(Boolean).join(\"/\").replaceAll(/\\/+/g, \"/\");\n}\n\nfunction expandHome(path: string): string {\n\tif (path === \"~\") return homeDirectory();\n\tif (path.startsWith(\"~/\")) return joinPath(homeDirectory(), path.slice(2));\n\treturn path;\n}\n\nfunction homeDirectory(): string {\n\tconst home = readEnv(\"HOME\") ?? readEnv(\"USERPROFILE\");\n\tif (!home) {\n\t\tthrow new Error(\"unable to resolve home directory for OpenAI Codex auth storage\");\n\t}\n\treturn home;\n}\n\nfunction codeworkHomeDirectory(): string {\n\tconst override = readEnv(CODEWORK_HOME_DIR);\n\tif (override) return expandHome(override);\n\treturn joinPath(homeDirectory(), \".codework\");\n}\n\n// Internal: the resolved location is exposed as `JsonOpenAICodexAuthStorage#path`.\nfunction defaultOpenAICodexAuthFilePath(): string {\n\tconst authFile = readEnv(CODEWORK_CREDENTIALS);\n\tif (authFile) return expandHome(authFile);\n\n\treturn joinPath(codeworkHomeDirectory(), \"aikit\", \"auth.json\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOpenAICodexCredentials(value: unknown): value is OpenAICodexOAuthCredentials {\n\tif (!isObject(value)) return false;\n\treturn (\n\t\ttypeof value.access === \"string\" &&\n\t\ttypeof value.refresh === \"string\" &&\n\t\ttypeof value.expires === \"number\" &&\n\t\ttypeof value.accountId === \"string\"\n\t);\n}\n\nfunction redactOAuthSecrets(value: string, secrets: readonly string[] = []): string {\n\tlet redacted = value;\n\tfor (const secret of secrets.filter(Boolean).sort((left, right) => right.length - left.length)) {\n\t\tredacted = redacted.replaceAll(secret, \"[REDACTED]\");\n\t}\n\treturn redacted\n\t\t.replace(\n\t\t\t/((?:\"?(?:access_token|refresh_token|id_token|code|code_verifier)\"?)\\s*[:=]\\s*)(?:\"[^\"]*\"|'[^']*'|[^&\\s,}]+)/gi,\n\t\t\t'$1\"[REDACTED]\"',\n\t\t)\n\t\t.replace(/Bearer\\s+\\S+/gi, \"Bearer [REDACTED]\");\n}\n\nfunction tokenEndpointResult(payload: TokenEndpointPayload, operation: \"exchange\" | \"refresh\"): OpenAICodexTokenResult {\n\tconst missing = [\n\t\t!payload.access_token && \"access_token\",\n\t\t!payload.refresh_token && \"refresh_token\",\n\t\ttypeof payload.expires_in !== \"number\" && \"expires_in\",\n\t].filter((field): field is string => Boolean(field));\n\tif (missing.length > 0) {\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tmessage: `OpenAI Codex token ${operation} response missing fields: ${missing.join(\", \")}`,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: \"success\",\n\t\taccess: payload.access_token!,\n\t\trefresh: payload.refresh_token!,\n\t\texpires: Date.now() + payload.expires_in! * 1000,\n\t};\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (const byte of bytes) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nfunction base64UrlDecode(value: string): string {\n\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\tconst padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n\treturn atob(padded);\n}\n\ntype WebCrypto = typeof globalThis.crypto;\n\nfunction getCrypto(): WebCrypto {\n\tif (!globalThis.crypto?.getRandomValues || !globalThis.crypto.subtle) {\n\t\tthrow new Error(\"openAI codex OAuth requires web crypto support\");\n\t}\n\treturn globalThis.crypto;\n}\n\nfunction createState(): string {\n\tconst bytes = new Uint8Array(16);\n\tgetCrypto().getRandomValues(bytes);\n\treturn Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function generatePKCE(): Promise<{\n\tverifier: string;\n\tchallenge: string;\n}> {\n\tconst bytes = new Uint8Array(32);\n\tgetCrypto().getRandomValues(bytes);\n\tconst verifier = base64UrlEncode(bytes);\n\n\tconst data = new TextEncoder().encode(verifier);\n\tconst hash = await getCrypto().subtle.digest(\"SHA-256\", data);\n\tconst challenge = base64UrlEncode(new Uint8Array(hash));\n\n\treturn { verifier, challenge };\n}\n\nfunction authorizationInput(code: string | null | undefined, state: string | null | undefined) {\n\treturn {\n\t\t...(code != null && { code }),\n\t\t...(state != null && { state }),\n\t};\n}\n\nexport function parseOpenAICodexAuthorizationInput(input: string): {\n\tcode?: string;\n\tstate?: string;\n} {\n\tconst value = input.trim();\n\tif (!value) return {};\n\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn authorizationInput(url.searchParams.get(\"code\"), url.searchParams.get(\"state\"));\n\t} catch {\n\t\t// Not a URL.\n\t}\n\n\tif (value.includes(\"#\")) {\n\t\tconst [code, state] = value.split(\"#\", 2);\n\t\treturn authorizationInput(code, state);\n\t}\n\n\tif (value.includes(\"code=\")) {\n\t\tconst params = new URLSearchParams(value);\n\t\treturn authorizationInput(params.get(\"code\"), params.get(\"state\"));\n\t}\n\n\treturn { code: value };\n}\n\nfunction decodeJwt(token: string): JwtPayload | null {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) return null;\n\t\treturn JSON.parse(base64UrlDecode(parts[1] ?? \"\")) as JwtPayload;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function getOpenAICodexAccountId(accessToken: string): string | null {\n\tconst payload = decodeJwt(accessToken);\n\tconst auth = payload?.[JWT_CLAIM_PATH];\n\tconst accountId = auth?.chatgpt_account_id;\n\treturn typeof accountId === \"string\" && accountId.length > 0 ? accountId : null;\n}\n\nexport async function createOpenAICodexAuthorizationFlow(\n\toptions: OpenAICodexAuthorizationOptions = {},\n): Promise<OpenAICodexAuthorizationFlow> {\n\tconst redirectUri = options.redirectUri ?? DEFAULT_REDIRECT_URI;\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst state = createState();\n\n\tconst url = new URL(AUTHORIZE_URL);\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", CLIENT_ID);\n\turl.searchParams.set(\"redirect_uri\", redirectUri);\n\turl.searchParams.set(\"scope\", options.scope ?? DEFAULT_SCOPE);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"state\", state);\n\turl.searchParams.set(\"id_token_add_organizations\", \"true\");\n\turl.searchParams.set(\"codex_cli_simplified_flow\", \"true\");\n\turl.searchParams.set(\"originator\", options.originator ?? DEFAULT_ORIGINATOR);\n\n\treturn { verifier, state, redirectUri, url: url.toString() };\n}\n\nexport async function exchangeOpenAICodexAuthorizationCode(\n\tcode: string,\n\tverifier: string,\n\tredirectUri: string = DEFAULT_REDIRECT_URI,\n): Promise<OpenAICodexTokenResult> {\n\ttry {\n\t\tconst response = await fetch(TOKEN_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\tcode,\n\t\t\t\tcode_verifier: verifier,\n\t\t\t\tredirect_uri: redirectUri,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text().catch(() => \"\");\n\t\t\treturn {\n\t\t\t\ttype: \"failed\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tmessage: `OpenAI Codex token exchange failed (${response.status}): ${redactOAuthSecrets(\n\t\t\t\t\ttext || response.statusText,\n\t\t\t\t\t[code, verifier],\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\n\t\treturn tokenEndpointResult((await response.json()) as TokenEndpointPayload, \"exchange\");\n\t} catch (error) {\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tmessage: `OpenAI Codex token exchange error: ${redactOAuthSecrets(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t[code, verifier],\n\t\t\t)}`,\n\t\t};\n\t}\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<OpenAICodexTokenResult> {\n\ttry {\n\t\tconst response = await fetch(TOKEN_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\trefresh_token: refreshToken,\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text().catch(() => \"\");\n\t\t\treturn {\n\t\t\t\ttype: \"failed\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tmessage: `OpenAI Codex token refresh failed (${response.status}): ${redactOAuthSecrets(\n\t\t\t\t\ttext || response.statusText,\n\t\t\t\t\t[refreshToken],\n\t\t\t\t)}`,\n\t\t\t};\n\t\t}\n\n\t\treturn tokenEndpointResult((await response.json()) as TokenEndpointPayload, \"refresh\");\n\t} catch (error) {\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tmessage: `OpenAI Codex token refresh error: ${redactOAuthSecrets(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t[refreshToken],\n\t\t\t)}`,\n\t\t};\n\t}\n}\n\nfunction oauthPage(options: { title: string; heading: string; message: string; details?: string }): string {\n\tconst escapeHtml = (value: string) =>\n\t\tvalue\n\t\t\t.replaceAll(\"&\", \"&\")\n\t\t\t.replaceAll(\"<\", \"<\")\n\t\t\t.replaceAll(\">\", \">\")\n\t\t\t.replaceAll('\"', \""\")\n\t\t\t.replaceAll(\"'\", \"'\");\n\tconst details = options.details ? escapeHtml(options.details) : undefined;\n\n\treturn dedent`\n\t<!doctype html>\n\t<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<title>${escapeHtml(options.title)}</title>\n\t\t<style>\n\t\t\thtml { color-scheme: dark; }\n\t\t\tbody {\n\t\t\tmargin: 0;\n\t\t\tmin-height: 100vh;\n\t\t\tdisplay: grid;\n\t\t\tplace-items: center;\n\t\t\tpadding: 24px;\n\t\t\tbackground: #09090b;\n\t\t\tcolor: #fafafa;\n\t\t\tfont-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n\t\t\ttext-align: center;\n\t\t\t}\n\t\t\tmain { width: 100%; max-width: 560px; }\n\t\t\th1 { margin: 0 0 10px; font-size: 28px; line-height: 1.15; font-weight: 650; }\n\t\t\tp { margin: 0; line-height: 1.7; color: #a1a1aa; font-size: 15px; }\n\t\t\t.details { margin-top: 16px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; color: #a1a1aa; white-space: pre-wrap; word-break: break-word; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<main>\n\t\t\t<h1>${escapeHtml(options.heading)}</h1>\n\t\t\t<p>${escapeHtml(options.message)}</p>\n\t\t\t${details ? `<div class=\"details\">${details}</div>` : \"\"}\n\t\t</main>\n\t</body>\n\t</html>\n\t`;\n}\n\nfunction oauthSuccessHtml(message: string): string {\n\treturn oauthPage({\n\t\ttitle: \"Authentication successful\",\n\t\theading: \"Authentication successful\",\n\t\tmessage,\n\t});\n}\n\nfunction oauthErrorHtml(message: string, details?: string): string {\n\treturn oauthPage({\n\t\ttitle: \"Authentication failed\",\n\t\theading: \"Authentication failed\",\n\t\tmessage,\n\t\t...(details !== undefined && { details }),\n\t});\n}\n\nasync function startLocalOAuthServer(state: string): Promise<OAuthServerInfo> {\n\tconst http = await import(\"node:http\").catch(() => undefined);\n\tif (!http) {\n\t\tthrow new Error(\"openAI codex OAuth callback server is only available in Node.js environments\");\n\t}\n\n\tlet settleWait: ((value: { code: string } | null) => void) | undefined;\n\tconst waitForCodePromise = new Promise<{ code: string } | null>((resolve) => {\n\t\tlet settled = false;\n\t\tsettleWait = (value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tresolve(value);\n\t\t};\n\t});\n\n\tconst server = http.createServer((req, res) => {\n\t\ttry {\n\t\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\t\tif (url.pathname !== \"/auth/callback\") {\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"Callback route not found.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.searchParams.get(\"state\") !== state) {\n\t\t\t\tres.statusCode = 400;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"State mismatch.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\tif (!code) {\n\t\t\t\tres.statusCode = 400;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"Missing authorization code.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.statusCode = 200;\n\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\tres.end(oauthSuccessHtml(\"OpenAI authentication completed. You can close this window.\"));\n\t\t\tsettleWait?.({ code });\n\t\t} catch (error) {\n\t\t\tres.statusCode = 500;\n\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\tres.end(\n\t\t\t\toauthErrorHtml(\n\t\t\t\t\t\"Internal error while processing OAuth callback.\",\n\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t});\n\tconst close = async (): Promise<void> => {\n\t\tif (!server.listening) return;\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tserver.close(() => resolve());\n\t\t\tserver.closeAllConnections();\n\t\t});\n\t};\n\n\treturn new Promise((resolve) => {\n\t\tserver\n\t\t\t.listen(1455, readEnv(CODEWORK_OAUTH_CALLBACK_HOST) || \"127.0.0.1\", () => {\n\t\t\t\tresolve({\n\t\t\t\t\tclose,\n\t\t\t\t\tcancelWait: () => {\n\t\t\t\t\t\tsettleWait?.(null);\n\t\t\t\t\t},\n\t\t\t\t\twaitForCode: () => waitForCodePromise,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.on(\"error\", () => {\n\t\t\t\tsettleWait?.(null);\n\t\t\t\tresolve({\n\t\t\t\t\tclose,\n\t\t\t\t\tcancelWait: () => {},\n\t\t\t\t\twaitForCode: async () => null,\n\t\t\t\t});\n\t\t\t});\n\t});\n}\n\n// Internal: the public login entry point is `OpenAICodexOAuthClient#login`,\n// which persists the credentials. Server integrations should use the\n// storage-free authorization helpers instead of this localhost-callback flow.\nasync function loginOpenAICodex(options: OpenAICodexLoginOptions): Promise<OpenAICodexOAuthCredentials> {\n\tconst flow = await createOpenAICodexAuthorizationFlow(options);\n\tconst server = await startLocalOAuthServer(flow.state);\n\n\toptions.onAuth({\n\t\turl: flow.url,\n\t\tinstructions: \"Complete the browser login to finish OpenAI Codex authentication.\",\n\t});\n\n\tlet code: string | undefined;\n\ttry {\n\t\tif (options.onManualCodeInput) {\n\t\t\tlet manualCode: string | undefined;\n\t\t\tlet manualError: Error | undefined;\n\t\t\tconst manualPromise = options\n\t\t\t\t.onManualCodeInput()\n\t\t\t\t.then((input) => {\n\t\t\t\t\tmanualCode = input;\n\t\t\t\t\tif (input.trim()) server.cancelWait();\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tmanualError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tserver.cancelWait();\n\t\t\t\t});\n\n\t\t\tconst result = await server.waitForCode();\n\t\t\tif (manualError) throw manualError;\n\n\t\t\tif (result?.code) {\n\t\t\t\tcode = result.code;\n\t\t\t} else if (manualCode) {\n\t\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(manualCode);\n\t\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"state mismatch\");\n\t\t\t\tcode = parsed.code;\n\t\t\t}\n\n\t\t\tif (!code) {\n\t\t\t\tawait manualPromise;\n\t\t\t\tif (manualError) throw manualError;\n\t\t\t\tif (manualCode) {\n\t\t\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(manualCode);\n\t\t\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"state mismatch\");\n\t\t\t\t\tcode = parsed.code;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst result = await server.waitForCode();\n\t\t\tif (result?.code) code = result.code;\n\t\t}\n\n\t\tif (!code) {\n\t\t\tconst input = await options.onPrompt({\n\t\t\t\tmessage: \"Paste the authorization code or full redirect URL:\",\n\t\t\t});\n\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(input);\n\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"state mismatch\");\n\t\t\tcode = parsed.code;\n\t\t}\n\n\t\tif (!code) throw new Error(\"missing authorization code\");\n\n\t\tconst tokenResult = await exchangeOpenAICodexAuthorizationCode(code, flow.verifier, flow.redirectUri);\n\t\tif (tokenResult.type !== \"success\") throw new Error(tokenResult.message);\n\n\t\tconst accountId = getOpenAICodexAccountId(tokenResult.access);\n\t\tif (!accountId) throw new Error(\"failed to extract accountId from token\");\n\n\t\treturn {\n\t\t\taccess: tokenResult.access,\n\t\t\trefresh: tokenResult.refresh,\n\t\t\texpires: tokenResult.expires,\n\t\t\taccountId,\n\t\t};\n\t} finally {\n\t\tawait server.close();\n\t}\n}\n\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OpenAICodexOAuthCredentials> {\n\tconst result = await refreshAccessToken(refreshToken);\n\tif (result.type !== \"success\") {\n\t\tthrow new Error(result.message);\n\t}\n\n\tconst accountId = getOpenAICodexAccountId(result.access);\n\tif (!accountId) {\n\t\tthrow new Error(\"failed to extract accountId from token\");\n\t}\n\n\treturn {\n\t\taccess: result.access,\n\t\trefresh: result.refresh,\n\t\texpires: result.expires,\n\t\taccountId,\n\t};\n}\n\nexport function openAICodexHeaders(credentials: OpenAICodexOAuthCredentials): Record<string, string> {\n\treturn {\n\t\tAuthorization: `Bearer ${credentials.access}`,\n\t\t\"chatgpt-account-id\": credentials.accountId,\n\t\t\"OpenAI-Beta\": \"responses=experimental\",\n\t};\n}\n\nexport class JsonOpenAICodexAuthStorage implements OpenAICodexAuthStorage {\n\treadonly path: string;\n\treadonly providerId: string;\n\n\tconstructor(options: JsonOpenAICodexAuthStorageOptions = {}) {\n\t\tthis.path = options.path ? expandHome(options.path) : defaultOpenAICodexAuthFilePath();\n\t\tthis.providerId = options.providerId ?? DEFAULT_PROVIDER_ID;\n\t}\n\n\tasync get(): Promise<OpenAICodexOAuthCredentials | undefined> {\n\t\tconst file = await this.readFile();\n\t\tif (!file) return undefined;\n\n\t\tif (isOpenAICodexCredentials(file)) return file;\n\n\t\tconst direct = file[this.providerId];\n\t\tif (isOpenAICodexCredentials(direct)) return direct;\n\n\t\tconst providers = file.providers;\n\t\tif (isObject(providers) && isOpenAICodexCredentials(providers[this.providerId])) {\n\t\t\treturn providers[this.providerId] as OpenAICodexOAuthCredentials;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tasync set(credentials: OpenAICodexOAuthCredentials): Promise<void> {\n\t\tconst current = await this.readFile();\n\t\tconst next = isObject(current) && !isOpenAICodexCredentials(current) ? current : {};\n\t\tnext[this.providerId] = credentials;\n\t\tawait this.writeFile(next);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst current = await this.readFile();\n\t\tif (!current) return;\n\n\t\tif (isOpenAICodexCredentials(current)) {\n\t\t\tawait this.writeFile({});\n\t\t\treturn;\n\t\t}\n\n\t\tdelete current[this.providerId];\n\t\tconst providers = current.providers;\n\t\tif (isObject(providers)) delete providers[this.providerId];\n\t\tawait this.writeFile(current);\n\t}\n\n\tprivate async readFile(): Promise<AuthFile | undefined> {\n\t\tconst fs = await import(\"node:fs/promises\");\n\t\ttry {\n\t\t\tconst text = await fs.readFile(this.path, \"utf8\");\n\t\t\tconst parsed = JSON.parse(text) as unknown;\n\t\t\treturn isObject(parsed) ? parsed : undefined;\n\t\t} catch (error) {\n\t\t\tif (isObject(error) && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async writeFile(value: AuthFile): Promise<void> {\n\t\tconst fs = await import(\"node:fs/promises\");\n\t\tconst path = await import(\"node:path\");\n\t\tawait fs.mkdir(path.dirname(this.path), { recursive: true });\n\t\tconst tempPath = `${this.path}.${process.pid}.${Date.now()}.tmp`;\n\t\tawait fs.writeFile(tempPath, `${JSON.stringify(value, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\t\tawait fs.chmod(tempPath, 0o600);\n\t\tawait fs.rename(tempPath, this.path);\n\t}\n}\n\nexport type OpenAICodexOAuthClientOptions = {\n\tstorage?: OpenAICodexAuthStorage;\n\trefreshSkewMs?: number;\n};\n\nexport class OpenAICodexOAuthClient {\n\treadonly storage: OpenAICodexAuthStorage;\n\treadonly refreshSkewMs: number;\n\n\tconstructor(options: OpenAICodexOAuthClientOptions = {}) {\n\t\tthis.storage = options.storage ?? new JsonOpenAICodexAuthStorage();\n\t\tthis.refreshSkewMs = options.refreshSkewMs ?? REFRESH_SKEW_MS;\n\t}\n\n\tasync login(options: OpenAICodexLoginOptions): Promise<OpenAICodexOAuthCredentials> {\n\t\tconst credentials = await loginOpenAICodex(options);\n\t\tawait this.storage.set(credentials);\n\t\treturn credentials;\n\t}\n\n\tasync getCredentials(): Promise<OpenAICodexOAuthCredentials | undefined> {\n\t\tconst credentials = await this.storage.get();\n\t\tif (!credentials) return undefined;\n\n\t\tif (credentials.expires > Date.now() + this.refreshSkewMs) {\n\t\t\treturn credentials;\n\t\t}\n\n\t\tconst refreshed = await refreshOpenAICodexToken(credentials.refresh);\n\t\tawait this.storage.set(refreshed);\n\t\treturn refreshed;\n\t}\n\n\tasync getApiKey(): Promise<string | undefined> {\n\t\treturn (await this.getCredentials())?.access;\n\t}\n\n\tasync getHeaders(): Promise<Record<string, string> | undefined> {\n\t\tconst credentials = await this.getCredentials();\n\t\treturn credentials ? openAICodexHeaders(credentials) : undefined;\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tawait this.storage.clear();\n\t}\n}\n\nexport const OPENAI_CODEX_API_KEY_ENV = \"OPENAI_CODEX_API_KEY\";\n\n/**\n * Resolve the OpenAI Codex API key the same way other provider API keys are\n * resolved: prefer the OPENAI_CODEX_API_KEY environment variable, then fall\n * back to stored OAuth credentials (refreshing them when close to expiry).\n *\n * The result can be passed directly as `apiKey` to the runtime options or to\n * `createOpenAICodex`. Returns undefined when no key is available.\n */\nexport async function getOpenAICodexApiKey(options: OpenAICodexOAuthClientOptions = {}): Promise<string | undefined> {\n\tconst envKey = readEnv(OPENAI_CODEX_API_KEY_ENV);\n\tif (envKey) return envKey;\n\n\treturn new OpenAICodexOAuthClient(options).getApiKey();\n}\n"],"mappings":"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"}
|
|
@@ -118,7 +118,11 @@ declare const Unknown: Type$1.TObject<{
|
|
|
118
118
|
retryAfterMs: Type$1.TOptional<Type$1.TNumber>;
|
|
119
119
|
_tag: Type$1.TLiteral<"Unknown">;
|
|
120
120
|
}>;
|
|
121
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
Provider-independent, JSON-safe failure data carried by terminal assistant messages.
|
|
124
|
+
Powered by ai-sdk as the underlying provider wire protocol.
|
|
125
|
+
*/
|
|
122
126
|
declare const FailureSchema: Type$1.TUnion<[Type$1.TObject<{
|
|
123
127
|
message: Type$1.TString;
|
|
124
128
|
retryable: Type$1.TBoolean;
|
|
@@ -237,4 +241,4 @@ declare function normalize(error: unknown): Failure;
|
|
|
237
241
|
declare function fromMessage(message: string): Failure;
|
|
238
242
|
//#endregion
|
|
239
243
|
export { Unavailable as _, Authorization as a, Failure as c, InvalidResponse as d, ModelUnavailable as f, Transport as g, Timeout as h, Authentication as i, FailureSchema as l, RateLimit as m, fromMessage as n, Configuration as o, Quota as p, normalize as r, ContentPolicy as s, failure_d_exports as t, InvalidRequest as u, Unknown as v, isFailure as y };
|
|
240
|
-
//# sourceMappingURL=failure-
|
|
244
|
+
//# sourceMappingURL=failure-5Wjd-qFH.d.mts.map
|
|
@@ -1,79 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { a as FailureSchema, c as ModelUnavailable, d as Timeout, f as Transport, h as isFailure, i as ContentPolicy, l as Quota, m as Unknown, n as Authorization, o as InvalidRequest, p as Unavailable, r as Configuration, s as InvalidResponse, t as Authentication, u as RateLimit } from "./schema-rXSoWhic.mjs";
|
|
3
3
|
import { APICallError, EmptyResponseBodyError, InvalidArgumentError, InvalidPromptError, InvalidResponseDataError, JSONParseError, LoadAPIKeyError, LoadSettingError, NoContentGeneratedError, NoSuchModelError, TypeValidationError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
|
|
4
4
|
import { RetryError } from "ai";
|
|
5
|
-
//#region src/llm/failure/schema.ts
|
|
6
|
-
const metadata = {
|
|
7
|
-
message: Type$1.String(),
|
|
8
|
-
retryable: Type$1.Boolean(),
|
|
9
|
-
status: Type$1.Optional(Type$1.Number()),
|
|
10
|
-
code: Type$1.Optional(Type$1.String()),
|
|
11
|
-
requestId: Type$1.Optional(Type$1.String()),
|
|
12
|
-
retryAfterMs: Type$1.Optional(Type$1.Number())
|
|
13
|
-
};
|
|
14
|
-
const variant = (tag) => Type$1.Object({
|
|
15
|
-
_tag: Type$1.Literal(tag),
|
|
16
|
-
...metadata
|
|
17
|
-
});
|
|
18
|
-
const Authentication = Type$1.Object({
|
|
19
|
-
_tag: Type$1.Literal("Authentication"),
|
|
20
|
-
reason: Type$1.Union([
|
|
21
|
-
Type$1.Literal("missing"),
|
|
22
|
-
Type$1.Literal("invalid"),
|
|
23
|
-
Type$1.Literal("expired")
|
|
24
|
-
]),
|
|
25
|
-
...metadata
|
|
26
|
-
});
|
|
27
|
-
const Configuration = variant("Configuration");
|
|
28
|
-
const Authorization = variant("Authorization");
|
|
29
|
-
const ModelUnavailable = variant("ModelUnavailable");
|
|
30
|
-
const RateLimit = variant("RateLimit");
|
|
31
|
-
const Quota = variant("Quota");
|
|
32
|
-
const InvalidRequest = variant("InvalidRequest");
|
|
33
|
-
const ContentPolicy = variant("ContentPolicy");
|
|
34
|
-
const Timeout = variant("Timeout");
|
|
35
|
-
const Transport = variant("Transport");
|
|
36
|
-
const Unavailable = variant("Unavailable");
|
|
37
|
-
const InvalidResponse = variant("InvalidResponse");
|
|
38
|
-
const Unknown = variant("Unknown");
|
|
39
|
-
/** Provider-independent, JSON-safe failure data carried by terminal assistant messages. */
|
|
40
|
-
const FailureSchema = Type$1.Union([
|
|
41
|
-
Authentication,
|
|
42
|
-
Configuration,
|
|
43
|
-
Authorization,
|
|
44
|
-
ModelUnavailable,
|
|
45
|
-
RateLimit,
|
|
46
|
-
Quota,
|
|
47
|
-
InvalidRequest,
|
|
48
|
-
ContentPolicy,
|
|
49
|
-
Timeout,
|
|
50
|
-
Transport,
|
|
51
|
-
Unavailable,
|
|
52
|
-
InvalidResponse,
|
|
53
|
-
Unknown
|
|
54
|
-
]);
|
|
55
|
-
const tags = /* @__PURE__ */ new Set([
|
|
56
|
-
"Authentication",
|
|
57
|
-
"Configuration",
|
|
58
|
-
"Authorization",
|
|
59
|
-
"ModelUnavailable",
|
|
60
|
-
"RateLimit",
|
|
61
|
-
"Quota",
|
|
62
|
-
"InvalidRequest",
|
|
63
|
-
"ContentPolicy",
|
|
64
|
-
"Timeout",
|
|
65
|
-
"Transport",
|
|
66
|
-
"Unavailable",
|
|
67
|
-
"InvalidResponse",
|
|
68
|
-
"Unknown"
|
|
69
|
-
]);
|
|
70
|
-
const record$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
71
|
-
/** Lightweight guard for failure data crossing package or persistence boundaries. */
|
|
72
|
-
function isFailure(value) {
|
|
73
|
-
const candidate = record$1(value);
|
|
74
|
-
return tags.has(candidate?._tag) && typeof candidate?.message === "string" && typeof candidate.retryable === "boolean" && (candidate.status === void 0 || typeof candidate.status === "number" && Number.isFinite(candidate.status)) && (candidate.code === void 0 || typeof candidate.code === "string") && (candidate.requestId === void 0 || typeof candidate.requestId === "string") && (candidate.retryAfterMs === void 0 || typeof candidate.retryAfterMs === "number" && Number.isFinite(candidate.retryAfterMs) && candidate.retryAfterMs >= 0) && (candidate._tag !== "Authentication" || candidate.reason === "missing" || candidate.reason === "invalid" || candidate.reason === "expired");
|
|
75
|
-
}
|
|
76
|
-
//#endregion
|
|
77
5
|
//#region src/llm/failure.ts
|
|
78
6
|
var failure_exports = /* @__PURE__ */ __exportAll({
|
|
79
7
|
Authentication: () => Authentication,
|
|
@@ -131,7 +59,7 @@ const apiMetadata = (error) => {
|
|
|
131
59
|
const nested = record(data?.error);
|
|
132
60
|
const structuredMessage = nonEmptyString(data?.message) ?? nonEmptyString(nested?.message);
|
|
133
61
|
const message = normalizeMessage(structuredMessage ?? (error.responseBody !== void 0 && error.message.includes(error.responseBody) ? `provider request failed${error.statusCode === void 0 ? "" : ` with http ${error.statusCode}`}` : errorMessage(error)));
|
|
134
|
-
const requestId = header(error.responseHeaders, "x-request-id") ?? header(error.responseHeaders, "request-id") ?? header(error.responseHeaders, "cf-ray");
|
|
62
|
+
const requestId = header(error.responseHeaders, "x-request-id") ?? header(error.responseHeaders, "x-oai-request-id") ?? header(error.responseHeaders, "request-id") ?? header(error.responseHeaders, "cf-ray");
|
|
135
63
|
const retryAfterMs = retryAfter(error.responseHeaders);
|
|
136
64
|
return {
|
|
137
65
|
message,
|
|
@@ -156,7 +84,10 @@ const fromAPICall = (error) => {
|
|
|
156
84
|
if (includes(details.code, [
|
|
157
85
|
"content_filter",
|
|
158
86
|
"content_policy",
|
|
159
|
-
"safety"
|
|
87
|
+
"safety",
|
|
88
|
+
"cyber_policy",
|
|
89
|
+
"bio_policy",
|
|
90
|
+
"misalignment_policy"
|
|
160
91
|
])) return {
|
|
161
92
|
_tag: "ContentPolicy",
|
|
162
93
|
...details
|
|
@@ -276,6 +207,6 @@ function fromMessage(message) {
|
|
|
276
207
|
};
|
|
277
208
|
}
|
|
278
209
|
//#endregion
|
|
279
|
-
export {
|
|
210
|
+
export { fromMessage as n, normalize as r, failure_exports as t };
|
|
280
211
|
|
|
281
|
-
//# sourceMappingURL=failure-
|
|
212
|
+
//# sourceMappingURL=failure-SAPyG-w2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure-SAPyG-w2.mjs","names":[],"sources":["../../src/llm/failure.ts"],"sourcesContent":["import {\n\tAPICallError,\n\tEmptyResponseBodyError,\n\tInvalidArgumentError,\n\tInvalidPromptError,\n\tInvalidResponseDataError,\n\tJSONParseError,\n\tLoadAPIKeyError,\n\tLoadSettingError,\n\tNoContentGeneratedError,\n\tNoSuchModelError,\n\tTypeValidationError,\n\tUnsupportedFunctionalityError,\n} from \"@ai-sdk/provider\";\nimport { RetryError } from \"ai\";\nimport type { Failure } from \"./failure/schema.ts\";\n\nexport * from \"./failure/schema.ts\";\n\ntype Metadata = Omit<Failure, \"_tag\" | \"reason\">;\n\nconst record = (value: unknown): Record<string, unknown> | undefined =>\n\ttypeof value === \"object\" && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n\nconst nonEmptyString = (value: unknown): string | undefined =>\n\ttypeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n\nconst normalizeMessage = (message: string): string => {\n\tconst trimmed = message.trim().replace(/[.!?]+$/u, \"\");\n\treturn trimmed.replace(/^[A-Za-z]+/u, (word) => word.toLowerCase());\n};\n\nconst errorMessage = (error: unknown): string => {\n\tconst value = record(error);\n\tconst data = record(value?.data);\n\tif (value?.name === \"ProtocolAuthError\") {\n\t\treturn normalizeMessage(nonEmptyString(data?.message) ?? \"provider credentials are missing\");\n\t}\n\tif (error instanceof Error) return normalizeMessage(nonEmptyString(error.message) ?? error.name);\n\treturn normalizeMessage(nonEmptyString(error) ?? \"the provider request failed for an unknown reason\");\n};\n\nconst isProtocolAuthError = (error: unknown): boolean => {\n\tconst value = record(error);\n\treturn value?.name === \"ProtocolAuthError\";\n};\n\nconst errorCode = (data: unknown): string | undefined => {\n\tconst top = record(data);\n\tconst nested = record(top?.error);\n\treturn (\n\t\tnonEmptyString(top?.code) ??\n\t\tnonEmptyString(top?.type) ??\n\t\tnonEmptyString(nested?.code) ??\n\t\tnonEmptyString(nested?.type)\n\t);\n};\n\nconst header = (headers: Record<string, string> | undefined, name: string): string | undefined => {\n\tif (headers === undefined) return undefined;\n\tconst expected = name.toLowerCase();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === expected) return nonEmptyString(value);\n\t}\n};\n\nconst retryAfter = (headers: Record<string, string> | undefined): number | undefined => {\n\tconst value = header(headers, \"retry-after\");\n\tif (value === undefined) return undefined;\n\tconst seconds = Number(value);\n\tif (Number.isFinite(seconds) && seconds >= 0) return seconds * 1_000;\n};\n\nconst apiMetadata = (error: APICallError): Metadata => {\n\tconst code = errorCode(error.data);\n\tconst data = record(error.data);\n\tconst nested = record(data?.error);\n\tconst structuredMessage = nonEmptyString(data?.message) ?? nonEmptyString(nested?.message);\n\tconst message = normalizeMessage(\n\t\tstructuredMessage ??\n\t\t\t(error.responseBody !== undefined && error.message.includes(error.responseBody)\n\t\t\t\t? `provider request failed${error.statusCode === undefined ? \"\" : ` with http ${error.statusCode}`}`\n\t\t\t\t: errorMessage(error)),\n\t);\n\tconst requestId =\n\t\theader(error.responseHeaders, \"x-request-id\") ??\n\t\theader(error.responseHeaders, \"x-oai-request-id\") ??\n\t\theader(error.responseHeaders, \"request-id\") ??\n\t\theader(error.responseHeaders, \"cf-ray\");\n\tconst retryAfterMs = retryAfter(error.responseHeaders);\n\treturn {\n\t\tmessage,\n\t\tretryable: error.isRetryable,\n\t\t...(error.statusCode === undefined ? {} : { status: error.statusCode }),\n\t\t...(code === undefined ? {} : { code }),\n\t\t...(requestId === undefined ? {} : { requestId }),\n\t\t...(retryAfterMs === undefined ? {} : { retryAfterMs }),\n\t};\n};\n\nconst includes = (value: string | undefined, terms: ReadonlyArray<string>): boolean =>\n\tvalue !== undefined && terms.some((term) => value.toLowerCase().includes(term));\n\nconst fromAPICall = (error: APICallError): Failure => {\n\tconst details = apiMetadata(error);\n\tif (includes(details.code, [\"quota\", \"billing\", \"credit\"])) return { _tag: \"Quota\", ...details };\n\tif (\n\t\tincludes(details.code, [\n\t\t\t\"content_filter\",\n\t\t\t\"content_policy\",\n\t\t\t\"safety\",\n\t\t\t\"cyber_policy\",\n\t\t\t\"bio_policy\",\n\t\t\t\"misalignment_policy\",\n\t\t])\n\t) {\n\t\treturn { _tag: \"ContentPolicy\", ...details };\n\t}\n\tif (error.statusCode === 401) return { _tag: \"Authentication\", reason: \"invalid\", ...details };\n\tif (error.statusCode === 403) return { _tag: \"Authorization\", ...details };\n\tif (error.statusCode === 404) return { _tag: \"ModelUnavailable\", ...details };\n\tif (error.statusCode === 408) return { _tag: \"Timeout\", ...details };\n\tif (error.statusCode === 429) return { _tag: \"RateLimit\", ...details };\n\tif (error.statusCode !== undefined && error.statusCode >= 500) return { _tag: \"Unavailable\", ...details };\n\tif (error.statusCode === undefined) return { _tag: \"Transport\", ...details };\n\tif (error.statusCode >= 400 && error.statusCode < 500) return { _tag: \"InvalidRequest\", ...details };\n\treturn { _tag: \"Unknown\", ...details };\n};\n\nconst resemblesTimeout = (error: unknown): boolean => {\n\tconst value = error instanceof Error ? `${error.name} ${error.message}` : String(error);\n\treturn /timeout|timed out/i.test(value);\n};\n\nconst resemblesTransportFailure = (error: unknown): boolean => {\n\tif (error instanceof TypeError) return true;\n\tconst value = error instanceof Error ? `${error.name} ${error.message}` : String(error);\n\treturn /fetch|network|socket|connection|econn|dns/i.test(value);\n};\n\n/** Normalize AI SDK and provider exceptions without retaining request bodies, response bodies, or headers. */\nexport function normalize(error: unknown): Failure {\n\tif (RetryError.isInstance(error) && error.lastError !== undefined && error.lastError !== error) {\n\t\treturn normalize(error.lastError);\n\t}\n\tif (LoadAPIKeyError.isInstance(error) || isProtocolAuthError(error)) {\n\t\treturn { _tag: \"Authentication\", reason: \"missing\", message: errorMessage(error), retryable: false };\n\t}\n\tif (LoadSettingError.isInstance(error)) {\n\t\treturn { _tag: \"Configuration\", message: errorMessage(error), retryable: false };\n\t}\n\tif (NoSuchModelError.isInstance(error)) {\n\t\treturn { _tag: \"ModelUnavailable\", message: errorMessage(error), retryable: false };\n\t}\n\tif (APICallError.isInstance(error)) return fromAPICall(error);\n\tif (\n\t\tInvalidPromptError.isInstance(error) ||\n\t\tInvalidArgumentError.isInstance(error) ||\n\t\tUnsupportedFunctionalityError.isInstance(error)\n\t) {\n\t\treturn { _tag: \"InvalidRequest\", message: errorMessage(error), retryable: false };\n\t}\n\tif (\n\t\tInvalidResponseDataError.isInstance(error) ||\n\t\tJSONParseError.isInstance(error) ||\n\t\tEmptyResponseBodyError.isInstance(error) ||\n\t\tNoContentGeneratedError.isInstance(error) ||\n\t\tTypeValidationError.isInstance(error)\n\t) {\n\t\treturn { _tag: \"InvalidResponse\", message: errorMessage(error), retryable: false };\n\t}\n\tif (resemblesTimeout(error)) return { _tag: \"Timeout\", message: errorMessage(error), retryable: true };\n\tif (resemblesTransportFailure(error)) {\n\t\treturn { _tag: \"Transport\", message: errorMessage(error), retryable: true };\n\t}\n\treturn { _tag: \"Unknown\", message: errorMessage(error), retryable: false };\n}\n\n/** Best-effort compatibility for terminal messages written before structured failures existed. */\nexport function fromMessage(message: string): Failure {\n\tconst normalized = normalizeMessage(message);\n\tif (/api key/i.test(normalized) && /missing|required|not set/i.test(normalized)) {\n\t\treturn { _tag: \"Authentication\", reason: \"missing\", message: normalized, retryable: false };\n\t}\n\tif (/api key|credential|token/i.test(normalized) && /invalid|expired|unauthorized/i.test(normalized)) {\n\t\treturn {\n\t\t\t_tag: \"Authentication\",\n\t\t\treason: /expired/i.test(normalized) ? \"expired\" : \"invalid\",\n\t\t\tmessage: normalized,\n\t\t\tretryable: false,\n\t\t};\n\t}\n\treturn { _tag: \"Unknown\", message: normalized, retryable: false };\n}\n"],"mappings":"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"}
|