class LittleGhost::ModelRegistry

Give application roles stable model choices without coupling agents to vendors. A registry joins provider factories with named, inheritable profiles.

A support application can keep its general and research agents on related profiles while selecting one provider in one place:

class CustomerSupportModels < LittleGhost::ModelRegistry
  def initialize
    super
    provider(:openai) do |model:, **|
      LittleGhost::Providers::OpenAI.new(
        api_key: ENV.fetch("OPENAI_API_KEY"), model: model
      )
    end
    profile "customer_support", provider: :openai, model: "gpt-5"
    profile "customer_support.research", inherit: "customer_support",
      settings: {temperature: 0.1}
  end
end

model = CustomerSupportModels.new.resolve("customer_support.research")
model.id       # => "gpt-5"
model.settings # => {temperature: 0.1}

Dotted roles resolve from the exact role toward shorter registered parents. Explicit profile inheritance supplies provider, model, settings, and metadata; per-invocation overrides then layer from inherited parents through the exact requested role. A final override passed to resolve wins over both. Settings and overrides are control-plane input: construct or allowlist them in application code rather than copying unchecked request fields. An override can select a different registered provider or model and change the destination, capability, and cost of a request.

Provider factories receive the resolved identity, settings, metadata, invocation, run context, and forwarding options. Resolution raises ConfigurationError for missing roles, providers, models, factories, or circular inheritance; exceptions raised inside a factory are not masked.