ferrous_llm_core/traits.rs
1//! Core traits for LLM providers.
2//!
3//! This module defines the foundational traits that LLM providers implement,
4//! following the Interface Segregation Principle - providers only implement
5//! the capabilities they support.
6
7use crate::config::ProviderConfig;
8use crate::error::ProviderError;
9use crate::types::*;
10use async_trait::async_trait;
11use futures::Stream;
12
13/// Base trait for chat-based LLM providers.
14///
15/// This trait defines the core chat functionality that most LLM providers support.
16/// Providers implement this trait to provide conversational AI capabilities.
17#[async_trait]
18pub trait ChatProvider: Send + Sync {
19 /// Provider-specific configuration type
20 type Config: ProviderConfig;
21
22 /// Provider-specific response type
23 type Response: ChatResponse;
24
25 /// Provider-specific error type
26 type Error: ProviderError;
27
28 /// Send a chat request and receive a response.
29 ///
30 /// # Arguments
31 /// * `request` - The chat request containing messages and parameters
32 ///
33 /// # Returns
34 /// A result containing the provider's response or an error
35 async fn chat(&self, request: ChatRequest) -> Result<Self::Response, Self::Error>;
36}
37
38/// Trait for providers that support text completion (non-chat).
39///
40/// This is separate from ChatProvider to allow providers to implement
41/// only the capabilities they support.
42#[async_trait]
43pub trait CompletionProvider: Send + Sync {
44 /// Provider-specific configuration type
45 type Config: ProviderConfig;
46
47 /// Provider-specific response type
48 type Response: CompletionResponse;
49
50 /// Provider-specific error type
51 type Error: ProviderError;
52
53 /// Complete a text prompt.
54 ///
55 /// # Arguments
56 /// * `request` - The completion request containing the prompt and parameters
57 ///
58 /// # Returns
59 /// A result containing the completion response or an error
60 async fn complete(&self, request: CompletionRequest) -> Result<Self::Response, Self::Error>;
61}
62
63/// Optional trait for providers that support streaming responses.
64///
65/// This extends ChatProvider to add streaming capabilities.
66#[async_trait]
67pub trait StreamingProvider: ChatProvider {
68 /// Stream item type for incremental responses
69 type StreamItem: Send + 'static;
70
71 /// Stream type for the response
72 type Stream: Stream<Item = Result<Self::StreamItem, Self::Error>> + Send + 'static;
73
74 /// Send a chat request and receive a streaming response.
75 ///
76 /// # Arguments
77 /// * `request` - The chat request containing messages and parameters
78 ///
79 /// # Returns
80 /// A result containing a stream of response chunks or an error
81 async fn chat_stream(&self, request: ChatRequest) -> Result<Self::Stream, Self::Error>;
82}
83
84/// Optional trait for providers that support tool/function calling.
85///
86/// This extends ChatProvider to add tool calling capabilities.
87#[async_trait]
88pub trait ToolProvider: ChatProvider {
89 /// Send a chat request with available tools.
90 ///
91 /// # Arguments
92 /// * `request` - The chat request containing messages and parameters
93 /// * `tools` - Available tools that the model can call
94 ///
95 /// # Returns
96 /// A result containing the response (potentially with tool calls) or an error
97 async fn chat_with_tools(
98 &self,
99 request: ChatRequest,
100 tools: &[Tool],
101 ) -> Result<Self::Response, Self::Error>;
102}
103
104/// Trait for providers that support text embeddings.
105///
106/// This is a separate capability from chat/completion as not all providers
107/// support embeddings, and embedding-only providers don't need chat capabilities.
108#[async_trait]
109pub trait EmbeddingProvider: Send + Sync {
110 /// Provider-specific configuration type
111 type Config: ProviderConfig;
112
113 /// Provider-specific error type
114 type Error: ProviderError;
115
116 /// Generate embeddings for the given texts.
117 ///
118 /// # Arguments
119 /// * `texts` - The texts to generate embeddings for
120 ///
121 /// # Returns
122 /// A result containing the embeddings or an error
123 async fn embed(&self, texts: &[String]) -> Result<Vec<Embedding>, Self::Error>;
124}
125
126/// Optional trait for providers that support image generation.
127#[async_trait]
128pub trait ImageProvider: Send + Sync {
129 /// Provider-specific configuration type
130 type Config: ProviderConfig;
131
132 /// Provider-specific response type
133 type Response: ImageResponse;
134
135 /// Provider-specific error type
136 type Error: ProviderError;
137
138 /// Generate images from a text prompt.
139 ///
140 /// # Arguments
141 /// * `request` - The image generation request
142 ///
143 /// # Returns
144 /// A result containing the generated images or an error
145 async fn generate_image(&self, request: ImageRequest) -> Result<Self::Response, Self::Error>;
146}
147
148/// Optional trait for providers that support speech-to-text.
149#[async_trait]
150pub trait SpeechToTextProvider: Send + Sync {
151 /// Provider-specific configuration type
152 type Config: ProviderConfig;
153
154 /// Provider-specific response type
155 type Response: SpeechToTextResponse;
156
157 /// Provider-specific error type
158 type Error: ProviderError;
159
160 /// Transcribe audio to text.
161 ///
162 /// # Arguments
163 /// * `request` - The speech-to-text request containing audio data
164 ///
165 /// # Returns
166 /// A result containing the transcription or an error
167 async fn speech_to_text(
168 &self,
169 request: SpeechToTextRequest,
170 ) -> Result<Self::Response, Self::Error>;
171}
172
173/// Optional trait for providers that support text-to-speech.
174#[async_trait]
175pub trait TextToSpeechProvider: Send + Sync {
176 /// Provider-specific configuration type
177 type Config: ProviderConfig;
178
179 /// Provider-specific response type
180 type Response: TextToSpeechResponse;
181
182 /// Provider-specific error type
183 type Error: ProviderError;
184
185 /// Convert text to speech.
186 ///
187 /// # Arguments
188 /// * `request` - The text-to-speech request
189 ///
190 /// # Returns
191 /// A result containing the audio data or an error
192 async fn text_to_speech(
193 &self,
194 request: TextToSpeechRequest,
195 ) -> Result<Self::Response, Self::Error>;
196}