package config import "time" const ( DefaultConfigPath = "./configs/dev.yaml" DefaultSource = "mcp" ) type Config struct { Server ServerConfig `yaml:"server"` MCP MCPConfig `yaml:"mcp"` Auth AuthConfig `yaml:"auth"` Database DatabaseConfig `yaml:"database"` AI AIConfig `yaml:"ai"` Capture CaptureConfig `yaml:"capture"` Search SearchConfig `yaml:"search"` Logging LoggingConfig `yaml:"logging"` Observability ObservabilityConfig `yaml:"observability"` Backfill BackfillConfig `yaml:"backfill"` MetadataRetry MetadataRetryConfig `yaml:"metadata_retry"` } type ServerConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` ReadTimeout time.Duration `yaml:"read_timeout"` WriteTimeout time.Duration `yaml:"write_timeout"` IdleTimeout time.Duration `yaml:"idle_timeout"` AllowedOrigins []string `yaml:"allowed_origins"` } type MCPConfig struct { Path string `yaml:"path"` ServerName string `yaml:"server_name"` Version string `yaml:"version"` Transport string `yaml:"transport"` } type AuthConfig struct { HeaderName string `yaml:"header_name"` QueryParam string `yaml:"query_param"` AllowQueryParam bool `yaml:"allow_query_param"` Keys []APIKey `yaml:"keys"` OAuth OAuthConfig `yaml:"oauth"` } type APIKey struct { ID string `yaml:"id"` Value string `yaml:"value"` Description string `yaml:"description"` } type OAuthConfig struct { Clients []OAuthClient `yaml:"clients"` } type OAuthClient struct { ID string `yaml:"id"` ClientID string `yaml:"client_id"` ClientSecret string `yaml:"client_secret"` Description string `yaml:"description"` } type DatabaseConfig struct { URL string `yaml:"url"` MaxConns int32 `yaml:"max_conns"` MinConns int32 `yaml:"min_conns"` MaxConnLifetime time.Duration `yaml:"max_conn_lifetime"` MaxConnIdleTime time.Duration `yaml:"max_conn_idle_time"` } type AIConfig struct { Provider string `yaml:"provider"` Embeddings AIEmbeddingConfig `yaml:"embeddings"` Metadata AIMetadataConfig `yaml:"metadata"` LiteLLM LiteLLMConfig `yaml:"litellm"` Ollama OllamaConfig `yaml:"ollama"` OpenRouter OpenRouterAIConfig `yaml:"openrouter"` } type AIEmbeddingConfig struct { Model string `yaml:"model"` Dimensions int `yaml:"dimensions"` } type AIMetadataConfig struct { Model string `yaml:"model"` FallbackModels []string `yaml:"fallback_models"` FallbackModel string `yaml:"fallback_model"` // legacy single fallback Temperature float64 `yaml:"temperature"` LogConversations bool `yaml:"log_conversations"` Timeout time.Duration `yaml:"timeout"` } type LiteLLMConfig struct { BaseURL string `yaml:"base_url"` APIKey string `yaml:"api_key"` UseResponsesAPI bool `yaml:"use_responses_api"` RequestHeaders map[string]string `yaml:"request_headers"` EmbeddingModel string `yaml:"embedding_model"` MetadataModel string `yaml:"metadata_model"` FallbackMetadataModels []string `yaml:"fallback_metadata_models"` FallbackMetadataModel string `yaml:"fallback_metadata_model"` // legacy single fallback } type OllamaConfig struct { BaseURL string `yaml:"base_url"` APIKey string `yaml:"api_key"` RequestHeaders map[string]string `yaml:"request_headers"` } type OpenRouterAIConfig struct { BaseURL string `yaml:"base_url"` APIKey string `yaml:"api_key"` AppName string `yaml:"app_name"` SiteURL string `yaml:"site_url"` ExtraHeaders map[string]string `yaml:"extra_headers"` } type CaptureConfig struct { Source string `yaml:"source"` MetadataDefaults CaptureMetadataDefault `yaml:"metadata_defaults"` } type CaptureMetadataDefault struct { Type string `yaml:"type"` TopicFallback string `yaml:"topic_fallback"` } type SearchConfig struct { DefaultLimit int `yaml:"default_limit"` DefaultThreshold float64 `yaml:"default_threshold"` MaxLimit int `yaml:"max_limit"` } type LoggingConfig struct { Level string `yaml:"level"` Format string `yaml:"format"` } type ObservabilityConfig struct { MetricsEnabled bool `yaml:"metrics_enabled"` PprofEnabled bool `yaml:"pprof_enabled"` } type BackfillConfig struct { Enabled bool `yaml:"enabled"` RunOnStartup bool `yaml:"run_on_startup"` Interval time.Duration `yaml:"interval"` BatchSize int `yaml:"batch_size"` MaxPerRun int `yaml:"max_per_run"` IncludeArchived bool `yaml:"include_archived"` } type MetadataRetryConfig struct { Enabled bool `yaml:"enabled"` RunOnStartup bool `yaml:"run_on_startup"` Interval time.Duration `yaml:"interval"` MaxPerRun int `yaml:"max_per_run"` IncludeArchived bool `yaml:"include_archived"` } func (c AIMetadataConfig) EffectiveFallbackModels() []string { models := make([]string, 0, len(c.FallbackModels)+1) for _, model := range c.FallbackModels { if model != "" { models = append(models, model) } } if c.FallbackModel != "" { models = append(models, c.FallbackModel) } return dedupeNonEmpty(models) } func (c LiteLLMConfig) EffectiveFallbackMetadataModels() []string { models := make([]string, 0, len(c.FallbackMetadataModels)+1) for _, model := range c.FallbackMetadataModels { if model != "" { models = append(models, model) } } if c.FallbackMetadataModel != "" { models = append(models, c.FallbackMetadataModel) } return dedupeNonEmpty(models) } func dedupeNonEmpty(values []string) []string { seen := make(map[string]struct{}, len(values)) out := make([]string, 0, len(values)) for _, value := range values { if value == "" { continue } if _, ok := seen[value]; ok { continue } seen[value] = struct{}{} out = append(out, value) } return out }