mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-14 19:02:17 +03:00
* fix(sse): stop dropping tool_search and stop leaking OpenAI-only params in Responses->Chat translation (#7532, #7533) #7532: `openai-responses.ts` unconditionally dropped `tool_search` when downgrading a Responses-shaped request to Chat Completions, hiding the tool from the model and breaking Codex's deferred/lazy tool-discovery protocol for any provider that gets downgraded (e.g. built-in providers like opencode-go). tool_search carries `execution: "client"` — the client resolves the call locally regardless of wire shape — so it is now mapped to a normal Chat function tool, mirroring the existing local_shell -> shell pattern in the same file, instead of being silently discarded. #7533: the same translator unconditionally copied two GPT-5/OpenAI-only fields (`verbosity`, `prompt_cache_key`) into the translated Chat body regardless of destination provider. A strict-protocol non-OpenAI upstream (NVIDIA confirmed by the reporter) 400s on unrecognized top-level parameters. Both fields are now gated on `credentials.provider === "openai"`, stripped otherwise; the existing OpenAI-destined behavior (needed for #517's prompt-caching fix) is preserved byte-identical via a dedicated sanity test. Regression tests: tests/unit/tool-search-filtered-responses-to-chat-7532.test.ts, tests/unit/verbosity-prompt-cache-key-provider-gate-7533.test.ts. Two existing tests that encoded the old buggy contract (unconditional tool_search drop / unconditional field leak with no credentials) were aligned to the corrected contract: tests/unit/translator-openai-responses-req.test.ts, tests/unit/openai-responses-verbosity.test.ts. Gates run green: file-size, complexity, cognitive-complexity, typecheck:core, lint (scoped to changed files), and the full touched-area unit test suite (329 tests, 0 failures). * fix(sse): keep prompt_cache_key/verbosity for the codex destination (#7533) The #7533 provider gate allowlisted only "openai", but /v1/responses routes EVERY request through this downgrade (handleResponsesCore -> convertResponsesApiFormat) regardless of provider, and codex is an OpenAI-operated upstream (chatgpt.com/backend-api/codex). Gating it out stripped prompt_cache_key for Codex and silently re-broke the prompt-cache affinity #517 exists to protect — with no test covering it. Allowlist is now {openai, codex} and carries two #517 regression guards. Non-OpenAI upstreams (NVIDIA) still get both fields stripped, per #7533.
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
/**
|
|
* Verbosity mapping across the OpenAI Chat <-> Responses request translators.
|
|
*
|
|
* Chat Completions carries GPT-5 verbosity as top-level `verbosity`; the Responses API
|
|
* nests it as `text.verbosity`. These tests pin both directions so the hint is not lost
|
|
* when a request crosses formats (e.g. a Chat client routed to a Responses backend).
|
|
*/
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
openaiToOpenAIResponsesRequest,
|
|
openaiResponsesToOpenAIRequest,
|
|
} from "../../open-sse/translator/request/openai-responses.ts";
|
|
|
|
function asRecord(value: unknown): Record<string, unknown> {
|
|
return value as Record<string, unknown>;
|
|
}
|
|
|
|
test("Chat -> Responses maps verbosity to text.verbosity", () => {
|
|
const out = asRecord(
|
|
openaiToOpenAIResponsesRequest(
|
|
"gpt-5.5",
|
|
{ model: "gpt-5.5", messages: [{ role: "user", content: "hi" }], verbosity: "low" },
|
|
true,
|
|
{}
|
|
)
|
|
);
|
|
assert.deepEqual(out.text, { verbosity: "low" });
|
|
assert.equal(out.verbosity, undefined);
|
|
});
|
|
|
|
test("Chat -> Responses ignores an invalid verbosity value", () => {
|
|
const out = asRecord(
|
|
openaiToOpenAIResponsesRequest(
|
|
"gpt-5.5",
|
|
{ model: "gpt-5.5", messages: [{ role: "user", content: "hi" }], verbosity: "loud" },
|
|
true,
|
|
{}
|
|
)
|
|
);
|
|
assert.equal(out.text, undefined);
|
|
});
|
|
|
|
test("Responses -> Chat maps text.verbosity to top-level verbosity and drops text", () => {
|
|
// #7533: verbosity is a GPT-5/OpenAI-only Chat Completions parameter and is only
|
|
// carried across for an OpenAI-destined request — pass `provider: "openai"` so this
|
|
// pins the real OpenAI-routed contract instead of the pre-#7533 unconditional one.
|
|
const out = asRecord(
|
|
openaiResponsesToOpenAIRequest(
|
|
"gpt-5.5",
|
|
{ model: "gpt-5.5", input: [{ role: "user", content: "hi" }], text: { verbosity: "high" } },
|
|
false,
|
|
{ provider: "openai" }
|
|
)
|
|
);
|
|
assert.equal(out.verbosity, "high");
|
|
assert.equal(out.text, undefined);
|
|
});
|
|
|
|
test("Responses -> Chat drops a stray non-verbosity text wrapper", () => {
|
|
const out = asRecord(
|
|
openaiResponsesToOpenAIRequest(
|
|
"gpt-5.5",
|
|
{ model: "gpt-5.5", input: [{ role: "user", content: "hi" }], text: { format: { type: "json" } } },
|
|
false,
|
|
{}
|
|
)
|
|
);
|
|
assert.equal(out.text, undefined);
|
|
assert.equal(out.verbosity, undefined);
|
|
});
|