Skip to content

Commit 26913e6

Browse files
committed
fix(codex): preserve public OpenAI app-server provider
1 parent 5c5711f commit 26913e6

3 files changed

Lines changed: 50 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai
3030

3131
### Fixes
3232

33+
- Agents/Codex: keep public OpenAI API-key profiles from being treated as native Codex app-server auth while preserving persisted Codex OAuth sessions.
3334
- Control UI: keep collapsed tool cards labeled with the tool name and action instead of generic output text. Thanks @shakkernerd.
3435
- Agents/Codex: surface Skill Workshop guidance in Codex app-server prompts when `skill_workshop` is available. Thanks @shakkernerd.
3536
- CLI: keep `plugins list --json` on the snapshot-only path so plugin sweeps avoid loading the full runtime status graph.

extensions/codex/src/app-server/session-binding.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ export function isCodexAppServerNativeAuthProfile(
337337
...lookup,
338338
authProfileId,
339339
});
340-
return isCodexAppServerNativeAuthProvider({
341-
provider: credential?.provider,
342-
config: lookup.config,
343-
});
340+
if (!credential || credential.type === "api_key") {
341+
return false;
342+
}
343+
return isOpenAiAuthProvider({ provider: credential.provider, config: lookup.config });
344344
} catch (error) {
345345
embeddedAgentLog.debug("failed to resolve codex app-server auth profile provider", {
346346
authProfileId,
@@ -403,7 +403,7 @@ function loadCodexAppServerAuthProfileStore(params: {
403403
);
404404
}
405405

406-
function isCodexAppServerNativeAuthProvider(params: {
406+
function isOpenAiAuthProvider(params: {
407407
provider?: string;
408408
config?: ProviderAuthAliasConfig;
409409
}): boolean {

extensions/codex/src/app-server/thread-lifecycle.test.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import {
1414
function createAttemptParams(params: {
1515
provider: string;
1616
authProfileId?: string;
17+
authProfileType?: "oauth" | "api_key";
1718
authProfileProvider?: string;
1819
authProfileProviders?: Record<string, string>;
20+
runtimeExternalProfileIds?: string[];
1921
bootstrapContextMode?: "full" | "lightweight";
2022
bootstrapContextRunKind?: "default" | "heartbeat" | "cron";
2123
images?: EmbeddedRunAttemptParams["images"];
@@ -25,6 +27,7 @@ function createAttemptParams(params: {
2527
(params.authProfileId
2628
? { [params.authProfileId]: params.authProfileProvider ?? "openai" }
2729
: {});
30+
const authProfileType = params.authProfileType ?? "oauth";
2831
return {
2932
provider: params.provider,
3033
modelId: "gpt-5.4",
@@ -40,15 +43,24 @@ function createAttemptParams(params: {
4043
profiles: Object.fromEntries(
4144
Object.entries(authProfileProviders).map(([profileId, provider]) => [
4245
profileId,
43-
{
44-
type: "oauth" as const,
45-
provider,
46-
access: "access-token",
47-
refresh: "refresh-token",
48-
expires: Date.now() + 60_000,
49-
},
46+
authProfileType === "api_key"
47+
? {
48+
type: "api_key" as const,
49+
provider,
50+
key: "sk-test",
51+
}
52+
: {
53+
type: "oauth" as const,
54+
provider,
55+
access: "access-token",
56+
refresh: "refresh-token",
57+
expires: Date.now() + 60_000,
58+
},
5059
]),
5160
),
61+
...(params.runtimeExternalProfileIds
62+
? { runtimeExternalProfileIds: params.runtimeExternalProfileIds }
63+
: {}),
5264
},
5365
} as EmbeddedRunAttemptParams;
5466
}
@@ -578,7 +590,11 @@ describe("Codex app-server model provider selection", () => {
578590
"omits public %s modelProvider when forwarding native Codex auth on thread/start",
579591
(provider) => {
580592
const request = buildThreadStartParams(
581-
createAttemptParams({ provider, authProfileId: "work" }),
593+
createAttemptParams({
594+
provider,
595+
authProfileId: "work",
596+
runtimeExternalProfileIds: ["work"],
597+
}),
582598
{
583599
cwd: "/repo",
584600
dynamicTools: [],
@@ -596,6 +612,7 @@ describe("Codex app-server model provider selection", () => {
596612
createAttemptParams({
597613
provider: "openai",
598614
authProfileProviders: { bound: "openai" },
615+
runtimeExternalProfileIds: ["bound"],
599616
}),
600617
{
601618
threadId: "thread-1",
@@ -613,6 +630,7 @@ describe("Codex app-server model provider selection", () => {
613630
createAttemptParams({
614631
provider: "openai",
615632
authProfileId: "openai:work",
633+
authProfileType: "api_key",
616634
authProfileProvider: "openai",
617635
}),
618636
{
@@ -626,6 +644,24 @@ describe("Codex app-server model provider selection", () => {
626644
expect(request.modelProvider).toBe("openai");
627645
});
628646

647+
it("omits public OpenAI modelProvider for persisted Codex OAuth profiles", () => {
648+
const request = buildThreadStartParams(
649+
createAttemptParams({
650+
provider: "openai",
651+
authProfileId: "openai:work",
652+
authProfileProvider: "openai",
653+
}),
654+
{
655+
cwd: "/repo",
656+
dynamicTools: [],
657+
appServer: createAppServerOptions() as never,
658+
developerInstructions: "test instructions",
659+
},
660+
);
661+
662+
expect(request).not.toHaveProperty("modelProvider");
663+
});
664+
629665
it("keeps public OpenAI modelProvider when no native Codex auth profile is selected", () => {
630666
const request = buildThreadStartParams(createAttemptParams({ provider: "openai" }), {
631667
cwd: "/repo",

0 commit comments

Comments
 (0)