fix(sse): preserve tools echo on response.completed lifecycle event (#8990) (#9003)

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
This commit is contained in:
Arnav Jaiswal
2026-08-06 06:12:18 +05:30
committed by GitHub
parent 19181567d4
commit c996dc93c2
3 changed files with 12 additions and 3 deletions

View File

@@ -0,0 +1 @@
- **fix(sse):** `stripResponsesLifecycleEcho` no longer strips `tools` from the `response.completed` snapshot — that terminal event is what Codex CLI rebuilds its tool list from, so stripping it left the client with zero tools. `tools` is still stripped from `response.created`/`response.in_progress`, and `instructions` (the >100KB size lever) is still stripped from all three ([#8990](https://github.com/diegosouzapw/OmniRoute/pull/8990))

View File

@@ -201,7 +201,10 @@ export function stripResponsesLifecycleEcho(parsed: unknown): boolean {
delete r.instructions;
changed = true;
}
if ("tools" in r) {
// Preserve tools on the terminal snapshot: response.completed is what
// Codex CLI rebuilds its tool list from (#8990). Same special-case as
// backfillResponsesCompletedOutput. Still stripped on created/in_progress.
if (obj.type !== "response.completed" && "tools" in r) {
delete r.tools;
changed = true;
}

View File

@@ -39,7 +39,10 @@ describe("stripResponsesLifecycleEcho", () => {
assert.deepEqual(event.response, {});
});
it("strips fields from response.completed (preserving usage)", () => {
it("strips instructions but PRESERVES tools on response.completed (#8990)", () => {
// response.completed is the terminal snapshot Codex CLI rebuilds its tool
// list from — stripping tools here left the client with zero tools. Same
// special-case precedent as backfillResponsesCompletedOutput.
const event = {
type: "response.completed",
response: {
@@ -54,8 +57,10 @@ describe("stripResponsesLifecycleEcho", () => {
const changed = stripResponsesLifecycleEcho(event);
assert.equal(changed, true);
// instructions is still stripped (the >100KB size lever, not reported broken).
assert.equal("instructions" in event.response, false);
assert.equal("tools" in event.response, false);
// tools MUST survive on the terminal snapshot.
assert.deepEqual(event.response.tools, [{ name: "bash" }]);
// Usage must survive — downstream tracking depends on it.
assert.deepEqual(event.response.usage, {
input_tokens: 100,