Skip to main content

oino_models/resolver/
mod.rs

1//! Model resolution and cycling: `--model`, `--models` / `enabledModels`, initial
2//! selection, session restore.
3//!
4//! Pure functions take model slices; functions that need credentials take a
5//! [`ModelCatalog`] (implemented by [`crate::ModelRegistry`]).
6
7mod cli;
8mod cycle;
9mod defaults;
10mod initial;
11mod reference;
12mod scope;
13
14use oino_ai::Model;
15
16pub use self::cli::{CliModel, CliModelError, CliModelRequest, resolve_cli_model};
17pub use self::cycle::{
18    CycleDirection, ThinkingSwitch, next_available_model, next_scoped_model,
19    thinking_level_for_model_switch,
20};
21pub use self::defaults::{
22    DEFAULT_MODEL_PER_PROVIDER, DEFAULT_THINKING_LEVEL, default_model_for_provider,
23};
24pub use self::initial::{
25    InitialModel, InitialModelOptions, RestoreNotice, RestoredModel, find_initial_model,
26    model_thinking_level_key, restore_model_from_session,
27};
28pub use self::reference::{
29    ModelReferenceRequest, ModelReferenceResult, ModelReferenceTarget, ThinkingSuffix,
30    find_exact_model_reference_match, resolve_model_reference,
31};
32pub use self::scope::{
33    ResolveModelScopeResult, ScopeDiagnostic, ScopeDiagnosticCode, ScopedModel, resolve_model_scope,
34};
35
36/// The catalog view the resolver needs.
37pub trait ModelCatalog {
38    /// Every model.
39    fn all(&self) -> Vec<Model>;
40    /// Models with usable credentials.
41    fn available(&self) -> Vec<Model>;
42    /// A model by provider and id.
43    fn find(&self, provider: &str, id: &str) -> Option<Model>;
44    /// Whether the provider has usable credentials.
45    fn has_configured_auth(&self, provider: &str) -> bool;
46}
47
48impl ModelCatalog for crate::ModelRegistry {
49    fn all(&self) -> Vec<Model> {
50        Self::all(self)
51    }
52
53    fn available(&self) -> Vec<Model> {
54        Self::available(self)
55    }
56
57    fn find(&self, provider: &str, id: &str) -> Option<Model> {
58        Self::find(self, provider, id)
59    }
60
61    fn has_configured_auth(&self, provider: &str) -> bool {
62        Self::has_configured_auth(self, provider)
63    }
64}
65
66/// [`resolve_cli_model`] against a catalog (all models, credentials as tie-breaker).
67///
68/// # Errors
69///
70/// See [`resolve_cli_model`].
71pub fn resolve_cli_model_in(
72    request: &CliModelRequest<'_>,
73    catalog: &dyn ModelCatalog,
74) -> Result<Option<CliModel>, CliModelError> {
75    resolve_cli_model(request, &catalog.all(), &|provider| {
76        catalog.has_configured_auth(provider)
77    })
78}
79
80/// Scope patterns against the available models.
81#[must_use]
82pub fn resolve_model_scope_in(
83    patterns: &[String],
84    catalog: &dyn ModelCatalog,
85) -> ResolveModelScopeResult {
86    resolve_model_scope(patterns, &catalog.available())
87}
88
89#[cfg(test)]
90mod tests;