Class: Prescient::ConfigurationLoader

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

Overview

Load and validate Prescient configuration data from YAML.

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',
  '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
COMMON_PROVIDER_KEYS =

Provider-specific keys shared by all supported adapters.

[
  '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
PROMPT_TEMPLATE_KEYS =

Prompt template keys supported by provider configuration.

['system_prompt', 'no_context_template', 'with_context_template'].freeze
ATTR_KEYS =

Configuration attributes supported by the loader.

[
  '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.



103
104
105
# File 'lib/prescient/configuration_loader.rb', line 103

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:



82
83
84
# File 'lib/prescient/configuration_loader.rb', line 82

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:



98
99
100
# File 'lib/prescient/configuration_loader.rb', line 98

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:



90
91
92
# File 'lib/prescient/configuration_loader.rb', line 90

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



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

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:



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

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:)
  configuration
end

#load_file(path) ⇒ Prescient::Configuration

Load configuration from a YAML file.

Parameters:

  • path (String)

    Configuration file path

Returns:



110
111
112
113
114
# File 'lib/prescient/configuration_loader.rb', line 110

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:



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

def load_hash(data, source: nil)
  configuration = Prescient::Configuration.new
  Prescient.send(:configure_default_providers, 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:



120
121
122
123
124
125
# File 'lib/prescient/configuration_loader.rb', line 120

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