This commit is contained in:
afjcjsbx 2026-04-24 18:21:01 +02:00
parent 94a6b0c0f5
commit dce29c181f
2 changed files with 37 additions and 8 deletions

View file

@ -2,6 +2,7 @@ package api
import ( import (
"bufio" "bufio"
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"net/http" "net/http"
@ -593,7 +594,15 @@ func toolSummaryContainsContent(summary, content string) bool {
} }
_, body, hasBody := strings.Cut(summary, "\n") _, body, hasBody := strings.Cut(summary, "\n")
return hasBody && strings.TrimSpace(body) == content if !hasBody {
return false
}
body = strings.TrimSpace(body)
if body == content {
return true
}
firstSection, _, _ := strings.Cut(body, "\n```")
return strings.TrimSpace(firstSection) == content
} }
func sessionAttachments(msg providers.Message) []sessionChatAttachment { func sessionAttachments(msg providers.Message) []sessionChatAttachment {
@ -714,7 +723,8 @@ func visibleAssistantToolSummaryMessages(
Role: "assistant", Role: "assistant",
Content: utils.FormatToolFeedbackMessage( Content: utils.FormatToolFeedbackMessage(
name, name,
visibleAssistantToolSummaryText(tc, toolFeedbackMaxArgsLength), visibleAssistantToolFeedbackExplanation(tc, toolFeedbackMaxArgsLength),
visibleAssistantToolArgsPreview(tc, toolFeedbackMaxArgsLength),
), ),
}) })
} }
@ -722,7 +732,7 @@ func visibleAssistantToolSummaryMessages(
return messages return messages
} }
func visibleAssistantToolSummaryText( func visibleAssistantToolFeedbackExplanation(
tc providers.ToolCall, tc providers.ToolCall,
toolFeedbackMaxArgsLength int, toolFeedbackMaxArgsLength int,
) string { ) string {
@ -731,18 +741,32 @@ func visibleAssistantToolSummaryText(
return utils.Truncate(explanation, toolFeedbackMaxArgsLength) return utils.Truncate(explanation, toolFeedbackMaxArgsLength)
} }
} }
return ""
}
func visibleAssistantToolArgsPreview(
tc providers.ToolCall,
toolFeedbackMaxArgsLength int,
) string {
argsJSON := "" argsJSON := ""
if tc.Function != nil { if tc.Function != nil {
argsJSON = tc.Function.Arguments argsJSON = tc.Function.Arguments
} }
if strings.TrimSpace(argsJSON) == "" && len(tc.Arguments) > 0 { if strings.TrimSpace(argsJSON) == "" && len(tc.Arguments) > 0 {
if encodedArgs, err := json.Marshal(tc.Arguments); err == nil { if encodedArgs, err := json.MarshalIndent(tc.Arguments, "", " "); err == nil {
argsJSON = string(encodedArgs) argsJSON = string(encodedArgs)
} }
} }
argsJSON = strings.TrimSpace(argsJSON)
if argsJSON == "" {
return ""
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, []byte(argsJSON), "", " "); err == nil {
argsJSON = pretty.String()
}
return utils.Truncate(strings.TrimSpace(argsJSON), toolFeedbackMaxArgsLength) return utils.Truncate(argsJSON, toolFeedbackMaxArgsLength)
} }
func visibleAssistantToolMessages(toolCalls []providers.ToolCall) []sessionChatMessage { func visibleAssistantToolMessages(toolCalls []providers.ToolCall) []sessionChatMessage {

View file

@ -1056,8 +1056,11 @@ func TestHandleGetSession_UsesConfiguredToolFeedbackMaxArgsLength(t *testing.T)
if !strings.Contains(resp.Messages[1].Content, wantPreview) { if !strings.Contains(resp.Messages[1].Content, wantPreview) {
t.Fatalf("tool summary = %q, want preview %q", resp.Messages[1].Content, wantPreview) t.Fatalf("tool summary = %q, want preview %q", resp.Messages[1].Content, wantPreview)
} }
if strings.Contains(resp.Messages[1].Content, argsJSON) { wantArgsPreview := visibleAssistantToolArgsPreview(providers.ToolCall{
t.Fatalf("tool summary = %q, expected configured truncation", resp.Messages[1].Content) Function: &providers.FunctionCall{Arguments: argsJSON},
}, 20)
if !strings.Contains(resp.Messages[1].Content, wantArgsPreview) {
t.Fatalf("tool summary = %q, want args preview %q", resp.Messages[1].Content, wantArgsPreview)
} }
if !strings.Contains(resp.Messages[1].Content, "`read_file`") { if !strings.Contains(resp.Messages[1].Content, "`read_file`") {
t.Fatalf("tool summary = %q, want read_file summary", resp.Messages[1].Content) t.Fatalf("tool summary = %q, want read_file summary", resp.Messages[1].Content)
@ -1132,7 +1135,9 @@ func TestHandleGetSession_FallsBackToLegacyToolArgumentsWhenExplanationMissing(t
t.Fatalf("len(resp.Messages) = %d, want at least 2", len(resp.Messages)) t.Fatalf("len(resp.Messages) = %d, want at least 2", len(resp.Messages))
} }
wantPreview := utils.Truncate(argsJSON, 20) wantPreview := visibleAssistantToolArgsPreview(providers.ToolCall{
Function: &providers.FunctionCall{Arguments: argsJSON},
}, 20)
if !strings.Contains(resp.Messages[1].Content, "`read_file`") { if !strings.Contains(resp.Messages[1].Content, "`read_file`") {
t.Fatalf("tool summary = %q, want read_file summary", resp.Messages[1].Content) t.Fatalf("tool summary = %q, want read_file summary", resp.Messages[1].Content)
} }