Module: Raif::ModelManifest::Dsl

Defined in:
lib/raif/model_manifest/dsl.rb

Defined Under Namespace

Classes: Context, EmbeddingModelDeclaration, EmbeddingProviderBuilder, EmbeddingProviderDeclaration, EmbeddingRegistryBuilder, ModelDeclaration, ProviderBuilder, ProviderDeclaration, UnknownDeclaration

Class Method Summary collapse

Class Method Details

.deep_freeze(value) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/raif/model_manifest/dsl.rb', line 110

def deep_freeze(value)
  case value
  when Hash then value.to_h { |key, nested| [deep_freeze(key), deep_freeze(nested)] }.freeze
  when Array then value.map { |nested| deep_freeze(nested) }.freeze
  else value.freeze
  end
end

.normalize_capabilities(capabilities) ⇒ Object

Manifest files are Ruby, so these hashes normally arrive symbol-keyed already. Normalizing anyway means the entry shape consumers rely on is guaranteed by the loader rather than by author discipline.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/raif/model_manifest/dsl.rb', line 47

def normalize_capabilities(capabilities)
  normalized = capabilities.transform_keys(&:to_sym)
  if normalized.key?(:provider_managed_tools)
    normalized[:provider_managed_tools] = Array(normalized[:provider_managed_tools]).map(&:to_sym)
  end

  # Existing declarations inherit tool-choice support from native tool use.
  TOOL_CHOICE_CAPABILITY_KEYS.each do |key|
    normalized[key] = normalized.fetch(:native_tool_use, false) unless normalized.key?(key)
  end

  deep_freeze(normalized)
end

.normalize_endpoint_lifecycle(lifecycle, endpoint:, source_path:) ⇒ Object

Endpoint lifecycle overrides are merged over the model-level lifecycle by ModelManifest.entries_for_model, so they are normalized to the same shape here (symbol keys, symbol replacement_key) but limited to ENDPOINT_LIFECYCLE_KEYS.



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/raif/model_manifest/dsl.rb', line 98

def normalize_endpoint_lifecycle(lifecycle, endpoint:, source_path:)
  normalized = lifecycle.transform_keys(&:to_sym)
  unknown = normalized.keys - ENDPOINT_LIFECYCLE_KEYS
  unless unknown.empty?
    raise ArgumentError, "#{source_path}: endpoint #{endpoint.inspect} lifecycle may only override " \
      "#{ENDPOINT_LIFECYCLE_KEYS.join(", ")}; got #{unknown.join(", ")}"
  end

  normalized[:replacement_key] &&= normalized[:replacement_key].to_sym
  normalized
end

.normalize_endpoints(endpoints, source_path:) ⇒ Object

Endpoint names become strings because that is what the adapter and key-prefix maps in ModelManifest are keyed by. Lifecycle overrides keep migration targets on the same API as the deprecated entry.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/raif/model_manifest/dsl.rb', line 80

def normalize_endpoints(endpoints, source_path:)
  endpoints.to_h do |endpoint, declaration|
    attributes = declaration.transform_keys(&:to_sym)
    unknown = attributes.keys - [:capabilities, :lifecycle]
    unless unknown.empty?
      raise ArgumentError, "#{source_path}: endpoint #{endpoint.inspect} declares unknown attributes: #{unknown.join(", ")}"
    end

    [endpoint.to_s, deep_freeze({
      capabilities: normalize_capabilities(attributes.fetch(:capabilities)),
      lifecycle: normalize_endpoint_lifecycle(attributes.fetch(:lifecycle, {}), endpoint: endpoint, source_path: source_path)
    })]
  end.freeze
end

.normalize_lifecycle(lifecycle) ⇒ Object

Every lifecycle field is always present, defaulting to nil, so callers can read retirement_date or replacement_key off any entry without first asking whether the model bothered to declare them. replacement_key is symbolized alongside status because callers match it against entry keys, which are symbols.



66
67
68
69
70
71
# File 'lib/raif/model_manifest/dsl.rb', line 66

def normalize_lifecycle(lifecycle)
  normalized = LIFECYCLE_KEYS.to_h { |key| [key, nil] }.merge(lifecycle.transform_keys(&:to_sym))
  normalized[:status] &&= normalized[:status].to_sym
  normalized[:replacement_key] &&= normalized[:replacement_key].to_sym
  deep_freeze(normalized)
end

.normalize_pricing(pricing) ⇒ Object



73
74
75
# File 'lib/raif/model_manifest/dsl.rb', line 73

def normalize_pricing(pricing)
  deep_freeze(pricing.transform_keys(&:to_sym))
end