ZovOS_AI/internal/ai/manager.go
Dan4ick 460d20539f feat: initial project structure - Phase 1 MVP
- Project infrastructure: go.mod, Makefile, .gitignore, README
- Configuration system with YAML parsing and env overrides
- Structured logging with slog
- AI provider interface with Ollama, OpenAI, Anthropic implementations
- Provider manager with runtime switching
- Agent orchestrator with ReAct loop (reason-act-observe)
- Tool registry with JSON Schema descriptions
- Terminal tool: shell command execution with safety controls
- Filesystem tools: read, write, list with path access control
- Conversation memory with session management
- Web UI server with WebSocket streaming
- Modern dark theme UI with glassmorphism, animations
- Frontend: WebSocket client, markdown rendering, tool call display
2026-03-20 00:38:22 +03:00

83 lines
1.8 KiB
Go

package ai
import (
"fmt"
"log/slog"
"sync"
)
// Manager manages multiple AI providers and routes requests.
type Manager struct {
mu sync.RWMutex
providers map[string]Provider
active string
log *slog.Logger
}
// NewManager creates a new provider manager.
func NewManager(log *slog.Logger) *Manager {
return &Manager{
providers: make(map[string]Provider),
log: log,
}
}
// Register adds a provider to the manager.
func (m *Manager) Register(p Provider) {
m.mu.Lock()
defer m.mu.Unlock()
m.providers[p.Name()] = p
m.log.Info("registered AI provider", "name", p.Name(), "models", p.Models())
}
// SetActive sets the active provider by name.
func (m *Manager) SetActive(name string) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, ok := m.providers[name]; !ok {
return fmt.Errorf("unknown provider: %s", name)
}
m.active = name
m.log.Info("switched active provider", "name", name)
return nil
}
// Active returns the currently active provider.
func (m *Manager) Active() (Provider, error) {
m.mu.RLock()
defer m.mu.RUnlock()
p, ok := m.providers[m.active]
if !ok {
return nil, fmt.Errorf("no active provider set (active=%q)", m.active)
}
return p, nil
}
// ActiveName returns the name of the currently active provider.
func (m *Manager) ActiveName() string {
m.mu.RLock()
defer m.mu.RUnlock()
return m.active
}
// List returns names of all registered providers.
func (m *Manager) List() []string {
m.mu.RLock()
defer m.mu.RUnlock()
names := make([]string, 0, len(m.providers))
for name := range m.providers {
names = append(names, name)
}
return names
}
// Get returns a provider by name.
func (m *Manager) Get(name string) (Provider, error) {
m.mu.RLock()
defer m.mu.RUnlock()
p, ok := m.providers[name]
if !ok {
return nil, fmt.Errorf("unknown provider: %s", name)
}
return p, nil
}