executeTool prints the tool-call line, optionally asks for confirmation, and dispatches to the registry.
(ctx context.Context, name, rawInput string)
| 142 | // executeTool prints the tool-call line, optionally asks for confirmation, |
| 143 | // and dispatches to the registry. |
| 144 | func (a *Agent) executeTool(ctx context.Context, name, rawInput string) (string, bool) { |
| 145 | fmt.Printf("%s[tool] %s %s\n", a.LogPrefix, name, rawInput) |
| 146 | src := "tool" |
| 147 | if a.Name != "" { |
| 148 | src = "tool/" + a.Name |
| 149 | } |
| 150 | reqID := debug.Recordp(src, debug.LevelInfo, |
| 151 | fmt.Sprintf("→ %s %s", name, truncate(rawInput, 200)), |
| 152 | rawInput) |
| 153 | |
| 154 | // Build the approval prompt. For write_file we additionally compute a |
| 155 | // unified diff against the current file contents; the UI shows that |
| 156 | // in a modal so the user can review the change before approving. |
| 157 | prompt, detail := "approve?", "" |
| 158 | if name == "write_file" { |
| 159 | if d := buildWriteDiff(rawInput); d != "" { |
| 160 | detail = d |
| 161 | if path := extractWritePath(rawInput); path != "" { |
| 162 | prompt = "approve write to " + path + "?" |
| 163 | } else { |
| 164 | prompt = "approve write?" |
| 165 | } |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | if a.Confirm != nil && !a.Confirm(prompt, detail) { |
| 170 | debug.Recordfc(reqID, src, debug.LevelWarn, "denied: %s", name) |
| 171 | return "user denied this tool call", true |
| 172 | } |
| 173 | |
| 174 | start := time.Now() |
| 175 | result, isErr := a.Tools.Execute(ctx, name, rawInput) |
| 176 | elapsed := time.Since(start).Round(time.Millisecond) |
| 177 | level := debug.LevelInfo |
| 178 | verdict := fmt.Sprintf("← %s (%v, %d bytes)", name, elapsed, len(result)) |
| 179 | if isErr { |
| 180 | level = debug.LevelError |
| 181 | verdict = fmt.Sprintf("← %s error (%v): %s", name, elapsed, truncate(result, 200)) |
| 182 | } |
| 183 | debug.Recordpc(reqID, src, level, verdict, result) |
| 184 | return result, isErr |
| 185 | } |
| 186 | |
| 187 | // compactorName returns a short label for whichever compaction strategy is |
| 188 | // active. Used in debug-log entries so it's obvious what ran. |
no test coverage detected