mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-19 21:52:21 +03:00
fix(codex): preserve final_answer responses replay (#1965)
Integrated into release/v3.7.9
This commit is contained in:
committed by
GitHub
parent
64b1a20010
commit
2082ffbad5
@@ -1,4 +1,5 @@
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
const INTERNAL_ASSISTANT_PHASES = new Set(["commentary"]);
|
||||
|
||||
function toRecord(value: unknown): JsonRecord | null {
|
||||
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : null;
|
||||
@@ -15,9 +16,9 @@ export function isInternalAssistantMessage(record: JsonRecord): boolean {
|
||||
const phase = typeof record.phase === "string" ? record.phase.trim().toLowerCase() : "";
|
||||
if (!phase) return false;
|
||||
|
||||
// OpenCode can send assistant-side commentary/analysis frames in Responses
|
||||
// shape. Those frames are local runtime state, not durable conversation turns.
|
||||
return phase !== "final";
|
||||
// Drop only known internal runtime frames. Visible assistant turns such as
|
||||
// `final` and `final_answer` must survive replay for Codex/OpenCode follow-ups.
|
||||
return INTERNAL_ASSISTANT_PHASES.has(phase);
|
||||
}
|
||||
|
||||
export function sanitizeResponsesInputItems(items: readonly unknown[], clone = true): unknown[] {
|
||||
|
||||
@@ -468,6 +468,57 @@ test("CodexExecutor.transformRequest does not replay internal assistant commenta
|
||||
assert.equal(result.input[3].type, "function_call_output");
|
||||
});
|
||||
|
||||
test("CodexExecutor.transformRequest preserves replayed assistant final_answer messages", () => {
|
||||
const executor = new CodexExecutor();
|
||||
rememberResponseConversationState(
|
||||
"resp_prev_final_answer_123",
|
||||
[
|
||||
{
|
||||
type: "message",
|
||||
role: "user",
|
||||
content: [{ type: "input_text", text: "9+10?" }],
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
phase: "final_answer",
|
||||
content: [{ type: "output_text", text: "19" }],
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const result = executor.transformRequest(
|
||||
"gpt-5.5-low",
|
||||
{
|
||||
_nativeCodexPassthrough: true,
|
||||
previous_response_id: "resp_prev_final_answer_123",
|
||||
input: [
|
||||
{
|
||||
type: "message",
|
||||
role: "user",
|
||||
content: [{ type: "input_text", text: "did you answered?" }],
|
||||
},
|
||||
],
|
||||
stream: false,
|
||||
},
|
||||
false,
|
||||
{ requestEndpointPath: "/responses" }
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
result.input.some((item) => JSON.stringify(item).includes('"text":"19"')),
|
||||
true
|
||||
);
|
||||
assert.equal(
|
||||
result.input.some((item) => {
|
||||
if (!item || typeof item !== "object" || Array.isArray(item)) return false;
|
||||
return item.role === "assistant" && item.phase === "final_answer";
|
||||
}),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
test("CodexExecutor.transformRequest strips raw internal assistant commentary without dropping useful Responses items", () => {
|
||||
const executor = new CodexExecutor();
|
||||
const body = {
|
||||
@@ -490,6 +541,12 @@ test("CodexExecutor.transformRequest strips raw internal assistant commentary wi
|
||||
phase: "final",
|
||||
content: [{ type: "output_text", text: "Visible final assistant answer." }],
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
phase: "final_answer",
|
||||
content: [{ type: "output_text", text: "Visible final_answer assistant answer." }],
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
role: "assistant",
|
||||
@@ -526,6 +583,12 @@ test("CodexExecutor.transformRequest strips raw internal assistant commentary wi
|
||||
result.input.some((item) => JSON.stringify(item).includes("Visible final assistant answer")),
|
||||
true
|
||||
);
|
||||
assert.equal(
|
||||
result.input.some((item) =>
|
||||
JSON.stringify(item).includes("Visible final_answer assistant answer")
|
||||
),
|
||||
true
|
||||
);
|
||||
assert.equal(
|
||||
result.input.some((item) =>
|
||||
JSON.stringify(item).includes("Visible assistant history without phase")
|
||||
|
||||
Reference in New Issue
Block a user