Skip to main content

oino_models/
lib.rs

1//! `oino-models`: the model registry, `models.json`, model resolution, `auth.json`
2//! storage and virtual models for Oino.
3//!
4//! Providers are WASM components: this crate never streams. It stores provider
5//! *registrations* (extension-api §4.4) and their models, merges `models.json` and config
6//! overrides in a fixed order, resolves credentials per request (core passes them to the
7//! component as `StreamOptions.apiKey`/`headers`) and resolves `--model`/`--models`/defaults.
8//! It has no async runtime; OAuth refresh is an injected [`OAuthRefresher`] future.
9//!
10//! # API map
11//!
12//! | Item | Purpose |
13//! |---|---|
14//! | [`ModelRegistry`] | shared catalog + auth (`Arc<RwLock>`) |
15//! | [`ProviderRegistration`], [`ProviderConfigOverride`] | provider data |
16//! | [`ModelsJson`] | `models.json` load with diagnostics |
17//! | [`AuthStorage`], [`AuthCredential`] | `auth.json` with locking, runtime keys |
18//! | [`auth::oauth`] | OAuth expiry + locked refresh |
19//! | [`config_value`] | `literal \| $ENV \| ${ENV} \| !command` |
20//! | [`resolver`] | `--model`, scopes, initial model, restore, cycling |
21//! | [`virtual_models`] | definitions, route wire types, validation, branch state |
22//! | [`auth_check`] | `oino auth check` (exit 0/1/2) |
23//! | [`ModelCache`] | `<agent>/cache/models/<provider>.json` |
24//! | [`auth::guidance`] | "No API key found …" texts |
25//!
26//! # Behaviour notes
27//!
28//! - No built-in catalog: models come from registrations (static or `list-models`) and
29//!   `models.json`. A model is *available* only when its provider has credentials **and** a loaded
30//!   component implements its API ([`ModelRegistry::diagnostics`] lists the others).
31//! - Config overrides keep the provider component's registration.
32//! - Registration `authHeader` is informational; `Authorization: Bearer` is injected only for
33//!   `models.json`/override `authHeader: true`.
34//! - Credential order: `--api-key` > `auth.json` > `models.json`/override
35//!   `apiKey` > registration `authEnv` (runtime.md §13 lists env before `apiKey`).
36//! - `models.json` `compat` is only checked for being an object; JSON syntax errors use
37//!   `serde_json` wording; `oauth: "radius"` validates but has no flow in core.
38//! - Virtual router state equal to the current state is not re-stored (no object identity
39//!   across WASM).
40
41#![forbid(unsafe_code)]
42#![cfg_attr(
43    test,
44    allow(
45        clippy::unwrap_used,
46        clippy::expect_used,
47        clippy::panic,
48        reason = "tests assert by unwrapping"
49    )
50)]
51
52pub mod auth;
53pub mod auth_check;
54mod cache;
55mod collate;
56mod compose;
57pub mod config_value;
58pub mod env;
59mod glob;
60mod json_text;
61mod models_json;
62mod registration;
63mod registry;
64pub mod resolver;
65mod schema;
66pub mod virtual_models;
67
68pub use auth::credential::{
69    ApiKeyCredential, AuthCredential, CredentialInfo, CredentialType, OAuthCredential,
70};
71pub use auth::oauth::{OAuthError, OAuthRefresher};
72pub use auth::storage::{AuthStorage, AuthStorageError};
73pub use cache::{CacheError, CachedModels, ModelCache};
74pub use config_value::{ConfigValueError, resolve_config_value};
75pub use env::{EnvSource, MapEnv, ProcessEnv};
76pub use models_json::{
77    ModelsJson, ModelsJsonModel, ModelsJsonModelOverride, ModelsJsonProvider, PartialCost,
78    SamplingByLevel,
79};
80pub use registration::{
81    AuthHeaderMode, ProviderConfigOverride, ProviderModelConfig, ProviderModels,
82    ProviderRegistration,
83};
84pub use registry::{
85    ApiKeyError, AuthCheck, AuthOverrides, AuthResolveError, AuthStatus, AuthStatusSource,
86    ModelRegistry, ModelRegistryOptions, RegistryDiagnostic, RegistryError, RequestAuth,
87    RequestAuthError, ResolvedAuth,
88};
89pub use virtual_models::{
90    RouteReason, RouteRequest, RouteResult, VIRTUAL_MODEL_API, VirtualModelDefinition,
91    VirtualModelRegistry,
92};