ai-zero-token 1.0.1 → 1.0.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/README.md +227 -70
- package/dist/api.js +0 -1
- package/dist/cli/commands/ask.js +131 -5
- package/dist/cli/commands/clear.js +0 -1
- package/dist/cli/commands/help.js +15 -10
- package/dist/cli/commands/login.js +0 -1
- package/dist/cli/commands/models.js +0 -1
- package/dist/cli/commands/serve.js +41 -4
- package/dist/cli/commands/start.js +10 -0
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/index.js +4 -1
- package/dist/cli/shared.js +57 -6
- package/dist/cli.js +0 -1
- package/dist/core/context.js +7 -2
- package/dist/core/models/openai-codex-models.js +0 -1
- package/dist/core/providers/http-client.js +97 -9
- package/dist/core/providers/openai-codex/chat.js +217 -24
- package/dist/core/providers/openai-codex/oauth.js +15 -4
- package/dist/core/providers/openai-codex/pkce.js +0 -1
- package/dist/core/services/auth-service.js +89 -16
- package/dist/core/services/chat-service.js +24 -14
- package/dist/core/services/config-service.js +0 -1
- package/dist/core/services/image-service.js +360 -0
- package/dist/core/services/model-service.js +4 -2
- package/dist/core/store/profile-store.js +79 -6
- package/dist/core/store/settings-store.js +1 -2
- package/dist/core/types.js +0 -1
- package/dist/http.js +0 -1
- package/dist/models.js +0 -1
- package/dist/oauth.js +0 -1
- package/dist/pkce.js +0 -1
- package/dist/server/admin-page.js +2615 -0
- package/dist/server/app.js +561 -39
- package/dist/server/index.js +0 -1
- package/dist/store.js +0 -1
- package/package.json +12 -3
- package/dist/api.js.map +0 -1
- package/dist/cli/commands/ask.js.map +0 -1
- package/dist/cli/commands/clear.js.map +0 -1
- package/dist/cli/commands/help.js.map +0 -1
- package/dist/cli/commands/login.js.map +0 -1
- package/dist/cli/commands/models.js.map +0 -1
- package/dist/cli/commands/serve.js.map +0 -1
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/shared.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/core/context.js.map +0 -1
- package/dist/core/models/openai-codex-models.js.map +0 -1
- package/dist/core/providers/http-client.js.map +0 -1
- package/dist/core/providers/openai-codex/chat.js.map +0 -1
- package/dist/core/providers/openai-codex/oauth.js.map +0 -1
- package/dist/core/providers/openai-codex/pkce.js.map +0 -1
- package/dist/core/services/auth-service.js.map +0 -1
- package/dist/core/services/chat-service.js.map +0 -1
- package/dist/core/services/config-service.js.map +0 -1
- package/dist/core/services/model-service.js.map +0 -1
- package/dist/core/store/profile-store.js.map +0 -1
- package/dist/core/store/settings-store.js.map +0 -1
- package/dist/core/types.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/models.js.map +0 -1
- package/dist/oauth.js.map +0 -1
- package/dist/pkce.js.map +0 -1
- package/dist/server/app.js.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/store.js.map +0 -1
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts"],"sourcesContent":["export { askOpenAICodex } from \"./core/providers/openai-codex/chat.js\";\n"],"mappings":";AAAA,SAAS,sBAAsB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/ask.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\nimport { parseAskArgs } from \"../shared.js\";\n\nexport async function runAskCommand(args: string[]): Promise<void> {\n const { model, prompt } = parseAskArgs(args);\n if (!prompt) {\n throw new Error('ask 需要一个 prompt,例如 bun src/cli.js ask \"你好\"');\n }\n\n const ctx = createGatewayContext();\n console.log('model:', ctx);\n// const result = await ctx.chatService.chat({\n// model,\n// input: prompt,\n// });\n\n// console.log(`provider: ${result.provider}`);\n// console.log(`model: ${result.model}`);\n// console.log(\"模型回复:\");\n// console.log(result.text || \"(返回成功,但没有解析出 output_text)\");\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAE7B,eAAsB,cAAc,MAA+B;AACjE,QAAM,EAAE,OAAO,OAAO,IAAI,aAAa,IAAI;AAC3C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,yFAA4C;AAAA,EAC9D;AAEA,QAAM,MAAM,qBAAqB;AACjC,UAAQ,IAAI,UAAU,GAAG;AAU3B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/clear.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\n\nexport async function runClearCommand(): Promise<void> {\n const ctx = createGatewayContext();\n await ctx.authService.logoutAll();\n console.log(\"已清空 demo 的本地状态。\");\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AAErC,eAAsB,kBAAiC;AACrD,QAAM,MAAM,qBAAqB;AACjC,QAAM,IAAI,YAAY,UAAU;AAChC,UAAQ,IAAI,8DAAiB;AAC/B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/help.ts"],"sourcesContent":["export function printHelp(): void {\n console.log(`用法:\n\n bun src/cli.js login\n bun src/cli.js models\n bun src/cli.js status\n bun src/cli.js ask \"你好,请简单介绍一下自己\"\n bun src/cli.js ask --model gpt-5.3-codex \"你好\"\n bun src/cli.js serve\n bun src/cli.js clear\n\n说明:\n\n login 走真实 OpenAI Codex OAuth,保存 access/refresh token\n models 查看这个 demo 当前内置支持的模型列表\n status 查看当前 demo 保存的账号和过期时间\n ask 用保存的 token 调真实 Codex Responses API\n serve 启动本地 HTTP 网关\n clear 清空 demo 的本地状态\n`);\n}\n"],"mappings":";AAAO,SAAS,YAAkB;AAChC,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAkBb;AACD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/login.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\nimport { getStateDir, getStorePath } from \"../../store.js\";\nimport { formatExpiry } from \"../shared.js\";\n\nexport async function runLoginCommand(): Promise<void> {\n const ctx = createGatewayContext();\n const profile = await ctx.authService.login(\"openai-codex\");\n console.log(\"登录成功。\");\n console.log(`profileId: ${profile.profileId}`);\n console.log(`accountId: ${profile.accountId}`);\n if (profile.email) {\n console.log(`email: ${profile.email}`);\n }\n console.log(`expires: ${formatExpiry(profile.expires)}`);\n console.log(`stateDir: ${getStateDir()}`);\n console.log(`store: ${getStorePath()}`);\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AACrC,SAAS,aAAa,oBAAoB;AAC1C,SAAS,oBAAoB;AAE7B,eAAsB,kBAAiC;AACrD,QAAM,MAAM,qBAAqB;AACjC,QAAM,UAAU,MAAM,IAAI,YAAY,MAAM,cAAc;AAC1D,UAAQ,IAAI,gCAAO;AACnB,UAAQ,IAAI,cAAc,QAAQ,SAAS,EAAE;AAC7C,UAAQ,IAAI,cAAc,QAAQ,SAAS,EAAE;AAC7C,MAAI,QAAQ,OAAO;AACjB,YAAQ,IAAI,UAAU,QAAQ,KAAK,EAAE;AAAA,EACvC;AACA,UAAQ,IAAI,YAAY,aAAa,QAAQ,OAAO,CAAC,EAAE;AACvD,UAAQ,IAAI,aAAa,YAAY,CAAC,EAAE;AACxC,UAAQ,IAAI,UAAU,aAAa,CAAC,EAAE;AACxC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/models.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\n\nexport async function runModelsCommand(): Promise<void> {\n const ctx = createGatewayContext();\n console.log(\"当前 demo 内置支持的模型:\");\n for (const model of await ctx.modelService.listModels()) {\n const suffix = model.isDefault ? \" (默认)\" : \"\";\n console.log(`- ${model.id}${suffix}`);\n }\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AAErC,eAAsB,mBAAkC;AACtD,QAAM,MAAM,qBAAqB;AACjC,UAAQ,IAAI,+DAAkB;AAC9B,aAAW,SAAS,MAAM,IAAI,aAAa,WAAW,GAAG;AACvD,UAAM,SAAS,MAAM,YAAY,oBAAU;AAC3C,YAAQ,IAAI,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE;AAAA,EACtC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/serve.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\nimport { startServer } from \"../../server/index.js\";\nimport { parseServeArgs } from \"../shared.js\";\n\nexport async function runServeCommand(args: string[]): Promise<void> {\n const { host, port } = parseServeArgs(args);\n const ctx = createGatewayContext();\n const status = await ctx.authService.getStatus();\n const server = await startServer({ host, port });\n console.log(\"本地网关已启动。\");\n console.log(`url: http://${server.host}:${server.port}`);\n console.log(`corsOrigin: ${server.corsOrigin}`);\n console.log(`activeProvider: ${status.activeProvider ?? \"none\"}`);\n console.log(`defaultModel: ${status.defaultModel}`);\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAE/B,eAAsB,gBAAgB,MAA+B;AACnE,QAAM,EAAE,MAAM,KAAK,IAAI,eAAe,IAAI;AAC1C,QAAM,MAAM,qBAAqB;AACjC,QAAM,SAAS,MAAM,IAAI,YAAY,UAAU;AAC/C,QAAM,SAAS,MAAM,YAAY,EAAE,MAAM,KAAK,CAAC;AAC/C,UAAQ,IAAI,kDAAU;AACtB,UAAQ,IAAI,eAAe,OAAO,IAAI,IAAI,OAAO,IAAI,EAAE;AACvD,UAAQ,IAAI,eAAe,OAAO,UAAU,EAAE;AAC9C,UAAQ,IAAI,mBAAmB,OAAO,kBAAkB,MAAM,EAAE;AAChE,UAAQ,IAAI,iBAAiB,OAAO,YAAY,EAAE;AACpD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/status.ts"],"sourcesContent":["import { createGatewayContext } from \"../../core/context.js\";\nimport { getSettingsPath } from \"../../core/store/settings-store.js\";\nimport { getStateDir, getStorePath } from \"../../store.js\";\nimport { formatExpiry } from \"../shared.js\";\n\nexport async function runStatusCommand(): Promise<void> {\n const ctx = createGatewayContext();\n const status = await ctx.authService.getStatus();\n if (!status.loggedIn) {\n console.log(\"当前没有已保存的登录状态。\");\n console.log(`stateDir: ${getStateDir()}`);\n console.log(`store: ${getStorePath()}`);\n return;\n }\n\n console.log(\"当前登录状态:\");\n console.log(`provider: ${status.activeProvider}`);\n console.log(`profileId: ${status.activeProfileId}`);\n console.log(`defaultModel: ${status.defaultModel}`);\n console.log(`serverHost: ${status.serverHost}`);\n console.log(`serverPort: ${status.serverPort}`);\n if (typeof status.expiresAt === \"number\") {\n console.log(`expires: ${formatExpiry(status.expiresAt)}`);\n console.log(`expired: ${Date.now() >= status.expiresAt ? \"yes\" : \"no\"}`);\n }\n console.log(`stateDir: ${getStateDir()}`);\n console.log(`store: ${getStorePath()}`);\n console.log(`settings: ${getSettingsPath()}`);\n}\n"],"mappings":";AAAA,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,aAAa,oBAAoB;AAC1C,SAAS,oBAAoB;AAE7B,eAAsB,mBAAkC;AACtD,QAAM,MAAM,qBAAqB;AACjC,QAAM,SAAS,MAAM,IAAI,YAAY,UAAU;AAC/C,MAAI,CAAC,OAAO,UAAU;AACpB,YAAQ,IAAI,gFAAe;AAC3B,YAAQ,IAAI,aAAa,YAAY,CAAC,EAAE;AACxC,YAAQ,IAAI,UAAU,aAAa,CAAC,EAAE;AACtC;AAAA,EACF;AAEA,UAAQ,IAAI,uCAAS;AACrB,UAAQ,IAAI,aAAa,OAAO,cAAc,EAAE;AAChD,UAAQ,IAAI,cAAc,OAAO,eAAe,EAAE;AAClD,UAAQ,IAAI,iBAAiB,OAAO,YAAY,EAAE;AAClD,UAAQ,IAAI,eAAe,OAAO,UAAU,EAAE;AAC9C,UAAQ,IAAI,eAAe,OAAO,UAAU,EAAE;AAC9C,MAAI,OAAO,OAAO,cAAc,UAAU;AACxC,YAAQ,IAAI,YAAY,aAAa,OAAO,SAAS,CAAC,EAAE;AACxD,YAAQ,IAAI,YAAY,KAAK,IAAI,KAAK,OAAO,YAAY,QAAQ,IAAI,EAAE;AAAA,EACzE;AACA,UAAQ,IAAI,aAAa,YAAY,CAAC,EAAE;AACxC,UAAQ,IAAI,UAAU,aAAa,CAAC,EAAE;AACtC,UAAQ,IAAI,aAAa,gBAAgB,CAAC,EAAE;AAC9C;","names":[]}
|
package/dist/cli/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["import { runAskCommand } from \"./commands/ask.js\";\nimport { runClearCommand } from \"./commands/clear.js\";\nimport { printHelp } from \"./commands/help.js\";\nimport { runLoginCommand } from \"./commands/login.js\";\nimport { runModelsCommand } from \"./commands/models.js\";\nimport { runServeCommand } from \"./commands/serve.js\";\nimport { runStatusCommand } from \"./commands/status.js\";\n\nexport async function runCli(argv: string[] = process.argv.slice(2)): Promise<void> {\n const [command, ...rest] = argv;\n\n switch (command) {\n case \"login\":\n await runLoginCommand();\n return;\n case \"status\":\n await runStatusCommand();\n return;\n case \"models\":\n await runModelsCommand();\n return;\n case \"ask\":\n await runAskCommand(rest);\n return;\n case \"serve\":\n await runServeCommand(rest);\n return;\n case \"clear\":\n await runClearCommand();\n return;\n case \"help\":\n case \"--help\":\n case \"-h\":\n case undefined:\n printHelp();\n return;\n default:\n throw new Error(`未知命令: ${command}`);\n }\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AAEjC,eAAsB,OAAO,OAAiB,QAAQ,KAAK,MAAM,CAAC,GAAkB;AAClF,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAE3B,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,gBAAgB;AACtB;AAAA,IACF,KAAK;AACH,YAAM,iBAAiB;AACvB;AAAA,IACF,KAAK;AACH,YAAM,iBAAiB;AACvB;AAAA,IACF,KAAK;AACH,YAAM,cAAc,IAAI;AACxB;AAAA,IACF,KAAK;AACH,YAAM,gBAAgB,IAAI;AAC1B;AAAA,IACF,KAAK;AACH,YAAM,gBAAgB;AACtB;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,gBAAU;AACV;AAAA,IACF;AACE,YAAM,IAAI,MAAM,6BAAS,OAAO,EAAE;AAAA,EACtC;AACF;","names":[]}
|
package/dist/cli/shared.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/shared.ts"],"sourcesContent":["export function formatExpiry(expires: number): string {\n return new Date(expires).toLocaleString(\"zh-CN\", {\n hour12: false,\n });\n}\n\nexport function parseAskArgs(args: string[]): { model?: string; prompt: string } {\n const rest = [...args];\n let model: string | undefined;\n for (let index = 0; index < rest.length; index += 1) {\n if (rest[index] !== \"--model\") {\n continue;\n }\n\n model = rest[index + 1];\n rest.splice(index, 2);\n break;\n }\n return {\n model,\n prompt: rest.join(\" \").trim(),\n };\n}\n\nexport function parseServeArgs(args: string[]): { host?: string; port?: number } {\n const rest = [...args];\n let host: string | undefined;\n let port: number | undefined;\n\n for (let index = 0; index < rest.length; index += 1) {\n if (rest[index] === \"--host\") {\n host = rest[index + 1];\n rest.splice(index, 2);\n index -= 1;\n continue;\n }\n\n if (rest[index] === \"--port\") {\n const value = Number.parseInt(rest[index + 1] ?? \"\", 10);\n if (Number.isFinite(value)) {\n port = value;\n }\n rest.splice(index, 2);\n index -= 1;\n }\n }\n\n return { host, port };\n}\n"],"mappings":";AAAO,SAAS,aAAa,SAAyB;AACpD,SAAO,IAAI,KAAK,OAAO,EAAE,eAAe,SAAS;AAAA,IAC/C,QAAQ;AAAA,EACV,CAAC;AACH;AAEO,SAAS,aAAa,MAAoD;AAC/E,QAAM,OAAO,CAAC,GAAG,IAAI;AACrB,MAAI;AACJ,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,QAAI,KAAK,KAAK,MAAM,WAAW;AAC7B;AAAA,IACF;AAEA,YAAQ,KAAK,QAAQ,CAAC;AACtB,SAAK,OAAO,OAAO,CAAC;AACpB;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,KAAK,KAAK,GAAG,EAAE,KAAK;AAAA,EAC9B;AACF;AAEO,SAAS,eAAe,MAAkD;AAC/E,QAAM,OAAO,CAAC,GAAG,IAAI;AACrB,MAAI;AACJ,MAAI;AAEJ,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,QAAI,KAAK,KAAK,MAAM,UAAU;AAC5B,aAAO,KAAK,QAAQ,CAAC;AACrB,WAAK,OAAO,OAAO,CAAC;AACpB,eAAS;AACT;AAAA,IACF;AAEA,QAAI,KAAK,KAAK,MAAM,UAAU;AAC5B,YAAM,QAAQ,OAAO,SAAS,KAAK,QAAQ,CAAC,KAAK,IAAI,EAAE;AACvD,UAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,eAAO;AAAA,MACT;AACA,WAAK,OAAO,OAAO,CAAC;AACpB,eAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,KAAK;AACtB;","names":[]}
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { runCli } from \"./cli/index.js\";\n\nrunCli().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`错误: ${message}`);\n process.exitCode = 1;\n});\n"],"mappings":";AAAA,SAAS,cAAc;AAEvB,OAAO,EAAE,MAAM,CAAC,UAAU;AACxB,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAQ,MAAM,iBAAO,OAAO,EAAE;AAC9B,UAAQ,WAAW;AACrB,CAAC;","names":[]}
|
package/dist/core/context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/context.ts"],"sourcesContent":["import { ConfigService } from \"./services/config-service.js\";\nimport { AuthService } from \"./services/auth-service.js\";\nimport { ChatService } from \"./services/chat-service.js\";\nimport { ModelService } from \"./services/model-service.js\";\n\nexport function createGatewayContext() {\n const configService = new ConfigService();\n const authService = new AuthService(configService);\n const modelService = new ModelService(configService);\n const chatService = new ChatService({\n authService,\n modelService,\n });\n\n return {\n configService,\n authService,\n modelService,\n chatService,\n };\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAEtB,SAAS,uBAAuB;AACrC,QAAM,gBAAgB,IAAI,cAAc;AACxC,QAAM,cAAc,IAAI,YAAY,aAAa;AACjD,QAAM,eAAe,IAAI,aAAa,aAAa;AACnD,QAAM,cAAc,IAAI,YAAY;AAAA,IAClC;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/models/openai-codex-models.ts"],"sourcesContent":["import type { ModelInfo } from \"../types.js\";\n\nexport const DEFAULT_CODEX_MODEL = \"gpt-5.4\";\n\nexport const CODEX_MODEL_INFOS: ModelInfo[] = [\n { provider: \"openai-codex\", id: \"gpt-5.4\", name: \"GPT-5.4\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.2\", name: \"GPT-5.2\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.2-codex\", name: \"GPT-5.2 Codex\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.3-codex\", name: \"GPT-5.3 Codex\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.3-codex-spark\", name: \"GPT-5.3 Codex Spark\", input: [\"text\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.1\", name: \"GPT-5.1\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.1-codex\", name: \"GPT-5.1 Codex\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.1-codex-mini\", name: \"GPT-5.1 Codex Mini\", input: [\"text\", \"image\"], source: \"static\" },\n { provider: \"openai-codex\", id: \"gpt-5.1-codex-max\", name: \"GPT-5.1 Codex Max\", input: [\"text\", \"image\"], source: \"static\" },\n];\n\nexport const SUPPORTED_CODEX_MODELS = [\n \"gpt-5.4\",\n \"gpt-5.2\",\n \"gpt-5.2-codex\",\n \"gpt-5.3-codex\",\n \"gpt-5.3-codex-spark\",\n \"gpt-5.1\",\n \"gpt-5.1-codex\",\n \"gpt-5.1-codex-mini\",\n \"gpt-5.1-codex-max\",\n] as const;\n\nexport type SupportedCodexModel = (typeof SUPPORTED_CODEX_MODELS)[number];\n\nexport function isSupportedCodexModel(model: string): model is SupportedCodexModel {\n return SUPPORTED_CODEX_MODELS.includes(model as SupportedCodexModel);\n}\n"],"mappings":";AAEO,MAAM,sBAAsB;AAE5B,MAAM,oBAAiC;AAAA,EAC5C,EAAE,UAAU,gBAAgB,IAAI,WAAW,MAAM,WAAW,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACvG,EAAE,UAAU,gBAAgB,IAAI,WAAW,MAAM,WAAW,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACvG,EAAE,UAAU,gBAAgB,IAAI,iBAAiB,MAAM,iBAAiB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACnH,EAAE,UAAU,gBAAgB,IAAI,iBAAiB,MAAM,iBAAiB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACnH,EAAE,UAAU,gBAAgB,IAAI,uBAAuB,MAAM,uBAAuB,OAAO,CAAC,MAAM,GAAG,QAAQ,SAAS;AAAA,EACtH,EAAE,UAAU,gBAAgB,IAAI,WAAW,MAAM,WAAW,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACvG,EAAE,UAAU,gBAAgB,IAAI,iBAAiB,MAAM,iBAAiB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EACnH,EAAE,UAAU,gBAAgB,IAAI,sBAAsB,MAAM,sBAAsB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAAA,EAC7H,EAAE,UAAU,gBAAgB,IAAI,qBAAqB,MAAM,qBAAqB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ,SAAS;AAC7H;AAEO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,SAAS,sBAAsB,OAA6C;AACjF,SAAO,uBAAuB,SAAS,KAA4B;AACrE;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/providers/http-client.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\n\ntype HttpTextResponse = {\n body: string;\n status: number;\n transport: \"fetch\" | \"curl\";\n};\n\ntype TextRequestInit = {\n body?: string;\n headers?: Record<string, string>;\n method: \"GET\" | \"POST\";\n timeoutMs?: number;\n url: string;\n};\n\nconst CURL_STATUS_MARKER = \"\\n__CURL_STATUS__:\";\n\nasync function runCurlRequest(init: TextRequestInit): Promise<HttpTextResponse> {\n const args = [\n \"--silent\",\n \"--show-error\",\n \"--location\",\n \"--request\",\n init.method,\n init.url,\n \"--write-out\",\n `${CURL_STATUS_MARKER}%{http_code}`,\n ];\n\n for (const [key, value] of Object.entries(init.headers ?? {})) {\n args.push(\"--header\", `${key}: ${value}`);\n }\n\n if (typeof init.body === \"string\") {\n args.push(\"--data-raw\", init.body);\n }\n\n const child = spawn(\"curl\", args, {\n env: process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk) => {\n stdout += chunk;\n });\n\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk;\n });\n\n const exitCode = await new Promise<number>((resolve, reject) => {\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolve(code ?? 1));\n });\n\n if (exitCode !== 0) {\n throw new Error(stderr.trim() || `curl 请求失败,退出码 ${exitCode}`);\n }\n\n const markerIndex = stdout.lastIndexOf(CURL_STATUS_MARKER);\n if (markerIndex === -1) {\n throw new Error(\"curl 响应缺少状态码标记。\");\n }\n\n const body = stdout.slice(0, markerIndex);\n const statusText = stdout.slice(markerIndex + CURL_STATUS_MARKER.length).trim();\n const status = Number.parseInt(statusText, 10);\n if (!Number.isFinite(status)) {\n throw new Error(`无法解析 curl 状态码: ${statusText}`);\n }\n\n return {\n body,\n status,\n transport: \"curl\",\n };\n}\n\nexport async function requestText(init: TextRequestInit): Promise<HttpTextResponse> {\n const useCurlOnly = process.env.OAUTH_DEMO_USE_CURL === \"1\";\n const timeoutMs = init.timeoutMs ?? 20000;\n\n if (!useCurlOnly) {\n try {\n const response = await fetch(init.url, {\n method: init.method,\n headers: init.headers,\n body: init.body,\n signal: AbortSignal.timeout(timeoutMs),\n });\n\n return {\n body: await response.text(),\n status: response.status,\n transport: \"fetch\",\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.log(`fetch 请求失败,准备回退到 curl: ${message}`);\n }\n }\n\n return runCurlRequest(init);\n}\n"],"mappings":";AAAA,SAAS,aAAa;AAgBtB,MAAM,qBAAqB;AAE3B,eAAe,eAAe,MAAkD;AAC9E,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA,GAAG,kBAAkB;AAAA,EACvB;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,GAAG;AAC7D,SAAK,KAAK,YAAY,GAAG,GAAG,KAAK,KAAK,EAAE;AAAA,EAC1C;AAEA,MAAI,OAAO,KAAK,SAAS,UAAU;AACjC,SAAK,KAAK,cAAc,KAAK,IAAI;AAAA,EACnC;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM;AAAA,IAChC,KAAK,QAAQ;AAAA,IACb,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,EAClC,CAAC;AAED,MAAI,SAAS;AACb,MAAI,SAAS;AAEb,QAAM,OAAO,YAAY,MAAM;AAC/B,QAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;AACjC,cAAU;AAAA,EACZ,CAAC;AAED,QAAM,OAAO,YAAY,MAAM;AAC/B,QAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;AACjC,cAAU;AAAA,EACZ,CAAC;AAED,QAAM,WAAW,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9D,UAAM,GAAG,SAAS,MAAM;AACxB,UAAM,GAAG,SAAS,CAAC,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAChD,CAAC;AAED,MAAI,aAAa,GAAG;AAClB,UAAM,IAAI,MAAM,OAAO,KAAK,KAAK,yDAAiB,QAAQ,EAAE;AAAA,EAC9D;AAEA,QAAM,cAAc,OAAO,YAAY,kBAAkB;AACzD,MAAI,gBAAgB,IAAI;AACtB,UAAM,IAAI,MAAM,mEAAiB;AAAA,EACnC;AAEA,QAAM,OAAO,OAAO,MAAM,GAAG,WAAW;AACxC,QAAM,aAAa,OAAO,MAAM,cAAc,mBAAmB,MAAM,EAAE,KAAK;AAC9E,QAAM,SAAS,OAAO,SAAS,YAAY,EAAE;AAC7C,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,UAAM,IAAI,MAAM,qDAAkB,UAAU,EAAE;AAAA,EAChD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb;AACF;AAEA,eAAsB,YAAY,MAAkD;AAClF,QAAM,cAAc,QAAQ,IAAI,wBAAwB;AACxD,QAAM,YAAY,KAAK,aAAa;AAEpC,MAAI,CAAC,aAAa;AAChB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK,KAAK;AAAA,QACrC,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,QACX,QAAQ,YAAY,QAAQ,SAAS;AAAA,MACvC,CAAC;AAED,aAAO;AAAA,QACL,MAAM,MAAM,SAAS,KAAK;AAAA,QAC1B,QAAQ,SAAS;AAAA,QACjB,WAAW;AAAA,MACb;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,cAAQ,IAAI,4EAA0B,OAAO,EAAE;AAAA,IACjD;AAAA,EACF;AAEA,SAAO,eAAe,IAAI;AAC5B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/providers/openai-codex/chat.ts"],"sourcesContent":["import type { OAuthProfile } from \"../../types.js\";\nimport { DEFAULT_CODEX_MODEL } from \"../../models/openai-codex-models.js\";\nimport { requestText } from \"../http-client.js\";\n\nconst CODEX_RESPONSES_URL = \"https://chatgpt.com/backend-api/codex/responses\";\n\ntype CodexSseEvent = {\n type?: string;\n response?: unknown;\n delta?: string;\n};\n\nfunction extractOutputText(payload: unknown): string {\n if (!payload || typeof payload !== \"object\") {\n return \"\";\n }\n\n const data = payload as {\n output_text?: unknown;\n output?: Array<{\n type?: string;\n content?: Array<{ type?: string; text?: string }>;\n text?: string;\n }>;\n };\n\n if (typeof data.output_text === \"string\" && data.output_text.trim()) {\n return data.output_text.trim();\n }\n\n for (const item of data.output ?? []) {\n if (typeof item?.text === \"string\" && item.text.trim()) {\n return item.text.trim();\n }\n\n for (const part of item?.content ?? []) {\n if ((part?.type === \"output_text\" || part?.type === \"text\") && typeof part.text === \"string\") {\n const trimmed = part.text.trim();\n if (trimmed) {\n return trimmed;\n }\n }\n }\n }\n\n return \"\";\n}\n\nfunction parseSseEvents(body: string): CodexSseEvent[] {\n const events: CodexSseEvent[] = [];\n for (const chunk of body.split(\"\\n\\n\")) {\n const lines = chunk\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(5).trim())\n .filter(Boolean);\n\n if (lines.length === 0) {\n continue;\n }\n\n const data = lines.join(\"\\n\").trim();\n if (!data || data === \"[DONE]\") {\n continue;\n }\n\n try {\n events.push(JSON.parse(data) as CodexSseEvent);\n } catch {\n // ignore malformed SSE chunks\n }\n }\n return events;\n}\n\nfunction extractCodexText(body: string): { text: string; raw: unknown } {\n const events = parseSseEvents(body);\n let responsePayload: unknown;\n let accumulated = \"\";\n\n for (const event of events) {\n if (\n event.type === \"response.completed\" ||\n event.type === \"response.done\" ||\n event.type === \"response.incomplete\"\n ) {\n responsePayload = event.response;\n }\n\n if (typeof event.delta === \"string\" && event.delta) {\n accumulated += event.delta;\n }\n }\n\n const completedText = extractOutputText(responsePayload);\n if (completedText) {\n return { text: completedText, raw: responsePayload ?? events };\n }\n\n return { text: accumulated.trim(), raw: responsePayload ?? events };\n}\n\nexport async function askOpenAICodex(params: {\n profile: OAuthProfile;\n prompt: string;\n model?: string;\n system?: string;\n}): Promise<{ text: string; raw: unknown }> {\n const response = await requestText({\n method: \"POST\",\n url: CODEX_RESPONSES_URL,\n headers: {\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${params.profile.access}`,\n \"ChatGPT-Account-Id\": params.profile.accountId,\n \"OpenAI-Beta\": \"responses=experimental\",\n Originator: \"pi\",\n \"User-Agent\": \"pi (bun demo)\",\n },\n body: JSON.stringify({\n model: params.model ?? DEFAULT_CODEX_MODEL,\n store: false,\n stream: true,\n instructions: params.system ?? \"\",\n input: [\n {\n role: \"user\",\n content: [{ type: \"input_text\", text: params.prompt }],\n },\n ],\n text: { verbosity: \"medium\" },\n include: [\"reasoning.encrypted_content\"],\n tool_choice: \"auto\",\n parallel_tool_calls: true,\n }),\n });\n\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`调用 Responses API 失败: HTTP ${response.status} via ${response.transport} ${response.body}`);\n }\n\n return extractCodexText(response.body);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/providers/openai-codex/oauth.ts"],"sourcesContent":["import http from \"node:http\";\nimport { randomBytes } from \"node:crypto\";\nimport { spawn } from \"node:child_process\";\nimport readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport type { OAuthProfile } from \"../../types.js\";\nimport { requestText } from \"../http-client.js\";\nimport { generatePKCE } from \"./pkce.js\";\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 REDIRECT_URI = \"http://localhost:1455/auth/callback\";\nconst SCOPE = \"openid profile email offline_access\";\nconst JWT_CLAIM_PATH = \"https://api.openai.com/auth\";\nconst SUCCESS_HTML = `<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>OAuth Success</title>\n</head>\n<body>\n <p>登录成功,请回到终端继续。</p>\n</body>\n</html>`;\n\ntype AuthorizationResult = {\n code?: string;\n state?: string;\n};\n\ntype TokenResult = {\n access: string;\n refresh: string;\n expires: number;\n};\n\nfunction createState(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = parts[1] ?? \"\";\n const normalized = payload.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = normalized.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (normalized.length % 4));\n const decoded = Buffer.from(normalized + padding, \"base64\").toString(\"utf8\");\n return JSON.parse(decoded) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction parseAuthorizationInput(value: string): AuthorizationResult {\n const trimmed = value.trim();\n if (!trimmed) {\n return {};\n }\n\n try {\n const url = new URL(trimmed);\n return {\n code: url.searchParams.get(\"code\") ?? undefined,\n state: url.searchParams.get(\"state\") ?? undefined,\n };\n } catch {\n // ignore\n }\n\n if (trimmed.includes(\"#\")) {\n const [code, state] = trimmed.split(\"#\", 2);\n return { code, state };\n }\n\n if (trimmed.includes(\"code=\")) {\n const params = new URLSearchParams(trimmed);\n return {\n code: params.get(\"code\") ?? undefined,\n state: params.get(\"state\") ?? undefined,\n };\n }\n\n return { code: trimmed };\n}\n\nfunction extractProfile(accessToken: string, refreshToken: string, expires: number): OAuthProfile {\n const payload = decodeJwtPayload(accessToken);\n const authClaim = payload?.[JWT_CLAIM_PATH] as Record<string, unknown> | undefined;\n const accountId = authClaim?.chatgpt_account_id;\n if (typeof accountId !== \"string\" || !accountId.trim()) {\n throw new Error(\"无法从 access token 中提取 accountId。\");\n }\n\n const email = typeof payload?.email === \"string\" && payload.email.trim() ? payload.email.trim() : undefined;\n const profileKey = email ?? accountId;\n\n return {\n provider: \"openai-codex\",\n profileId: `openai-codex:${profileKey}`,\n mode: \"oauth_account\",\n access: accessToken,\n refresh: refreshToken,\n expires,\n accountId,\n email,\n };\n}\n\nasync function exchangeAuthorizationCode(code: string, verifier: string): Promise<TokenResult> {\n const response = await requestText({\n method: \"POST\",\n url: TOKEN_URL,\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: CLIENT_ID,\n code,\n code_verifier: verifier,\n redirect_uri: REDIRECT_URI,\n }).toString(),\n });\n\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`授权码换 token 失败: HTTP ${response.status} via ${response.transport} ${response.body}`);\n }\n\n const json = JSON.parse(response.body) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== \"number\") {\n throw new Error(\"token 响应缺少 access_token / refresh_token / expires_in。\");\n }\n\n return {\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + json.expires_in * 1000,\n };\n}\n\nexport async function refreshOpenAICodexToken(profile: OAuthProfile): Promise<OAuthProfile> {\n const response = await requestText({\n method: \"POST\",\n url: TOKEN_URL,\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: profile.refresh,\n client_id: CLIENT_ID,\n }).toString(),\n });\n\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`刷新 token 失败: HTTP ${response.status} via ${response.transport} ${response.body}`);\n }\n\n const json = JSON.parse(response.body) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== \"number\") {\n throw new Error(\"刷新响应缺少 access_token / refresh_token / expires_in。\");\n }\n\n return extractProfile(\n json.access_token,\n json.refresh_token,\n Date.now() + json.expires_in * 1000,\n );\n}\n\nfunction tryOpenBrowser(url: string): boolean {\n try {\n if (process.platform === \"darwin\") {\n const child = spawn(\"open\", [url], { stdio: \"ignore\", detached: true });\n child.unref();\n return true;\n }\n\n if (process.platform === \"win32\") {\n const child = spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { stdio: \"ignore\", detached: true });\n child.unref();\n return true;\n }\n\n const child = spawn(\"xdg-open\", [url], { stdio: \"ignore\", detached: true });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nasync function promptLine(message: string): Promise<string> {\n const rl = readline.createInterface({ input, output });\n try {\n return (await rl.question(message)).trim();\n } finally {\n rl.close();\n }\n}\n\nasync function startLocalCallbackServer(expectedState: string): Promise<{\n close: () => void;\n waitForCode: () => Promise<string | null>;\n}> {\n let lastCode: string | null = null;\n let closed = false;\n\n const server = http.createServer((req, res) => {\n try {\n const url = new URL(req.url || \"\", \"http://127.0.0.1\");\n if (url.pathname !== \"/auth/callback\") {\n res.statusCode = 404;\n res.end(\"Not found\");\n return;\n }\n\n const state = url.searchParams.get(\"state\");\n const code = url.searchParams.get(\"code\");\n if (state !== expectedState) {\n res.statusCode = 400;\n res.end(\"State mismatch\");\n return;\n }\n\n if (!code) {\n res.statusCode = 400;\n res.end(\"Missing authorization code\");\n return;\n }\n\n lastCode = code;\n res.statusCode = 200;\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(SUCCESS_HTML);\n } catch {\n res.statusCode = 500;\n res.end(\"Internal error\");\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(1455, \"127.0.0.1\", () => resolve());\n server.on(\"error\", () => resolve());\n });\n\n return {\n close: () => {\n if (closed) {\n return;\n }\n closed = true;\n server.close();\n },\n waitForCode: async () => {\n for (let index = 0; index < 600; index += 1) {\n if (lastCode) {\n return lastCode;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n return null;\n },\n };\n}\n\nasync function requestManualCode(expectedState: string): Promise<string> {\n const manual = await promptLine(\"没有自动回调,请粘贴完整回调 URL 或 code: \");\n const parsed = parseAuthorizationInput(manual);\n if (parsed.state && parsed.state !== expectedState) {\n throw new Error(\"state 不匹配,已拒绝本次授权结果。\");\n }\n if (!parsed.code) {\n throw new Error(\"没有解析出 authorization code。\");\n }\n return parsed.code;\n}\n\nexport async function loginOpenAICodex(): Promise<OAuthProfile> {\n const { verifier, challenge } = await generatePKCE();\n const state = createState();\n const authorizeUrl = new URL(AUTHORIZE_URL);\n\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"client_id\", CLIENT_ID);\n authorizeUrl.searchParams.set(\"redirect_uri\", REDIRECT_URI);\n authorizeUrl.searchParams.set(\"scope\", SCOPE);\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"state\", state);\n authorizeUrl.searchParams.set(\"id_token_add_organizations\", \"true\");\n authorizeUrl.searchParams.set(\"codex_cli_simplified_flow\", \"true\");\n authorizeUrl.searchParams.set(\"originator\", \"pi\");\n\n const callbackServer = await startLocalCallbackServer(state);\n const url = authorizeUrl.toString();\n\n console.log(\"开始 OpenAI Codex OAuth 登录。\");\n console.log(`回调地址: ${REDIRECT_URI}`);\n console.log(`授权地址: ${url}`);\n if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {\n console.log(\"检测到代理环境变量,token 交换会复用当前终端代理。\");\n } else {\n console.log(\"当前未检测到 HTTP_PROXY / HTTPS_PROXY。\");\n }\n if (process.env.OAUTH_DEMO_USE_CURL === \"1\") {\n console.log(\"已启用 curl-only 模式进行 token 请求。\");\n }\n\n const opened = tryOpenBrowser(url);\n if (opened) {\n console.log(\"已尝试打开浏览器。\");\n } else {\n console.log(\"未能自动打开浏览器,请手动打开上面的授权地址。\");\n }\n\n try {\n const code = (await callbackServer.waitForCode()) ?? (await requestManualCode(state));\n console.log(\"已收到授权回调,正在交换 access token...\");\n const token = await exchangeAuthorizationCode(code, verifier);\n console.log(\"token 交换成功,正在解析账号信息...\");\n return extractProfile(token.access, token.refresh, token.expires);\n } finally {\n callbackServer.close();\n }\n}\n"],"mappings":"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","names":["child"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/providers/openai-codex/pkce.ts"],"sourcesContent":["function base64urlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nexport async function generatePKCE(): Promise<{ verifier: string; challenge: string }> {\n const verifierBytes = new Uint8Array(32);\n crypto.getRandomValues(verifierBytes);\n const verifier = base64urlEncode(verifierBytes);\n\n const encoder = new TextEncoder();\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encoder.encode(verifier));\n const challenge = base64urlEncode(new Uint8Array(hashBuffer));\n\n return { verifier, challenge };\n}\n"],"mappings":";AAAA,SAAS,gBAAgB,OAA2B;AAClD,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACxB,cAAU,OAAO,aAAa,IAAI;AAAA,EACpC;AACA,SAAO,KAAK,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,MAAM,EAAE;AAC9E;AAEA,eAAsB,eAAiE;AACrF,QAAM,gBAAgB,IAAI,WAAW,EAAE;AACvC,SAAO,gBAAgB,aAAa;AACpC,QAAM,WAAW,gBAAgB,aAAa;AAE9C,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,aAAa,MAAM,OAAO,OAAO,OAAO,WAAW,QAAQ,OAAO,QAAQ,CAAC;AACjF,QAAM,YAAY,gBAAgB,IAAI,WAAW,UAAU,CAAC;AAE5D,SAAO,EAAE,UAAU,UAAU;AAC/B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/services/auth-service.ts"],"sourcesContent":["import {\n clearStore,\n getActiveProfile,\n saveProfile,\n} from \"../store/profile-store.js\";\nimport type { GatewayStatus, OAuthProfile, ProviderId } from \"../types.js\";\nimport {\n loginOpenAICodex,\n refreshOpenAICodexToken,\n} from \"../providers/openai-codex/oauth.js\";\nimport { ConfigService } from \"./config-service.js\";\n\nexport class AuthService {\n constructor(private readonly configService: ConfigService) {}\n\n async login(provider: ProviderId): Promise<OAuthProfile> {\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n\n const profile = await loginOpenAICodex();\n await saveProfile(profile);\n return {\n ...profile,\n mode: \"oauth_account\",\n };\n }\n\n async getActiveProfile(provider: ProviderId = \"openai-codex\"): Promise<OAuthProfile | null> {\n const profile = await getActiveProfile();\n if (!profile || profile.provider !== provider) {\n return null;\n }\n\n return {\n ...profile,\n mode: \"oauth_account\",\n };\n }\n\n async requireUsableProfile(provider: ProviderId = \"openai-codex\"): Promise<OAuthProfile> {\n const profile = await this.getActiveProfile(provider);\n if (!profile) {\n throw new Error(`还没有登录 ${provider}。先运行 bun src/cli.js login`);\n }\n\n if (Date.now() < profile.expires) {\n return profile;\n }\n\n const refreshed = await refreshOpenAICodexToken(profile);\n await saveProfile(refreshed);\n return {\n ...refreshed,\n mode: \"oauth_account\",\n };\n }\n\n async logoutAll(): Promise<void> {\n await clearStore();\n }\n\n async getStatus(): Promise<GatewayStatus> {\n const profile = await this.getActiveProfile();\n const defaultModel = await this.configService.getDefaultModel();\n const server = await this.configService.getServerConfig();\n return {\n ok: true,\n activeProvider: profile?.provider,\n activeProfileId: profile?.profileId,\n defaultModel,\n loggedIn: Boolean(profile),\n expiresAt: profile?.expires,\n serverHost: server.host,\n serverPort: server.port,\n };\n }\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAGA,MAAM,YAAY;AAAA,EACvB,YAA6B,eAA8B;AAA9B;AAAA,EAA+B;AAAA,EAE5D,MAAM,MAAM,UAA6C;AACvD,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AAEA,UAAM,UAAU,MAAM,iBAAiB;AACvC,UAAM,YAAY,OAAO;AACzB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,WAAuB,gBAA8C;AAC1F,UAAM,UAAU,MAAM,iBAAiB;AACvC,QAAI,CAAC,WAAW,QAAQ,aAAa,UAAU;AAC7C,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,WAAuB,gBAAuC;AACvF,UAAM,UAAU,MAAM,KAAK,iBAAiB,QAAQ;AACpD,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,kCAAS,QAAQ,+CAA2B;AAAA,IAC9D;AAEA,QAAI,KAAK,IAAI,IAAI,QAAQ,SAAS;AAChC,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,MAAM,wBAAwB,OAAO;AACvD,UAAM,YAAY,SAAS;AAC3B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,YAA2B;AAC/B,UAAM,WAAW;AAAA,EACnB;AAAA,EAEA,MAAM,YAAoC;AACxC,UAAM,UAAU,MAAM,KAAK,iBAAiB;AAC5C,UAAM,eAAe,MAAM,KAAK,cAAc,gBAAgB;AAC9D,UAAM,SAAS,MAAM,KAAK,cAAc,gBAAgB;AACxD,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS;AAAA,MAC1B;AAAA,MACA,UAAU,QAAQ,OAAO;AAAA,MACzB,WAAW,SAAS;AAAA,MACpB,YAAY,OAAO;AAAA,MACnB,YAAY,OAAO;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/services/chat-service.ts"],"sourcesContent":["import type { ChatRequest, ChatResult } from \"../types.js\";\nimport { askOpenAICodex } from \"../providers/openai-codex/chat.js\";\nimport { AuthService } from \"./auth-service.js\";\nimport { ModelService } from \"./model-service.js\";\n\ntype ChatServiceDeps = {\n authService: AuthService;\n modelService: ModelService;\n};\n\nexport class ChatService {\n constructor(private readonly deps: ChatServiceDeps) {}\n\n async chat(request: ChatRequest): Promise<ChatResult> {\n const provider = request.provider ?? \"openai-codex\";\n const model = await this.deps.modelService.resolveModel(provider, request.model);\n const profile = await this.deps.authService.requireUsableProfile(provider);\n const result = await askOpenAICodex({\n profile,\n prompt: request.input,\n model,\n system: request.system,\n });\n\n return {\n provider,\n model,\n text: result.text,\n raw: result.raw,\n };\n }\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AASxB,MAAM,YAAY;AAAA,EACvB,YAA6B,MAAuB;AAAvB;AAAA,EAAwB;AAAA,EAErD,MAAM,KAAK,SAA2C;AACpD,UAAM,WAAW,QAAQ,YAAY;AACrC,UAAM,QAAQ,MAAM,KAAK,KAAK,aAAa,aAAa,UAAU,QAAQ,KAAK;AAC/E,UAAM,UAAU,MAAM,KAAK,KAAK,YAAY,qBAAqB,QAAQ;AACzE,UAAM,SAAS,MAAM,eAAe;AAAA,MAClC;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB;AAAA,MACA,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM,OAAO;AAAA,MACb,KAAK,OAAO;AAAA,IACd;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/services/config-service.ts"],"sourcesContent":["import type { GatewaySettings, ProviderId } from \"../types.js\";\nimport { DEFAULT_CODEX_MODEL, isSupportedCodexModel } from \"../models/openai-codex-models.js\";\nimport {\n createDefaultSettings,\n loadSettings,\n saveSettings,\n} from \"../store/settings-store.js\";\n\nexport class ConfigService {\n async getSettings(): Promise<GatewaySettings> {\n return this.ensureSettings();\n }\n\n async ensureSettings(): Promise<GatewaySettings> {\n const settings = await loadSettings();\n await saveSettings(settings);\n return settings;\n }\n\n async getDefaultProvider(): Promise<ProviderId> {\n const settings = await this.getSettings();\n return settings.defaultProvider;\n }\n\n async getDefaultModel(provider: ProviderId = \"openai-codex\"): Promise<string> {\n const settings = await this.getSettings();\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n return isSupportedCodexModel(settings.defaultModel) ? settings.defaultModel : DEFAULT_CODEX_MODEL;\n }\n\n async setDefaultModel(model: string, provider: ProviderId = \"openai-codex\"): Promise<GatewaySettings> {\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n if (!isSupportedCodexModel(model)) {\n throw new Error(`当前 demo 未内置模型: ${model}`);\n }\n\n const settings = await this.getSettings();\n const next = {\n ...settings,\n defaultProvider: provider,\n defaultModel: model,\n };\n await saveSettings(next);\n return next;\n }\n\n async getServerConfig(): Promise<{ host: string; port: number }> {\n const settings = await this.getSettings();\n return settings.server;\n }\n\n async setServerConfig(params: { host?: string; port?: number }): Promise<GatewaySettings> {\n const settings = await this.getSettings();\n const next = {\n ...settings,\n server: {\n host: params.host ?? settings.server.host,\n port: params.port ?? settings.server.port,\n },\n };\n await saveSettings(next);\n return next;\n }\n\n async resetSettings(): Promise<GatewaySettings> {\n const defaults = createDefaultSettings();\n await saveSettings(defaults);\n return defaults;\n }\n}\n"],"mappings":";AACA,SAAS,qBAAqB,6BAA6B;AAC3D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,cAAc;AAAA,EACzB,MAAM,cAAwC;AAC5C,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAA2C;AAC/C,UAAM,WAAW,MAAM,aAAa;AACpC,UAAM,aAAa,QAAQ;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,qBAA0C;AAC9C,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,gBAAgB,WAAuB,gBAAiC;AAC5E,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AACA,WAAO,sBAAsB,SAAS,YAAY,IAAI,SAAS,eAAe;AAAA,EAChF;AAAA,EAEA,MAAM,gBAAgB,OAAe,WAAuB,gBAA0C;AACpG,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AACA,QAAI,CAAC,sBAAsB,KAAK,GAAG;AACjC,YAAM,IAAI,MAAM,qDAAkB,KAAK,EAAE;AAAA,IAC3C;AAEA,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,UAAM,OAAO;AAAA,MACX,GAAG;AAAA,MACH,iBAAiB;AAAA,MACjB,cAAc;AAAA,IAChB;AACA,UAAM,aAAa,IAAI;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAA2D;AAC/D,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,gBAAgB,QAAoE;AACxF,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,UAAM,OAAO;AAAA,MACX,GAAG;AAAA,MACH,QAAQ;AAAA,QACN,MAAM,OAAO,QAAQ,SAAS,OAAO;AAAA,QACrC,MAAM,OAAO,QAAQ,SAAS,OAAO;AAAA,MACvC;AAAA,IACF;AACA,UAAM,aAAa,IAAI;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAA0C;AAC9C,UAAM,WAAW,sBAAsB;AACvC,UAAM,aAAa,QAAQ;AAC3B,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/services/model-service.ts"],"sourcesContent":["import {\n CODEX_MODEL_INFOS,\n isSupportedCodexModel,\n} from \"../models/openai-codex-models.js\";\nimport type { ModelInfo, ProviderId } from \"../types.js\";\nimport { ConfigService } from \"./config-service.js\";\n\nexport class ModelService {\n constructor(private readonly configService: ConfigService) {}\n\n async listModels(provider: ProviderId = \"openai-codex\"): Promise<ModelInfo[]> {\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n\n const defaultModel = await this.configService.getDefaultModel(provider);\n return CODEX_MODEL_INFOS.map((model) => ({\n ...model,\n isDefault: model.id === defaultModel,\n }));\n }\n\n async getDefaultModel(provider: ProviderId = \"openai-codex\"): Promise<string> {\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n\n return this.configService.getDefaultModel(provider);\n }\n\n async resolveModel(provider: ProviderId = \"openai-codex\", requested?: string): Promise<string> {\n if (provider !== \"openai-codex\") {\n throw new Error(`暂不支持 provider: ${provider}`);\n }\n\n if (!requested) {\n return this.configService.getDefaultModel(provider);\n }\n\n if (!isSupportedCodexModel(requested)) {\n throw new Error(`当前 demo 未内置模型: ${requested}`);\n }\n\n return requested;\n }\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAIA,MAAM,aAAa;AAAA,EACxB,YAA6B,eAA8B;AAA9B;AAAA,EAA+B;AAAA,EAE5D,MAAM,WAAW,WAAuB,gBAAsC;AAC5E,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AAEA,UAAM,eAAe,MAAM,KAAK,cAAc,gBAAgB,QAAQ;AACtE,WAAO,kBAAkB,IAAI,CAAC,WAAW;AAAA,MACvC,GAAG;AAAA,MACH,WAAW,MAAM,OAAO;AAAA,IAC1B,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,gBAAgB,WAAuB,gBAAiC;AAC5E,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AAEA,WAAO,KAAK,cAAc,gBAAgB,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAM,aAAa,WAAuB,gBAAgB,WAAqC;AAC7F,QAAI,aAAa,gBAAgB;AAC/B,YAAM,IAAI,MAAM,sCAAkB,QAAQ,EAAE;AAAA,IAC9C;AAEA,QAAI,CAAC,WAAW;AACd,aAAO,KAAK,cAAc,gBAAgB,QAAQ;AAAA,IACpD;AAEA,QAAI,CAAC,sBAAsB,SAAS,GAAG;AACrC,YAAM,IAAI,MAAM,qDAAkB,SAAS,EAAE;AAAA,IAC/C;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/store/profile-store.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { OAuthProfile } from \"../types.js\";\n\ntype DemoStore = {\n version: 1;\n activeProfileId?: string;\n profiles: Record<string, OAuthProfile>;\n};\n\nconst projectDir = path.dirname(fileURLToPath(new URL(\"../../../package.json\", import.meta.url)));\nconst stateDir = path.join(projectDir, \".state\");\nconst storePath = path.join(stateDir, \"store.json\");\n\nfunction createEmptyStore(): DemoStore {\n return {\n version: 1,\n profiles: {},\n };\n}\n\nexport function getStateDir(): string {\n return stateDir;\n}\n\nexport function getStorePath(): string {\n return storePath;\n}\n\nexport async function loadStore(): Promise<DemoStore> {\n try {\n const raw = await fs.readFile(storePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<DemoStore>;\n const normalizedProfiles = Object.fromEntries(\n Object.entries(parsed.profiles ?? {}).map(([profileId, profile]) => [\n profileId,\n {\n ...profile,\n mode: \"oauth_account\" as const,\n },\n ]),\n );\n return {\n version: 1,\n activeProfileId: parsed.activeProfileId,\n profiles: normalizedProfiles,\n };\n } catch {\n return createEmptyStore();\n }\n}\n\nexport async function saveStore(store: DemoStore): Promise<void> {\n await fs.mkdir(stateDir, { recursive: true });\n await fs.writeFile(storePath, `${JSON.stringify(store, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function saveProfile(profile: OAuthProfile): Promise<void> {\n const store = await loadStore();\n store.profiles[profile.profileId] = profile;\n store.activeProfileId = profile.profileId;\n await saveStore(store);\n}\n\nexport async function getActiveProfile(): Promise<OAuthProfile | null> {\n const store = await loadStore();\n const activeId = store.activeProfileId?.trim();\n if (activeId && store.profiles[activeId]) {\n return store.profiles[activeId] ?? null;\n }\n\n const first = Object.values(store.profiles)[0];\n return first ?? null;\n}\n\nexport async function clearStore(): Promise<void> {\n await fs.rm(stateDir, { recursive: true, force: true });\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAS9B,MAAM,aAAa,KAAK,QAAQ,cAAc,IAAI,IAAI,yBAAyB,YAAY,GAAG,CAAC,CAAC;AAChG,MAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;AAC/C,MAAM,YAAY,KAAK,KAAK,UAAU,YAAY;AAElD,SAAS,mBAA8B;AACrC,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,CAAC;AAAA,EACb;AACF;AAEO,SAAS,cAAsB;AACpC,SAAO;AACT;AAEO,SAAS,eAAuB;AACrC,SAAO;AACT;AAEA,eAAsB,YAAgC;AACpD,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,SAAS,WAAW,MAAM;AAC/C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAM,qBAAqB,OAAO;AAAA,MAChC,OAAO,QAAQ,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,OAAO,MAAM;AAAA,QAClE;AAAA,QACA;AAAA,UACE,GAAG;AAAA,UACH,MAAM;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,iBAAiB,OAAO;AAAA,MACxB,UAAU;AAAA,IACZ;AAAA,EACF,QAAQ;AACN,WAAO,iBAAiB;AAAA,EAC1B;AACF;AAEA,eAAsB,UAAU,OAAiC;AAC/D,QAAM,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAM,GAAG,UAAU,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AAC7E;AAEA,eAAsB,YAAY,SAAsC;AACtE,QAAM,QAAQ,MAAM,UAAU;AAC9B,QAAM,SAAS,QAAQ,SAAS,IAAI;AACpC,QAAM,kBAAkB,QAAQ;AAChC,QAAM,UAAU,KAAK;AACvB;AAEA,eAAsB,mBAAiD;AACrE,QAAM,QAAQ,MAAM,UAAU;AAC9B,QAAM,WAAW,MAAM,iBAAiB,KAAK;AAC7C,MAAI,YAAY,MAAM,SAAS,QAAQ,GAAG;AACxC,WAAO,MAAM,SAAS,QAAQ,KAAK;AAAA,EACrC;AAEA,QAAM,QAAQ,OAAO,OAAO,MAAM,QAAQ,EAAE,CAAC;AAC7C,SAAO,SAAS;AAClB;AAEA,eAAsB,aAA4B;AAChD,QAAM,GAAG,GAAG,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACxD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/store/settings-store.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GatewaySettings } from \"../types.js\";\n\nconst projectDir = path.dirname(fileURLToPath(new URL(\"../../../package.json\", import.meta.url)));\nconst stateDir = path.join(projectDir, \".state\");\nconst settingsPath = path.join(stateDir, \"settings.json\");\n\nexport function createDefaultSettings(): GatewaySettings {\n return {\n version: 1,\n defaultProvider: \"openai-codex\",\n defaultModel: \"gpt-5.4\",\n server: {\n host: \"127.0.0.1\",\n port: 8787,\n },\n };\n}\n\nexport function getSettingsPath(): string {\n return settingsPath;\n}\n\nexport async function loadSettings(): Promise<GatewaySettings> {\n try {\n const raw = await fs.readFile(settingsPath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<GatewaySettings>;\n const defaults = createDefaultSettings();\n return {\n version: 1,\n defaultProvider: parsed.defaultProvider ?? defaults.defaultProvider,\n defaultModel: parsed.defaultModel ?? defaults.defaultModel,\n server: {\n host: parsed.server?.host ?? defaults.server.host,\n port: parsed.server?.port ?? defaults.server.port,\n },\n };\n } catch {\n return createDefaultSettings();\n }\n}\n\nexport async function saveSettings(settings: GatewaySettings): Promise<void> {\n await fs.mkdir(stateDir, { recursive: true });\n await fs.writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}\\n`, \"utf8\");\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAG9B,MAAM,aAAa,KAAK,QAAQ,cAAc,IAAI,IAAI,yBAAyB,YAAY,GAAG,CAAC,CAAC;AAChG,MAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;AAC/C,MAAM,eAAe,KAAK,KAAK,UAAU,eAAe;AAEjD,SAAS,wBAAyC;AACvD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,kBAA0B;AACxC,SAAO;AACT;AAEA,eAAsB,eAAyC;AAC7D,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,SAAS,cAAc,MAAM;AAClD,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAM,WAAW,sBAAsB;AACvC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,iBAAiB,OAAO,mBAAmB,SAAS;AAAA,MACpD,cAAc,OAAO,gBAAgB,SAAS;AAAA,MAC9C,QAAQ;AAAA,QACN,MAAM,OAAO,QAAQ,QAAQ,SAAS,OAAO;AAAA,QAC7C,MAAM,OAAO,QAAQ,QAAQ,SAAS,OAAO;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO,sBAAsB;AAAA,EAC/B;AACF;AAEA,eAAsB,aAAa,UAA0C;AAC3E,QAAM,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAM,GAAG,UAAU,cAAc,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACnF;","names":[]}
|
package/dist/core/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/http.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http.ts"],"sourcesContent":["export { requestText } from \"./core/providers/http-client.js\";\n"],"mappings":";AAAA,SAAS,mBAAmB;","names":[]}
|
package/dist/models.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/models.ts"],"sourcesContent":["export {\n CODEX_MODEL_INFOS,\n DEFAULT_CODEX_MODEL,\n SUPPORTED_CODEX_MODELS,\n isSupportedCodexModel,\n} from \"./core/models/openai-codex-models.js\";\nexport type { SupportedCodexModel } from \"./core/models/openai-codex-models.js\";\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
|
package/dist/oauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/oauth.ts"],"sourcesContent":["export {\n loginOpenAICodex,\n refreshOpenAICodexToken,\n} from \"./core/providers/openai-codex/oauth.js\";\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,OACK;","names":[]}
|
package/dist/pkce.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pkce.ts"],"sourcesContent":["export { generatePKCE } from \"./core/providers/openai-codex/pkce.js\";\n"],"mappings":";AAAA,SAAS,oBAAoB;","names":[]}
|
package/dist/server/app.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/app.ts"],"sourcesContent":["import Fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport { z } from \"zod\";\nimport { createGatewayContext } from \"../core/context.js\";\n\nconst responsesBodySchema = z.object({\n model: z.string().optional(),\n input: z.union([\n z.string(),\n z.array(\n z.object({\n role: z.string().optional(),\n content: z\n .array(\n z.object({\n type: z.string().optional(),\n text: z.string().optional(),\n }),\n )\n .optional(),\n }),\n ),\n ]),\n instructions: z.string().optional(),\n stream: z.boolean().optional(),\n});\n\nfunction extractTextInput(input: z.infer<typeof responsesBodySchema>[\"input\"]): string {\n if (typeof input === \"string\") {\n return input;\n }\n\n const chunks: string[] = [];\n for (const item of input) {\n for (const part of item.content ?? []) {\n if (typeof part.text === \"string\" && part.text.trim()) {\n chunks.push(part.text.trim());\n }\n }\n }\n\n return chunks.join(\"\\n\").trim();\n}\n\nexport function createApp(params?: {\n corsOrigin?: true | string | RegExp | Array<string | RegExp>;\n}) {\n const app = Fastify({\n logger: false,\n });\n const ctx = createGatewayContext();\n\n void app.register(cors, {\n origin: params?.corsOrigin ?? true,\n methods: [\"GET\", \"POST\", \"OPTIONS\"],\n });\n\n app.get(\"/_gateway/health\", async () => ({ ok: true }));\n\n app.get(\"/_gateway/status\", async () => ctx.authService.getStatus());\n\n app.get(\"/_gateway/models\", async () => ({\n data: await ctx.modelService.listModels(),\n }));\n\n app.get(\"/v1/models\", async () => ({\n object: \"list\",\n data: (await ctx.modelService.listModels()).map((model) => ({\n id: model.id,\n object: \"model\",\n owned_by: model.provider,\n })),\n }));\n\n app.post(\"/v1/responses\", async (request, reply) => {\n const parsed = responsesBodySchema.safeParse(request.body);\n if (!parsed.success) {\n reply.code(400);\n return {\n error: {\n type: \"validation_error\",\n message: parsed.error.issues[0]?.message ?? \"请求体格式错误\",\n },\n };\n }\n\n if (parsed.data.stream) {\n reply.code(501);\n return {\n error: {\n type: \"not_supported\",\n message: \"第一阶段暂不支持 stream=true\",\n },\n };\n }\n\n const input = extractTextInput(parsed.data.input);\n if (!input) {\n reply.code(400);\n return {\n error: {\n type: \"validation_error\",\n message: \"没有解析出有效的 input 文本\",\n },\n };\n }\n\n const result = await ctx.chatService.chat({\n model: parsed.data.model,\n input,\n system: parsed.data.instructions,\n });\n\n return {\n object: \"response\",\n provider: result.provider,\n model: result.model,\n output_text: result.text,\n output: [\n {\n type: \"message\",\n role: \"assistant\",\n content: [\n {\n type: \"output_text\",\n text: result.text,\n },\n ],\n },\n ],\n };\n });\n\n return app;\n}\n"],"mappings":"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","names":[]}
|
package/dist/server/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/index.ts"],"sourcesContent":["import { ConfigService } from \"../core/services/config-service.js\";\nimport { createApp } from \"./app.js\";\n\nfunction resolveCorsOrigin(): true | string | RegExp | Array<string | RegExp> {\n const raw = process.env.AZT_CORS_ORIGIN?.trim();\n if (!raw || raw === \"*\") {\n return true;\n }\n\n const values = raw\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n\n return values.length <= 1 ? values[0] ?? true : values;\n}\n\nexport async function startServer(params?: { host?: string; port?: number }) {\n const app = createApp({\n corsOrigin: resolveCorsOrigin(),\n });\n const configService = new ConfigService();\n const defaults = await configService.getServerConfig();\n const host = params?.host ?? defaults.host;\n const port = params?.port ?? defaults.port;\n\n await app.listen({\n host,\n port,\n });\n\n return {\n app,\n host,\n port,\n corsOrigin: process.env.AZT_CORS_ORIGIN?.trim() || \"*\",\n };\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAE1B,SAAS,oBAAqE;AAC5E,QAAM,MAAM,QAAQ,IAAI,iBAAiB,KAAK;AAC9C,MAAI,CAAC,OAAO,QAAQ,KAAK;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,IACZ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;AAEjB,SAAO,OAAO,UAAU,IAAI,OAAO,CAAC,KAAK,OAAO;AAClD;AAEA,eAAsB,YAAY,QAA2C;AAC3E,QAAM,MAAM,UAAU;AAAA,IACpB,YAAY,kBAAkB;AAAA,EAChC,CAAC;AACD,QAAM,gBAAgB,IAAI,cAAc;AACxC,QAAM,WAAW,MAAM,cAAc,gBAAgB;AACrD,QAAM,OAAO,QAAQ,QAAQ,SAAS;AACtC,QAAM,OAAO,QAAQ,QAAQ,SAAS;AAEtC,QAAM,IAAI,OAAO;AAAA,IACf;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,QAAQ,IAAI,iBAAiB,KAAK,KAAK;AAAA,EACrD;AACF;","names":[]}
|
package/dist/store.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts"],"sourcesContent":["export type { OAuthProfile as OpenAICodexProfile } from \"./core/types.js\";\nexport {\n clearStore,\n getActiveProfile,\n getStateDir,\n getStorePath,\n loadStore,\n saveProfile,\n saveStore,\n} from \"./core/store/profile-store.js\";\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
|