Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions open-sse/translator/helpers/openaiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ export function filterToOpenAIFormat(body) {
// Strip Claude-specific fields that OpenAI-compatible providers reject
delete body.metadata;
delete body.anthropic_version;
// Codex clients send a top-level `client_metadata` object; OpenAI rejects it
// with 400 "Unknown parameter: 'client_metadata'" (9router#1157).
delete body.client_metadata;

// Map max_output_tokens (from Vercel AI SDK) to max_tokens logic
if (body.max_output_tokens !== undefined) {
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/translator-strip-client-metadata-1157.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import test from "node:test";
import assert from "node:assert/strict";

const openaiHelper = await import("../../open-sse/translator/helpers/openaiHelper.ts");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using a dynamic import() at the top level of a test file is non-standard and bypasses static import benefits. Use a static import statement instead for better readability, standard static analysis, and tool compatibility.

Suggested change
const openaiHelper = await import("../../open-sse/translator/helpers/openaiHelper.ts");
import { filterToOpenAIFormat } from "../../open-sse/translator/helpers/openaiHelper.ts";


// Regression for upstream issue 9router#1157: Codex-origin requests carry a
// top-level `client_metadata` object. On the OpenAI->OpenAI chat-completions
// passthrough, `filterToOpenAIFormat` is the only sanitizer, and it forwarded
// `client_metadata` to api.openai.com, which rejects it with
// 400 "Unknown parameter: 'client_metadata'". It must be stripped alongside
// the other Claude/Codex-specific fields.
test("filterToOpenAIFormat strips top-level client_metadata (9router#1157)", () => {
const body = {
messages: [{ role: "user", content: "hi" }],
client_metadata: { user_id: "abc", session_id: "xyz" },
metadata: { remove: true },
anthropic_version: "2023-06-01",
};

const result = openaiHelper.filterToOpenAIFormat(body);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Update this line to use the statically imported filterToOpenAIFormat function directly.

  const result = filterToOpenAIFormat(body);


assert.equal("client_metadata" in result, false);
assert.equal("metadata" in result, false);
assert.equal("anthropic_version" in result, false);
assert.equal(result.messages.length, 1);
});
Loading