| 30 | /// LLM client trait |
| 31 | #[async_trait] |
| 32 | pub trait LlmClient: Send + Sync { |
| 33 | /// Complete a conversation (non-streaming) |
| 34 | async fn complete( |
| 35 | &self, |
| 36 | messages: &[Message], |
| 37 | system: Option<&str>, |
| 38 | tools: &[ToolDefinition], |
| 39 | ) -> Result<LlmResponse>; |
| 40 | |
| 41 | /// Complete a conversation with streaming |
| 42 | /// Returns a receiver for streaming events. |
| 43 | /// The cancel_token is checked during the HTTP request; if cancelled, the request is aborted. |
| 44 | async fn complete_streaming( |
| 45 | &self, |
| 46 | messages: &[Message], |
| 47 | system: Option<&str>, |
| 48 | tools: &[ToolDefinition], |
| 49 | cancel_token: CancellationToken, |
| 50 | ) -> Result<mpsc::Receiver<StreamEvent>>; |
| 51 | |
| 52 | /// Report the strongest provider-native structured-output enforcement this |
| 53 | /// client supports. Used by [`structured`] to decide whether to force a |
| 54 | /// tool call, request a native `response_format`, or fall back to |
| 55 | /// prompt-and-parse. Defaults to no native support. |
| 56 | fn native_structured_support(&self) -> structured::NativeStructuredSupport { |
| 57 | structured::NativeStructuredSupport::None |
| 58 | } |
| 59 | |
| 60 | /// Complete a conversation while honoring a structured-output directive |
| 61 | /// (forced `tool_choice` and/or native `response_format`). |
| 62 | /// |
| 63 | /// The default implementation ignores the directive and behaves exactly |
| 64 | /// like [`LlmClient::complete`], so existing clients keep working unchanged; |
| 65 | /// providers that support native structured output override this. |
| 66 | async fn complete_structured( |
| 67 | &self, |
| 68 | messages: &[Message], |
| 69 | system: Option<&str>, |
| 70 | tools: &[ToolDefinition], |
| 71 | _directive: &structured::StructuredDirective, |
| 72 | ) -> Result<LlmResponse> { |
| 73 | self.complete(messages, system, tools).await |
| 74 | } |
| 75 | |
| 76 | /// Streaming counterpart of [`LlmClient::complete_structured`]. Defaults to |
| 77 | /// [`LlmClient::complete_streaming`], ignoring the directive. |
| 78 | async fn complete_streaming_structured( |
| 79 | &self, |
| 80 | messages: &[Message], |
| 81 | system: Option<&str>, |
| 82 | tools: &[ToolDefinition], |
| 83 | _directive: &structured::StructuredDirective, |
| 84 | cancel_token: CancellationToken, |
| 85 | ) -> Result<mpsc::Receiver<StreamEvent>> { |
| 86 | self.complete_streaming(messages, system, tools, cancel_token) |
| 87 | .await |
| 88 | } |
| 89 | } |
nothing calls this directly
no outgoing calls
no test coverage detected