Files
OmniRoute/tests/unit/responses-chat-translation-gaps.test.ts
Gioxa 29080e0a00 fix(translator): translate Codex agent messages for Chat (#9171)
Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates green: static + changed tests + vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-213228-suite.log
2026-08-05 21:44:11 -03:00

233 lines
7.0 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
const { openaiResponsesToOpenAIRequest } =
await import("../../open-sse/translator/request/openai-responses.ts");
function translate(body: Record<string, unknown>): Record<string, unknown> {
return openaiResponsesToOpenAIRequest("gpt-5", body, false, null) as Record<string, unknown>;
}
test("Responses -> Chat preserves json_schema structured output", () => {
const result = translate({
input: "Return JSON",
text: {
format: {
type: "json_schema",
name: "answer",
description: "Structured answer",
schema: { type: "object", properties: { answer: { type: "string" } } },
strict: true,
},
},
});
assert.deepEqual(result.response_format, {
type: "json_schema",
json_schema: {
name: "answer",
description: "Structured answer",
schema: { type: "object", properties: { answer: { type: "string" } } },
strict: true,
},
});
assert.equal(result.text, undefined);
});
test("Responses -> Chat preserves json_object structured output", () => {
const result = translate({ input: "Return JSON", text: { format: { type: "json_object" } } });
assert.deepEqual(result.response_format, { type: "json_object" });
assert.equal(result.text, undefined);
});
test("Responses -> Chat restricts tools selected by allowed_tools", () => {
const result = translate({
input: "Use one tool",
tools: [
{ type: "function", name: "keep", parameters: { type: "object" } },
{ type: "function", name: "remove", parameters: { type: "object" } },
],
tool_choice: {
type: "allowed_tools",
mode: "required",
tools: [{ type: "function", name: "keep" }],
},
});
assert.equal(result.tool_choice, "required");
assert.deepEqual(
(result.tools as Array<{ function: { name: string } }>).map((tool) => tool.function.name),
["keep"]
);
});
test("Responses -> Chat resolves allowed_tools against flattened namespace tools", () => {
const result = translate({
input: "Use a namespaced tool",
tools: [
{
type: "namespace",
name: "server",
tools: [{ name: "mcp__server__read", parameters: { type: "object" } }],
},
],
tool_choice: {
type: "allowed_tools",
mode: "auto",
tools: [{ type: "function", name: "mcp__server__read" }],
},
});
assert.equal(result.tool_choice, "auto");
assert.equal(
(result.tools as Array<{ function: { name: string } }>)[0].function.name,
"mcp__server__read"
);
});
test("Responses -> Chat rejects malformed or unavailable allowed_tools", () => {
assert.throws(
() =>
translate({
input: "Use a tool",
tools: [{ type: "function", name: "available", parameters: { type: "object" } }],
tool_choice: {
type: "allowed_tools",
mode: "required",
tools: [{ type: "function", name: "missing" }],
},
}),
(error: unknown) =>
error instanceof Error &&
(error as Error & { errorType?: string }).errorType === "unsupported_feature"
);
assert.throws(
() =>
translate({
input: "Use a tool",
tools: [{ type: "function", name: "available", parameters: { type: "object" } }],
tool_choice: {
type: "allowed_tools",
mode: "required",
tools: [{ type: "web_search", name: "available" }],
},
}),
(error: unknown) =>
error instanceof Error &&
(error as Error & { errorType?: string }).errorType === "unsupported_feature"
);
});
test("Responses -> Chat rejects input item types without a lossless Chat equivalent", () => {
for (const item of [
{ type: "item_reference", id: "item_123" },
{ type: "computer_call_output", call_id: "call_1", output: {} },
{ type: "mcp_call", name: "remote", arguments: "{}" },
{ type: "web_search_call", id: "search_1" },
{ unexpected: true },
]) {
assert.throws(
() => translate({ input: [item] }),
(error: unknown) =>
error instanceof Error &&
(error as Error & { errorType?: string }).errorType === "unsupported_feature" &&
error.message.includes("input item type")
);
}
});
test("Responses -> Chat converts plaintext agent_message items to assistant history", () => {
const result = translate({
input: [
{ type: "message", role: "user", content: [{ type: "input_text", text: "Run the task" }] },
{
type: "agent_message",
author: "worker",
recipient: "parent",
content: [{ type: "input_text", text: "Task completed" }],
},
],
});
assert.deepEqual(result.messages, [
{ role: "user", content: [{ type: "text", text: "Run the task" }] },
{ role: "assistant", content: [{ type: "text", text: "Task completed" }] },
]);
});
test("Responses -> Chat skips encrypted or mixed agent_message items", () => {
const result = translate({
input: [
{ type: "message", role: "user", content: [{ type: "input_text", text: "Run the task" }] },
{
type: "agent_message",
author: "worker",
recipient: "parent",
content: [
{ type: "input_text", text: "Message Type: NEW_TASK\nPayload:\n" },
{ type: "encrypted_content", encrypted_content: "opaque" },
],
},
],
});
assert.deepEqual(result.messages, [
{ role: "user", content: [{ type: "text", text: "Run the task" }] },
]);
});
test("Responses -> Chat consumes additional_tools input items without emitting messages", () => {
const result = translate({
input: [
{ type: "message", role: "user", content: [{ type: "input_text", text: "Use it" }] },
{
type: "additional_tools",
tools: [{ type: "function", name: "extra", parameters: { type: "object" } }],
},
],
});
assert.equal((result.messages as unknown[]).length, 1);
assert.equal((result.tools as Array<{ function: { name: string } }>)[0].function.name, "extra");
});
test("Responses -> Chat converts refusal history to valid Chat text content", () => {
const result = translate({
input: [
{
type: "message",
role: "assistant",
content: [{ type: "refusal", refusal: "I cannot help with that." }],
},
],
});
assert.deepEqual(result.messages, [
{
role: "assistant",
content: [{ type: "text", text: "I cannot help with that." }],
},
]);
});
test("Responses -> Chat strips Responses-only execution and cache fields", () => {
const result = translate({
input: "Hello",
max_tool_calls: 3,
conversation: "conv_123",
prompt_cache_options: { retention: "24h" },
prompt_cache_retention: "24h",
metadata: { keep: true },
parallel_tool_calls: true,
});
assert.equal(result.max_tool_calls, undefined);
assert.equal(result.conversation, undefined);
assert.equal(result.prompt_cache_options, undefined);
assert.equal(result.prompt_cache_retention, undefined);
assert.deepEqual(result.metadata, { keep: true });
assert.equal(result.parallel_tool_calls, true);
});