慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4 test: trim doctor command hotspots · openclaw/openclaw@c66f16a test: isolate agent auth and spawn hotspots · openclaw/openclaw@9285935 test: stabilize MCP startup disposal race · openclaw/openclaw@dd9d2eb test: merge browser contract server suites · openclaw/openclaw@5817a76 test: narrow ollama provider discovery setup · openclaw/openclaw@a0d9598 build: declare qa-lab aimock runtime dependency · openclaw/openclaw@24431e5 test: speed up safe-bins exec harness · openclaw/openclaw@ee856ab test: preserve tool helpers in embedded runner mocks · openclaw/openclaw@acd86a0 refactor: move memory embeddings into provider plugins · openclaw/openclaw@77e6e4c test: reuse system-run temp fixtures · openclaw/openclaw@7e9ff0f test: trim hotspot wait overhead · openclaw/openclaw@12a59b0 Check: avoid duplicate boundary prep · openclaw/openclaw@baf11b8 test: reduce hotspot fixture overhead · openclaw/openclaw@3a59edd feat(ui): overhaul settings and slash command UX (#67819) thanks @Bun… · openclaw/openclaw@2cfb660 QA Matrix: exit cleanly on failure · openclaw/openclaw@42805d2 QA Matrix: isolate scenario coverage · openclaw/openclaw@7e659e1 Matrix: refresh crypto bootstrap state · openclaw/openclaw@94081d8 QA Lab: add provider registry · openclaw/openclaw@bb7e982 Matrix: add plugin changelog · openclaw/openclaw@4acab55 test: trim more hotspot overhead · openclaw/openclaw@f485311
修:由 OpenAI 经 Codex 图像 API 密钥导引 · openclaw/openclaw@38e1654
steipete · 2026-05-24 · via Recent Commits to openclaw:main

@@ -172,6 +172,42 @@ function createCodexOAuthAuthStore() {

172172

};

173173

}

174174175+

function createCodexApiKeyAuthStore() {

176+

return {

177+

version: 1 as const,

178+

profiles: {

179+

"openai-codex:manual": {

180+

type: "api_key" as const,

181+

provider: "openai-codex",

182+

key: "codex-api-key",

183+

},

184+

},

185+

};

186+

}

187+188+

function createCodexTokenAuthStore() {

189+

return {

190+

version: 1 as const,

191+

profiles: {

192+

"openai-codex:token": {

193+

type: "token" as const,

194+

provider: "openai-codex",

195+

token: "codex-token",

196+

},

197+

},

198+

};

199+

}

200+201+

function createMixedCodexAuthStore() {

202+

return {

203+

version: 1 as const,

204+

profiles: {

205+

...createCodexTokenAuthStore().profiles,

206+

...createCodexApiKeyAuthStore().profiles,

207+

},

208+

};

209+

}

210+175211

type MockWithCalls = {

176212

mock: {

177213

calls: readonly (readonly unknown[])[];

@@ -841,6 +877,180 @@ describe("openai image generation provider", () => {

841877

});

842878

});

843879880+

it("does not treat Codex API key profiles as configured Codex OAuth image auth", async () => {

881+

mockGeneratedPngResponse();

882+

resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

883+

if (params?.provider === "openai") {

884+

return { apiKey: "openai-key", source: "profile:openai", mode: "api-key" };

885+

}

886+

throw new Error(`Unexpected auth provider ${params?.provider ?? ""}`);

887+

});

888+889+

const provider = buildOpenAIImageGenerationProvider();

890+

await provider.generateImage({

891+

provider: "openai",

892+

model: "gpt-image-2",

893+

prompt: "Draw with OpenAI auth despite a Codex API key profile",

894+

cfg: {},

895+

authStore: createCodexApiKeyAuthStore(),

896+

});

897+898+

expect(resolveApiKeyForProviderMock).toHaveBeenCalledTimes(1);

899+

expect(authResolutionCall().provider).toBe("openai");

900+

expect(jsonRequestCall().url).toBe("https://api.openai.com/v1/images/generations");

901+

expect(httpConfigCall().provider).toBe("openai");

902+

expect(logInfoMock).not.toHaveBeenCalledWith(

903+

expect.stringContaining("transport=codex-responses"),

904+

);

905+

});

906+907+

it("uses native OpenAI image requests when only Codex API key auth is available", async () => {

908+

mockGeneratedPngResponse();

909+

resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

910+

if (params?.provider === "openai") {

911+

return {};

912+

}

913+

if (params?.provider === "openai-codex") {

914+

return {

915+

apiKey: "codex-api-key",

916+

source: "profile:openai-codex:manual",

917+

mode: "api-key",

918+

};

919+

}

920+

return {};

921+

});

922+923+

const provider = buildOpenAIImageGenerationProvider();

924+

await provider.generateImage({

925+

provider: "openai",

926+

model: "gpt-image-2",

927+

prompt: "Draw through Codex API key auth",

928+

cfg: {},

929+

authStore: createCodexApiKeyAuthStore(),

930+

});

931+932+

expect(resolveApiKeyForProviderMock).toHaveBeenCalledTimes(2);

933+

expect(authResolutionCall(0).provider).toBe("openai");

934+

expect(authResolutionCall(1).provider).toBe("openai-codex");

935+

const configCall = httpConfigCall();

936+

expect(configCall.defaultBaseUrl).toBe("https://api.openai.com/v1");

