Class: HTM::Config

Inherits:
MywayConfig::Base
  • Object
show all
Includes:
Builder, Database, Validator
Defined in:
lib/htm/config.rb,
lib/htm/config.rb,
lib/htm/config/builder.rb,
lib/htm/config/database.rb,
lib/htm/config/validator.rb

Overview

HTM Configuration using Anyway Config

Schema is defined in lib/htm/config/defaults.yml (single source of truth) Configuration uses nested sections for better organization:

- HTM.config.database.host
- HTM.config.embedding.provider
- HTM.config.providers.openai.api_key

Configuration sources (lowest to highest priority):

  1. Bundled defaults: lib/htm/config/defaults.yml (ships with gem)

  2. XDG user config:

    • ~/Library/Application Support/htm/htm.yml (macOS only)

    • ~/.config/htm/htm.yml (XDG default)

    • $XDG_CONFIG_HOME/htm/htm.yml (if XDG_CONFIG_HOME is set)

  3. Project config: ./config/htm.yml (environment-specific)

  4. Local overrides: ./config/htm.local.yml (gitignored)

  5. Environment variables (HTM_*)

  6. Explicit values passed to configure block

Examples:

Configure with environment variables

export HTM_EMBEDDING__PROVIDER=openai
export HTM_EMBEDDING__MODEL=text-embedding-3-small
export HTM_PROVIDERS__OPENAI__API_KEY=sk-xxx

Configure with XDG user config (~/.config/htm/htm.yml)

embedding:
  provider: ollama
  model: nomic-embed-text:latest
providers:
  ollama:
    url: http://localhost:11434

Configure with Ruby block

HTM.configure do |config|
  config.embedding.provider = :openai
  config.embedding.model = 'text-embedding-3-small'
end

Defined Under Namespace

Modules: Builder, Database, Validator

Constant Summary collapse

DEFAULT_DIMENSIONS =

Default embedding dimensions by provider

{
  openai: 1536,
  anthropic: 1024,
  gemini: 768,
  azure: 1536,
  ollama: 768,
  huggingface: 768,
  openrouter: 1536,
  bedrock: 1536,
  deepseek: 1536
}.freeze

Constants included from Validator

Validator::SUPPORTED_JOB_BACKENDS, Validator::SUPPORTED_PROVIDERS, Validator::SUPPORTED_WEEK_STARTS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Builder

#build_default_embedding_generator, #build_default_logger, #build_default_proposition_extractor, #build_default_tag_extractor, #build_default_token_counter, #build_proposition_extraction_prompt, #build_proposition_system_prompt, #build_tag_extraction_prompt, #build_tag_system_prompt, #extract_embedding_from_response, #extract_text_from_response, #parse_proposition_response, #parse_tag_response

Methods included from Database

#actual_database_name, #database_config, #database_configured?, #database_host, #database_name, #database_password, #database_port, #database_url, #database_user, #expected_database_name, #parse_database_url, #valid_database_name?, #validate_database!, #validate_database_name!

Methods included from Validator

#validate_callables, #validate_config, #validate_job_backend, #validate_logger, #validate_provider, #validate_providers, #validate_relevance_weights, #validate_week_start

Constructor Details

#initializeConfig

Instance Methods



108
109
110
111
112
# File 'lib/htm/config.rb', line 108

def initialize(...)
  super
  @ollama_models_refreshed = false
  @ollama_refresh_mutex = Mutex.new
end

Instance Attribute Details

#embedding_generatorObject

Callable Accessors (not loaded from config sources)



102
103
104
# File 'lib/htm/config.rb', line 102

def embedding_generator
  @embedding_generator
end

#loggerObject

Callable Accessors (not loaded from config sources)



102
103
104
# File 'lib/htm/config.rb', line 102

def logger
  @logger
end

#proposition_extractorObject

Callable Accessors (not loaded from config sources)



102
103
104
# File 'lib/htm/config.rb', line 102

