ailoop_core/traits.rs
1use futures::stream::BoxStream;
2
3use crate::{request::ChatRequest, stream::StreamChunk};
4
5/// Factory for [`CompletionModel`] handles bound to a provider
6/// account / endpoint.
7///
8/// A `CompletionClient` typically holds the HTTP client, credentials,
9/// and base URL; calling [`Self::completion_model`] fixes a specific
10/// model identifier so it can be passed to the engine. Adapters with
11/// multiple model families (e.g. Anthropic's chat models, Azure's Chat
12/// Completions deployments) implement one client and produce one model
13/// type.
14pub trait CompletionClient {
15 /// Concrete `CompletionModel` this client produces.
16 type Model: CompletionModel;
17
18 /// Build a model handle for `model_name` (Anthropic model id,
19 /// Azure deployment name, etc.). Implementations clone whatever
20 /// state the model needs out of the client.
21 fn completion_model(&self, model_name: impl Into<String>) -> Self::Model;
22}
23
24/// Provider-agnostic streaming completion contract.
25///
26/// Implementors map [`ChatRequest`] to the provider's wire format,
27/// open the streaming response, and translate per-chunk events into
28/// [`StreamChunk`]s. Implementations must be `Send + Sync` because
29/// [`RetryingModel`](crate::RetryingModel) and the engine hold them
30/// across `await` boundaries; the trait does not declare these
31/// super-bounds yet — every use site adds them — but new
32/// implementations should satisfy them.
33#[async_trait::async_trait]
34pub trait CompletionModel {
35 /// Error type for the model's transport / setup failures.
36 /// Implement [`crate::Retryable`] on it to make the model
37 /// composable with [`RetryingModel`](crate::RetryingModel).
38 type Error: std::error::Error + Send + Sync + 'static;
39
40 /// Adapter family name used in telemetry, e.g. `"anthropic"` or
41 /// `"azure-openai"`. Stable across model ids — changing model
42 /// name does not change this.
43 fn name(&self) -> &str;
44 /// Model identifier this handle is bound to: Anthropic model id
45 /// (`"claude-sonnet-4-5"`), Azure deployment name, etc. The
46 /// engine surfaces this in tracing and the JSON tracer envelope.
47 fn model(&self) -> &str;
48
49 /// Open a streaming completion. Returns a stream of
50 /// `Result<StreamChunk, Self::Error>` so per-chunk transport
51 /// errors can be surfaced mid-stream. Setup-time failures (auth,
52 /// schema, transport open) return the outer `Err`.
53 async fn chat_stream(
54 &self,
55 req: ChatRequest,
56 ) -> Result<BoxStream<'static, Result<StreamChunk, Self::Error>>, Self::Error>;
57}