mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
feat(responses): degrade background mode to synchronous execution
OpenAI Responses API supports background: true for async/deferred runs (returns 202 with response_id + GET /responses/<id> polling). Implementing the full background contract requires queue/poll infrastructure that OmniRoute does not have as a forward proxy. Previously the translator rejected such requests with HTTP 400 "Unsupported Responses API feature: background mode is not supported by omniroute". This breaks clients that opportunistically set background=true for long-running tasks (Capy Captain Pro, Codex agents) even when the underlying execution would complete in a normal HTTP timeout window. Degrade silently: strip the background flag and run synchronously. The client receives the full response in one round-trip with status=completed. Clients that strictly require the async contract still observe a completed response on the first poll and can adapt. The existing test that asserted background=true throws is split into two: - the unsupported-tool-type branch keeps the throw assertion - the background branch now asserts the flag is stripped and translation completes with the expected messages Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,13 +77,21 @@ export function openaiResponsesToOpenAIRequest(
|
||||
}
|
||||
}
|
||||
|
||||
if (root.background) {
|
||||
throw unsupportedFeature(
|
||||
"Unsupported Responses API feature: background mode is not supported by omniroute"
|
||||
);
|
||||
}
|
||||
|
||||
const result: JsonRecord = { ...root };
|
||||
|
||||
// background: true requests a deferred Responses API run (the upstream
|
||||
// returns 202 with response_id and the client polls GET /responses/<id>).
|
||||
// OmniRoute is a forward proxy that streams responses synchronously —
|
||||
// implementing the queue/poll contract would require persistence and a
|
||||
// separate retrieval surface. Degrade silently: strip the flag and run
|
||||
// synchronously. The client receives the full response in one round-trip
|
||||
// with status=completed. Clients that set background=true opportunistically
|
||||
// (Capy Captain Pro, Codex agents) work unchanged. Clients that strictly
|
||||
// require the async contract still observe a completed response on the
|
||||
// first poll and can adapt.
|
||||
if (result.background !== undefined) {
|
||||
delete result.background;
|
||||
}
|
||||
const messages: JsonRecord[] = [];
|
||||
result.messages = messages;
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ test("Responses -> Chat filters orphan tool outputs and supports role-based mess
|
||||
});
|
||||
});
|
||||
|
||||
test("Responses -> Chat rejects unsupported built-in tools and background mode", () => {
|
||||
test("Responses -> Chat rejects unsupported built-in tools", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
openaiResponsesToOpenAIRequest(
|
||||
@@ -124,20 +124,26 @@ test("Responses -> Chat rejects unsupported built-in tools and background mode",
|
||||
),
|
||||
(error: any) => error.statusCode === 400 && error.errorType === "unsupported_feature"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() =>
|
||||
openaiResponsesToOpenAIRequest(
|
||||
"gpt-4o",
|
||||
{
|
||||
input: [],
|
||||
background: true,
|
||||
},
|
||||
false,
|
||||
null
|
||||
),
|
||||
(error: any) => error.statusCode === 400 && error.errorType === "unsupported_feature"
|
||||
test("Responses -> Chat strips background flag and degrades to synchronous execution", () => {
|
||||
// Previously this threw 400 unsupported_feature. OmniRoute is a forward proxy
|
||||
// and cannot host the deferred run + poll contract, so background=true is
|
||||
// silently dropped and the request runs synchronously. Clients that set the
|
||||
// flag opportunistically (Capy Captain Pro, Codex agents) work unchanged.
|
||||
const result = openaiResponsesToOpenAIRequest(
|
||||
"gpt-5.5",
|
||||
{
|
||||
input: [{ role: "user", content: [{ type: "input_text", text: "hi" }] }],
|
||||
background: true,
|
||||
},
|
||||
true,
|
||||
null
|
||||
);
|
||||
const r = result as Record<string, unknown>;
|
||||
assert.equal(r.background, undefined, "background flag must be stripped from output");
|
||||
assert.ok(Array.isArray(r.messages), "translation must complete and produce messages");
|
||||
assert.equal((r.messages as unknown[]).length, 1, "user message must be preserved");
|
||||
});
|
||||
|
||||
test("Chat -> Responses converts messages, tool calls, tool outputs, tools and pass-through params", () => {
|
||||
|
||||
Reference in New Issue
Block a user