mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 21:02:12 +03:00
fix(sse): normalize assistant input_text to output_text in Codex Responses input (#6932)
codex-cli replays assistant history with content parts typed as `input_text`, but the Responses API only accepts `output_text` (or `refusal`) on assistant turns — `input_text` is user-only. `normalizeCodexMessageContentPart` previously only rewrote parts literally typed `text`, leaving explicit `input_text` on assistant turns untouched, which the Codex/OpenAI backend rejects with a 400. Rewrite explicit `input_text` (and `text`) to `output_text` on assistant-role parts, dropping the assistant-only `annotations`, `logprobs`, and `obfuscation` fields. Mode-agnostic, applies to all Codex models. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- fix(sse): `normalizeCodexMessageContentPart` now rewrites explicit `type: "input_text"` (not just `type: "text"`) to `output_text` on assistant-role Codex Responses input parts, so replayed assistant history sent by codex-cli as `input_text` is no longer rejected by the Codex/OpenAI backend (#6932)
|
||||
@@ -10,6 +10,15 @@ function normalizeCodexMessageContentPart(part: unknown, role: string): unknown
|
||||
|
||||
const record = { ...(part as JsonRecord) };
|
||||
if (record.type === "text") record.type = textPartTypeForRole(role);
|
||||
// Assistant history in the Responses API must use `output_text` (or `refusal`),
|
||||
// never `input_text` (which is user-only). codex-cli sends assistant turns as
|
||||
// `input_text`; normalize them so the Codex/OpenAI backend accepts the replay.
|
||||
if (role === "assistant" && (record.type === "input_text" || record.type === "text")) {
|
||||
record.type = "output_text";
|
||||
delete record.annotations;
|
||||
delete record.logprobs;
|
||||
delete record.obfuscation;
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,60 @@ test("Codex Responses input: null input normalizes to an empty list (not [null])
|
||||
assert.deepEqual(body.input, []);
|
||||
});
|
||||
|
||||
test("Codex Responses input: assistant history normalized to output_text (OpenAI/Codex rejects input_text on assistant turns)", () => {
|
||||
const body: Record<string, unknown> = {
|
||||
input: [
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
content: [
|
||||
{
|
||||
type: "input_text",
|
||||
text: "Previous assistant answer",
|
||||
annotations: [{ type: "url_citation", url: "https://example.com" }],
|
||||
logprobs: [{ token: "Previous" }],
|
||||
obfuscation: "opaque",
|
||||
},
|
||||
{ type: "scoped_content", scope: "internal", content: "Preserve me" },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "input_image", image_url: "https://example.com/image.png", detail: "high" },
|
||||
{ type: "input_file", file_id: "file_123" },
|
||||
],
|
||||
},
|
||||
{ type: "function_call", call_id: "call_123", name: "lookup", arguments: "{}" },
|
||||
{ type: "function_call_output", call_id: "call_123", output: "done" },
|
||||
],
|
||||
};
|
||||
|
||||
normalizeCodexResponsesInput(body);
|
||||
|
||||
assert.deepEqual(body.input, [
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "output_text", text: "Previous assistant answer" },
|
||||
{ type: "scoped_content", scope: "internal", content: "Preserve me" },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "input_image", image_url: "https://example.com/image.png", detail: "high" },
|
||||
{ type: "input_file", file_id: "file_123" },
|
||||
],
|
||||
},
|
||||
{ type: "function_call", call_id: "call_123", name: "lookup", arguments: "{}" },
|
||||
{ type: "function_call_output", call_id: "call_123", output: "done" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("Responses→Chat: null input normalizes to an empty list (not [null])", () => {
|
||||
assert.deepEqual(normalizeResponsesInputForChat(null), []);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user