ZovOS_AI/internal/app/app.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
3 KiB
Go

package app
import (
"fmt"
"log/slog"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/agent"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/ai"
aiAnthropic "git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/ai/anthropic"
aiOllama "git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/ai/ollama"
aiOpenAI "git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/ai/openai"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/config"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/tools"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/tools/filesystem"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/tools/terminal"
"git.bebrik.xyz/Dan4ick/ZovOS_AI/internal/ui"
)
// Run initializes all components and starts the application.
func Run(cfg *config.Config, log *slog.Logger) error {
// --- AI Providers ---
aiManager := ai.NewManager(log)
// Always register Ollama (local, no API key needed)
ollamaProvider := aiOllama.New(cfg.AI.Ollama, log)
aiManager.Register(ollamaProvider)
// Register cloud providers if API keys are configured
if cfg.AI.OpenAI.APIKey != "" {
openaiProvider := aiOpenAI.New(cfg.AI.OpenAI, log)
aiManager.Register(openaiProvider)
}
if cfg.AI.Anthropic.APIKey != "" {
anthropicProvider := aiAnthropic.New(cfg.AI.Anthropic, log)
aiManager.Register(anthropicProvider)
}
// Set active provider
if err := aiManager.SetActive(cfg.AI.DefaultProvider); err != nil {
// Fallback to ollama
log.Warn("default provider not available, falling back to ollama", "provider", cfg.AI.DefaultProvider, "error", err)
if err := aiManager.SetActive("ollama"); err != nil {
return fmt.Errorf("no AI providers available: %w", err)
}
}
// --- Tools ---
toolsRegistry := tools.NewRegistry(log)
terminal.RegisterTools(toolsRegistry, cfg.Tools.Terminal, log)
filesystem.RegisterTools(toolsRegistry, cfg.Tools.Filesystem, log)
log.Info("tools registered", "count", len(toolsRegistry.Names()), "tools", toolsRegistry.Names())
// --- Agent ---
activeProvider, err := aiManager.Active()
if err != nil {
return fmt.Errorf("getting active provider: %w", err)
}
ag := agent.New(activeProvider, toolsRegistry, cfg.Agent, log)
memory := agent.NewMemory()
// --- UI Server ---
server := ui.NewServer(cfg.Server, aiManager, ag, memory, log)
log.Info("ZovOS AI starting",
"provider", aiManager.ActiveName(),
"tools", toolsRegistry.Names(),
"address", fmt.Sprintf("http://%s:%d", cfg.Server.Host, cfg.Server.Port),
)
fmt.Printf("\n ╔══════════════════════════════════════════╗\n")
fmt.Printf(" ║ 🤖 ZovOS AI is running! ║\n")
fmt.Printf(" ║ ║\n")
fmt.Printf(" ║ Open: http://localhost:%d ║\n", cfg.Server.Port)
fmt.Printf(" ║ Provider: %-29s║\n", aiManager.ActiveName())
fmt.Printf(" ║ ║\n")
fmt.Printf(" ╚══════════════════════════════════════════╝\n\n")
return server.Start()
}