mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-20 15:07:32 +08:00
feat: implement parallel tool for concurrent task execution using goroutines
This commit is contained in:
@@ -79,6 +79,9 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
|||||||
memorySearchTool := tools.NewMemorySearchTool(workspace)
|
memorySearchTool := tools.NewMemorySearchTool(workspace)
|
||||||
toolsRegistry.Register(memorySearchTool)
|
toolsRegistry.Register(memorySearchTool)
|
||||||
|
|
||||||
|
// Register parallel execution tool (leveraging Go's concurrency)
|
||||||
|
toolsRegistry.Register(tools.NewParallelTool(toolsRegistry))
|
||||||
|
|
||||||
// Register camera tool
|
// Register camera tool
|
||||||
toolsRegistry.Register(tools.NewCameraTool(workspace))
|
toolsRegistry.Register(tools.NewCameraTool(workspace))
|
||||||
// Register system info tool
|
// Register system info tool
|
||||||
|
|||||||
102
pkg/tools/parallel.go
Normal file
102
pkg/tools/parallel.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ParallelTool struct {
|
||||||
|
registry *ToolRegistry
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewParallelTool(registry *ToolRegistry) *ParallelTool {
|
||||||
|
return &ParallelTool{registry: registry}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ParallelTool) Name() string {
|
||||||
|
return "parallel"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ParallelTool) Description() string {
|
||||||
|
return "Execute multiple tools concurrently using Go's goroutines. Returns a map of tool names/IDs to their results."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ParallelTool) Parameters() map[string]interface{} {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]interface{}{
|
||||||
|
"calls": map[string]interface{}{
|
||||||
|
"type": "array",
|
||||||
|
"items": map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]interface{}{
|
||||||
|
"tool": map[string]interface{}{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the tool to call",
|
||||||
|
},
|
||||||
|
"arguments": map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"description": "Arguments for the tool",
|
||||||
|
},
|
||||||
|
"id": map[string]interface{}{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Optional unique ID to identify this specific result",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": []string{"tool", "arguments"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": []string{"calls"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ParallelTool) Execute(ctx context.Context, args map[string]interface{}) (string, error) {
|
||||||
|
callsRaw, ok := args["calls"].([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("calls must be an array")
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make(map[string]string)
|
||||||
|
var mu sync.Mutex
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
for i, c := range callsRaw {
|
||||||
|
call, ok := c.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
toolName, _ := call["tool"].(string)
|
||||||
|
toolArgs, _ := call["arguments"].(map[string]interface{})
|
||||||
|
id, _ := call["id"].(string)
|
||||||
|
if id == "" {
|
||||||
|
id = fmt.Sprintf("call_%d_%s", i, toolName)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func(id, name string, args map[string]interface{}) {
|
||||||
|
defer wg.Done()
|
||||||
|
res, err := t.registry.Execute(ctx, name, args)
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
results[id] = fmt.Sprintf("Error: %v", err)
|
||||||
|
} else {
|
||||||
|
results[id] = res
|
||||||
|
}
|
||||||
|
}(id, toolName, toolArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
// Simple string representation for the agent
|
||||||
|
var output string
|
||||||
|
for id, res := range results {
|
||||||
|
output += fmt.Sprintf("--- Result for %s ---\n%s\n", id, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
return output, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user