Skip to main content

adk_model/
lib.rs

1//! # adk-model
2#![allow(clippy::result_large_err)]
3#![deny(missing_docs)]
4//!
5//! LLM model integrations for ADK (Gemini, OpenAI, OpenRouter, Anthropic, DeepSeek, Groq,
6//! Ollama, Fireworks AI, Together AI, Mistral AI, Perplexity, Cerebras, SambaNova, Amazon
7//! Bedrock, Azure AI Inference).
8//!
9//! ## Overview
10//!
11//! This crate provides LLM implementations for ADK agents. Currently supports:
12//!
13//! - [`GeminiModel`] - Google's Gemini models (3 Pro, 2.5 Flash, etc.)
14//! - `OpenAIClient` - OpenAI models (GPT-5, GPT-5-mini, o3, etc.) — requires `openai` feature
15//! - `AzureOpenAIClient` - Azure OpenAI Service — requires `openai` feature
16//! - `OpenAICompatible` - Any OpenAI-compatible API (xAI, Fireworks, Together, Mistral, Perplexity, Cerebras, SambaNova, or custom) — requires `openai` feature, use `OpenAICompatibleConfig` presets
17//! - `AnthropicClient` - Anthropic Claude models — requires `anthropic` feature
18//! - `DeepSeekClient` - DeepSeek models — requires `deepseek` feature
19//! - `GroqClient` - Groq ultra-fast inference — requires `groq` feature
20//! - `OpenRouterClient` - OpenRouter-native chat, responses, and discovery APIs — requires `openrouter` feature
21//! - `OllamaModel` - Local LLMs via Ollama — requires `ollama` feature
22//! - `BedrockClient` - Amazon Bedrock via AWS SDK — requires `bedrock` feature
23//! - `AzureAIClient` - Azure AI Inference endpoints — requires `azure-ai` feature
24//! - [`MockLlm`] - Mock LLM for testing
25//!
26//! ## Quick Start
27//!
28//! ### Gemini
29//!
30//! ```rust,no_run
31//! use adk_model::GeminiModel;
32//! use std::sync::Arc;
33//!
34//! let api_key = std::env::var("GOOGLE_API_KEY").unwrap();
35//! let model = GeminiModel::new(&api_key, "gemini-2.5-flash").unwrap();
36//! ```
37//!
38//! ### OpenAI
39//!
40//! ```rust,ignore
41//! use adk_model::openai::{OpenAIClient, OpenAIConfig};
42//!
43//! let model = OpenAIClient::new(OpenAIConfig::new(
44//!     std::env::var("OPENAI_API_KEY").unwrap(),
45//!     "gpt-5-mini",
46//! )).unwrap();
47//! ```
48//!
49//! ### OpenRouter
50//!
51//! ```rust,ignore
52//! use adk_core::{Content, Llm, LlmRequest};
53//! use adk_model::openrouter::{OpenRouterClient, OpenRouterConfig};
54//! use futures::StreamExt;
55//!
56//! let client = OpenRouterClient::new(
57//!     OpenRouterConfig::new(
58//!         std::env::var("OPENROUTER_API_KEY").unwrap(),
59//!         "openai/gpt-4.1-mini",
60//!     )
61//!     .with_http_referer("https://github.com/zavora-ai/adk-rust")
62//!     .with_title("ADK-Rust"),
63//! ).unwrap();
64//!
65//! let request = LlmRequest::new(
66//!     "openai/gpt-4.1-mini",
67//!     vec![Content::new("user").with_text("Reply in one short sentence.")],
68//! );
69//!
70//! # tokio_test::block_on(async {
71//! let mut stream = client.generate_content(request, true).await.unwrap();
72//! while let Some(item) = stream.next().await {
73//!     let _response = item.unwrap();
74//! }
75//! # });
76//! ```
77//!
78//! Native OpenRouter APIs such as model discovery, credits, routing configuration, plugins, and
79//! exact Responses payload access remain available on `OpenRouterClient` itself.
80//!
81//! ### Anthropic
82//!
83//! ```rust,ignore
84//! use adk_model::anthropic::{AnthropicClient, AnthropicConfig};
85//!
86//! let model = AnthropicClient::new(AnthropicConfig::new(
87//!     std::env::var("ANTHROPIC_API_KEY").unwrap(),
88//!     "claude-sonnet-4-5-20250929",
89//! )).unwrap();
90//! ```
91//!
92//! ### DeepSeek
93//!
94//! ```rust,ignore
95//! use adk_model::deepseek::{DeepSeekClient, DeepSeekConfig};
96//!
97//! // Chat model
98//! let chat = DeepSeekClient::chat(std::env::var("DEEPSEEK_API_KEY").unwrap()).unwrap();
99//!
100//! // Reasoner with thinking mode
101//! let reasoner = DeepSeekClient::reasoner(std::env::var("DEEPSEEK_API_KEY").unwrap()).unwrap();
102//! ```
103//!
104//! ### OpenAI-Compatible Providers (Fireworks, Together, Mistral, Perplexity, Cerebras, SambaNova, xAI)
105//!
106//! All OpenAI-compatible providers use `OpenAICompatible` with provider presets:
107//!
108//! ```rust,ignore
109//! use adk_model::openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};
110//!
111//! // Fireworks AI
112//! let model = OpenAICompatible::new(OpenAICompatibleConfig::fireworks(
113//!     std::env::var("FIREWORKS_API_KEY").unwrap(),
114//!     "accounts/fireworks/models/llama-v3p1-8b-instruct",
115//! )).unwrap();
116//!
117//! // Together AI
118//! let model = OpenAICompatible::new(OpenAICompatibleConfig::together(
119//!     std::env::var("TOGETHER_API_KEY").unwrap(),
120//!     "meta-llama/Llama-3.3-70B-Instruct-Turbo",
121//! )).unwrap();
122//!
123//! // Or any custom OpenAI-compatible endpoint
124//! let model = OpenAICompatible::new(
125//!     OpenAICompatibleConfig::new("your-api-key", "your-model")
126//!         .with_base_url("https://your-endpoint.com/v1")
127//!         .with_provider_name("my-provider"),
128//! ).unwrap();
129//! ```
130//!
131//! ### Amazon Bedrock
132//!
133//! ```rust,ignore
134//! use adk_model::bedrock::{BedrockClient, BedrockConfig};
135//!
136//! // Uses AWS IAM credentials from the environment (no API key needed)
137//! let config = BedrockConfig::new("us-east-1", "anthropic.claude-sonnet-4-20250514-v1:0");
138//! let model = BedrockClient::new(config).await.unwrap();
139//! ```
140//!
141//! ### Azure AI Inference
142//!
143//! ```rust,ignore
144//! use adk_model::azure_ai::{AzureAIClient, AzureAIConfig};
145//!
146//! let model = AzureAIClient::new(AzureAIConfig::new(
147//!     "https://my-endpoint.eastus.inference.ai.azure.com",
148//!     std::env::var("AZURE_AI_API_KEY").unwrap(),
149//!     "meta-llama-3.1-8b-instruct",
150//! )).unwrap();
151//! ```
152//!
153//! ### Ollama (Local)
154//!
155//! ```rust,ignore
156//! use adk_model::ollama::{OllamaModel, OllamaConfig};
157//!
158//! // Default: localhost:11434
159//! let model = OllamaModel::new(OllamaConfig::new("llama3.2")).unwrap();
160//! ```
161//!
162//! ## Supported Models
163//!
164//! ### Gemini
165//! | Model | Description |
166//! |-------|-------------|
167//! | `gemini-3-pro-preview` | Most intelligent, complex agentic workflows (1M context) |
168//! | `gemini-3-flash-preview` | Frontier intelligence at Flash speed (1M context) |
169//! | `gemini-2.5-pro` | Advanced reasoning and multimodal (1M context) |
170//! | `gemini-2.5-flash` | Balanced speed and capability, recommended (1M context) |
171//! | `gemini-2.5-flash-lite` | Ultra-fast for high-volume tasks (1M context) |
172//!
173//! ### OpenAI
174//! | Model | Description |
175//! |-------|-------------|
176//! | `gpt-5` | Strongest coding and agentic model with adaptive reasoning |
177//! | `gpt-5-mini` | Efficient variant for most tasks |
178//! | `o3` | Advanced reasoning model for complex problem solving |
179//! | `o4-mini` | Efficient reasoning model (200K context) |
180//! | `gpt-4.1` | General purpose model with 1M context |
181//!
182//! ### Anthropic
183//! | Model | Description |
184//! |-------|-------------|
185//! | `claude-opus-4-5-20251101` | Most capable for complex autonomous tasks |
186//! | `claude-sonnet-4-5-20250929` | Best balance of intelligence, speed, and cost |
187//! | `claude-haiku-4-5-20251001` | Ultra-efficient for high-volume workloads |
188//! | `claude-opus-4-20250514` | Hybrid model with extended thinking |
189//! | `claude-sonnet-4-20250514` | Balanced model with extended thinking |
190//!
191//! ### DeepSeek
192//! | Model | Description |
193//! |-------|-------------|
194//! | `deepseek-chat` | V3.2 non-thinking mode for fast general-purpose tasks |
195//! | `deepseek-reasoner` | V3.2 thinking mode with chain-of-thought reasoning |
196//!
197//! ### Groq
198//! | Model | Description |
199//! |-------|-------------|
200//! | `meta-llama/llama-4-scout-17b-16e-instruct` | Llama 4 Scout via Groq LPU |
201//! | `llama-3.3-70b-versatile` | Versatile large model |
202//! | `llama-3.1-8b-instant` | Ultra-fast at 560 T/s |
203//!
204//! ### OpenAI-Compatible Providers (via `openai` feature)
205//!
206//! Use `OpenAICompatibleConfig` presets — one client, one feature flag:
207//!
208//! | Provider | Preset | Env Var |
209//! |----------|--------|---------|
210//! | Fireworks AI | `OpenAICompatibleConfig::fireworks()` | `FIREWORKS_API_KEY` |
211//! | Together AI | `OpenAICompatibleConfig::together()` | `TOGETHER_API_KEY` |
212//! | Mistral AI | `OpenAICompatibleConfig::mistral()` | `MISTRAL_API_KEY` |
213//! | Perplexity | `OpenAICompatibleConfig::perplexity()` | `PERPLEXITY_API_KEY` |
214//! | Cerebras | `OpenAICompatibleConfig::cerebras()` | `CEREBRAS_API_KEY` |
215//! | SambaNova | `OpenAICompatibleConfig::sambanova()` | `SAMBANOVA_API_KEY` |
216//! | xAI (Grok) | `OpenAICompatibleConfig::xai()` | `XAI_API_KEY` |
217//!
218//! ### Other Providers
219//!
220//! | Provider | Feature Flag | Env Var |
221//! |----------|-------------|---------|
222//! | Amazon Bedrock | `bedrock` | AWS IAM credentials |
223//! | Azure AI Inference | `azure-ai` | `AZURE_AI_API_KEY` |
224//! | OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
225//!
226//! ## Features
227//!
228//! - Async streaming with backpressure
229//! - Tool/function calling support
230//! - Multimodal input (text, images, audio, video, PDF)
231//! - Generation configuration (temperature, top_p, etc.)
232//! - OpenAI-compatible APIs (Ollama, vLLM, etc.)
233//!
234//! ## OpenRouter Scope Boundary
235//!
236//! `OpenRouterClient` exposes the provider's native surfaces:
237//!
238//! - chat completions
239//! - responses
240//! - model discovery and credits
241//! - provider routing and fallback
242//! - OpenRouter plugins and built-in tools
243//! - exact provider metadata and annotations
244//!
245//! The generic `Llm` adapter exists for agent compatibility and covers text generation,
246//! streaming, reasoning parts, tool/function calling, and OpenRouter request options through
247//! `openrouter::OpenRouterRequestOptions`.
248//!
249//! Use the native OpenRouter APIs whenever you need exact request or response parity, discovery,
250//! or provider-specific features that do not fit the generic `LlmRequest` / `LlmResponse`
251//! shape without information loss.
252//!
253//! For end-to-end agentic validation, see the local `examples/openrouter` crate and the
254//! `adk-model/examples/openrouter_*` binaries.
255
256#[cfg(feature = "anthropic")]
257pub mod anthropic;
258pub(crate) mod attachment;
259#[cfg(feature = "azure-ai")]
260pub mod azure_ai;
261#[cfg(feature = "bedrock")]
262pub mod bedrock;
263#[cfg(feature = "deepseek")]
264pub mod deepseek;
265/// Gemini model provider (Google AI Studio and Vertex AI).
266#[cfg(feature = "gemini")]
267pub mod gemini;
268#[cfg(feature = "groq")]
269pub mod groq;
270/// Mock LLM for testing without real API calls.
271pub mod mock;
272#[cfg(feature = "ollama")]
273pub mod ollama;
274#[cfg(feature = "openai")]
275pub mod openai;
276#[cfg(feature = "openai")]
277pub mod openai_compatible;
278#[cfg(feature = "openrouter")]
279pub mod openrouter;
280/// Canonical provider identifiers and metadata.
281pub mod provider;
282/// Retry logic with exponential backoff for transient provider errors.
283pub mod retry;
284pub mod tool_call_parser;
285#[cfg(any(
286    feature = "openai",
287    feature = "ollama",
288    feature = "deepseek",
289    feature = "groq",
290    feature = "bedrock",
291    feature = "azure-ai"
292))]
293pub(crate) mod tool_result;
294pub mod usage_tracking;
295
296#[cfg(feature = "anthropic")]
297pub use anthropic::AnthropicClient;
298#[cfg(feature = "azure-ai")]
299pub use azure_ai::{AzureAIClient, AzureAIConfig};
300#[cfg(feature = "bedrock")]
301pub use bedrock::{BedrockClient, BedrockConfig};
302#[cfg(feature = "deepseek")]
303pub use deepseek::{DeepSeekClient, DeepSeekConfig};
304#[cfg(feature = "gemini")]
305pub use gemini::GeminiModel;
306#[cfg(feature = "groq")]
307pub use groq::{GroqClient, GroqConfig};
308pub use mock::MockLlm;
309#[cfg(feature = "ollama")]
310pub use ollama::{OllamaConfig, OllamaModel};
311#[cfg(feature = "openai")]
312pub use openai::{AzureConfig, AzureOpenAIClient, OpenAIClient, OpenAIConfig, ReasoningEffort};
313#[cfg(feature = "openai")]
314pub use openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};
315#[cfg(feature = "openrouter")]
316pub use openrouter::{OpenRouterApiMode, OpenRouterClient, OpenRouterConfig};
317pub use provider::ModelProvider;
318pub use retry::RetryConfig;
319pub use retry::ServerRetryHint;