Skip to content

Commit 302e995

Browse files
authored
fix: keep exec command fallback tracking consistent (#220)
* fix: keep exec command fallback tracking consistent * Test response item history fallback statuses
1 parent 94712ca commit 302e995

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

src/ResponseItemHistoryFallback.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,16 @@ function createFunctionCallUpdate(item: JsonRecord): LegacyFunctionCallUpdate |
367367
return null;
368368
}
369369

370+
const isExecCommand = name === "exec_command";
370371
const args = parseFunctionArguments(item["arguments"]);
371-
const command = name === "exec_command" ? commandFromFunctionArguments(args) : null;
372-
const cwd = name === "exec_command" ? cwdFromFunctionArguments(args) : "";
372+
const command = isExecCommand ? commandFromFunctionArguments(args) : null;
373+
const cwd = isExecCommand ? cwdFromFunctionArguments(args) : "";
373374
const commandAction = command ? inferCommandAction(command, cwd) : null;
374375
if (commandAction) {
375376
return {
376377
update: createCommandActionEvent(toolCallId, "inProgress", cwd, commandAction),
377378
usesTerminal: false,
378-
isExecCommand: true,
379+
isExecCommand,
379380
};
380381
}
381382

@@ -389,13 +390,13 @@ function createFunctionCallUpdate(item: JsonRecord): LegacyFunctionCallUpdate |
389390
};
390391

391392
if (!functionCallUsesTerminal(item)) {
392-
return { update, usesTerminal: false, isExecCommand: false };
393+
return { update, usesTerminal: false, isExecCommand };
393394
}
394395

395396
return {
396397
update: withTerminalContent(update, toolCallId, cwd),
397398
usesTerminal: true,
398-
isExecCommand: true,
399+
isExecCommand,
399400
};
400401
}
401402

src/__tests__/CodexACPAgent/response-item-history-fallback.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ describe("ResponseItemHistoryFallback", () => {
1919
]);
2020
});
2121

22+
it("does not recover function calls when all parsed tool call ids already exist", () => {
23+
const updates = parseResponseItemHistoryFallback(jsonl([
24+
functionCall("call-existing-a", "rg \"ExistingA\" src"),
25+
functionCallOutput("call-existing-a", "Chunk ID: existing-a\nProcess exited with code 0\nOutput:\nsrc/a.ts\n"),
26+
functionCall("call-existing-b", "rg \"ExistingB\" src"),
27+
functionCallOutput("call-existing-b", "Chunk ID: existing-b\nProcess exited with code 0\nOutput:\nsrc/b.ts\n"),
28+
]), "terminal_output", new Set(["call-existing-a", "call-existing-b"]));
29+
30+
expect(toolCallIds(updates)).toEqual([]);
31+
expect(toolCallUpdateStatuses(updates)).toEqual([]);
32+
});
33+
2234
it("does not duplicate adjacent reasoning from event and response item records", () => {
2335
const updates = parseResponseItemHistoryFallback(jsonl([
2436
{
@@ -53,6 +65,17 @@ describe("ResponseItemHistoryFallback", () => {
5365
{ toolCallId: "call-read-failed", status: "failed" },
5466
]);
5567
});
68+
69+
it("marks exec command outputs without exit footers completed when they do not report errors", () => {
70+
const updates = parseResponseItemHistoryFallback(jsonl([
71+
functionCall("call-read-ok", "cat existing.txt"),
72+
functionCallOutput("call-read-ok", "existing file contents\n"),
73+
]), "terminal_output");
74+
75+
expect(toolCallUpdateStatuses(updates)).toEqual([
76+
{ toolCallId: "call-read-ok", status: "completed" },
77+
]);
78+
});
5679
});
5780

5881
function jsonl(records: unknown[]): string {

0 commit comments

Comments
 (0)