def proposition_extractor
  @proposition_extractor
end

#tag_extractorObject

Callable Accessors (not loaded from config sources)



102
103
104
# File 'lib/htm/config.rb', line 102

def tag_extractor
  @tag_extractor
end

#token_counterObject

Callable Accessors (not loaded from config sources)



102
103
104
# File 'lib/htm/config.rb', line 102

def token_counter
  @token_counter
end

Class Method Details

.active_xdg_config_fileObject



363
364
365
# File 'lib/htm/config.rb', line 363

def self.active_xdg_config_file
  MywayConfig::Loaders::XdgConfigLoader.find_config_file(config_name)
end

.envObject



70
71
72
73
74
75
76
# File 'lib/htm/config.rb', line 70

def env
  Anyway::Settings.current_environment ||
    ENV['HTM_ENV'] ||
    ENV['RAILS_ENV'] ||
    ENV['RACK_ENV'] ||
    'development'
end

.valid_environment?Boolean

Check if current environment is valid (defined in config)

Returns:

  • (Boolean)

    true if environment has a config section



317
318
319
# File 'lib/htm/config.rb', line 317

def self.valid_environment?
  MywayConfig::Loaders::DefaultsLoader.valid_environment?(config_name, env)
end

.validate_environment!true

Validate that the current environment is configured

Returns:

  • (true)

    if environment is valid

Raises:



325
326
327
328
329
330
331
332
333
334
# File 'lib/htm/config.rb', line 325

def self.validate_environment!
  current = env
  return true if valid_environment?

  valid = valid_environments.join(', ')
  raise HTM::ConfigurationError,
        "Invalid environment '#{current}'. " \
        "Valid environments are: #{valid}. " \
        "Set HTM_ENV to a valid environment or add a '#{current}:' section to your config."
end

.xdg_config_fileObject



353
354
355
356
357
358
359
360
361
# File 'lib/htm/config.rb', line 353

def self.xdg_config_file
  xdg_home = ENV.fetch('XDG_CONFIG_HOME', nil)
  base = if xdg_home && !xdg_home.empty?
           xdg_home
         else
           File.expand_path('~/.config')
         end
  File.join(base, 'htm', 'htm.yml')
end

.xdg_config_pathsObject

XDG Config Path Helpers



349
350
351
# File 'lib/htm/config.rb', line 349

def self.xdg_config_paths
  MywayConfig::Loaders::XdgConfigLoader.config_paths(config_name)
end

Instance Method Details

#anthropic_api_keyObject



245
246
247
# File 'lib/htm/config.rb', line 245

def anthropic_api_key
  providers.anthropic&.api_key
end

#azure_api_keyObject



253
254
255
# File 'lib/htm/config.rb', line 253

def azure_api_key
  providers.azure&.api_key
end

#azure_api_versionObject



261
262
263
# File 'lib/htm/config.rb', line 261

def azure_api_version
  providers.azure&.api_version
end

#azure_endpointObject



257
258
259
# File 'lib/htm/config.rb', line 257

def azure_endpoint
  providers.azure&.endpoint
end

#bedrock_access_keyObject



277
278
279
# File 'lib/htm/config.rb', line 277

def bedrock_access_key
  providers.bedrock&.access_key
end

#bedrock_regionObject



285
286
287
# File 'lib/htm/config.rb', line 285

def bedrock_region
  providers.bedrock&.region || 'us-east-1'
end

#bedrock_secret_keyObject



281
282
283
# File 'lib/htm/config.rb', line 281

def bedrock_secret_key
  providers.bedrock&.secret_key
end

#chunk_overlapObject



181
182
183
# File 'lib/htm/config.rb', line 181

def chunk_overlap
  chunking.chunk_overlap.to_i
end

#chunk_sizeObject

Chunking convenience accessors



177
178
179
# File 'lib/htm/config.rb', line 177

