From f78baed0f06e40a3be64d21c69422ef8a6def832 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 Apr 2026 14:49:34 -0400 Subject: [PATCH] fix(tools): drastically reduce tool call description lengths --- internal/agent/agent_tool.go | 2 +- internal/agent/agentic_fetch_tool.go | 2 +- internal/agent/tools/diagnostics.go | 2 +- internal/agent/tools/download.go | 2 +- internal/agent/tools/edit.go | 2 +- internal/agent/tools/fetch.go | 2 +- internal/agent/tools/glob.go | 2 +- internal/agent/tools/grep.go | 2 +- internal/agent/tools/job_kill.go | 2 +- internal/agent/tools/job_output.go | 2 +- internal/agent/tools/list_mcp_resources.go | 2 +- internal/agent/tools/ls.go | 2 +- internal/agent/tools/lsp_restart.go | 2 +- internal/agent/tools/multiedit.go | 2 +- internal/agent/tools/read_mcp_resource.go | 2 +- internal/agent/tools/references.go | 2 +- internal/agent/tools/sourcegraph.go | 2 +- internal/agent/tools/todos.go | 2 +- internal/agent/tools/tools.go | 15 +++++++++++++++ internal/agent/tools/view.go | 2 +- internal/agent/tools/web_fetch.go | 2 +- internal/agent/tools/web_search.go | 2 +- internal/agent/tools/write.go | 2 +- 23 files changed, 37 insertions(+), 22 deletions(-) diff --git a/internal/agent/agent_tool.go b/internal/agent/agent_tool.go index 0d7677dee702b813e0a0d6f02e67837f084d5c29..05278e40dca5b5bd53e2b4722fd6ad9e6917a888 100644 --- a/internal/agent/agent_tool.go +++ b/internal/agent/agent_tool.go @@ -39,7 +39,7 @@ func (c *coordinator) agentTool(ctx context.Context) (fantasy.AgentTool, error) } return fantasy.NewParallelAgentTool( AgentToolName, - string(agentToolDescription), + tools.FirstLineDescription(agentToolDescription), func(ctx context.Context, params AgentParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Prompt == "" { return fantasy.NewTextErrorResponse("prompt is required"), nil diff --git a/internal/agent/agentic_fetch_tool.go b/internal/agent/agentic_fetch_tool.go index 03a3e116ebd5ff3784a67bbcf3304d2ce515ad1e..b0a478dbb29462bd3296c2e2d0f945303adf069c 100644 --- a/internal/agent/agentic_fetch_tool.go +++ b/internal/agent/agentic_fetch_tool.go @@ -65,7 +65,7 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) ( return fantasy.NewParallelAgentTool( tools.AgenticFetchToolName, - string(agenticFetchToolDescription), + tools.FirstLineDescription(agenticFetchToolDescription), func(ctx context.Context, params tools.AgenticFetchParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { validationResult, err := validateAgenticFetchParams(ctx, params) if err != nil { diff --git a/internal/agent/tools/diagnostics.go b/internal/agent/tools/diagnostics.go index 79b67be95d3312af47a7d5bc1765cc320a9894d1..801c1986e9a7d322c4ad3ca5dbdaec6eec856e1d 100644 --- a/internal/agent/tools/diagnostics.go +++ b/internal/agent/tools/diagnostics.go @@ -27,7 +27,7 @@ var diagnosticsDescription []byte func NewDiagnosticsTool(lspManager *lsp.Manager) fantasy.AgentTool { return fantasy.NewAgentTool( DiagnosticsToolName, - string(diagnosticsDescription), + FirstLineDescription(diagnosticsDescription), func(ctx context.Context, params DiagnosticsParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if lspManager.Clients().Len() == 0 { return fantasy.NewTextErrorResponse("no LSP clients available"), nil diff --git a/internal/agent/tools/download.go b/internal/agent/tools/download.go index def4968cababe0ffabbd88d929a692394bb86b36..c1384a13ccaa016f4436e7bc73514ea1bbabad1b 100644 --- a/internal/agent/tools/download.go +++ b/internal/agent/tools/download.go @@ -48,7 +48,7 @@ func NewDownloadTool(permissions permission.Service, workingDir string, client * } return fantasy.NewParallelAgentTool( DownloadToolName, - string(downloadDescription), + FirstLineDescription(downloadDescription), func(ctx context.Context, params DownloadParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.URL == "" { return fantasy.NewTextErrorResponse("URL parameter is required"), nil diff --git a/internal/agent/tools/edit.go b/internal/agent/tools/edit.go index 8d17902f097f6e0b4ebee7d0d684618c91bb0e04..a2292f6a00968cc2a8f25d8cf4628204a396b0dc 100644 --- a/internal/agent/tools/edit.go +++ b/internal/agent/tools/edit.go @@ -68,7 +68,7 @@ func NewEditTool( ) fantasy.AgentTool { return fantasy.NewAgentTool( EditToolName, - string(editDescription), + FirstLineDescription(editDescription), func(ctx context.Context, params EditParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.FilePath == "" { return fantasy.NewTextErrorResponse("file_path is required"), nil diff --git a/internal/agent/tools/fetch.go b/internal/agent/tools/fetch.go index e8d11d98ef930d5f8b77bd31ffd945199c93c69d..b9620567384fe992db29b492704862353fd3c3ba 100644 --- a/internal/agent/tools/fetch.go +++ b/internal/agent/tools/fetch.go @@ -39,7 +39,7 @@ func NewFetchTool(permissions permission.Service, workingDir string, client *htt return fantasy.NewParallelAgentTool( FetchToolName, - string(fetchDescription), + FirstLineDescription(fetchDescription), func(ctx context.Context, params FetchParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.URL == "" { return fantasy.NewTextErrorResponse("URL parameter is required"), nil diff --git a/internal/agent/tools/glob.go b/internal/agent/tools/glob.go index 641a84dd29ff6993b1fb54d0e5675dc3f5d56ae6..1db99fb5d306955a12e189c0ba23c93bd40630cc 100644 --- a/internal/agent/tools/glob.go +++ b/internal/agent/tools/glob.go @@ -34,7 +34,7 @@ type GlobResponseMetadata struct { func NewGlobTool(workingDir string) fantasy.AgentTool { return fantasy.NewAgentTool( GlobToolName, - string(globDescription), + FirstLineDescription(globDescription), func(ctx context.Context, params GlobParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Pattern == "" { return fantasy.NewTextErrorResponse("pattern is required"), nil diff --git a/internal/agent/tools/grep.go b/internal/agent/tools/grep.go index 8a894a4984ac7f90f89b8a2c7f1d1c637e79aecb..c4bbc9b134679ce97769984f3d00a9f89315d82d 100644 --- a/internal/agent/tools/grep.go +++ b/internal/agent/tools/grep.go @@ -105,7 +105,7 @@ func escapeRegexPattern(pattern string) string { func NewGrepTool(workingDir string, config config.ToolGrep) fantasy.AgentTool { return fantasy.NewAgentTool( GrepToolName, - string(grepDescription), + FirstLineDescription(grepDescription), func(ctx context.Context, params GrepParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Pattern == "" { return fantasy.NewTextErrorResponse("pattern is required"), nil diff --git a/internal/agent/tools/job_kill.go b/internal/agent/tools/job_kill.go index 575496d96714d34147e97b5ca2aefaacd6c68df5..90a44cb131da16a68a4c6cafcd0c6a3f7b2605a9 100644 --- a/internal/agent/tools/job_kill.go +++ b/internal/agent/tools/job_kill.go @@ -29,7 +29,7 @@ type JobKillResponseMetadata struct { func NewJobKillTool() fantasy.AgentTool { return fantasy.NewAgentTool( JobKillToolName, - string(jobKillDescription), + FirstLineDescription(jobKillDescription), func(ctx context.Context, params JobKillParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.ShellID == "" { return fantasy.NewTextErrorResponse("missing shell_id"), nil diff --git a/internal/agent/tools/job_output.go b/internal/agent/tools/job_output.go index 092fe3fea13cd7fe99004e1927167813f0ca6d87..1252d8c199783c77153478bcd9e3e67484fe0628 100644 --- a/internal/agent/tools/job_output.go +++ b/internal/agent/tools/job_output.go @@ -33,7 +33,7 @@ type JobOutputResponseMetadata struct { func NewJobOutputTool() fantasy.AgentTool { return fantasy.NewAgentTool( JobOutputToolName, - string(jobOutputDescription), + FirstLineDescription(jobOutputDescription), func(ctx context.Context, params JobOutputParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.ShellID == "" { return fantasy.NewTextErrorResponse("missing shell_id"), nil diff --git a/internal/agent/tools/list_mcp_resources.go b/internal/agent/tools/list_mcp_resources.go index 7ea8998a1dc80955b2a5b0a79d4aef7d19fb9011..90570f62b98976629fd7376fe5a8b4a643477649 100644 --- a/internal/agent/tools/list_mcp_resources.go +++ b/internal/agent/tools/list_mcp_resources.go @@ -31,7 +31,7 @@ var listMCPResourcesDescription []byte func NewListMCPResourcesTool(cfg *config.ConfigStore, permissions permission.Service) fantasy.AgentTool { return fantasy.NewParallelAgentTool( ListMCPResourcesToolName, - string(listMCPResourcesDescription), + FirstLineDescription(listMCPResourcesDescription), func(ctx context.Context, params ListMCPResourcesParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { params.MCPName = strings.TrimSpace(params.MCPName) if params.MCPName == "" { diff --git a/internal/agent/tools/ls.go b/internal/agent/tools/ls.go index 20bb1bad4c2d92bb02e564045d4553206ffd12a1..88def883e50a1355feee93585a6230511c520564 100644 --- a/internal/agent/tools/ls.go +++ b/internal/agent/tools/ls.go @@ -58,7 +58,7 @@ var lsDescription []byte func NewLsTool(permissions permission.Service, workingDir string, lsConfig config.ToolLs) fantasy.AgentTool { return fantasy.NewAgentTool( LSToolName, - string(lsDescription), + FirstLineDescription(lsDescription), func(ctx context.Context, params LSParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { searchPath, err := fsext.Expand(cmp.Or(params.Path, workingDir)) if err != nil { diff --git a/internal/agent/tools/lsp_restart.go b/internal/agent/tools/lsp_restart.go index 588f27bfe097326b99d6090067ad9b78243a3986..ebbca2d5f0c5619155935737f8a19c0d1ce6d3af 100644 --- a/internal/agent/tools/lsp_restart.go +++ b/internal/agent/tools/lsp_restart.go @@ -27,7 +27,7 @@ type LSPRestartParams struct { func NewLSPRestartTool(lspManager *lsp.Manager) fantasy.AgentTool { return fantasy.NewAgentTool( LSPRestartToolName, - string(lspRestartDescription), + FirstLineDescription(lspRestartDescription), func(ctx context.Context, params LSPRestartParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if lspManager.Clients().Len() == 0 { return fantasy.NewTextErrorResponse("no LSP clients available to restart"), nil diff --git a/internal/agent/tools/multiedit.go b/internal/agent/tools/multiedit.go index 28af9206a6485900dc05356c68bcdc091c01fe02..a491a179ff01cd27ea57e19d2cec6cfb323a4f96 100644 --- a/internal/agent/tools/multiedit.go +++ b/internal/agent/tools/multiedit.go @@ -66,7 +66,7 @@ func NewMultiEditTool( ) fantasy.AgentTool { return fantasy.NewAgentTool( MultiEditToolName, - string(multieditDescription), + FirstLineDescription(multieditDescription), func(ctx context.Context, params MultiEditParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.FilePath == "" { return fantasy.NewTextErrorResponse("file_path is required"), nil diff --git a/internal/agent/tools/read_mcp_resource.go b/internal/agent/tools/read_mcp_resource.go index c96b00194b92b05e40953a49a90c3453fe6b16b2..9a61a151a3e25606b32db051bc6f34d52e2ded05 100644 --- a/internal/agent/tools/read_mcp_resource.go +++ b/internal/agent/tools/read_mcp_resource.go @@ -33,7 +33,7 @@ var readMCPResourceDescription []byte func NewReadMCPResourceTool(cfg *config.ConfigStore, permissions permission.Service) fantasy.AgentTool { return fantasy.NewParallelAgentTool( ReadMCPResourceToolName, - string(readMCPResourceDescription), + FirstLineDescription(readMCPResourceDescription), func(ctx context.Context, params ReadMCPResourceParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { params.MCPName = strings.TrimSpace(params.MCPName) params.URI = strings.TrimSpace(params.URI) diff --git a/internal/agent/tools/references.go b/internal/agent/tools/references.go index aef683eb9dfee44b92e96cd3cb88b8654eb03b2a..d6fc03dfd933c71ef01e6d11662c88cc1c316b02 100644 --- a/internal/agent/tools/references.go +++ b/internal/agent/tools/references.go @@ -36,7 +36,7 @@ var referencesDescription []byte func NewReferencesTool(lspManager *lsp.Manager) fantasy.AgentTool { return fantasy.NewAgentTool( ReferencesToolName, - string(referencesDescription), + FirstLineDescription(referencesDescription), func(ctx context.Context, params ReferencesParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Symbol == "" { return fantasy.NewTextErrorResponse("symbol is required"), nil diff --git a/internal/agent/tools/sourcegraph.go b/internal/agent/tools/sourcegraph.go index e6d1014daf80aa062ebccead936b5f39bf2c5632..8effed6f65b033b475aec6ce41a7a8a64b801dee 100644 --- a/internal/agent/tools/sourcegraph.go +++ b/internal/agent/tools/sourcegraph.go @@ -45,7 +45,7 @@ func NewSourcegraphTool(client *http.Client) fantasy.AgentTool { } return fantasy.NewParallelAgentTool( SourcegraphToolName, - string(sourcegraphDescription), + FirstLineDescription(sourcegraphDescription), func(ctx context.Context, params SourcegraphParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Query == "" { return fantasy.NewTextErrorResponse("Query parameter is required"), nil diff --git a/internal/agent/tools/todos.go b/internal/agent/tools/todos.go index eb110420d9adc68f22eacdc69a68948b49da988f..2f69f7bf84581d9f0e0776d73660bef7ba34ba43 100644 --- a/internal/agent/tools/todos.go +++ b/internal/agent/tools/todos.go @@ -36,7 +36,7 @@ type TodosResponseMetadata struct { func NewTodosTool(sessions session.Service) fantasy.AgentTool { return fantasy.NewAgentTool( TodosToolName, - string(todosDescription), + FirstLineDescription(todosDescription), func(ctx context.Context, params TodosParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { sessionID := GetSessionFromContext(ctx) if sessionID == "" { diff --git a/internal/agent/tools/tools.go b/internal/agent/tools/tools.go index 50a2f7af24f9b1bc920fb88bc9a0df1123db9ebc..88e70008110e23b7f9c6afa125ef6daaa306cb35 100644 --- a/internal/agent/tools/tools.go +++ b/internal/agent/tools/tools.go @@ -2,6 +2,7 @@ package tools import ( "context" + "strings" ) type ( @@ -54,3 +55,17 @@ func GetSupportsImagesFromContext(ctx context.Context) bool { func GetModelNameFromContext(ctx context.Context) string { return getContextValue(ctx, ModelNameContextKey, "") } + +// FirstLineDescription returns the first non-empty line from the embedded +// markdown description. This extracts just the concise summary line, +// significantly reducing token usage while preserving essential tool context. +func FirstLineDescription(content []byte) string { + lines := strings.Split(string(content), "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if line != "" { + return line + } + } + return "" +} diff --git a/internal/agent/tools/view.go b/internal/agent/tools/view.go index dc05e53bc1eb9e947e994827886f57971be4219e..37e3c3a1ead9ff53455f2447272cf0be60c734d2 100644 --- a/internal/agent/tools/view.go +++ b/internal/agent/tools/view.go @@ -69,7 +69,7 @@ func NewViewTool( ) fantasy.AgentTool { return fantasy.NewAgentTool( ViewToolName, - string(viewDescription), + FirstLineDescription(viewDescription), func(ctx context.Context, params ViewParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.FilePath == "" { return fantasy.NewTextErrorResponse("file_path is required"), nil diff --git a/internal/agent/tools/web_fetch.go b/internal/agent/tools/web_fetch.go index 3f9849724ff9a5deef9131482c2527a55b550098..1b09012db9c7dd95ef322dbb41b2fb2fd4d7a3b7 100644 --- a/internal/agent/tools/web_fetch.go +++ b/internal/agent/tools/web_fetch.go @@ -31,7 +31,7 @@ func NewWebFetchTool(workingDir string, client *http.Client) fantasy.AgentTool { return fantasy.NewParallelAgentTool( WebFetchToolName, - string(webFetchToolDescription), + FirstLineDescription(webFetchToolDescription), func(ctx context.Context, params WebFetchParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.URL == "" { return fantasy.NewTextErrorResponse("url is required"), nil diff --git a/internal/agent/tools/web_search.go b/internal/agent/tools/web_search.go index e441aeebad9d699bb1fa33330b2d70559ae868ff..45541154783a98ad5a61ee5240b8c0ddf8f18f79 100644 --- a/internal/agent/tools/web_search.go +++ b/internal/agent/tools/web_search.go @@ -29,7 +29,7 @@ func NewWebSearchTool(client *http.Client) fantasy.AgentTool { return fantasy.NewParallelAgentTool( WebSearchToolName, - string(webSearchToolDescription), + FirstLineDescription(webSearchToolDescription), func(ctx context.Context, params WebSearchParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.Query == "" { return fantasy.NewTextErrorResponse("query is required"), nil diff --git a/internal/agent/tools/write.go b/internal/agent/tools/write.go index fbc2b8f11e9a84a9848af8eba5d2c2d1aa8ca258..5158a361c84c9365ea4f86000ba3ac5cb8760e35 100644 --- a/internal/agent/tools/write.go +++ b/internal/agent/tools/write.go @@ -52,7 +52,7 @@ func NewWriteTool( ) fantasy.AgentTool { return fantasy.NewAgentTool( WriteToolName, - string(writeDescription), + FirstLineDescription(writeDescription), func(ctx context.Context, params WriteParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) { if params.FilePath == "" { return fantasy.NewTextErrorResponse("file_path is required"), nil