Class: Woods::ResolvedConfig
- Inherits:
-
Object
- Object
- Woods::ResolvedConfig
- Defined in:
- lib/woods/resolved_config.rb
Overview
Immutable Whole Value representing the resolved embedding configuration captured at embed time and read back by the MCP server at boot.
This is NOT a declared-config bag of fields — it records what was *actually used* during embedding (provider class, model, host, dimension, store types). The MCP server compares a stored ResolvedConfig against the current host config to detect incompatible re-deployments.
Build via ResolvedConfig.from_hash (parses woods.json) or ResolvedConfig.from_configuration (captures the current Configuration at embed time).
Constant Summary collapse
- SCHEMA_VERSION_SUPPORTED =
The only schema version this gem release can read or write.
1
Instance Attribute Summary collapse
- #created_at ⇒ Time readonly
-
#embedding_provider ⇒ Hash
readonly
Provider details — :class, :model, :host, :num_ctx, :read_timeout, :dimension.
-
#gem_version ⇒ String
readonly
Gem version at embed time (e.g. “1.2.0”).
- #schema_version ⇒ Integer readonly
-
#stores ⇒ Hash
readonly
Store types — :vector_store, :metadata_store, :graph_store (Symbols).
Class Method Summary collapse
-
.from_configuration(config, gem_version: nil, provider: nil) ⇒ ResolvedConfig
Capture the current Configuration as a ResolvedConfig.
-
.from_hash(raw) ⇒ ResolvedConfig
Parse a
woods.jsonhash into a ResolvedConfig.
Instance Method Summary collapse
-
#assert_compatible!(stored_config) ⇒ void
Assert that
stored_config(the config captured at embed time) is compatible withself(the live host config). -
#dimension ⇒ Integer
Embedding dimension declared by the provider.
-
#initialize(schema_version:, gem_version:, created_at:, embedding_provider:, stores:) ⇒ ResolvedConfig
constructor
A new instance of ResolvedConfig.
-
#matches?(other) ⇒ Boolean
Returns
trueifotheruses the same provider class, model, dimension, and store types. -
#provider_signature ⇒ String
Short string identifying this provider configuration, useful for log messages and ConfigMismatch error text.
- #to_h ⇒ Hash
-
#to_snapshot_json ⇒ Hash
Serialize to a Hash suitable for
JSON.generateand round-trippable through ResolvedConfig.from_hash.
Constructor Details
#initialize(schema_version:, gem_version:, created_at:, embedding_provider:, stores:) ⇒ ResolvedConfig
Returns a new instance of ResolvedConfig.
116 117 118 119 120 121 122 123 |
# File 'lib/woods/resolved_config.rb', line 116 def initialize(schema_version:, gem_version:, created_at:, embedding_provider:, stores:) @schema_version = schema_version @gem_version = gem_version.to_s.freeze @created_at = created_at @embedding_provider = deep_freeze() @stores = deep_freeze(stores) freeze end |
Instance Attribute Details
#created_at ⇒ Time (readonly)
39 40 41 |
# File 'lib/woods/resolved_config.rb', line 39 def created_at @created_at end |
#embedding_provider ⇒ Hash (readonly)
Returns Provider details — :class, :model, :host, :num_ctx, :read_timeout, :dimension.
42 43 44 |
# File 'lib/woods/resolved_config.rb', line 42 def @embedding_provider end |
#gem_version ⇒ String (readonly)
Returns Gem version at embed time (e.g. “1.2.0”).
36 37 38 |
# File 'lib/woods/resolved_config.rb', line 36 def gem_version @gem_version end |
#schema_version ⇒ Integer (readonly)
33 34 35 |
# File 'lib/woods/resolved_config.rb', line 33 def schema_version @schema_version end |
#stores ⇒ Hash (readonly)
Returns Store types — :vector_store, :metadata_store, :graph_store (Symbols).
45 46 47 |
# File 'lib/woods/resolved_config.rb', line 45 def stores @stores end |
Class Method Details
.from_configuration(config, gem_version: nil, provider: nil) ⇒ ResolvedConfig
Capture the current Configuration as a Woods::ResolvedConfig.
The provider: kwarg lets callers pass a live embedding provider so the dimension is discovered at runtime instead of being read from a declared-only field. This matters for Ollama — dimensions come from the model, not the config — and doesn’t hurt OpenAI, whose provider exposes the same #dimensions interface.
When provider: is omitted, dimension falls back to config.embedding_options[:dimension] (useful for specs and for offline ResolvedConfig construction where no provider exists).
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/woods/resolved_config.rb', line 82 def self.from_configuration(config, gem_version: nil, provider: nil) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity require_relative 'version' opts = config. || {} declared_dim = opts[:dimension] || opts['dimension'] dim = declared_dim || (provider.respond_to?(:dimensions) ? provider.dimensions : nil) provider_hash = { class: resolve_provider_class(config.), model: (opts[:model] || opts['model'] || config.).to_s, dimension: dim.to_i, host: opts[:host] || opts['host'], num_ctx: opts[:num_ctx] || opts['num_ctx'], read_timeout: opts[:read_timeout] || opts['read_timeout'] }.compact new( schema_version: SCHEMA_VERSION_SUPPORTED, gem_version: (gem_version || Woods::VERSION).to_s, created_at: Time.now.utc, embedding_provider: provider_hash, stores: { vector_store: config.vector_store, metadata_store: config., graph_store: config.graph_store } ) end |
.from_hash(raw) ⇒ ResolvedConfig
Parse a woods.json hash into a Woods::ResolvedConfig.
52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/woods/resolved_config.rb', line 52 def self.from_hash(raw) data = normalize_keys(raw) validate_schema_version!(data[:schema_version].to_i) new( schema_version: data[:schema_version].to_i, gem_version: data[:gem_version].to_s, created_at: parse_time(data[:created_at]), embedding_provider: parse_provider(data[:embedding_provider] || {}), stores: parse_stores(data[:stores] || {}) ) end |
Instance Method Details
#assert_compatible!(stored_config) ⇒ void
This method returns an undefined value.
Assert that stored_config (the config captured at embed time) is compatible with self (the live host config). Raises typed errors so the operator can diagnose the mismatch without reading source.
163 164 165 166 |
# File 'lib/woods/resolved_config.rb', line 163 def assert_compatible!(stored_config) assert_dimensions_match!(stored_config) assert_provider_matches!(stored_config) end |
#dimension ⇒ Integer
Returns Embedding dimension declared by the provider.
126 127 128 |
# File 'lib/woods/resolved_config.rb', line 126 def dimension [:dimension].to_i end |
#matches?(other) ⇒ Boolean
Returns true if other uses the same provider class, model, dimension, and store types. Ignores gem version, read_timeout, num_ctx, and created_at.
146 147 148 149 150 151 152 153 |
# File 'lib/woods/resolved_config.rb', line 146 def matches?(other) [:class] == other.[:class] && [:model] == other.[:model] && dimension == other.dimension && stores[:vector_store] == other.stores[:vector_store] && stores[:metadata_store] == other.stores[:metadata_store] && stores[:graph_store] == other.stores[:graph_store] end |
#provider_signature ⇒ String
Short string identifying this provider configuration, useful for log messages and ConfigMismatch error text.
134 135 136 137 138 139 |
# File 'lib/woods/resolved_config.rb', line 134 def provider_signature klass = [:class].to_s.split('::').last model = [:model] host = [:host] host ? "#{klass}/#{model}@#{host}" : "#{klass}/#{model}" end |
#to_h ⇒ Hash
183 184 185 |
# File 'lib/woods/resolved_config.rb', line 183 def to_h to_snapshot_json.freeze end |
#to_snapshot_json ⇒ Hash
Serialize to a Hash suitable for JSON.generate and round-trippable through from_hash.
172 173 174 175 176 177 178 179 180 |
# File 'lib/woods/resolved_config.rb', line 172 def to_snapshot_json { 'schema_version' => schema_version, 'gem_version' => gem_version, 'created_at' => created_at.iso8601, 'embedding_provider' => .transform_keys(&:to_s), 'stores' => stores.transform_keys(&:to_s).transform_values(&:to_s) } end |