def chunk_size
  chunking.chunk_size.to_i
end

#circuit_breaker_failure_thresholdObject

Circuit breaker convenience accessors



186
187
188
# File 'lib/htm/config.rb', line 186

def circuit_breaker_failure_threshold
  circuit_breaker.failure_threshold.to_i
end

#circuit_breaker_half_open_max_callsObject



194
195
196
# File 'lib/htm/config.rb', line 194

def circuit_breaker_half_open_max_calls
  circuit_breaker.half_open_max_calls.to_i
end

#circuit_breaker_reset_timeoutObject



190
191
192
# File 'lib/htm/config.rb', line 190

def circuit_breaker_reset_timeout
  circuit_breaker.reset_timeout.to_i
end

#configure_ruby_llm(provider = nil) ⇒ Object



378
379
380
381
382
# File 'lib/htm/config.rb', line 378

def configure_ruby_llm(provider = nil)
  require 'ruby_llm'
  provider ||= embedding_provider
  RubyLLM.configure { |config| apply_provider_config(config, provider) }
end

#deepseek_api_keyObject



289
290
291
# File 'lib/htm/config.rb', line 289

def deepseek_api_key
  providers.deepseek&.api_key
end

#embedding_dimensionsObject



128
129
130
# File 'lib/htm/config.rb', line 128

def embedding_dimensions
  embedding.dimensions.to_i
end

#embedding_modelObject



124
125
126
# File 'lib/htm/config.rb', line 124

def embedding_model
  embedding.model
end

#embedding_providerObject

Embedding convenience accessors



119
120
121
122
# File 'lib/htm/config.rb', line 119

def embedding_provider
  provider = embedding.provider
  provider.is_a?(Symbol) ? provider : provider&.to_sym
end

#embedding_timeoutObject



132
133
134
# File 'lib/htm/config.rb', line 132

def embedding_timeout
  embedding.timeout.to_i
end

#environmentObject

NOTE: test?, development?, production? are auto-generated by MywayConfig::Base based on environment keys in defaults.yml



300
301
302
# File 'lib/htm/config.rb', line 300

def environment
  self.class.env
end

#extract_propositionsObject



172
173
174
# File 'lib/htm/config.rb', line 172

def extract_propositions
  proposition.enabled
end

#gemini_api_keyObject



249
250
251
# File 'lib/htm/config.rb', line 249

def gemini_api_key
  providers.gemini&.api_key
end

#huggingface_api_keyObject



269
270
271
# File 'lib/htm/config.rb', line 269

def huggingface_api_key
  providers.huggingface&.api_key
end

#job_backendObject

Job backend convenience accessor



220
221
222
223
224
225
# File 'lib/htm/config.rb', line 220

def job_backend
  backend = job.backend
  return nil if backend.nil?

  backend.is_a?(Symbol) ? backend : backend.to_sym
end

#max_embedding_dimensionObject



136
137
138
# File 'lib/htm/config.rb', line 136

def max_embedding_dimension
  embedding.max_dimension.to_i
end

#max_tag_depthObject



154
155
156
# File 'lib/htm/config.rb', line 154

def max_tag_depth
  tag.max_depth.to_i
end

#normalize_ollama_model(model_name) ⇒ Object

Ollama Helpers



371
372
373
374
375
376
# File 'lib/htm/config.rb', line 371

def normalize_ollama_model(model_name)
  return model_name if model_name.nil? || model_name.empty?
  return model_name if model_name.include?(':')

  "#{model_name}:latest"
end

#ollama_urlObject



265
266
267
# File 'lib/htm/config.rb', line 265

def ollama_url
  providers.ollama&.url || 'http://localhost:11434'
end

#openai_api_keyObject

Provider credential convenience accessors



233
234
235
# File 'lib/htm/config.rb', line 233

def openai_api_key
  providers.openai&.api_key
end

#openai_organizationObject



237
238
239
# File 'lib/htm/config.rb', line 237

