ask-core 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3344dad8d0965fe27ab622e6ff3a216bc000de33d844ca801b534763d0b7337c
4
- data.tar.gz: 0053ed57a1a8c5c24e691352f1ef0781555ba0e1d4278fc05a9ee9c688f217ed
3
+ metadata.gz: e87a2c3690127974ace8b8143002728a1eb6bebbaae9d54b321c5f4342c20485
4
+ data.tar.gz: 605fb219de7a80fcf33a97b21a9a2149f688e7bdd25a066484f235e41e127420
5
5
  SHA512:
6
- metadata.gz: 3bb49abe262df54f05dca655031e434dd94afa029709431d0def3a2ba13fb745aac3479c6c97634f466e6da1da35674fa464afa261a914b0c5ca66f2213c74c0
7
- data.tar.gz: f009877f5d58f03b0b20bca5922a3d87f43f83951bdaa9ebae81b0def2f78fba4ee4aee79a703771966e6466736f86cb8d121dc065e19f3c4e99dd7fe1e9f46b
6
+ metadata.gz: 1b8852000559343d48f693bb80cda7b7bc4ed9ecf935fc3e2336c80798277a35e31e4dd37a8453ae9d69adbc88a3e80650f26b6eaf64fa7d757f0711301106c1
7
+ data.tar.gz: 8713f24a5530fbc86f347016e3eb811e4e2ddb14cf5d08368bf6f8d28ffa3aa5c32127a91c75923146ffc3e940295a6edff2bab4c2df7838f50bd207e7dc3232
data/CHANGELOG.md CHANGED
@@ -1,4 +1,15 @@
1
- ## [0.2.1] - 2026-06-25
1
+ ## [0.2.3] 2026-07-14
2
+
3
+ ### Changed
4
+ - `Ask::ModelCatalog.find(model_id)` now returns `Array<Ask::ModelInfo>` (all matches) — provider preference disambiguation is removed. Provider-scoped `find(model_id, provider)` still returns a single model or raises.
5
+ - Removed `Ask::ModelCatalog::PROVIDER_PREFERENCE`. No preference list anywhere — all providers and models are treated equally.
6
+
7
+ ## [0.2.2] — 2026-07-14
8
+
9
+ ### Added
10
+ - `Ask::ModelCatalog::PROVIDER_PREFERENCE` — includes `opencode`, `opencode_go`, `mimo` for proper disambiguation of models served by aggregator providers.
11
+
12
+ ## [0.2.1] — 2026-06-25
2
13
 
3
14
  ### Changed
4
15
  - Testing infrastructure: rubocop, overcommit, bin/setup, gemspec validation, SimpleCov, CI matrix, .minitest config
data/lib/ask/models.rb CHANGED
@@ -256,12 +256,11 @@ module Ask
256
256
  end
257
257
  end
258
258
 
259
- # Catalog of available AI models. Provides model resolution by name/ID,
260
- # filtering by capability, and refresh from the models.dev API.
259
+ # Catalog of available AI models.
261
260
  #
262
- # Ask::ModelCatalog.find("gpt-4o")
263
- # Ask::ModelCatalog.chat_models
264
- # Ask::ModelCatalog.refresh!
261
+ # Ask::ModelCatalog.find("gpt-4o") # => ModelInfo or raises
262
+ # Ask::ModelCatalog.find("gpt-4o", provider: "openai") # => ModelInfo or raises
263
+ # Ask::ModelCatalog.where("gpt-4o") # => [ModelInfo, ...] (all matches)
265
264
  #
266
265
  class ModelCatalog
267
266
  include Enumerable
@@ -269,15 +268,8 @@ module Ask
269
268
  # @return [String] URL for the models.dev API
270
269
  MODELS_DEV_URL = "https://models.dev/api.json".freeze
271
270
 
272
- # Ordered provider preference for disambiguation.
273
- PROVIDER_PREFERENCE = %w[
274
- openai anthropic gemini vertexai bedrock
275
- openrouter deepseek mistral perplexity xai
276
- azure ollama gpustack github
277
- ].freeze
278
-
279
271
  # Methods delegated to the singleton instance.
280
- DELEGATES = %i[all each find chat_models embedding_models
272
+ DELEGATES = %i[all each find where chat_models embedding_models
281
273
  audio_models image_models by_family by_provider
282
274
  refresh!].freeze
283
275
 
@@ -317,19 +309,28 @@ module Ask
317
309
  @models.each(&block)
318
310
  end
319
311
 
320
- # Find a model by ID, optionally scoped to a provider.
312
+ # Find a single model by ID. Scopes to provider when given.
321
313
  # @param model_id [String] model identifier
322
- # @param provider [String, nil] provider slug
314
+ # @param provider [String, nil] provider slug (optional keyword)
323
315
  # @return [Ask::ModelInfo]
324
- # @raise [ModelNotFound] if the model is not found
325
- def find(model_id, provider = nil)
316
+ # @raise [ModelNotFound] if no matching model is found
317
+ def find(model_id, provider: nil)
326
318
  if provider
327
- find_with_provider(model_id, provider.to_s)
319
+ @models.find { |m| m.id == model_id && m.provider == provider.to_s } ||
320
+ raise(ModelNotFound, "Model #{model_id.inspect} not found for provider #{provider.inspect}.")
328
321
  else
329
- find_without_provider(model_id)
322
+ @models.find { |m| m.id == model_id } ||
323
+ raise(ModelNotFound, "Unknown model: #{model_id.inspect}.")
330
324
  end
331
325
  end
332
326
 
327
+ # Find all models matching an ID. Never raises.
328
+ # @param model_id [String] model identifier
329
+ # @return [Array<Ask::ModelInfo>] matching models (empty if none)
330
+ def where(model_id)
331
+ @models.select { |m| m.id == model_id }
332
+ end
333
+
333
334
  # @return [Ask::ModelCatalog] new catalog containing only chat models
334
335
  def chat_models
335
336
  self.class.new(@models.select(&:chat?))
@@ -389,31 +390,6 @@ module Ask
389
390
 
390
391
  private
391
392
 
392
- def find_with_provider(model_id, provider)
393
- exact = @models.find { |m| m.id == model_id && m.provider == provider }
394
- return exact if exact
395
-
396
- @models.find { |m| m.id == model_id && m.provider == provider } ||
397
- raise(ModelNotFound, "Model #{model_id.inspect} not found for provider #{provider.inspect}. " \
398
- "Try ModelCatalog.refresh! to update the catalog.")
399
- end
400
-
401
- def find_without_provider(model_id)
402
- matches = @models.select { |m| m.id == model_id }
403
- return preferred_match(matches) if matches.any?
404
-
405
- raise ModelNotFound, "Unknown model: #{model_id.inspect}. " \
406
- "Try ModelCatalog.refresh! to update the catalog."
407
- end
408
-
409
- def preferred_match(candidates)
410
- return candidates.first if candidates.size == 1
411
-
412
- candidates.min_by do |model|
413
- PROVIDER_PREFERENCE.index(model.provider) || PROVIDER_PREFERENCE.length
414
- end
415
- end
416
-
417
393
  def fetch_from_models_dev(timeout: 10)
418
394
  uri = URI(MODELS_DEV_URL)
419
395
  http = Net::HTTP.new(uri.host, uri.port)
data/lib/ask/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ask
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto