fix(auth): restore codex oauth error and resume handling

This commit is contained in:
Vincent Koc
2026-04-18 08:47:11 -07:00
committed by Peter Steinberger
parent a018257487
commit 4a4f52b097
4 changed files with 233 additions and 119 deletions

View File

@@ -11,7 +11,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { CodexServerNotification } from "./protocol.js";
import { runCodexAppServerAttempt, __testing } from "./run-attempt.js";
import { writeCodexAppServerBinding } from "./session-binding.js";
import { buildThreadResumeParams, buildTurnStartParams } from "./thread-lifecycle.js";
import {
buildThreadResumeParams,
buildTurnStartParams,
startOrResumeThread,
} from "./thread-lifecycle.js";
let tempDir: string;
@@ -512,4 +516,46 @@ describe("runCodexAppServerAttempt", () => {
}),
);
});
it("preserves the bound auth profile when resume params omit authProfileId", async () => {
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");
await writeCodexAppServerBinding(sessionFile, {
threadId: "thread-existing",
cwd: workspaceDir,
authProfileId: "openai-codex:bound",
model: "gpt-5.4-codex",
modelProvider: "openai",
});
const params = createParams(sessionFile, workspaceDir);
delete params.authProfileId;
const binding = await startOrResumeThread({
client: {
request: async (method) => {
if (method === "thread/resume") {
return { thread: { id: "thread-existing" }, modelProvider: "openai" };
}
throw new Error(`unexpected method: ${method}`);
},
} as never,
params,
cwd: workspaceDir,
dynamicTools: [],
appServer: {
start: {
transport: "stdio",
command: "codex",
args: ["app-server"],
headers: {},
},
requestTimeoutMs: 60_000,
approvalPolicy: "never",
approvalsReviewer: "user",
sandbox: "workspace-write",
},
});
expect(binding.authProfileId).toBe("openai-codex:bound");
});
});

View File

@@ -50,10 +50,11 @@ export async function startOrResumeThread(params: {
appServer: params.appServer,
}),
);
const boundAuthProfileId = params.params.authProfileId ?? binding.authProfileId;
await writeCodexAppServerBinding(params.params.sessionFile, {
threadId: response.thread.id,
cwd: params.cwd,
authProfileId: params.params.authProfileId,
authProfileId: boundAuthProfileId,
model: params.params.modelId,
modelProvider: response.modelProvider ?? normalizeModelProvider(params.params.provider),
dynamicToolsFingerprint,
@@ -63,7 +64,7 @@ export async function startOrResumeThread(params: {
...binding,
threadId: response.thread.id,
cwd: params.cwd,
authProfileId: params.params.authProfileId,
authProfileId: boundAuthProfileId,
model: params.params.modelId,
modelProvider: response.modelProvider ?? normalizeModelProvider(params.params.provider),
dynamicToolsFingerprint,