Skip to main content

telos_agent/model/provider/
mod.rs

1//! Model provider abstraction — pluggable LLM backends.
2//!
3//! Built-in backends: [`DeepSeekProvider`].
4//! The default [`ModelProvider::stream_complete`] wraps [`ModelProvider::complete`]
5//! so non-streaming providers automatically get a (single-chunk) streaming impl.
6
7use async_trait::async_trait;
8use futures_core::stream::Stream;
9
10use crate::error::AgentError;
11
12#[cfg(test)]
13mod test;
14
15pub mod deepseek;
16pub mod routed;
17mod traits;
18pub(crate) mod types;
19
20pub use deepseek::{
21    DeepSeekBalance, DeepSeekBalanceInfo, DeepSeekChatOptions, DeepSeekConfig, DeepSeekFimChoice,
22    DeepSeekFimRequest, DeepSeekFimResponse, DeepSeekModel, DeepSeekModelList, DeepSeekProvider,
23    DeepSeekResponseFormat,
24};
25pub use routed::{RoutedModelConfig, RoutedProvider};
26pub use traits::{ErasedProvider, ModelProvider};
27pub use types::{
28    CompletionRequest, CompletionResponse, ModelHint, ProviderEvent, StopReason, TokenUsage,
29};
30
31// Implement ModelProvider for reference-to-dyn-trait-object.
32#[async_trait]
33impl ModelProvider for &(dyn ModelProvider + Send + Sync) {
34    async fn complete(&self, request: CompletionRequest) -> Result<CompletionResponse, AgentError> {
35        (**self).complete(request).await
36    }
37
38    fn stream_complete<'a>(
39        &'a self,
40        request: CompletionRequest,
41    ) -> std::pin::Pin<Box<dyn Stream<Item = Result<ProviderEvent, AgentError>> + Send + 'a>> {
42        (**self).stream_complete(request)
43    }
44
45    fn estimate_tokens(&self, text: &str) -> usize {
46        (**self).estimate_tokens(text)
47    }
48}
49
50/// Implement [`ModelProvider`] for `Arc<dyn ModelProvider + Send + Sync>`.
51#[async_trait]
52impl ModelProvider for std::sync::Arc<dyn ModelProvider + Send + Sync> {
53    async fn complete(&self, request: CompletionRequest) -> Result<CompletionResponse, AgentError> {
54        (**self).complete(request).await
55    }
56
57    fn stream_complete<'a>(
58        &'a self,
59        request: CompletionRequest,
60    ) -> std::pin::Pin<Box<dyn Stream<Item = Result<ProviderEvent, AgentError>> + Send + 'a>> {
61        (**self).stream_complete(request)
62    }
63
64    fn estimate_tokens(&self, text: &str) -> usize {
65        (**self).estimate_tokens(text)
66    }
67}