Class: Prescient::ConfigurationLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/prescient/configuration_loader.rb

Overview

Load and validate Prescient configuration data from YAML. rubocop:disable Metrics/ClassLength

Constant Summary collapse

CONFIGURATION_VERSION =

Supported YAML configuration schema version.

1
TOP_LEVEL_KEYS =

Allowed top-level configuration keys.

[
  "$schema",
  "default_provider",
  "default_provider_env",
  "fallback_providers",
  "fallback_providers_env",
  "providers",
  "tools",
  "retry_attempts",
  "retry_attempts_env",
  "retry_delay",
  "retry_delay_env",
  "sensitive_keys",
  "sensitive_keys_env",
  "timeout",
  "timeout_env",
  "version"
].freeze
PROVIDER_TYPES =

Provider names mapped to their adapter classes.

{
  "ollama" => Prescient::Provider::Ollama,
  "anthropic" => Prescient::Provider::Anthropic,
  "openai" => Prescient::Provider::OpenAI,
  "huggingface" => Prescient::Provider::HuggingFace,
  "gemini" => Prescient::Provider::Gemini,
  "mistral" => Prescient::Provider::Mistral,
  "deepseek" => Prescient::Provider::DeepSeek,
  "xai" => Prescient::Provider::XAI
}.freeze
TOOL_TYPES =

Tool names mapped to lazily resolved adapter constants.

{
  "searchapi" => :SearchApi,
  "searxng" => :SearXNG
}.freeze
COMMON_PROVIDER_KEYS =

Provider-specific keys shared by all supported adapters.

%w[
  api_key
  api_key_env
  chat_model
  chat_model_env
  context_configs
  context_configs_env
  embedding_dimensions
  embedding_dimensions_env
  embedding_model
  embedding_model_env
  model
  model_env
  prompt_templates
  prompt_templates_env
  timeout
  timeout_env
  url
  url_env
].freeze
COMMON_TOOL_KEYS =

Tool-specific keys accepted by all configured adapters.

%w[
  api_key
  api_key_env
  categories
  categories_env
  engine
  engine_env
  gl
  gl_env
  hl
  hl_env
  language
  language_env
  location
  location_env
  max_response_bytes
  max_response_bytes_env
  max_results
  max_results_env
  timeout
  timeout_env
  url
  url_env
].freeze
PROMPT_TEMPLATE_KEYS =

Prompt template keys supported by provider configuration.

%w[system_prompt no_context_template with_context_template].freeze
ATTR_KEYS =

Configuration attributes supported by the loader.

%w[
  default_provider
  fallback_providers
  retry_attempts
  retry_delay
  sensitive_keys
  timeout
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env = ENV) ⇒ ConfigurationLoader

Returns a new instance of ConfigurationLoader.



138
139
140
# File 'lib/prescient/configuration_loader.rb', line 138

def initialize(env = ENV)
  @env = env
end

Class Method Details

.load_file(path, env: ENV) ⇒ Prescient::Configuration

Load and validate configuration from a YAML file.

Parameters:

  • path (String)

    Configuration file path

  • env (Hash) (defaults to: ENV)

    Environment variables used during expansion

Returns:



117
118
119
# File 'lib/prescient/configuration_loader.rb', line 117

def load_file(path, env: ENV)
  new(env).load_file(path)
end

.load_hash(data, env: ENV) ⇒ Prescient::Configuration

Load and validate configuration from a Ruby hash.

Parameters:

  • data (Hash)

    Configuration data

  • env (Hash) (defaults to: ENV)

    Environment variables used during expansion

Returns:



133
134
135
# File 'lib/prescient/configuration_loader.rb', line 133

def load_hash(data, env: ENV)
  new(env).load_hash(data)
end

.load_yaml(content, env: ENV) ⇒ Prescient::Configuration

Load and validate configuration from YAML content.

Parameters:

  • content (String)

    YAML configuration content

  • env (Hash) (defaults to: ENV)

    Environment variables used during expansion

Returns:



125
126
127
# File 'lib/prescient/configuration_loader.rb', line 125

def load_yaml(content, env: ENV)
  new(env).load_yaml(content)
end

.schema_pathString

Return the packaged JSON Schema path.

Returns:

  • (String)

    Absolute path to the configuration schema



192
193
194
# File 'lib/prescient/configuration_loader.rb', line 192

def self.schema_path
  File.expand_path("../../schema/prescient.configuration.schema.json", __dir__)
end

Instance Method Details

#apply!(configuration, data, source: nil) ⇒ Prescient::Configuration

Apply validated configuration data to an existing configuration object.

Parameters:

  • configuration (Prescient::Configuration)

    Target configuration

  • data (Hash)

    Configuration data

  • source (String, nil) (defaults to: nil)

    Source label used in validation errors

Returns:



179
180
181
182
183
184
185
186
187
188
# File 'lib/prescient/configuration_loader.rb', line 179

def apply!(configuration, data, source: nil)
  normalized = normalize_keys(data)
  validate_root!(normalized, source:)
  validate_version!(normalized, source:)

  apply_scalar_settings(configuration, normalized, source:)
  apply_provider_settings(configuration, normalized, source:)
  apply_tool_settings(configuration, normalized, source:)
  configuration
end

#load_file(path) ⇒ Prescient::Configuration

Load configuration from a YAML file.

Parameters:

  • path (String)

    Configuration file path

Returns:



145
146
147
148
149
# File 'lib/prescient/configuration_loader.rb', line 145

def load_file(path)
  load_yaml(File.read(path), source: path)
rescue Errno::ENOENT
  raise Prescient::Error, "Configuration file not found: #{path}"
end

#load_hash(data, source: nil) ⇒ Prescient::Configuration

Load configuration from a Ruby hash.

Parameters:

  • data (Hash)

    Configuration data

  • source (String, nil) (defaults to: nil)

    Source label used in validation errors

Returns:



166
167
168
169
170
171
172
# File 'lib/prescient/configuration_loader.rb', line 166

def load_hash(data, source: nil)
  configuration = Prescient::Configuration.new
  Prescient.send(:configure_default_providers, configuration, @env)
  Prescient.send(:configure_default_tools, configuration, @env)
  apply!(configuration, data, source:)
  configuration
end

#load_yaml(content, source: nil) ⇒ Prescient::Configuration

Load configuration from YAML content.

Parameters:

  • content (String)

    YAML configuration content

  • source (String, nil) (defaults to: nil)

    Source label used in validation errors

Returns:



155
156
157
158
159
160
# File 'lib/prescient/configuration_loader.rb', line 155

def load_yaml(content, source: nil)
  data = YAML.safe_load(content, permitted_classes: [], permitted_symbols: [], aliases: true)
  load_hash(data || {}, source:)
rescue Psych::SyntaxError => e
  raise Prescient::Error, "Invalid YAML configuration#{" in #{source}" if source}: #{e.message}"
end