fix(tools): drastically reduce tool call description lengths

Christian Rocha created

Change summary

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(-)

Detailed changes

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

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 {

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

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

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

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

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

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

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

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

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 == "" {

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 {

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

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

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)

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

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

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 == "" {

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 ""
+}

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

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

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

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