diff --git a/src/ResponseItemHistoryFallback.ts b/src/ResponseItemHistoryFallback.ts index eb6f7da..7dc7716 100644 --- a/src/ResponseItemHistoryFallback.ts +++ b/src/ResponseItemHistoryFallback.ts @@ -367,15 +367,16 @@ function createFunctionCallUpdate(item: JsonRecord): LegacyFunctionCallUpdate | return null; } + const isExecCommand = name === "exec_command"; const args = parseFunctionArguments(item["arguments"]); - const command = name === "exec_command" ? commandFromFunctionArguments(args) : null; - const cwd = name === "exec_command" ? cwdFromFunctionArguments(args) : ""; + const command = isExecCommand ? commandFromFunctionArguments(args) : null; + const cwd = isExecCommand ? cwdFromFunctionArguments(args) : ""; const commandAction = command ? inferCommandAction(command, cwd) : null; if (commandAction) { return { update: createCommandActionEvent(toolCallId, "inProgress", cwd, commandAction), usesTerminal: false, - isExecCommand: true, + isExecCommand, }; } @@ -389,13 +390,13 @@ function createFunctionCallUpdate(item: JsonRecord): LegacyFunctionCallUpdate | }; if (!functionCallUsesTerminal(item)) { - return { update, usesTerminal: false, isExecCommand: false }; + return { update, usesTerminal: false, isExecCommand }; } return { update: withTerminalContent(update, toolCallId, cwd), usesTerminal: true, - isExecCommand: true, + isExecCommand, }; } diff --git a/src/__tests__/CodexACPAgent/response-item-history-fallback.test.ts b/src/__tests__/CodexACPAgent/response-item-history-fallback.test.ts index f481088..7230179 100644 --- a/src/__tests__/CodexACPAgent/response-item-history-fallback.test.ts +++ b/src/__tests__/CodexACPAgent/response-item-history-fallback.test.ts @@ -19,6 +19,18 @@ describe("ResponseItemHistoryFallback", () => { ]); }); + it("does not recover function calls when all parsed tool call ids already exist", () => { + const updates = parseResponseItemHistoryFallback(jsonl([ + functionCall("call-existing-a", "rg \"ExistingA\" src"), + functionCallOutput("call-existing-a", "Chunk ID: existing-a\nProcess exited with code 0\nOutput:\nsrc/a.ts\n"), + functionCall("call-existing-b", "rg \"ExistingB\" src"), + functionCallOutput("call-existing-b", "Chunk ID: existing-b\nProcess exited with code 0\nOutput:\nsrc/b.ts\n"), + ]), "terminal_output", new Set(["call-existing-a", "call-existing-b"])); + + expect(toolCallIds(updates)).toEqual([]); + expect(toolCallUpdateStatuses(updates)).toEqual([]); + }); + it("does not duplicate adjacent reasoning from event and response item records", () => { const updates = parseResponseItemHistoryFallback(jsonl([ { @@ -53,6 +65,17 @@ describe("ResponseItemHistoryFallback", () => { { toolCallId: "call-read-failed", status: "failed" }, ]); }); + + it("marks exec command outputs without exit footers completed when they do not report errors", () => { + const updates = parseResponseItemHistoryFallback(jsonl([ + functionCall("call-read-ok", "cat existing.txt"), + functionCallOutput("call-read-ok", "existing file contents\n"), + ]), "terminal_output"); + + expect(toolCallUpdateStatuses(updates)).toEqual([ + { toolCallId: "call-read-ok", status: "completed" }, + ]); + }); }); function jsonl(records: unknown[]): string {