From 0fb6af9354f4edcbd1cde35a9f949dc951bef778 Mon Sep 17 00:00:00 2001 From: pr-eval Date: Thu, 25 Jun 2026 18:43:58 +0200 Subject: [PATCH] fix(coding-agent): keep ast_grep/ast_edit patterns in transcript summaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding `paths` to the global PRIMARY_ARG_KEYS hid the pattern for the structural tools: ast_grep ({pat,paths}) and ast_edit ({ops,paths}) rendered scope-only (e.g. `ast_grep(src/**/*.ts)`), dropping `pat`/`ops` — the most decision-relevant argument. Drop the global `paths` key and special-case `find` (mirroring `search`) so find/search still surface scope while ast_grep/ast_edit keep showing their pattern via the existing fallback. Adds regression tests for both structural tools. --- .../src/session/session-history-format.ts | 5 +- .../session/session-history-format.test.ts | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/session/session-history-format.ts b/packages/coding-agent/src/session/session-history-format.ts index f577eea30..b089037c9 100644 --- a/packages/coding-agent/src/session/session-history-format.ts +++ b/packages/coding-agent/src/session/session-history-format.ts @@ -53,7 +53,6 @@ const PRIMARY_ARG_KEYS = [ "command", "cmd", "pattern", - "paths", "url", "query", "prompt", @@ -113,6 +112,10 @@ function primaryArg(name: string, args: Record | undefined): st if (pattern) return oneLine(pattern); if (paths) return oneLine(paths); } + if (name === "find") { + const paths = primaryArgValue(args.paths); + if (paths) return oneLine(paths); + } for (const key of PRIMARY_ARG_KEYS) { const value = args[key]; const summary = primaryArgValue(value); diff --git a/packages/coding-agent/test/session/session-history-format.test.ts b/packages/coding-agent/test/session/session-history-format.test.ts index 5ba1cc7c6..ba6f81e98 100644 --- a/packages/coding-agent/test/session/session-history-format.test.ts +++ b/packages/coding-agent/test/session/session-history-format.test.ts @@ -172,6 +172,64 @@ describe("formatSessionHistoryMarkdown", () => { ); }); + it("keeps the ast_grep pattern visible instead of only its paths scope", () => { + const output = formatSessionHistoryMarkdown([ + { + role: "assistant", + content: [ + { + type: "toolCall", + id: "tc-astgrep", + name: "ast_grep", + arguments: { pat: "console.log($$$)", paths: ["packages/coding-agent/src/**/*.ts"] }, + }, + ], + timestamp: 1, + }, + { + role: "toolResult", + toolCallId: "tc-astgrep", + toolName: "ast_grep", + content: [{ type: "text", text: "match" }], + isError: false, + timestamp: 2, + }, + ]); + + expect(output).toContain("→ ast_grep(console.log($$$)) ⇒ ok · 1 line"); + }); + + it("keeps the ast_edit op pattern visible instead of only its paths scope", () => { + const output = formatSessionHistoryMarkdown([ + { + role: "assistant", + content: [ + { + type: "toolCall", + id: "tc-astedit", + name: "ast_edit", + arguments: { + ops: [{ pat: "oldApi($$$A)", out: "newApi($$$A)" }], + paths: ["packages/coding-agent/src/**/*.ts"], + }, + }, + ], + timestamp: 1, + }, + { + role: "toolResult", + toolCallId: "tc-astedit", + toolName: "ast_edit", + content: [{ type: "text", text: "1 change" }], + isError: false, + timestamp: 2, + }, + ]); + + expect(output).toContain("oldApi($$$A)"); + expect(output).not.toContain("→ ast_edit(packages/coding-agent/src/**/*.ts)"); + }); + it("renders tool intent comments immediately before tool call lines when includeToolIntent is true", () => { const messages = [ {