937+

expect(configCall.defaultHeaders).toEqual({

938+

Authorization: "Bearer codex-api-key",

939+

});

940+

expect(configCall.provider).toBe("openai");

941+

expect(configCall.api).toBeUndefined();

942+

expect(jsonRequestCall().url).toBe("https://api.openai.com/v1/images/generations");

943+

expect(postMultipartRequestMock).not.toHaveBeenCalled();

944+

expect(logInfoMock).not.toHaveBeenCalledWith(

945+

expect.stringContaining("transport=codex-responses"),

946+

);

947+

});

948+949+

it("uses native OpenAI image requests when mixed Codex profiles resolve to an API key", async () => {

950+

mockGeneratedPngResponse();

951+

resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

952+

if (params?.provider === "openai-codex") {

953+

return {

954+

apiKey: "codex-api-key",

955+

source: "profile:openai-codex:manual",

956+

mode: "api-key",

957+

};

958+

}

959+

throw new Error(`Unexpected auth provider ${params?.provider ?? ""}`);

960+

});

961+962+

const provider = buildOpenAIImageGenerationProvider();

963+

await provider.generateImage({

964+

provider: "openai",

965+

model: "gpt-image-2",

966+

prompt: "Draw through resolved Codex API key auth",

967+

cfg: {},

968+

authStore: createMixedCodexAuthStore(),

969+

});

970+971+

expect(resolveApiKeyForProviderMock).toHaveBeenCalledTimes(1);

972+

expect(authResolutionCall().provider).toBe("openai-codex");

973+

expect(httpConfigCall().defaultBaseUrl).toBe("https://api.openai.com/v1");

974+

expect(httpConfigCall().defaultHeaders).toEqual({

975+

Authorization: "Bearer codex-api-key",

976+

});

977+

expect(httpConfigCall().provider).toBe("openai");

978+

expect(jsonRequestCall().url).toBe("https://api.openai.com/v1/images/generations");

979+

expect(logInfoMock).not.toHaveBeenCalledWith(

980+

expect.stringContaining("transport=codex-responses"),

981+

);

982+

});

983+984+

it("keeps Codex token auth on the Codex image transport", async () => {

985+

mockCodexImageStream({ imageData: "codex-token-image" });

986+

resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

987+

if (params?.provider === "openai") {

988+

return {};

989+

}

990+

if (params?.provider === "openai-codex") {

991+

return {

992+

apiKey: "codex-token",

993+

source: "profile:openai-codex:token",

994+

mode: "token",

995+

};

996+

}

997+

return {};

998+

});

999+1000+

const provider = buildOpenAIImageGenerationProvider();

1001+

const result = await provider.generateImage({

1002+

provider: "openai",

1003+

model: "gpt-image-2",

1004+

prompt: "Draw through Codex token auth",

1005+

cfg: {},

1006+

authStore: createCodexTokenAuthStore(),

1007+

});

1008+1009+

expect(resolveApiKeyForProviderMock).toHaveBeenCalledTimes(1);

1010+

expect(authResolutionCall().provider).toBe("openai-codex");

1011+

expect(httpConfigCall().defaultBaseUrl).toBe("https://chatgpt.com/backend-api/codex");

1012+

expect(httpConfigCall().provider).toBe("openai-codex");

1013+

expect(httpConfigCall().api).toBe("openai-codex-responses");

1014+

expect(jsonRequestCall().url).toBe("https://chatgpt.com/backend-api/codex/responses");

1015+

expect(postMultipartRequestMock).not.toHaveBeenCalled();

1016+

expect(result.images[0]?.buffer).toEqual(Buffer.from("codex-token-image"));

1017+

});

1018+1019+

it("uses configured Codex token auth before probing an available OpenAI API key", async () => {

1020+

mockCodexImageStream({ imageData: "codex-token-image" });

1021+

resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

1022+

if (params?.provider === "openai") {

1023+

return { apiKey: "openai-key", source: "OPENAI_API_KEY", mode: "api-key" };

1024+

}

1025+

if (params?.provider === "openai-codex") {

1026+

return {

1027+

apiKey: "codex-token",

1028+

source: "profile:openai-codex:token",

1029+

mode: "token",

1030+

};

1031+

}

1032+

return {};

1033+

});

1034+1035+

const provider = buildOpenAIImageGenerationProvider();

1036+

await provider.generateImage({

1037+

provider: "openai",

1038+

model: "gpt-image-2",

1039+

prompt: "Draw using configured Codex token auth",

1040+

cfg: {},

1041+

authStore: createCodexTokenAuthStore(),

1042+

});

1043+1044+

expect(resolveApiKeyForProviderMock).toHaveBeenCalledTimes(1);

1045+

expect(authResolutionCall().provider).toBe("openai-codex");

1046+

expect(

1047+

resolveApiKeyForProviderMock.mock.calls.some(

1048+

([call]) => (call as AuthResolutionCall).provider === "openai",

1049+

),

1050+

).toBe(false);

1051+

expect(jsonRequestCall().url).toBe("https://chatgpt.com/backend-api/codex/responses");

1052+

});

1053+8441054

it("routes transparent default-model Codex OAuth requests to the alpha-capable image model", async () => {

8451055

mockCodexAuthOnly();

8461056

mockCodexImageStream({ imageData: "codex-transparent-image" });