fix: reduce max read size from 5mb to 1mb for view and fetch tools (#2447)

Andrey Nering created

5MB is way too much. Many models simply don't have the context windows
to handle that. 1MB seems to works well.

Worth noting that:

* For the view tool, the model will be instruced to read in pieces
* For the fetch tool, the content will be truncated with a note

To reproduce (I tested with Kimi K2.5), use the following prompt:

    read this: https://developers.openai.com/api/reference/resources/responses

Change summary

internal/agent/tools/fetch.go | 17 ++++++++---------
internal/agent/tools/view.go  |  6 +++---
2 files changed, 11 insertions(+), 12 deletions(-)

Detailed changes

internal/agent/tools/fetch.go 🔗

@@ -16,7 +16,10 @@ import (
 	"github.com/charmbracelet/crush/internal/permission"
 )
 
-const FetchToolName = "fetch"
+const (
+	FetchToolName = "fetch"
+	MaxFetchSize  = 1 * 1024 * 1024 // 1MB
+)
 
 //go:embed fetch.md
 var fetchDescription []byte
@@ -105,11 +108,7 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt
 				return fantasy.NewTextErrorResponse(fmt.Sprintf("Request failed with status code: %d", resp.StatusCode)), nil
 			}
 
-			// maxFetchResponseSizeBytes is the maximum size of response body to read (5MB)
-			const maxFetchResponseSizeBytes = int64(5 * 1024 * 1024)
-
-			maxSize := maxFetchResponseSizeBytes
-			body, err := io.ReadAll(io.LimitReader(resp.Body, maxSize))
+			body, err := io.ReadAll(io.LimitReader(resp.Body, MaxFetchSize))
 			if err != nil {
 				return fantasy.NewTextErrorResponse("Failed to read response body: " + err.Error()), nil
 			}
@@ -161,9 +160,9 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt
 				}
 			}
 			// truncate content if it exceeds max read size
-			if int64(len(content)) > MaxReadSize {
-				content = content[:MaxReadSize]
-				content += fmt.Sprintf("\n\n[Content truncated to %d bytes]", MaxReadSize)
+			if int64(len(content)) > MaxFetchSize {
+				content = content[:MaxFetchSize]
+				content += fmt.Sprintf("\n\n[Content truncated to %d bytes]", MaxFetchSize)
 			}
 
 			return fantasy.NewTextResponse(content), nil

internal/agent/tools/view.go 🔗

@@ -53,7 +53,7 @@ type ViewResponseMetadata struct {
 
 const (
 	ViewToolName     = "view"
-	MaxReadSize      = 5 * 1024 * 1024 // 5MB
+	MaxViewSize      = 1 * 1024 * 1024 // 1MB
 	DefaultReadLimit = 2000
 	MaxLineLength    = 2000
 )
@@ -155,9 +155,9 @@ func NewViewTool(
 			}
 
 			// Based on the specifications we should not limit the skills read.
-			if !isSkillFile && fileInfo.Size() > MaxReadSize {
+			if !isSkillFile && fileInfo.Size() > MaxViewSize {
 				return fantasy.NewTextErrorResponse(fmt.Sprintf("File is too large (%d bytes). Maximum size is %d bytes",
-					fileInfo.Size(), MaxReadSize)), nil
+					fileInfo.Size(), MaxViewSize)), nil
 			}
 
 			// Set default limit if not provided (no limit for SKILL.md files)