From 97b1c3efecc2d5f9050566f4e15596263a743ff7 Mon Sep 17 00:00:00 2001 From: David Siewert Date: Mon, 27 Apr 2026 15:42:18 +0600 Subject: [PATCH] fix duplicate toolFeedbackArgsPreview function declaration --- config/config.example.json | 4 +- pkg/agent/agent_test.go | 3 +- pkg/agent/agent_utils.go | 15 +---- pkg/agent/pipeline_execute.go | 4 +- pkg/config/config.go | 8 +-- pkg/config/defaults.go | 8 +-- tool_feedback.go | 86 ----------------------------- tool_feedback_test.go | 101 ---------------------------------- 8 files changed, 11 insertions(+), 218 deletions(-) delete mode 100644 tool_feedback.go delete mode 100644 tool_feedback_test.go diff --git a/config/config.example.json b/config/config.example.json index 665a6fd11..30460c231 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -14,9 +14,7 @@ "tool_feedback": { "enabled": false, "max_args_length": 300, - "separate_messages": false, - "pretty_print": true, - "disable_escape_html": true + "separate_messages": false } } }, diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 6e5bc8191..01657d43a 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -4519,8 +4519,7 @@ func TestRun_PicoToolFeedbackSuppressesDuplicateInterimAssistantContent(t *testi MaxTokens: 4096, MaxToolIterations: 10, ToolFeedback: config.ToolFeedbackConfig{ - Enabled: true, - PrettyPrint: true, + Enabled: true, }, }, }, diff --git a/pkg/agent/agent_utils.go b/pkg/agent/agent_utils.go index 90d9f43b9..8e42c1493 100644 --- a/pkg/agent/agent_utils.go +++ b/pkg/agent/agent_utils.go @@ -4,7 +4,6 @@ package agent import ( "context" - "encoding/json" "fmt" "maps" "path/filepath" @@ -177,19 +176,7 @@ func toolFeedbackArgsPreview(args map[string]any, maxLen int) string { args = map[string]any{} } - argsJSON, err := json.MarshalIndent(args, "", " ") - if err != nil { - return utils.Truncate(fmt.Sprintf("%v", args), maxLen) - } - return utils.Truncate(string(argsJSON), maxLen) -} - -func toolFeedbackArgsPreviewWithOptions(args map[string]any, maxLen int, prettyPrint, disableEscapeHTML bool) string { - if args == nil { - args = map[string]any{} - } - - argsJSON := utils.FormatArgsJSON(args, prettyPrint, disableEscapeHTML) + argsJSON := utils.FormatArgsJSON(args, true, false) return utils.Truncate(argsJSON, maxLen) } diff --git a/pkg/agent/pipeline_execute.go b/pkg/agent/pipeline_execute.go index ec3514f10..e1be2a74b 100644 --- a/pkg/agent/pipeline_execute.go +++ b/pkg/agent/pipeline_execute.go @@ -91,7 +91,7 @@ toolLoop: feedbackMsg := utils.FormatToolFeedbackMessage( toolName, toolFeedbackExplanation, - toolFeedbackArgsPreviewWithOptions(toolArgs, toolFeedbackMaxLen, al.cfg.Agents.Defaults.ToolFeedback.PrettyPrint, al.cfg.Agents.Defaults.ToolFeedback.DisableEscapeHTML), +toolFeedbackArgsPreview(toolArgs, toolFeedbackMaxLen), ) fbCtx, fbCancel := context.WithTimeout(turnCtx, 3*time.Second) _ = al.bus.PublishOutbound(fbCtx, outboundMessageForTurnWithKind(ts, feedbackMsg, messageKindToolFeedback)) @@ -373,7 +373,7 @@ toolLoop: feedbackMsg := utils.FormatToolFeedbackMessage( toolName, toolFeedbackExplanation, - toolFeedbackArgsPreviewWithOptions(toolArgs, toolFeedbackMaxLen, al.cfg.Agents.Defaults.ToolFeedback.PrettyPrint, al.cfg.Agents.Defaults.ToolFeedback.DisableEscapeHTML), + toolFeedbackArgsPreview(toolArgs, toolFeedbackMaxLen), ) fbCtx, fbCancel := context.WithTimeout(turnCtx, 3*time.Second) _ = al.bus.PublishOutbound(fbCtx, outboundMessageForTurnWithKind(ts, feedbackMsg, messageKindToolFeedback)) diff --git a/pkg/config/config.go b/pkg/config/config.go index b31c2b63d..48a1cccde 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -247,11 +247,9 @@ type SubTurnConfig struct { } type ToolFeedbackConfig struct { - Enabled bool `json:"enabled" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_ENABLED"` - MaxArgsLength int `json:"max_args_length" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_MAX_ARGS_LENGTH"` - SeparateMessages bool `json:"separate_messages" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_SEPARATE_MESSAGES"` - PrettyPrint bool `json:"pretty_print" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_PRETTY_PRINT"` - DisableEscapeHTML bool `json:"disable_escape_html" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_DISABLE_ESCAPE_HTML"` + Enabled bool `json:"enabled" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_ENABLED"` + MaxArgsLength int `json:"max_args_length" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_MAX_ARGS_LENGTH"` + SeparateMessages bool `json:"separate_messages" env:"PICOCLAW_AGENTS_DEFAULTS_TOOL_FEEDBACK_SEPARATE_MESSAGES"` } type AgentDefaults struct { diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 32e3cbbe1..f3aaca7ab 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -35,11 +35,9 @@ func DefaultConfig() *Config { SummarizeTokenPercent: 75, SteeringMode: "one-at-a-time", ToolFeedback: ToolFeedbackConfig{ - Enabled: false, - MaxArgsLength: 300, - SeparateMessages: false, - PrettyPrint: true, - DisableEscapeHTML: true, + Enabled: false, + MaxArgsLength: 300, + SeparateMessages: false, }, SplitOnMarker: false, }, diff --git a/tool_feedback.go b/tool_feedback.go deleted file mode 100644 index b8cf3c384..000000000 --- a/tool_feedback.go +++ /dev/null @@ -1,86 +0,0 @@ -package utils - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" -) - -const ToolFeedbackContinuationHint = "Continuing the current task." - -func FormatArgsJSON(args map[string]any, prettyPrint, disableEscapeHTML bool) string { - var buf bytes.Buffer - enc := json.NewEncoder(&buf) - if prettyPrint { - enc.SetIndent("", " ") - } - if disableEscapeHTML { - enc.SetEscapeHTML(false) - } - if err := enc.Encode(args); err != nil { - return "{}" - } - return strings.TrimSpace(buf.String()) -} - -func FormatToolFeedbackMessage(toolName, explanation, argsPreview string) string { - toolName = strings.TrimSpace(toolName) - explanation = strings.TrimSpace(explanation) - argsPreview = strings.TrimSpace(argsPreview) - - bodyLines := make([]string, 0, 2) - if explanation != "" { - bodyLines = append(bodyLines, explanation) - } - if argsPreview != "" { - bodyLines = append(bodyLines, "```json\n"+argsPreview+"\n```") - } - body := strings.Join(bodyLines, "\n") - - if toolName == "" { - return body - } - if body == "" { - return fmt.Sprintf("\U0001f527 `%s`", toolName) - } - - return fmt.Sprintf("\U0001f527 `%s`\n%s", toolName, body) -} - -func FitToolFeedbackMessage(content string, maxLen int) string { - content = strings.TrimSpace(content) - if content == "" || maxLen <= 0 { - return "" - } - if len([]rune(content)) <= maxLen { - return content - } - - firstLine, rest, hasRest := strings.Cut(content, "\n") - firstLine = strings.TrimSpace(firstLine) - rest = strings.TrimSpace(rest) - - if !hasRest || rest == "" { - return Truncate(firstLine, maxLen) - } - - if len([]rune(firstLine)) >= maxLen { - return Truncate(firstLine, maxLen) - } - - remaining := maxLen - len([]rune(firstLine)) - 1 - if remaining <= 0 { - return Truncate(firstLine, maxLen) - } - - return firstLine + "\n" + Truncate(rest, remaining) -} - -func Truncate(s string, maxLen int) string { - runes := []rune(s) - if len(runes) <= maxLen { - return s - } - return string(runes[:maxLen]) -} diff --git a/tool_feedback_test.go b/tool_feedback_test.go deleted file mode 100644 index ef76c1506..000000000 --- a/tool_feedback_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package utils - -import ( - "encoding/json" - "testing" -) - -func TestFormatArgsJSON_Defaults(t *testing.T) { - args := map[string]any{"path": "README.md", "line": 42} - got := FormatArgsJSON(args, false, false) - var gotVal, wantVal any - if err := json.Unmarshal([]byte(got), &gotVal); err != nil { - t.Fatalf("FormatArgsJSON() returned invalid JSON: %v", err) - } - want := `{"path":"README.md","line":42}` - if err := json.Unmarshal([]byte(want), &wantVal); err != nil { - t.Fatalf("invalid test want JSON: %v", err) - } - if !jsonValEq(gotVal, wantVal) { - t.Fatalf("FormatArgsJSON() = %q, want %q", got, want) - } -} - -func TestFormatArgsJSON_PrettyPrint(t *testing.T) { - args := map[string]any{"path": "README.md", "line": 42} - got := FormatArgsJSON(args, true, false) - var gotVal any - if err := json.Unmarshal([]byte(got), &gotVal); err != nil { - t.Fatalf("FormatArgsJSON() returned invalid JSON: %v", err) - } - want := `{"path":"README.md","line":42}` - var wantVal any - if err := json.Unmarshal([]byte(want), &wantVal); err != nil { - t.Fatalf("invalid test want JSON: %v", err) - } - if !jsonValEq(gotVal, wantVal) { - t.Fatalf("FormatArgsJSON() prettyPrint = %q, want structure %q", got, want) - } -} - -func TestFormatArgsJSON_DisableEscapeHTML(t *testing.T) { - args := map[string]any{"msg": "a < b && c > d"} - got := FormatArgsJSON(args, false, true) - var gotVal, wantVal any - want := `{"msg":"a < b && c > d"}` - if err := json.Unmarshal([]byte(got), &gotVal); err != nil { - t.Fatalf("FormatArgsJSON() returned invalid JSON: %v", err) - } - if err := json.Unmarshal([]byte(want), &wantVal); err != nil { - t.Fatalf("invalid test want JSON: %v", err) - } - if !jsonValEq(gotVal, wantVal) { - t.Fatalf("FormatArgsJSON() disableEscapeHTML = %q, want %q", got, want) - } -} - -func TestFormatArgsJSON_PrettyPrintAndDisableEscapeHTML(t *testing.T) { - args := map[string]any{"msg": "a < b && c > d"} - got := FormatArgsJSON(args, true, true) - var gotVal, wantVal any - want := `{"msg":"a < b && c > d"}` - if err := json.Unmarshal([]byte(got), &gotVal); err != nil { - t.Fatalf("FormatArgsJSON() returned invalid JSON: %v", err) - } - if err := json.Unmarshal([]byte(want), &wantVal); err != nil { - t.Fatalf("invalid test want JSON: %v", err) - } - if !jsonValEq(gotVal, wantVal) { - t.Fatalf("FormatArgsJSON() combined = %q, want %q", got, want) - } -} - -func TestFormatArgsJSON_EscapeHTMLByDefault(t *testing.T) { - args := map[string]any{"msg": "a < b && c > d"} - got := FormatArgsJSON(args, false, false) - var gotVal, wantVal any - want := `{"msg":"a \u003c b \u0026\u0026 c \u003e d"}` - if err := json.Unmarshal([]byte(got), &gotVal); err != nil { - t.Fatalf("FormatArgsJSON() returned invalid JSON: %v", err) - } - if err := json.Unmarshal([]byte(want), &wantVal); err != nil { - t.Fatalf("invalid test want JSON: %v", err) - } - if !jsonValEq(gotVal, wantVal) { - t.Fatalf("FormatArgsJSON() default escape = %q, want %q", got, want) - } -} - -func TestFormatArgsJSON_NilArgs(t *testing.T) { - got := FormatArgsJSON(nil, false, false) - want := `null` - if got != want { - t.Fatalf("FormatArgsJSON() nil = %q, want %q", got, want) - } -} - -func jsonValEq(a, b any) bool { - aJSON, _ := json.Marshal(a) - bJSON, _ := json.Marshal(b) - return string(aJSON) == string(bJSON) -}