Skip to content

Commit db85f7f

Browse files
Eva (agent)claude
authored andcommitted
fix: reset websocket lineage after final answers
1 parent 544c046 commit db85f7f

2 files changed

Lines changed: 73 additions & 8 deletions

File tree

src/agents/openai-ws-request.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,30 @@ function inputItemsStartWith(input: InputItem[], baseline: InputItem[]): boolean
7878
return baseline.every((item, index) => stringifyStable(item) === stringifyStable(input[index]));
7979
}
8080

81+
function responseInputEndedWithFinalAnswer(input: InputItem[]): boolean {
82+
const lastConversationItem = input.findLast(
83+
(item) =>
84+
item.type === "message" ||
85+
item.type === "function_call" ||
86+
item.type === "function_call_output",
87+
);
88+
return (
89+
lastConversationItem?.type === "message" &&
90+
lastConversationItem.role === "assistant" &&
91+
lastConversationItem.phase === "final_answer"
92+
);
93+
}
94+
95+
function suffixStartsNewUserTurn(input: InputItem[]): boolean {
96+
const firstConversationItem = input.find(
97+
(item) =>
98+
item.type === "message" ||
99+
item.type === "function_call" ||
100+
item.type === "function_call_output",
101+
);
102+
return firstConversationItem?.type === "message" && firstConversationItem.role === "user";
103+
}
104+
81105
export function planOpenAIWebSocketRequestPayload(params: {
82106
fullPayload: ResponseCreateEvent;
83107
previousRequestPayload?: ResponseCreateEvent;
@@ -97,14 +121,22 @@ export function planOpenAIWebSocketRequestPayload(params: {
97121
) {
98122
const baseline = [...previousInputItems, ...previousResponseInputItems];
99123
if (inputItemsStartWith(fullInputItems, baseline)) {
100-
return {
101-
mode: "incremental",
102-
payload: {
103-
...params.fullPayload,
104-
previous_response_id: params.previousResponseId,
105-
input: fullInputItems.slice(baseline.length),
106-
},
107-
};
124+
const incrementalInput = fullInputItems.slice(baseline.length);
125+
if (
126+
!(
127+
responseInputEndedWithFinalAnswer(previousResponseInputItems) &&
128+
suffixStartsNewUserTurn(incrementalInput)
129+
)
130+
) {
131+
return {
132+
mode: "incremental",
133+
payload: {
134+
...params.fullPayload,
135+
previous_response_id: params.previousResponseId,
136+
input: incrementalInput,
137+
},
138+
};
139+
}
108140
}
109141
}
110142

src/agents/openai-ws-stream.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,39 @@ describe("planOpenAIWebSocketRequestPayload", () => {
18351835
expect(plan.payload.input).toEqual([{ type: "message", role: "user", content: "Next" }]);
18361836
});
18371837

1838+
it("uses full context when a new user turn follows a final answer", () => {
1839+
const previousInputItems: InputItem[] = [{ type: "message", role: "user", content: "Fix X" }];
1840+
const previousRequest: ResponseCreateEvent = {
1841+
type: "response.create",
1842+
model: "gpt-5.4",
1843+
store: false,
1844+
instructions: "You are helpful.",
1845+
input: previousInputItems,
1846+
};
1847+
const previousResponseInputItems: InputItem[] = [
1848+
{ type: "message", role: "assistant", content: "Done — fixed X.", phase: "final_answer" },
1849+
];
1850+
const fullPayload: ResponseCreateEvent = {
1851+
...previousRequest,
1852+
input: [
1853+
...previousInputItems,
1854+
...previousResponseInputItems,
1855+
{ type: "message", role: "user", content: "Now inspect Y" },
1856+
],
1857+
};
1858+
1859+
const plan = planOpenAIWebSocketRequestPayload({
1860+
fullPayload,
1861+
previousRequestPayload: previousRequest,
1862+
previousResponseId: "resp_prev_final",
1863+
previousResponseInputItems,
1864+
});
1865+
1866+
expect(plan.mode).toBe("full_context");
1867+
expect(plan.payload.previous_response_id).toBeUndefined();
1868+
expect(plan.payload.input).toEqual(fullPayload.input);
1869+
});
1870+
18381871
it("falls back to full context when non-input fields differ", () => {
18391872
const previousInputItems: InputItem[] = [{ type: "message", role: "user", content: "Hello" }];
18401873
const previousRequest: ResponseCreateEvent = {

0 commit comments

Comments
 (0)