- Add bubbletea/lipgloss/glamour dependencies for TUI - Create internal/tui package with EventWriter, styles, and bubbletea Model - Support streaming output display in conversation window - Add right panel with statistics and active agent status - Implement multi-agent collaboration with sub-agents - Add AgentCallTool for delegating tasks to sub-agents - Support parallel tool execution with goroutines - Auto-discover sub-agents from ~/.orca/prompts/ directory - Fix orchestrator routing based on msg.To field - Add non-blocking event writer with timeout to prevent blocking
112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
// Package tool 定义 Tool 接口和工具管理系统。
|
|
//
|
|
// 工具是可以由智能体或 LLM 调用的原子能力。
|
|
// 每个工具都有名称、描述、参数模式(用于 LLM 函数调用)
|
|
// 和执行实际工作的 Execute 方法。
|
|
package tool
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// Manager 是管理工具注册和执行的安全注册表。
|
|
//
|
|
// 工具按名称(区分大小写)注册,可以通过管理器发现、
|
|
// 列出和调用。重复注册将返回错误。
|
|
type Manager struct {
|
|
mu sync.RWMutex
|
|
tools map[string]Tool
|
|
}
|
|
|
|
// NewManager 创建新的空工具管理器。
|
|
func NewManager() *Manager {
|
|
return &Manager{
|
|
tools: make(map[string]Tool),
|
|
}
|
|
}
|
|
|
|
// Register 将工具添加到管理器。如果已注册了同名工具,则返回错误。
|
|
func (m *Manager) Register(tool Tool) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
name := tool.Name()
|
|
if _, exists := m.tools[name]; exists {
|
|
return fmt.Errorf("tool %q is already registered", name)
|
|
}
|
|
|
|
m.tools[name] = tool
|
|
return nil
|
|
}
|
|
|
|
// Unregister 按名称从管理器中移除工具。
|
|
func (m *Manager) Unregister(name string) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
if _, exists := m.tools[name]; !exists {
|
|
return fmt.Errorf("tool %q is not registered", name)
|
|
}
|
|
|
|
delete(m.tools, name)
|
|
return nil
|
|
}
|
|
|
|
// Get 按名称检索工具。如果未找到则返回 false。
|
|
func (m *Manager) Get(name string) (Tool, bool) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
|
|
t, ok := m.tools[name]
|
|
return t, ok
|
|
}
|
|
|
|
// List 返回按名称排序的所有已注册工具。
|
|
func (m *Manager) List() []Tool {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
|
|
result := make([]Tool, 0, len(m.tools))
|
|
for _, t := range m.tools {
|
|
result = append(result, t)
|
|
}
|
|
|
|
sort.Slice(result, func(i, j int) bool {
|
|
return result[i].Name() < result[j].Name()
|
|
})
|
|
return result
|
|
}
|
|
|
|
// Execute 按名称查找工具并使用给定参数调用它。
|
|
// 如果未找到工具则返回错误。
|
|
func (m *Manager) Execute(name string, ctx context.Context, args map[string]interface{}) (*Result, error) {
|
|
tool, ok := m.Get(name)
|
|
if !ok {
|
|
return nil, fmt.Errorf("tool %q not found", name)
|
|
}
|
|
return tool.Execute(ctx, args)
|
|
}
|
|
|
|
// Count 返回已注册工具的数量。
|
|
func (m *Manager) Count() int {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
return len(m.tools)
|
|
}
|
|
|
|
// Names 返回按字母顺序排序的所有已注册工具名称。
|
|
func (m *Manager) Names() []string {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
|
|
names := make([]string, 0, len(m.tools))
|
|
for name := range m.tools {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
return names
|
|
}
|