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() }