def openai_organization
  providers.openai&.organization
end

#openai_projectObject



241
242
243
# File 'lib/htm/config.rb', line 241

def openai_project
  providers.openai&.project
end

#openrouter_api_keyObject



273
274
275
# File 'lib/htm/config.rb', line 273

def openrouter_api_key
  providers.openrouter&.api_key
end

#proposition_modelObject



164
165
166
# File 'lib/htm/config.rb', line 164

def proposition_model
  proposition.model
end

#proposition_providerObject

Proposition convenience accessors



159
160
161
162
# File 'lib/htm/config.rb', line 159

def proposition_provider
  provider = proposition.provider
  provider.is_a?(Symbol) ? provider : provider&.to_sym
end

#proposition_timeoutObject



168
169
170
# File 'lib/htm/config.rb', line 168

def proposition_timeout
  proposition.timeout.to_i
end

#refresh_ollama_models!Object



384
385
386
387
388
389
390
391
392
# File 'lib/htm/config.rb', line 384

def refresh_ollama_models!
  @ollama_refresh_mutex.synchronize do
    unless @ollama_models_refreshed
      require 'ruby_llm'
      RubyLLM.models.refresh!
      @ollama_models_refreshed = true
    end
  end
end

#relevance_access_weightObject



211
212
213
# File 'lib/htm/config.rb', line 211

def relevance_access_weight
  relevance.access_weight.to_f
end

#relevance_recency_half_life_hoursObject



215
216
217
# File 'lib/htm/config.rb', line 215

def relevance_recency_half_life_hours
  relevance.recency_half_life_hours.to_f
end

#relevance_recency_weightObject



207
208
209
# File 'lib/htm/config.rb', line 207

def relevance_recency_weight
  relevance.recency_weight.to_f
end

#relevance_semantic_weightObject

Relevance scoring convenience accessors



199
200
201
# File 'lib/htm/config.rb', line 199

def relevance_semantic_weight
  relevance.semantic_weight.to_f
end

#relevance_tag_weightObject



203
204
205
# File 'lib/htm/config.rb', line 203

def relevance_tag_weight
  relevance.tag_weight.to_f
end

#reset_to_defaultsObject



394
395
396
397
398
399
400
# File 'lib/htm/config.rb', line 394

def reset_to_defaults
  @embedding_generator = build_default_embedding_generator
  @tag_extractor = build_default_tag_extractor
  @proposition_extractor = build_default_proposition_extractor
  @token_counter = build_default_token_counter
  @logger = build_default_logger
end

#service_nameObject

Service name convenience accessor



228
229
230
# File 'lib/htm/config.rb', line 228

def service_name
  service.name
end

#tag_modelObject



146
147
148
# File 'lib/htm/config.rb', line 146

def tag_model
  tag.model
end

#tag_providerObject

Tag convenience accessors



141
142
143
144
# File 'lib/htm/config.rb', line 141

def tag_provider
  provider = tag.provider
  provider.is_a?(Symbol) ? provider : provider&.to_sym
end

#tag_timeoutObject



150
151
152
# File 'lib/htm/config.rb', line 150

def tag_timeout
  tag.timeout.to_i
end

#valid_environment?Boolean

Instance method delegates

Returns:

  • (Boolean)


337
338
339
# File 'lib/htm/config.rb', line 337

def valid_environment?
  self.class.valid_environment?
end

#validate!Object



402
403
404
405
# File 'lib/htm/config.rb', line 402

def validate!
  validate_callables
  validate_logger
end

#validate_environment!Object



341
342
343
# File 'lib/htm/config.rb', line 341

def validate_environment!
  self.class.validate_environment!
end

#validate_settings!Object



407
408
409
410
411
412
# File 'lib/htm/config.rb', line 407

def validate_settings!
  validate_providers
  validate_job_backend
  validate_week_start
  validate_relevance_weights
end