From 2a29a7eba924167c0d346aeae4c76a11700411cc Mon Sep 17 00:00:00 2001 From: CrisisAlpha Date: Fri, 20 Feb 2026 14:44:40 +0800 Subject: [PATCH] fix(web_fetch): include fetched page content in ForLLM response The web_fetch tool's ForLLM field only returned metadata (byte count, extractor type, truncation status) but omitted the actual extracted text. This caused the LLM to never see fetched page content, making the tool effectively useless and causing repeated fetch loops. Append the extracted text content to ForLLM so the LLM can read and reason about fetched web pages. Fixes #388 Co-authored-by: Cursor --- pkg/tools/web.go | 2 +- pkg/tools/web_test.go | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pkg/tools/web.go b/pkg/tools/web.go index 1f5c58ea5..1c4a52721 100644 --- a/pkg/tools/web.go +++ b/pkg/tools/web.go @@ -477,7 +477,7 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]interface{}) resultJSON, _ := json.MarshalIndent(result, "", " ") return &ToolResult{ - ForLLM: fmt.Sprintf("Fetched %d bytes from %s (extractor: %s, truncated: %v)", len(text), urlStr, extractor, truncated), + ForLLM: fmt.Sprintf("Fetched %d bytes from %s (extractor: %s, truncated: %v)\n\n%s", len(text), urlStr, extractor, truncated, text), ForUser: string(resultJSON), } } diff --git a/pkg/tools/web_test.go b/pkg/tools/web_test.go index 7e6d62213..a4d259ae0 100644 --- a/pkg/tools/web_test.go +++ b/pkg/tools/web_test.go @@ -36,9 +36,14 @@ func TestWebTool_WebFetch_Success(t *testing.T) { t.Errorf("Expected ForUser to contain 'Test Page', got: %s", result.ForUser) } - // ForLLM should contain summary - if !strings.Contains(result.ForLLM, "bytes") && !strings.Contains(result.ForLLM, "extractor") { - t.Errorf("Expected ForLLM to contain summary, got: %s", result.ForLLM) + // ForLLM should contain summary metadata + if !strings.Contains(result.ForLLM, "bytes") || !strings.Contains(result.ForLLM, "extractor") { + t.Errorf("Expected ForLLM to contain summary metadata, got: %s", result.ForLLM) + } + + // ForLLM should contain the actual fetched page content + if !strings.Contains(result.ForLLM, "Test Page") { + t.Errorf("Expected ForLLM to contain actual page content 'Test Page', got: %s", result.ForLLM) } } @@ -68,9 +73,14 @@ func TestWebTool_WebFetch_JSON(t *testing.T) { } // ForUser should contain formatted JSON - if !strings.Contains(result.ForUser, "key") && !strings.Contains(result.ForUser, "value") { + if !strings.Contains(result.ForUser, "key") || !strings.Contains(result.ForUser, "value") { t.Errorf("Expected ForUser to contain JSON data, got: %s", result.ForUser) } + + // ForLLM should contain the actual JSON content, not just metadata + if !strings.Contains(result.ForLLM, "key") || !strings.Contains(result.ForLLM, "value") { + t.Errorf("Expected ForLLM to contain actual JSON content, got: %s", result.ForLLM) + } } // TestWebTool_WebFetch_InvalidURL verifies error handling for invalid URL @@ -224,7 +234,7 @@ func TestWebTool_WebFetch_HTMLExtraction(t *testing.T) { } // ForUser should contain extracted text (without script/style tags) - if !strings.Contains(result.ForUser, "Title") && !strings.Contains(result.ForUser, "Content") { + if !strings.Contains(result.ForUser, "Title") || !strings.Contains(result.ForUser, "Content") { t.Errorf("Expected ForUser to contain extracted text, got: %s", result.ForUser) } @@ -232,6 +242,11 @@ func TestWebTool_WebFetch_HTMLExtraction(t *testing.T) { if strings.Contains(result.ForUser, "