Class: Ask::ModelCatalog

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ask/models.rb

Overview

Catalog of available AI models.

Ask::ModelCatalog.find("gpt-4o")                  # => ModelInfo or raises
Ask::ModelCatalog.find("gpt-4o", provider: "openai")  # => ModelInfo or raises
Ask::ModelCatalog.where("gpt-4o")                 # => [ModelInfo, ...] (all matches)

Constant Summary collapse

MODELS_DEV_URL =

Returns URL for the models.dev API.

Returns:

  • (String)

    URL for the models.dev API

"https://models.dev/api.json".freeze
DELEGATES =

Methods delegated to the singleton instance.

%i[all each find where chat_models embedding_models
audio_models image_models by_family by_provider
refresh!].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(models = nil) ⇒ ModelCatalog

Returns a new instance of ModelCatalog.

Parameters:

  • models (Array<Ask::ModelInfo>, nil) (defaults to: nil)

    initial model list



295
296
297
# File 'lib/ask/models.rb', line 295

def initialize(models = nil)
  @models = models || []
end

Class Method Details

.instanceAsk::ModelCatalog

Returns the process-wide singleton instance.

Returns:



284
285
286
# File 'lib/ask/models.rb', line 284

def instance
  @instance ||= new
end

.reset_instance!Object

Reset the singleton instance (useful for testing).



289
290
291
# File 'lib/ask/models.rb', line 289

def reset_instance!
  @instance = nil
end

Instance Method Details

#allArray<Ask::ModelInfo>

Returns all models in the catalog.

Returns:



302
303
304
# File 'lib/ask/models.rb', line 302

def all
  @models
end

#audio_modelsAsk::ModelCatalog

Returns new catalog containing only audio models.

Returns:



345
346
347
# File 'lib/ask/models.rb', line 345

def audio_models
  self.class.new(@models.select(&:audio?))
end

#by_family(family) ⇒ Ask::ModelCatalog

Returns new catalog filtered by family.

Parameters:

  • family (String)

    family name

Returns:



356
357
358
# File 'lib/ask/models.rb', line 356

def by_family(family)
  self.class.new(@models.select { |m| m.family.to_s == family.to_s })
end

#by_provider(provider) ⇒ Ask::ModelCatalog

Returns new catalog filtered by provider.

Parameters:

  • provider (String)

    provider slug

Returns:



362
363
364
# File 'lib/ask/models.rb', line 362

def by_provider(provider)
  self.class.new(@models.select { |m| m.provider == provider.to_s })
end

#chat_modelsAsk::ModelCatalog

Returns new catalog containing only chat models.

Returns:



335
336
337
# File 'lib/ask/models.rb', line 335

def chat_models
  self.class.new(@models.select(&:chat?))
end

#each {|Ask::ModelInfo| ... } ⇒ Enumerator

Yields:

Returns:

  • (Enumerator)


308
309
310
# File 'lib/ask/models.rb', line 308

def each(&block)
  @models.each(&block)
end

#embedding_modelsAsk::ModelCatalog

Returns new catalog containing only embedding models.

Returns:



340
341
342
# File 'lib/ask/models.rb', line 340

def embedding_models
  self.class.new(@models.select(&:embedding?))
end

#find(model_id, provider: nil) ⇒ Ask::ModelInfo

Find a single model by ID. Scopes to provider when given.

Parameters:

  • model_id (String)

    model identifier

  • provider (String, nil) (defaults to: nil)

    provider slug (optional keyword)

Returns:

Raises:



317
318
319
320
321
322
323
324
325
# File 'lib/ask/models.rb', line 317

def find(model_id, provider: nil)
  if provider
    @models.find { |m| m.id == model_id && m.provider == provider.to_s } ||
      raise(ModelNotFound, "Model #{model_id.inspect} not found for provider #{provider.inspect}.")
  else
    @models.find { |m| m.id == model_id } ||
      raise(ModelNotFound, "Unknown model: #{model_id.inspect}.")
  end
end

#image_modelsAsk::ModelCatalog

Returns new catalog containing only image models.

Returns:



350
351
352
# File 'lib/ask/models.rb', line 350

def image_models
  self.class.new(@models.select(&:image?))
end

#lengthInteger Also known as: size

Returns number of models.

Returns:

  • (Integer)

    number of models



367
# File 'lib/ask/models.rb', line 367

def length = @models.length

#refresh!(timeout: 10) ⇒ self

Fetch the latest model data from the models.dev API. Falls back to current models if the API is unreachable.

Parameters:

  • timeout (Integer) (defaults to: 10)

    HTTP timeout in seconds

Returns:

  • (self)


376
377
378
379
# File 'lib/ask/models.rb', line 376

def refresh!(timeout: 10)
  @models = fetch_from_models_dev(timeout: timeout)
  self
end

#register(model) ⇒ self

Register a single model, skipping duplicates.

Parameters:

Returns:

  • (self)


386
387
388
389
# File 'lib/ask/models.rb', line 386

def register(model)
  @models << model unless @models.any? { |m| m.id == model.id && m.provider == model.provider }
  self
end

#where(model_id) ⇒ Array<Ask::ModelInfo>

Find all models matching an ID. Never raises.

Parameters:

  • model_id (String)

    model identifier

Returns:



330
331
332
# File 'lib/ask/models.rb', line 330

def where(model_id)
  @models.select { |m| m.id == model_id }
end