mirror of
https://github.com/whit3rabbit/anyllm-proxy.git
synced 2026-09-21 16:00:49 +00:00
Add provider catalog runtime support
This commit is contained in:
Generated
+3
@@ -89,7 +89,10 @@ dependencies = [
|
||||
name = "anyllm_providers"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -6,5 +6,15 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
runtime-catalog = ["dep:serde_json"]
|
||||
remote-catalog = ["runtime-catalog", "dep:reqwest"]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "1", optional = true }
|
||||
reqwest = { version = "0.12", optional = true, default-features = false, features = ["native-tls", "stream"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
|
||||
@@ -98,9 +98,48 @@ Other public items (re-exported from the crate root):
|
||||
- Single-model lookup: `get_model(provider_id, model_id)`.
|
||||
- Migration helper: `canonical_provider_id(provider_id)`.
|
||||
|
||||
## Runtime LiteLLM updates
|
||||
|
||||
The default crate remains static and does no I/O. If your app needs newer
|
||||
LiteLLM provider/model rows without waiting for an `anyllm_providers` release,
|
||||
enable the opt-in runtime catalog features:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
anyllm_providers = { version = "0.9", features = ["remote-catalog"] }
|
||||
```
|
||||
|
||||
`runtime-catalog` adds owned catalog types and a parser for LiteLLM's
|
||||
`model_prices_and_context_window.json`. `remote-catalog` also adds explicit
|
||||
fetch/cache helpers using a caller-provided `reqwest::Client`:
|
||||
|
||||
```rust
|
||||
use anyllm_providers::{ProviderCatalog, RemoteCatalogOptions};
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.redirect(reqwest::redirect::Policy::none())
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.build()?;
|
||||
|
||||
let cache_dir = std::env::temp_dir().join("anyllm-provider-catalog");
|
||||
let options = RemoteCatalogOptions::default()
|
||||
.with_cache_dir(&cache_dir)
|
||||
.with_stale_on_error(true);
|
||||
|
||||
let catalog = ProviderCatalog::fetch_litellm_with_options(&client, &options).await?;
|
||||
for p in catalog.all_providers() {
|
||||
println!("{}: {} models", p.id, catalog.list_models(&p.id).len());
|
||||
}
|
||||
```
|
||||
|
||||
Known providers keep the bundled auth, protocol, env-var, and base-url metadata.
|
||||
Brand-new LiteLLM providers are exposed with `ProviderStatus::Stub`, a guessed
|
||||
API-key env var, and an empty default base URL so callers do not silently route
|
||||
to the wrong endpoint.
|
||||
|
||||
## Integrating into a TUI (or any client app)
|
||||
|
||||
This crate gives you the catalog. It does **not** ship an HTTP client, an async runtime, or a key store, so a TUI integrates it as a read-only data source and supplies its own transport (typically `reqwest`) and config (typically `std::env` or a config file).
|
||||
In its default mode this crate gives you the static catalog. It does **not** ship an HTTP client, an async runtime, or a key store, so a TUI integrates it as a read-only data source and supplies its own transport (typically `reqwest`) and config (typically `std::env` or a config file).
|
||||
|
||||
The recommended local integration can use **Ollama** and **LM Studio** as built-in providers. Both are local, OpenAI-compatible, require no API key, and their catalog entries (`auth: AuthKind::None`, `protocol: ProviderProtocol::OpenAICompat`) reflect that. Ollama is part of the LiteLLM snapshot; LM Studio is a legacy-only local provider that still resolves through `get_provider("lm_studio")` but is not returned by `all_providers()`.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,16 @@
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub mod catalog;
|
||||
pub mod model;
|
||||
pub mod provider;
|
||||
pub mod providers;
|
||||
pub mod registry;
|
||||
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub use catalog::{
|
||||
CatalogError, CatalogMetadata, OwnedModelDef, OwnedProviderDef, ProviderCatalog,
|
||||
};
|
||||
#[cfg(feature = "remote-catalog")]
|
||||
pub use catalog::{RemoteCatalogOptions, DEFAULT_MAX_CATALOG_BYTES, LITELLM_CATALOG_URL};
|
||||
pub use model::{ModelCapabilities, ModelDef, ModelStatus};
|
||||
pub use provider::{AuthKind, ProviderCapabilities, ProviderDef, ProviderProtocol, ProviderStatus};
|
||||
pub use registry::{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/// Features a specific model supports.
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ModelCapabilities {
|
||||
pub streaming: bool,
|
||||
pub tool_use: bool,
|
||||
@@ -9,7 +9,7 @@ pub struct ModelCapabilities {
|
||||
}
|
||||
|
||||
/// Availability of a model.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ModelStatus {
|
||||
Available,
|
||||
Deprecated,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// Wire format / HTTP client strategy used to communicate with a provider.
|
||||
/// Maps to proxy's `BackendKind` variants.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ProviderProtocol {
|
||||
/// Standard OpenAI Chat Completions (Groq, Together, Mistral, etc.)
|
||||
OpenAICompat,
|
||||
@@ -21,7 +21,7 @@ pub enum ProviderProtocol {
|
||||
}
|
||||
|
||||
/// How the provider expects authentication.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum AuthKind {
|
||||
/// `Authorization: Bearer <key>`
|
||||
Bearer,
|
||||
@@ -36,7 +36,7 @@ pub enum AuthKind {
|
||||
}
|
||||
|
||||
/// Implementation maturity of a provider.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ProviderStatus {
|
||||
/// HTTP client exists and has been live-tested.
|
||||
Implemented,
|
||||
@@ -48,7 +48,7 @@ pub enum ProviderStatus {
|
||||
}
|
||||
|
||||
/// Capabilities advertised for a provider (endpoint-level, not model-level).
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ProviderCapabilities {
|
||||
pub chat_completions: bool,
|
||||
pub streaming: bool,
|
||||
|
||||
@@ -93,6 +93,26 @@ static LEGACY_ONLY_MODELS: &[(&str, &[ModelDef])] = &[
|
||||
("xinference", providers::xinference::MODELS),
|
||||
];
|
||||
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub(crate) fn advertised_provider_defs() -> &'static [&'static ProviderDef] {
|
||||
ALL_PROVIDERS
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub(crate) fn legacy_only_provider_defs() -> &'static [&'static ProviderDef] {
|
||||
LEGACY_ONLY_PROVIDERS
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub(crate) fn advertised_model_groups() -> &'static [(&'static str, &'static [ModelDef])] {
|
||||
ALL_MODELS
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-catalog")]
|
||||
pub(crate) fn legacy_only_model_groups() -> &'static [(&'static str, &'static [ModelDef])] {
|
||||
LEGACY_ONLY_MODELS
|
||||
}
|
||||
|
||||
/// Return the LiteLLM-canonical provider id for a local legacy provider id.
|
||||
pub fn canonical_provider_id(id: &str) -> &str {
|
||||
PROVIDER_ALIASES
|
||||
|
||||
@@ -10,7 +10,7 @@ repository.workspace = true
|
||||
anyllm_translate = { path = "../translator", version = "0.9.6" }
|
||||
anyllm_client = { path = "../client", version = "0.9.6" }
|
||||
anyllm_batch_engine = { path = "../batch_engine", version = "0.9.6" }
|
||||
anyllm_providers = { path = "../providers", version = "0.9.6" }
|
||||
anyllm_providers = { path = "../providers", version = "0.9.6", features = ["runtime-catalog"] }
|
||||
axum = { version = "0.8", features = ["ws", "multipart"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "native-tls", "http2", "multipart"] }
|
||||
|
||||
Reference in New Issue
Block a user