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 VTCode, supporting Gemini, OpenAI, Anthropic, 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-2.5-pro, gemini-2.5-flash-preview-05-20 |
21//! | OpenAI | ✅ | gpt-5, gpt-4.1, gpt-5-mini |
22//! | Anthropic | ✅ | claude-4.1-opus, claude-4-sonnet |
23//! | DeepSeek | ✅ | deepseek-chat |
24//!
25//! ## Basic Usage
26//!
27//! ```rust,no_run
28//! use vtcode_core::llm::{AnyClient, make_client};
29//! use vtcode_core::utils::dot_config::ProviderConfigs;
30//!
31//! #[tokio::main]
32//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
33//!     // Configure providers
34//!     let providers = ProviderConfigs {
35//!         gemini: Some(vtcode_core::utils::dot_config::ProviderConfig {
36//!             api_key: std::env::var("GEMINI_API_KEY")?,
37//!             model: "gemini-2.5-flash".to_string(),
38//!             ..Default::default()
39//!         }),
40//!         ..Default::default()
41//!     };
42//!
43//!     // Create client
44//!     let client = make_client(&providers, "gemini")?;
45//!
46//!     // Make a request
47//!     let messages = vec![
48//!         vtcode_core::llm::types::Message {
49//!             role: "user".to_string(),
50//!             content: "Hello, how can you help me with coding?".to_string(),
51//!         }
52//!     ];
53//!
54//!     let response = client.chat(&messages, None).await?;
55//!     println!("Response: {}", response.content);
56//!
57//!     Ok(())
58//! }
59//! ```
60//!
61//! ## Provider Configuration
62//!
63//! ```rust,no_run
64//! use vtcode_core::utils::dot_config::{ProviderConfigs, ProviderConfig};
65//!
66//! let config = ProviderConfigs {
67//!     gemini: Some(ProviderConfig {
68//!         api_key: "your-api-key".to_string(),
69//!         model: "gemini-2.5-flash".to_string(),
70//!         temperature: Some(0.7),
71//!         max_tokens: Some(4096),
72//!         ..Default::default()
73//!     }),
74//!     openai: Some(ProviderConfig {
75//!         api_key: "your-openai-key".to_string(),
76//!         model: "gpt-5".to_string(),
77//!         temperature: Some(0.3),
78//!         max_tokens: Some(8192),
79//!         ..Default::default()
80//!     }),
81//!     ..Default::default()
82//! };
83//! ```
84//!
85//! ## Advanced Features
86//!
87//! ### Streaming Responses
88//! ```rust,no_run
89//! use vtcode_core::llm::AnyClient;
90//! use futures::StreamExt;
91//!
92//! let client = make_client(&providers, "gemini")?;
93//!
94//! let mut stream = client.chat_stream(&messages, None).await?;
95//! while let Some(chunk) = stream.next().await {
96//!     match chunk {
97//!         Ok(response) => print!("{}", response.content),
98//!         Err(e) => eprintln!("Error: {}", e),
99//!     }
100//! }
101//! ```
102//!
103//! ### Function Calling
104//! ```rust,no_run
105//! use vtcode_core::llm::types::{FunctionDeclaration, FunctionCall};
106//!
107//! let functions = vec![
108//!     FunctionDeclaration {
109//!         name: "read_file".to_string(),
110//!         description: "Read a file from the filesystem".to_string(),
111//!         parameters: serde_json::json!({
112//!             "type": "object",
113//!             "properties": {
114//!                 "path": {"type": "string", "description": "File path to read"}
115//!             },
116//!             "required": ["path"]
117//!         }),
118//!     }
119//! ];
120//!
121//! let response = client.chat_with_functions(&messages, &functions, None).await?;
122//!
123//! if let Some(function_call) = response.function_call {
124//!     match function_call.name.as_str() {
125//!         "read_file" => {
126//!             // Handle function call
127//!         }
128//!         _ => {}
129//!     }
130//! }
131//! ```
132//!
133//! ## Error Handling
134//!
135//! The LLM layer provides comprehensive error handling:
136//!
137//! ```rust,no_run
138//! use vtcode_core::llm::LLMError;
139//!
140//! match client.chat(&messages, None).await {
141//!     Ok(response) => println!("Success: {}", response.content),
142//!     Err(LLMError::Authentication) => eprintln!("Authentication failed"),
143//!     Err(LLMError::RateLimit) => eprintln!("Rate limit exceeded"),
144//!     Err(LLMError::Network(e)) => eprintln!("Network error: {}", e),
145//!     Err(LLMError::Provider(e)) => eprintln!("Provider error: {}", e),
146//!     Err(e) => eprintln!("Other error: {}", e),
147//! }
148//! ```
149//!
150//! ## Performance Considerations
151//!
152//! - **Connection Pooling**: Efficient connection reuse
153//! - **Request Batching**: Where supported by providers
154//! - **Caching**: Built-in prompt caching for repeated requests
155//! - **Timeout Handling**: Configurable timeouts and retries
156//! - **Rate Limiting**: Automatic rate limit handling
157//!
158//! # LLM abstraction layer with modular architecture
159//!
160//! This module provides a unified interface for different LLM providers
161//! with provider-specific implementations.
162
163pub mod client;
164pub mod error_display;
165pub mod factory;
166pub mod provider;
167pub mod providers;
168pub mod types;
169
170#[cfg(test)]
171mod error_display_test;
172
173// Re-export main types for backward compatibility
174pub use client::{AnyClient, make_client};
175pub use factory::{create_provider_with_config, get_factory};
176pub use provider::{LLMStream, LLMStreamEvent};
177pub use providers::{AnthropicProvider, GeminiProvider, OpenAIProvider};
178pub use types::{BackendKind, LLMError, LLMResponse};