1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! # multi-llm
//!
//! Unified multi-provider LLM client with support for OpenAI, Anthropic, Ollama, and LMStudio.
//!
//! ## Key Features
//!
//! - **Multiple Providers**: Seamless switching between LLM providers
//! - **Unified Messages**: Provider-agnostic message architecture with caching hints
//! - **Prompt Caching**: Native support for Anthropic prompt caching
//! - **Tool Calling**: First-class function/tool calling support
//! - **Resilience**: Built-in retry logic, rate limiting, and error handling
//!
//! ## Example
//!
//! ```rust,no_run
//! use multi_llm::{UnifiedLLMClient, LLMConfig, OpenAIConfig, DefaultLLMParams, UnifiedMessage};
//!
//! # async fn example() -> anyhow::Result<()> {
//! let config = LLMConfig {
//! provider: Box::new(OpenAIConfig {
//! api_key: Some("your-api-key".to_string()),
//! base_url: "https://api.openai.com".to_string(),
//! default_model: "gpt-4".to_string(),
//! max_context_tokens: 128_000,
//! retry_policy: Default::default(),
//! }),
//! default_params: DefaultLLMParams::default(),
//! };
//!
//! let client = UnifiedLLMClient::from_config(config)?;
//! let messages = vec![UnifiedMessage::user("Hello, how are you?")];
//! // Use client.execute_llm(...) for actual requests
//! # Ok(())
//! # }
//! ```
// Allow missing errors documentation - errors are self-documenting via type signatures
// Allow unreachable in provider clone - all types are covered but compiler can't verify
// =============================================================================
// Module declarations
// =============================================================================
// Public modules - flattened structure matching DESIGN.md
// Internal modules
pub
pub
// =============================================================================
// Public API re-exports (~28 types as per issue #4)
// =============================================================================
// Client
pub use UnifiedLLMClient;
// Configuration
pub use ;
// Errors
pub use ;
// Messages - the core unified message architecture
pub use ;
// Provider trait and types
pub use ;
// Providers
pub use ;
// Token counting (from internals, re-exported for public use)
pub use ;
// Retry policy (from internals, re-exported for public use)
pub use RetryPolicy;
// Event types - only available with "events" feature
pub use ;
pub use LLMBusinessEvent;
// =============================================================================
// Helper macro for handling response types with/without events feature
// =============================================================================
/// Extract the Response from execute_llm results, regardless of events feature.
///
/// When the `events` feature is enabled, `execute_llm` returns
/// `Result<(Response, Vec<LLMBusinessEvent>)>`. Without the feature, it returns
/// `Result<Response>`. This macro handles both cases uniformly.
///
/// # Example
///
/// ```rust,ignore
/// use multi_llm::{unwrap_response, UnifiedLLMClient, LlmProvider};
///
/// let response = unwrap_response!(client.execute_llm(request, None, None).await?);
/// println!("Content: {}", response.content);
/// ```
///
/// # With events feature
///
/// If you need access to the events, don't use this macro - instead pattern match directly:
///
/// ```rust,ignore
/// #[cfg(feature = "events")]
/// let (response, events) = client.execute_llm(request, None, None).await?;
/// ```
/// Extract the Response from execute_llm results (non-events version).
///
/// See the `events` feature version for full documentation.