- 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
163 lines
3.6 KiB
Go
163 lines
3.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig `yaml:"server"`
|
|
AI AIConfig `yaml:"ai"`
|
|
Agent AgentConfig `yaml:"agent"`
|
|
Tools ToolsConfig `yaml:"tools"`
|
|
Logging LoggingConfig `yaml:"logging"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Host string `yaml:"host"`
|
|
Port int `yaml:"port"`
|
|
}
|
|
|
|
type AIConfig struct {
|
|
DefaultProvider string `yaml:"default_provider"`
|
|
Ollama OllamaConfig `yaml:"ollama"`
|
|
OpenAI OpenAIConfig `yaml:"openai"`
|
|
Anthropic AnthropicConfig `yaml:"anthropic"`
|
|
Google GoogleConfig `yaml:"google"`
|
|
}
|
|
|
|
type OllamaConfig struct {
|
|
BaseURL string `yaml:"base_url"`
|
|
Model string `yaml:"model"`
|
|
}
|
|
|
|
type OpenAIConfig struct {
|
|
APIKey string `yaml:"api_key"`
|
|
Model string `yaml:"model"`
|
|
BaseURL string `yaml:"base_url"`
|
|
}
|
|
|
|
type AnthropicConfig struct {
|
|
APIKey string `yaml:"api_key"`
|
|
Model string `yaml:"model"`
|
|
BaseURL string `yaml:"base_url"`
|
|
}
|
|
|
|
type GoogleConfig struct {
|
|
APIKey string `yaml:"api_key"`
|
|
Model string `yaml:"model"`
|
|
}
|
|
|
|
type AgentConfig struct {
|
|
MaxIterations int `yaml:"max_iterations"`
|
|
TimeoutSeconds int `yaml:"timeout_seconds"`
|
|
SystemPrompt string `yaml:"system_prompt"`
|
|
}
|
|
|
|
type ToolsConfig struct {
|
|
Terminal TerminalToolConfig `yaml:"terminal"`
|
|
Browser BrowserToolConfig `yaml:"browser"`
|
|
Desktop DesktopToolConfig `yaml:"desktop"`
|
|
Filesystem FilesystemToolConfig `yaml:"filesystem"`
|
|
Clipboard ClipboardToolConfig `yaml:"clipboard"`
|
|
}
|
|
|
|
type TerminalToolConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Shell string `yaml:"shell"`
|
|
TimeoutSeconds int `yaml:"timeout_seconds"`
|
|
BlockedCommands []string `yaml:"blocked_commands"`
|
|
}
|
|
|
|
type BrowserToolConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Headless bool `yaml:"headless"`
|
|
}
|
|
|
|
type DesktopToolConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
}
|
|
|
|
type FilesystemToolConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
AllowedPaths []string `yaml:"allowed_paths"`
|
|
}
|
|
|
|
type ClipboardToolConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string `yaml:"level"`
|
|
Format string `yaml:"format"`
|
|
}
|
|
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading config file: %w", err)
|
|
}
|
|
|
|
cfg := &Config{}
|
|
if err := yaml.Unmarshal(data, cfg); err != nil {
|
|
return nil, fmt.Errorf("parsing config file: %w", err)
|
|
}
|
|
|
|
cfg.applyEnvOverrides()
|
|
cfg.setDefaults()
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func (c *Config) applyEnvOverrides() {
|
|
if key := os.Getenv("OPENAI_API_KEY"); key != "" {
|
|
c.AI.OpenAI.APIKey = key
|
|
}
|
|
if key := os.Getenv("ANTHROPIC_API_KEY"); key != "" {
|
|
c.AI.Anthropic.APIKey = key
|
|
}
|
|
if key := os.Getenv("GOOGLE_API_KEY"); key != "" {
|
|
c.AI.Google.APIKey = key
|
|
}
|
|
if url := os.Getenv("OLLAMA_BASE_URL"); url != "" {
|
|
c.AI.Ollama.BaseURL = url
|
|
}
|
|
}
|
|
|
|
func (c *Config) setDefaults() {
|
|
if c.Server.Port == 0 {
|
|
c.Server.Port = 8080
|
|
}
|
|
if c.Server.Host == "" {
|
|
c.Server.Host = "0.0.0.0"
|
|
}
|
|
if c.AI.DefaultProvider == "" {
|
|
c.AI.DefaultProvider = "ollama"
|
|
}
|
|
if c.AI.Ollama.BaseURL == "" {
|
|
c.AI.Ollama.BaseURL = "http://localhost:11434"
|
|
}
|
|
if c.AI.Ollama.Model == "" {
|
|
c.AI.Ollama.Model = "llama3"
|
|
}
|
|
if c.Agent.MaxIterations == 0 {
|
|
c.Agent.MaxIterations = 20
|
|
}
|
|
if c.Agent.TimeoutSeconds == 0 {
|
|
c.Agent.TimeoutSeconds = 300
|
|
}
|
|
if c.Tools.Terminal.Shell == "" {
|
|
c.Tools.Terminal.Shell = "/bin/bash"
|
|
}
|
|
if c.Tools.Terminal.TimeoutSeconds == 0 {
|
|
c.Tools.Terminal.TimeoutSeconds = 60
|
|
}
|
|
if c.Logging.Level == "" {
|
|
c.Logging.Level = "info"
|
|
}
|
|
if c.Logging.Format == "" {
|
|
c.Logging.Format = "text"
|
|
}
|
|
}
|