Skip to main content

vtcode_core/llm/
mod.rs

1//! # LLM Integration Layer
2//!
3//! This module provides a unified, modular interface for integrating multiple LLM providers
4//! with VT Code, supporting Gemini, OpenAI, Anthropic, Meta AI, xAI, and DeepSeek.
5//!
6//! ## Architecture Overview
7//!
8//! The LLM layer is designed with several key principles:
9//!
10//! - **Unified Interface**: Single `AnyClient` trait for all providers
11//! - **Provider Agnostic**: Easy switching between providers
12//! - **Configuration Driven**: TOML-based provider configuration
13//! - **Error Handling**: Comprehensive error types and recovery
14//! - **Async Support**: Full async/await support for all operations
15//!
16//! ## Supported Providers
17//!
18//! | Provider | Status | Models |
19//! |----------|--------|---------|
20//! | Gemini | ✓ | gemini-3.1-pro-preview, gemini-3-flash-preview |
21//! | OpenAI | ✓ | gpt-5, o3, o4-mini, gpt-5-mini, gpt-5-nano |
22//! | Anthropic | ✓ | claude-4.1-opus, claude-4-sonnet |
23//! | xAI | ✓ | grok-4.6, grok-4.5, grok-build-0.1, grok-4.3 |
24//! | DeepSeek | ✓ | deepseek-chat, deepseek-reasoner |
25//! | Meta AI | ✓ | muse-spark-1.1, muse-spark-1.2 |
26//! | Z.AI | ✓ | glm-5 |
27//! | Ollama | ✓ | gpt-oss:20b (local) |
28//!
29//! ## Basic Usage
30//!
31//! ```rust,ignore
32//! use vtcode_core::llm::{AnyClient, make_client};
33//! use vtcode_core::utils::dot_config::ProviderConfigs;
34//!
35//! #[tokio::main]
36//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
37//!     // Configure providers
38//!     let providers = ProviderConfigs {
39//!         gemini: Some(vtcode_core::utils::dot_config::ProviderConfig {
40//!             api_key: std::env::var("GEMINI_API_KEY")?,
41//!             model: "gemini-3-flash-preview".to_string(),
42//!             ..Default::default()
43//!         }),
44//!         ..Default::default()
45//!     };
46//!
47//!     // Create client
48//!     let client = make_client(&providers, "gemini")?;
49//!
50//!     // Make a request
51//!     let messages = vec![
52//!         vtcode_core::llm::types::Message {
53//!             role: "user".to_string(),
54//!             content: "Hello, how can you help me with coding?".to_string(),
55//!         }
56//!     ];
57//!
58//!     let response = client.chat(&messages, None).await?;
59//!     println!("Response: {}", response.content);
60//!
61//!     Ok(())
62//! }
63//! ```
64//!
65//! ## Provider Configuration
66//!
67//! ```rust,ignore
68//! use vtcode_core::utils::dot_config::{ProviderConfigs, ProviderConfig};
69//!
70//! let config = ProviderConfigs {
71//!     gemini: Some(ProviderConfig {
72//!         api_key: "your-api-key".to_string(),
73//!         model: "gemini-3-flash-preview".to_string(),
74//!         temperature: Some(0.7),
75//!         max_tokens: Some(4096),
76//!         ..Default::default()
77//!     }),
78//!     openai: Some(ProviderConfig {
79//!         api_key: "your-openai-key".to_string(),
80//!         model: "gpt-5".to_string(),
81//!         temperature: Some(0.3),
82//!         max_tokens: Some(8192),
83//!         ..Default::default()
84//!     }),
85//!     ..Default::default()
86//! };
87//! ```
88//!
89//! ## Advanced Features
90//!
91//! ### Streaming Responses
92//! ```rust,ignore
93//! use vtcode_core::llm::AnyClient;
94//! use futures::StreamExt;
95//!
96//! let client = make_client(&providers, "gemini")?;
97//!
98//! let mut stream = client.chat_stream(&messages, None).await?;
99//! while let Some(chunk) = stream.next().await {
100//!     match chunk {
101//!         Ok(response) => print!("{}", response.content),
102//!         Err(e) => eprintln!("Error: {}", e),
103//!     }
104//! }
105//! ```
106//!
107//! ### Function Calling
108//! ```rust,ignore
109//! use vtcode_core::llm::types::{FunctionDeclaration, FunctionCall};
110//!
111//! let functions = vec![
112//!     FunctionDeclaration {
113//!         name: "read_file".to_string(),
114//!         description: "Read a file from the filesystem".to_string(),
115//!         parameters: serde_json::json!({
116//!             "type": "object",
117//!             "properties": {
118//!                 "path": {"type": "string", "description": "File path to read"}
119//!             },
120//!             "required": ["path"]
121//!         }),
122//!     }
123//! ];
124//!
125//! let response = client.chat_with_functions(&messages, &functions, None).await?;
126//!
127//! if let Some(function_call) = response.function_call {
128//!     match function_call.name.as_str() {
129//!         "read_file" => {
130//!             // Handle function call
131//!         }
132//!         _ => {}
133//!     }
134//! }
135//! ```
136//!
137//! ## Error Handling
138//!
139//! The LLM layer provides comprehensive error handling:
140//!
141//! ```rust,ignore
142//! use vtcode_core::llm::LLMError;
143//!
144//! match client.chat(&messages, None).await {
145//!     Ok(response) => println!("Success: {}", response.content),
146//!     Err(LLMError::Authentication) => eprintln!("Authentication failed"),
147//!     Err(LLMError::RateLimit { metadata: None }) => eprintln!("Rate limit exceeded"),
148//!     Err(LLMError::Network { message: e, metadata: None }) => eprintln!("Network error: {}", e),
149//!     Err(LLMError::Provider { message: e, metadata: None }) => eprintln!("Provider error: {}", e),
150//!     Err(e) => eprintln!("Other error: {}", e),
151//! }
152//! ```
153//!
154//! ## Performance Considerations
155//!
156//! - **Connection Pooling**: Efficient connection reuse
157//! - **Request Batching**: Where supported by providers
158//! - **Caching**: Built-in prompt caching for repeated requests
159//! - **Timeout Handling**: Configurable timeouts and retries
160//! - **Rate Limiting**: Automatic rate limit handling
161//!
162//! # LLM abstraction layer with modular architecture
163//!
164//! This module provides a unified interface for different LLM providers
165//! with provider-specific implementations.
166
167/// Provider capability declarations and feature detection.
168pub mod capabilities;
169/// Context-Generic Provider (CGP) wiring for the LLM factory.
170pub mod cgp;
171/// Simplified LLM client trait and adapter.
172pub mod client;
173/// Adapter between config-level and factory-level provider configurations.
174pub mod config_adapter;
175/// Human-readable error formatting for LLM errors.
176pub mod error_display;
177/// LLM provider factory and global registry.
178pub mod factory;
179/// Shared HTTP client utilities for provider implementations.
180pub mod http_client;
181/// Lightweight (cheap/fast) model routing for auxiliary features.
182pub mod lightweight_routing;
183#[cfg(feature = "mock")]
184/// Mock LLM client for testing.
185pub mod mock_client;
186/// Model resolution, availability checks, and dynamic metadata.
187pub mod model_resolver;
188/// Core LLM provider trait and error types.
189pub mod provider;
190/// Shared provider utilities to eliminate duplicate code.
191pub mod provider_base;
192/// Generic provider builder with builder-pattern construction.
193pub mod provider_builder;
194/// Per-provider configuration types and the unified creation shim.
195pub mod provider_config;
196/// Re-exported provider implementations.
197pub mod providers;
198/// Shared idle-gap tracker for detecting when the provider prompt cache has
199/// likely expired between dispatched LLM requests.
200pub mod request_gap;
201/// Adapter for the Rig agent framework.
202pub mod rig_adapter;
203pub use vtcode_llm::reasoning_effort;
204mod single_response;
205/// Tool-call correlation and intent extraction for LLM responses.
206pub mod tool_bridge;
207/// LLM request/response types, errors, and backend kind.
208pub mod types;
209/// Provider-normalized usage accumulation and cache-aware session cost estimation.
210pub mod usage_cost;
211/// Shared utilities for request/response processing.
212pub mod utils;
213
214// Re-export main types for backward compatibility
215pub use capabilities::ProviderCapabilities;
216pub use client::{AnyClient, ProviderClientAdapter, make_client};
217pub use factory::{create_provider_with_config, get_factory, get_models_manager, infer_provider_from_model};
218pub use lightweight_routing::{
219    LightweightFeature, LightweightRouteResolution, LightweightRouteSource, ModelRoute, auto_lightweight_model,
220    create_provider_for_model_route, lightweight_model_choices, main_model_route, resolve_api_key_for_model_route,
221    resolve_lightweight_route,
222};
223pub use model_resolver::{DynamicModelMeta, DynamicModelRef, ModelAvailability, ModelResolver, ResolvedModel};
224pub use provider::{FinishReason, LLMStream, LLMStreamEvent, Usage};
225pub use providers::{
226    AnthropicProvider, GeminiProvider, HuggingFaceProvider, MergeGatewayProvider, MetaProvider, OllamaProvider,
227    OpenAIProvider, ZAIProvider,
228};
229pub use single_response::collect_single_response;
230pub use tool_bridge::{
231    CorrelationStats, IntentFulfillment, MessageCorrelationTracker, MessageToolCorrelation, ToolExecution, ToolIntent,
232    ToolIntentExtractor,
233};
234
235pub use types::{BackendKind, LLMError, LLMResponse};
236
237pub use config_adapter::{
238    AdapterEvent, AdapterHooks, AdapterHooksProvider, OwnedProviderConfig, ProviderConfig, as_factory_config,
239    as_factory_config_with_hooks,
240};
241#[cfg(feature = "mock")]
242pub use mock_client::StaticResponseClient;