Core features: - Microkernel architecture with Actor model - Session management with JSONL persistence - Tool system (5 built-in tools) - Skill system with SKILL.md parsing - Sandbox security execution - Ollama integration with gemma4:e4b - Prompt-based tool calling (compatible with native function calling) - REPL interface 11 packages, all tests passing
148 lines
4.1 KiB
Go
148 lines
4.1 KiB
Go
// Package config provides the configuration types for the Orca framework.
|
|
//
|
|
// Configuration is organized into logical groups: LLM (Ollama), sandbox,
|
|
// and session management. Default values are provided for all settings.
|
|
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// Config is the top-level configuration for the Orca framework.
|
|
type Config struct {
|
|
Ollama OllamaConfig `json:"ollama"`
|
|
Sandbox SandboxConfig `json:"sandbox"`
|
|
Session SessionConfig `json:"session"`
|
|
}
|
|
|
|
// OllamaConfig holds configuration for the Ollama LLM backend.
|
|
type OllamaConfig struct {
|
|
// BaseURL is the Ollama API endpoint (e.g., "http://localhost:11434").
|
|
BaseURL string `json:"base_url"`
|
|
// Model is the Ollama model name to use (e.g., "gemma4:e4b", "codellama").
|
|
Model string `json:"model"`
|
|
// Timeout is the maximum duration to wait for an Ollama response.
|
|
Timeout time.Duration `json:"timeout"`
|
|
}
|
|
|
|
// SandboxConfig holds configuration for the command execution sandbox.
|
|
type SandboxConfig struct {
|
|
// Timeout is the maximum duration for a sandboxed command.
|
|
Timeout time.Duration `json:"timeout"`
|
|
// MaxMemory is the maximum memory allocation for the sandbox (in bytes).
|
|
MaxMemory int64 `json:"max_memory"`
|
|
// WorkingDir is the default working directory for sandboxed commands.
|
|
WorkingDir string `json:"working_dir"`
|
|
}
|
|
|
|
// SessionConfig holds configuration for session management.
|
|
type SessionConfig struct {
|
|
// StorageDir is the directory for session JSONL files.
|
|
StorageDir string `json:"storage_dir"`
|
|
// MaxHistory is the maximum number of messages to retain per session.
|
|
MaxHistory int `json:"max_history"`
|
|
}
|
|
|
|
// DefaultConfig returns a Config with sensible defaults.
|
|
func DefaultConfig() *Config {
|
|
return &Config{
|
|
Ollama: OllamaConfig{
|
|
BaseURL: "http://localhost:11434",
|
|
Model: "gemma4:e4b",
|
|
Timeout: 120 * time.Second,
|
|
},
|
|
Sandbox: SandboxConfig{
|
|
Timeout: 30 * time.Second,
|
|
MaxMemory: 512 * 1024 * 1024, // 512 MB
|
|
WorkingDir: "/tmp/orca/sandbox",
|
|
},
|
|
Session: SessionConfig{
|
|
StorageDir: func() string {
|
|
home, _ := os.UserHomeDir()
|
|
return home + "/.orca/sessions"
|
|
}(),
|
|
MaxHistory: 100,
|
|
},
|
|
}
|
|
}
|
|
|
|
// LoadConfigFromEnv reads configuration from environment variables,
|
|
// overriding defaults where environment variables are set.
|
|
func LoadConfigFromEnv() *Config {
|
|
cfg := DefaultConfig()
|
|
|
|
if v := os.Getenv("ORCA_OLLAMA_BASE_URL"); v != "" {
|
|
cfg.Ollama.BaseURL = v
|
|
}
|
|
if v := os.Getenv("ORCA_OLLAMA_MODEL"); v != "" {
|
|
cfg.Ollama.Model = v
|
|
}
|
|
if v := os.Getenv("ORCA_OLLAMA_TIMEOUT"); v != "" {
|
|
if d, err := time.ParseDuration(v); err == nil {
|
|
cfg.Ollama.Timeout = d
|
|
}
|
|
}
|
|
if v := os.Getenv("ORCA_SANDBOX_TIMEOUT"); v != "" {
|
|
if d, err := time.ParseDuration(v); err == nil {
|
|
cfg.Sandbox.Timeout = d
|
|
}
|
|
}
|
|
if v := os.Getenv("ORCA_SANDBOX_MAX_MEMORY"); v != "" {
|
|
if n, err := strconv.ParseInt(v, 10, 64); err == nil {
|
|
cfg.Sandbox.MaxMemory = n
|
|
}
|
|
}
|
|
if v := os.Getenv("ORCA_SANDBOX_WORKING_DIR"); v != "" {
|
|
cfg.Sandbox.WorkingDir = v
|
|
}
|
|
if v := os.Getenv("ORCA_SESSION_STORAGE_DIR"); v != "" {
|
|
cfg.Session.StorageDir = v
|
|
}
|
|
if v := os.Getenv("ORCA_SESSION_MAX_HISTORY"); v != "" {
|
|
if n, err := strconv.Atoi(v); err == nil {
|
|
cfg.Session.MaxHistory = n
|
|
}
|
|
}
|
|
|
|
return cfg
|
|
}
|
|
|
|
// IsValid checks whether the configuration has valid values.
|
|
func (c *Config) IsValid() error {
|
|
if c.Ollama.BaseURL == "" {
|
|
return errConfig("ollama.base_url must not be empty")
|
|
}
|
|
if c.Ollama.Model == "" {
|
|
return errConfig("ollama.model must not be empty")
|
|
}
|
|
if c.Ollama.Timeout <= 0 {
|
|
return errConfig("ollama.timeout must be positive")
|
|
}
|
|
if c.Sandbox.Timeout <= 0 {
|
|
return errConfig("sandbox.timeout must be positive")
|
|
}
|
|
if c.Sandbox.MaxMemory <= 0 {
|
|
return errConfig("sandbox.max_memory must be positive")
|
|
}
|
|
if c.Session.MaxHistory <= 0 {
|
|
return errConfig("session.max_history must be positive")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// errConfig creates a configuration error.
|
|
func errConfig(msg string) error {
|
|
return &ConfigError{Message: msg}
|
|
}
|
|
|
|
// ConfigError represents a configuration validation error.
|
|
type ConfigError struct {
|
|
Message string
|
|
}
|
|
|
|
func (e *ConfigError) Error() string {
|
|
return "config: " + e.Message
|
|
}
|