1mod admission;
7pub mod anthropic;
8mod error;
9pub mod factory;
10pub mod http;
11pub mod openai;
12pub mod structured;
13mod token_estimation;
14mod types;
15pub mod zhipu;
16
17pub use admission::{
19 ModelGenerationAdmission, ModelGenerationAdmissionError, ModelGenerationConcurrency,
20 ModelGenerationPermit,
21};
22pub use anthropic::AnthropicClient;
23pub(crate) use error::non_retryable_llm_error_message;
24pub use error::NonRetryableLlmError;
25pub use factory::{create_client_with_config, LlmConfig};
26pub use http::{
27 clear_http_metrics_callback, default_http_client, set_http_metrics_callback, HttpClient,
28 HttpMetricsCallback, HttpMetricsRecord, HttpResponse, StreamingHttpResponse,
29};
30pub use openai::OpenAiClient;
31pub(crate) use token_estimation::{estimate_message_tokens, estimate_prompt_tokens};
32pub use types::*;
33pub use zhipu::ZhipuClient;
34
35use anyhow::Result;
36use async_trait::async_trait;
37use tokio::sync::mpsc;
38use tokio_util::sync::CancellationToken;
39
40#[async_trait]
42pub trait LlmClient: Send + Sync {
43 fn model_generation_concurrency(&self) -> ModelGenerationConcurrency {
50 ModelGenerationConcurrency::single_flight()
51 }
52
53 fn fork_for_session(&self, _session_id: &str) -> Option<std::sync::Arc<dyn LlmClient>> {
60 None
61 }
62
63 async fn complete(
65 &self,
66 messages: &[Message],
67 system: Option<&str>,
68 tools: &[ToolDefinition],
69 ) -> Result<LlmResponse>;
70
71 async fn complete_streaming(
75 &self,
76 messages: &[Message],
77 system: Option<&str>,
78 tools: &[ToolDefinition],
79 cancel_token: CancellationToken,
80 ) -> Result<mpsc::Receiver<StreamEvent>>;
81
82 fn native_structured_support(&self) -> structured::NativeStructuredSupport {
87 structured::NativeStructuredSupport::None
88 }
89
90 async fn complete_structured(
97 &self,
98 messages: &[Message],
99 system: Option<&str>,
100 tools: &[ToolDefinition],
101 _directive: &structured::StructuredDirective,
102 ) -> Result<LlmResponse> {
103 self.complete(messages, system, tools).await
104 }
105
106 async fn complete_streaming_structured(
109 &self,
110 messages: &[Message],
111 system: Option<&str>,
112 tools: &[ToolDefinition],
113 _directive: &structured::StructuredDirective,
114 cancel_token: CancellationToken,
115 ) -> Result<mpsc::Receiver<StreamEvent>> {
116 self.complete_streaming(messages, system, tools, cancel_token)
117 .await
118 }
119}
120
121#[cfg(test)]
123#[path = "tests.rs"]
124mod tests_file;