From 097df699eb83229655d065104a1fd026298c39a9 Mon Sep 17 00:00:00 2001 From: afjcjsbx Date: Sun, 8 Mar 2026 13:34:01 +0100 Subject: [PATCH] removed unused call_discovered_tool --- pkg/agent/loop.go | 3 -- pkg/tools/search_tool.go | 65 +--------------------------------- pkg/tools/search_tools_test.go | 51 -------------------------- 3 files changed, 1 insertion(+), 118 deletions(-) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 60941b2f0..5103085b5 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -341,9 +341,6 @@ func (al *AgentLoop) Run(ctx context.Context) error { if useBM25 { agent.Tools.Register(tools.NewBM25SearchTool(agent.Tools, ttl, maxSearchResults)) } - - // Always record the fallback - agent.Tools.Register(tools.NewCallDiscoveredTool(agent.Tools, ttl)) } } } diff --git a/pkg/tools/search_tool.go b/pkg/tools/search_tool.go index cb61f2f28..89f982d6e 100644 --- a/pkg/tools/search_tool.go +++ b/pkg/tools/search_tool.go @@ -99,69 +99,6 @@ func (t *BM25SearchTool) Execute(ctx context.Context, args map[string]any) *Tool return formatDiscoveryResponse(t.registry, t.registry.SearchBM25(query, t.maxSearchResults), t.ttl) } -type CallDiscoveredTool struct { - registry *ToolRegistry - ttl int -} - -func NewCallDiscoveredTool(r *ToolRegistry, ttl int) *CallDiscoveredTool { - return &CallDiscoveredTool{registry: r, ttl: ttl} -} - -func (t *CallDiscoveredTool) Name() string { - return "call_discovered_tool" -} - -func (t *CallDiscoveredTool) Description() string { - return "Fallback tool. Execute a tool found via search by passing its required arguments as a JSON object." -} - -func (t *CallDiscoveredTool) Parameters() map[string]any { - return map[string]any{ - "type": "object", - "properties": map[string]any{ - "tool_name": map[string]any{ - "type": "string", - }, - "arguments": map[string]any{ - "type": "object", - "description": "Arguments to pass to the tool", - }, - }, - "required": []string{"tool_name"}, - } -} - -func (t *CallDiscoveredTool) Execute(ctx context.Context, args map[string]any) *ToolResult { - name, ok := args["tool_name"].(string) - if !ok || name == "" { - return ErrorResult("Missing or invalid 'tool_name' argument") - } - - parsedArgs := make(map[string]any) - - // Check whether the key "arguments" exists in the payload - if argVal, exists := args["arguments"]; exists && argVal != nil { - // If it exists, we try to map cast it - var valid bool - parsedArgs, valid = argVal.(map[string]any) - if !valid { - // The LLM has passed something, but it is NOT a JSON object! - // We have to tell him clearly to get him to correct. - return ErrorResult(fmt.Sprintf( - "Invalid 'arguments' format for tool '%s'. Expected a JSON object, but got %T. Please fix and try again.", - name, - argVal, - )) - } - } - - // Renew the TTL to keep it visible if it is actively used - t.registry.PromoteTool(name, t.ttl) - - return t.registry.Execute(ctx, name, parsedArgs) -} - // ToolSearchResult represents the result returned to the LLM. type ToolSearchResult struct { Name string `json:"name"` @@ -217,7 +154,7 @@ func formatDiscoveryResponse(registry *ToolRegistry, results []ToolSearchResult, } msg := fmt.Sprintf( - "Found %d tools:\n%s\n\nSUCCESS: These tools have been temporarily UNLOCKED as native tools! In your next response, you can call them directly just like any normal tool, without needing 'call_discovered_tool'.", + "Found %d tools:\n%s\n\nSUCCESS: These tools have been temporarily UNLOCKED as native tools! In your next response, you can call them directly just like any normal tool", len(results), string(b), ) diff --git a/pkg/tools/search_tools_test.go b/pkg/tools/search_tools_test.go index a7f68fb3d..c1e2efbfc 100644 --- a/pkg/tools/search_tools_test.go +++ b/pkg/tools/search_tools_test.go @@ -138,57 +138,6 @@ func TestBM25SearchTool_Execute(t *testing.T) { }) } -func TestCallDiscoveredTool_Execute(t *testing.T) { - reg := setupPopulatedRegistry() - tool := NewCallDiscoveredTool(reg, 8) - ctx := context.Background() - - t.Run("Missing Name", func(t *testing.T) { - res := tool.Execute(ctx, map[string]any{"arguments": map[string]any{}}) - if !res.IsError { - t.Error("Expected error for missing tool_name") - } - }) - - t.Run("Invalid Arguments Type Fallback", func(t *testing.T) { - // If the LLM hallucinates and passes a string instead of an object/map, - // does a graceful fallback to empty map. - res := tool.Execute(ctx, map[string]any{ - "tool_name": "mcp_read_file", - "arguments": "invalid-string-instead-of-object", - }) - // It must be an error - if !res.IsError { - t.Fatalf("Expected an error for invalid argument type, but got success: %v", res.ForLLM) - } - // The error message should contain the explanation that we have added - if !strings.Contains(res.ForLLM, "Invalid 'arguments' format") { - t.Errorf("Expected instructional error message, got: %v", res.ForLLM) - } - }) - - t.Run("Successful Passthrough", func(t *testing.T) { - res := tool.Execute(ctx, map[string]any{ - "tool_name": "mcp_read_file", - "arguments": map[string]any{"path": "/tmp/test.txt"}, - }) - - if res.IsError { - t.Fatalf("Unexpected error: %v", res.ForLLM) - } - if !strings.Contains(res.ForLLM, "mock executed: mcp_read_file") { - t.Errorf("Expected underlying tool to be executed, got: %v", res.ForLLM) - } - - // The tool should renew the TTL of the tool called - reg.mu.RLock() - defer reg.mu.RUnlock() - if reg.tools["mcp_read_file"].TTL != 8 { - t.Errorf("Expected TTL to be renewed to 8") - } - }) -} - func TestToolRegistry_SearchLimitsAndCoreFiltering(t *testing.T) { reg := NewToolRegistry()