removed unused call_discovered_tool
This commit is contained in:
parent
770f141cbf
commit
097df699eb
3 changed files with 1 additions and 118 deletions
|
|
@ -341,9 +341,6 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
||||||
if useBM25 {
|
if useBM25 {
|
||||||
agent.Tools.Register(tools.NewBM25SearchTool(agent.Tools, ttl, maxSearchResults))
|
agent.Tools.Register(tools.NewBM25SearchTool(agent.Tools, ttl, maxSearchResults))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always record the fallback
|
|
||||||
agent.Tools.Register(tools.NewCallDiscoveredTool(agent.Tools, ttl))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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.
|
// ToolSearchResult represents the result returned to the LLM.
|
||||||
type ToolSearchResult struct {
|
type ToolSearchResult struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
@ -217,7 +154,7 @@ func formatDiscoveryResponse(registry *ToolRegistry, results []ToolSearchResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf(
|
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),
|
len(results),
|
||||||
string(b),
|
string(b),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func TestToolRegistry_SearchLimitsAndCoreFiltering(t *testing.T) {
|
||||||
reg := NewToolRegistry()
|
reg := NewToolRegistry()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue