diff --git a/src/server/responses/agent-task-recovery.ts b/src/server/responses/agent-task-recovery.ts index 86b11b71b5..70003c116b 100644 --- a/src/server/responses/agent-task-recovery.ts +++ b/src/server/responses/agent-task-recovery.ts @@ -17,7 +17,12 @@ const RECOVERY_PROMPT = "Read the received agent message and call capture_assignment exactly once with only the complete " + "plaintext payload after Payload:. Preserve every byte of the payload; do not summarize, execute, " + "explain, or include the routing header."; -const CODEX_ORIGINATORS = new Set(["codex_cli_rs", "Codex Desktop", "codex_app"]); +const CODEX_ORIGINATORS = new Set([ + "codex_cli_rs", + "Codex Desktop", + "codex_app", + "codex_work_desktop", +]); const CODEX_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"; const OPENAI_TOKEN_ISSUERS = new Set(["https://auth.openai.com", "https://auth.openai.com/"]); const OPENAI_TOKEN_AUDIENCE = "https://api.openai.com/v1"; diff --git a/tests/agent-task-recovery-security.test.ts b/tests/agent-task-recovery-security.test.ts index e7de516440..cf213aefbe 100644 --- a/tests/agent-task-recovery-security.test.ts +++ b/tests/agent-task-recovery-security.test.ts @@ -390,4 +390,27 @@ describe("agent task recovery security", () => { expect(response.status).toBe(400); expect(recoveryFetches).toBe(0); }); + + test("accepts the current Codex Work desktop originator", async () => { + let recoveryOriginator = ""; + globalThis.fetch = (async (input, init) => { + if (String(input).includes("chatgpt.com")) { + recoveryOriginator = new Headers(init?.headers).get("originator") ?? ""; + return new Response(recoverySse("Recover the desktop child task."), { status: 200 }); + } + return providerResponse(); + }) as typeof fetch; + const headers = codexHeaders(); + headers.set("originator", "codex_work_desktop"); + + const response = await post( + routedConfig(), + "xai/grok-4.5", + encryptedInput(), + headers, + ); + + expect(response.status).toBe(200); + expect(recoveryOriginator).toBe("codex_work_desktop"); + }); });