Module: Legion::Extensions::Llm::Inventory::RecordSupport
- Defined in:
- lib/legion/extensions/llm/inventory/records.rb
Overview
Shared normalization/validation used by the immutable inventory and routing records. Kept internal to the records so no record implements a competing validator. See phase-1-lex-llm-additive.md sections 10 and 15.
Constant Summary collapse
- SECRET_KEY_TOKENS =
%w[ credential authorization token secret password apikey prompt endpointurl callable ].freeze
- PUBLICATION_SOURCES =
%i[provider_catalog provider_static_catalog provider_control_plane].freeze
Class Method Summary collapse
- .boolean!(value:, field:) ⇒ Object
- .check_unknown_kwargs!(kwargs:, members:) ⇒ Object
- .embedding_dimensions_value_evidence!(evidence, field) ⇒ Object
- .frozen_metadata(value:, field: :metadata) ⇒ Object
- .model_revision_value_evidence!(evidence, field) ⇒ Object
- .nonempty_nfc!(value:, field:) ⇒ Object
- .nonnegative_integer(value:, field:) ⇒ Object
- .nonnegative_integer?(value) ⇒ Boolean
- .normalize_provider_family(value:, field: :provider_family) ⇒ Object
- .optional_sanitized_reason(value:, field:, max_bytes: 1024) ⇒ Object
- .optional_time(value:, field:) ⇒ Object
- .positive_int_value_evidence!(evidence, field) ⇒ Object
- .publication_source!(value:) ⇒ Object
- .reject_secret_keys!(value, field) ⇒ Object
- .sanitized_reason(value:, field:, max_bytes: 1024) ⇒ Object
-
.scalar_value_evidences(kwargs) ⇒ Object
Validates and returns the five scalar ValueEvidence fields shared by OfferingDraft, OfferingRecord, and LaneRecord as a member Hash.
- .secret_key?(key) ⇒ Boolean
- .tokenizer_value_evidence!(evidence, field) ⇒ Object
- .valid_utf8?(string) ⇒ Boolean
- .validate_capability_evidence!(evidence) ⇒ Object
- .validate_operation_evidence!(evidence) ⇒ Object
- .validate_quota_domain_value!(value:, field:) ⇒ Object
- .validate_quota_domains!(quota_domains) ⇒ Object
- .value_evidence!(evidence, field) ⇒ Object
Class Method Details
.boolean!(value:, field:) ⇒ Object
70 71 72 73 74 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 70 def boolean!(value:, field:) return value if [true, false].include?(value) raise Errors::ValidationError, "#{field} must be true or false" end |
.check_unknown_kwargs!(kwargs:, members:) ⇒ Object
34 35 36 37 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 34 def check_unknown_kwargs!(kwargs:, members:) unknown = kwargs.keys - members raise Errors::ValidationError, "unknown keyword(s): #{unknown.join(', ')}" unless unknown.empty? end |
.embedding_dimensions_value_evidence!(evidence, field) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 192 def (evidence, field) value_evidence!(evidence, field) return evidence unless evidence.known? dims = evidence.value valid = dims.is_a?(::Array) && !dims.empty? && dims.all? { |dim| dim.is_a?(::Integer) && dim.positive? } && dims == dims.uniq && dims == dims.sort raise Errors::ValidationError, "known #{field} must be a sorted, unique Array of positive Integers" unless valid evidence end |
.frozen_metadata(value:, field: :metadata) ⇒ Object
90 91 92 93 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 90 def (value:, field: :metadata) reject_secret_keys!(value, field) ImmutableValue.copy_and_freeze(value: value, field: field) end |
.model_revision_value_evidence!(evidence, field) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 205 def model_revision_value_evidence!(evidence, field) value_evidence!(evidence, field) return evidence unless evidence.known? revision = evidence.value valid = revision.is_a?(::String) && !revision.strip.empty? && valid_utf8?(revision) && revision.unicode_normalized?(:nfc) raise Errors::ValidationError, "known #{field} must be a nonempty NFC String" unless valid evidence end |
.nonempty_nfc!(value:, field:) ⇒ Object
233 234 235 236 237 238 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 233 def nonempty_nfc!(value:, field:) valid = value.is_a?(::String) && !value.strip.empty? && valid_utf8?(value) && value.unicode_normalized?(:nfc) raise Errors::ValidationError, "#{field} must be a nonempty NFC String" unless valid value end |
.nonnegative_integer(value:, field:) ⇒ Object
60 61 62 63 64 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 60 def nonnegative_integer(value:, field:) raise Errors::ValidationError, "#{field} must be a nonnegative Integer" unless nonnegative_integer?(value) value end |
.nonnegative_integer?(value) ⇒ Boolean
66 67 68 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 66 def nonnegative_integer?(value) value.is_a?(::Integer) && !value.negative? end |
.normalize_provider_family(value:, field: :provider_family) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 76 def normalize_provider_family(value:, field: :provider_family) text = Identity.normalize_text(value: value, field: field).downcase raise Errors::ValidationError, "#{field} must be snake-case ASCII" unless text.match?(/\A[a-z][a-z0-9_]*\z/) text.to_sym end |
.optional_sanitized_reason(value:, field:, max_bytes: 1024) ⇒ Object
54 55 56 57 58 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 54 def optional_sanitized_reason(value:, field:, max_bytes: 1024) return nil if value.nil? sanitized_reason(value: value, field: field, max_bytes: max_bytes) end |
.optional_time(value:, field:) ⇒ Object
83 84 85 86 87 88 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 83 def optional_time(value:, field:) return nil if value.nil? raise Errors::ValidationError, "#{field} must be a Time" unless value.is_a?(::Time) value.dup.freeze end |
.positive_int_value_evidence!(evidence, field) ⇒ Object
185 186 187 188 189 190 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 185 def positive_int_value_evidence!(evidence, field) value_evidence!(evidence, field) raise Errors::ValidationError, "known #{field} must be a positive Integer" if evidence.known? && !(evidence.value.is_a?(::Integer) && evidence.value.positive?) evidence end |
.publication_source!(value:) ⇒ Object
240 241 242 243 244 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 240 def publication_source!(value:) raise Errors::ValidationError, "publication_source must be one of #{PUBLICATION_SOURCES.inspect}" unless PUBLICATION_SOURCES.include?(value) value end |
.reject_secret_keys!(value, field) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 95 def reject_secret_keys!(value, field) case value when ::Hash value.each do |key, nested| raise Errors::ValidationError, "#{field} contains a secret-like key" if secret_key?(key) reject_secret_keys!(nested, field) end when ::Array value.each { |element| reject_secret_keys!(element, field) } end end |
.sanitized_reason(value:, field:, max_bytes: 1024) ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 43 def sanitized_reason(value:, field:, max_bytes: 1024) raise Errors::ValidationError, "#{field} must be a String" unless value.is_a?(::String) raise Errors::ValidationError, "#{field} is not valid UTF-8" unless valid_utf8?(value) trimmed = value.strip raise Errors::ValidationError, "#{field} must not be empty" if trimmed.empty? raise Errors::ValidationError, "#{field} exceeds #{max_bytes} UTF-8 bytes" if trimmed.bytesize > max_bytes trimmed.b.dup.force_encoding(::Encoding::UTF_8).freeze end |
.scalar_value_evidences(kwargs) ⇒ Object
Validates and returns the five scalar ValueEvidence fields shared by OfferingDraft, OfferingRecord, and LaneRecord as a member Hash.
165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 165 def scalar_value_evidences(kwargs) { context_evidence: positive_int_value_evidence!(kwargs[:context_evidence], :context_evidence), max_output_evidence: positive_int_value_evidence!(kwargs[:max_output_evidence], :max_output_evidence), embedding_dimensions_evidence: ( kwargs[:embedding_dimensions_evidence], :embedding_dimensions_evidence ), model_revision_evidence: model_revision_value_evidence!( kwargs[:model_revision_evidence], :model_revision_evidence ), tokenizer_evidence: tokenizer_value_evidence!(kwargs[:tokenizer_evidence], :tokenizer_evidence) } end |
.secret_key?(key) ⇒ Boolean
108 109 110 111 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 108 def secret_key?(key) normalized = key.to_s.downcase.gsub(/[^a-z0-9]/, '') SECRET_KEY_TOKENS.any? { |token| normalized.include?(token) } end |
.tokenizer_value_evidence!(evidence, field) ⇒ Object
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 217 def tokenizer_value_evidence!(evidence, field) value_evidence!(evidence, field) return evidence unless evidence.known? descriptor = evidence.value unless descriptor.is_a?(::Hash) && descriptor.keys.sort == %i[estimator parameters version] raise Errors::ValidationError, "known #{field} must be exactly {estimator:, version:, parameters:}" end nonempty_nfc!(value: descriptor[:estimator], field: "#{field}.estimator") nonempty_nfc!(value: descriptor[:version], field: "#{field}.version") raise Errors::ValidationError, "#{field}.parameters must be a Hash" unless descriptor[:parameters].is_a?(::Hash) evidence end |
.valid_utf8?(string) ⇒ Boolean
39 40 41 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 39 def valid_utf8?(string) [::Encoding::UTF_8, ::Encoding::US_ASCII].include?(string.encoding) && string.valid_encoding? end |
.validate_capability_evidence!(evidence) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 130 def validate_capability_evidence!(evidence) raise Errors::ValidationError, 'capability_evidence must be a Hash' unless evidence.is_a?(::Hash) normalized = {} evidence.each do |key, value| cap = Legion::Extensions::Llm::Capabilities.canonical(key) raise Errors::ValidationError, "capability_evidence key #{cap} is not canonical" unless Legion::Extensions::Llm::Capabilities::CANONICAL.include?(cap) raise Errors::ValidationError, "capability_evidence[#{cap}] must be a CapabilityEvidence" unless value.is_a?(CapabilityEvidence) raise Errors::ValidationError, "capability_evidence[#{cap}] capability must match key" unless value.capability == cap raise Errors::ValidationError, "duplicate capability_evidence key #{cap}" if normalized.key?(cap) normalized[cap] = value end normalized.freeze end |
.validate_operation_evidence!(evidence) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 113 def validate_operation_evidence!(evidence) raise Errors::ValidationError, 'operation_evidence must be a Hash' unless evidence.is_a?(::Hash) normalized = {} evidence.each do |key, value| op = Taxonomies.normalize_operation(value: key, allow_aliases: false) raise Errors::ValidationError, "operation_evidence[#{op}] must be an OperationEvidence" unless value.is_a?(OperationEvidence) raise Errors::ValidationError, "operation_evidence[#{op}] operation must match key" unless value.operation == op raise Errors::ValidationError, "duplicate operation_evidence key #{op}" if normalized.key?(op) normalized[op] = value end raise Errors::ValidationError, 'operation_evidence keys must equal Taxonomies::OPERATIONS exactly' unless normalized.keys.sort == Taxonomies::OPERATIONS.sort normalized.freeze end |
.validate_quota_domain_value!(value:, field:) ⇒ Object
157 158 159 160 161 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 157 def validate_quota_domain_value!(value:, field:) raise Errors::ValidationError, "#{field} must be a nonempty opaque String" unless value.is_a?(::String) && valid_utf8?(value) && !value.strip.empty? value.dup.freeze end |
.validate_quota_domains!(quota_domains) ⇒ Object
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 146 def validate_quota_domains!(quota_domains) raise Errors::ValidationError, 'quota_domains must be a Hash' unless quota_domains.is_a?(::Hash) normalized = {} quota_domains.each do |key, value| op = Taxonomies.normalize_operation(value: key, allow_aliases: false) normalized[op] = validate_quota_domain_value!(value: value, field: "quota_domains[#{op}]") end normalized.freeze end |
.value_evidence!(evidence, field) ⇒ Object
179 180 181 182 183 |
# File 'lib/legion/extensions/llm/inventory/records.rb', line 179 def value_evidence!(evidence, field) raise Errors::ValidationError, "#{field} must be a ValueEvidence" unless evidence.is_a?(ValueEvidence) evidence end |