(inputs []EditFileInput)
| 35 | } |
| 36 | |
| 37 | func RenderGroupedEditFileToolUse(inputs []EditFileInput) string { |
| 38 | if len(inputs) == 0 { |
| 39 | return "" |
| 40 | } |
| 41 | if len(inputs) == 1 { |
| 42 | in := inputs[0] |
| 43 | return RenderEditFileToolUse(in.FilePath, in.OldString, in.NewString, in.ReplaceAll) |
| 44 | } |
| 45 | type group struct { |
| 46 | filePath string |
| 47 | edits []EditFileInput |
| 48 | } |
| 49 | seen := map[string]int{} |
| 50 | var groups []group |
| 51 | for _, in := range inputs { |
| 52 | idx, ok := seen[in.FilePath] |
| 53 | if !ok { |
| 54 | seen[in.FilePath] = len(groups) |
| 55 | groups = append(groups, group{filePath: in.FilePath}) |
| 56 | idx = len(groups) - 1 |
| 57 | } |
| 58 | groups[idx].edits = append(groups[idx].edits, in) |
| 59 | } |
| 60 | parts := make([]string, 0, len(groups)) |
| 61 | for _, g := range groups { |
| 62 | if len(g.edits) == 1 { |
| 63 | in := g.edits[0] |
| 64 | parts = append(parts, RenderEditFileToolUse(in.FilePath, in.OldString, in.NewString, in.ReplaceAll)) |
| 65 | continue |
| 66 | } |
| 67 | oldLines := 0 |
| 68 | newLines := 0 |
| 69 | for _, edit := range g.edits { |
| 70 | oldLines += countDisplayLines(edit.OldString) |
| 71 | newLines += countDisplayLines(edit.NewString) |
| 72 | } |
| 73 | parts = append(parts, fmt.Sprintf("edit_file: %s (%d edits, [-]%d lines, [+]%d lines)", filepath.Base(g.filePath), len(g.edits), oldLines, newLines)) |
| 74 | } |
| 75 | return strings.Join(parts, "\n") |
| 76 | } |
| 77 | |
| 78 | func RenderEditFileToolResult(content string, isError bool) string { |
| 79 | if isError { |
nothing calls this directly
no test coverage detected