Skip to main content

tea_model/
provider.rs

1use std::fmt::Debug;
2use std::pin::Pin;
3
4use futures_core::Stream;
5use tea_protocol::ModelId;
6
7use crate::{ModelCancellation, ModelEvent, ModelRequest, ModelSpec, ProviderId};
8
9/// Provider-neutral asynchronous stream of normalized model events.
10///
11/// Streams should be lazy: polling owns request progress. Implementations must
12/// not create detached tasks. A fully consumed stream starts with exactly one
13/// `Started` event and ends with exactly one `Completed` or `Failed` event.
14pub trait ModelStream: Stream<Item = ModelEvent> + Send {}
15
16impl<T> ModelStream for T where T: Stream<Item = ModelEvent> + Send {}
17
18/// Heap-owned object-safe model stream returned by provider adapters.
19pub type BoxModelStream = Pin<Box<dyn ModelStream + 'static>>;
20
21/// Object-safe provider-neutral model adapter port.
22///
23/// Request setup, transport, protocol, cancellation, and runtime failures must
24/// be emitted through the returned stream as terminal failure events. Provider
25/// implementations must not panic for expected failures or create a nested
26/// asynchronous runtime.
27pub trait ModelProvider: Debug + Send + Sync {
28    /// Returns the stable adapter/provider identity.
29    fn provider_id(&self) -> &ProviderId;
30
31    /// Returns models advertised by this adapter in deterministic order.
32    fn models(&self) -> &[ModelSpec];
33
34    /// Finds an advertised model by canonical ID.
35    fn model(&self, model_id: &ModelId) -> Option<&ModelSpec> {
36        self.models()
37            .iter()
38            .find(|model| model.model_id() == model_id)
39    }
40
41    /// Creates a lazy normalized stream for one immutable request.
42    ///
43    /// `cancellation` is cooperative. Completion must not be reported until
44    /// resources owned directly by the stream have been cleaned up. Dropping
45    /// the stream abandons it; implementations must therefore keep resource
46    /// ownership inside the stream rather than a detached task.
47    fn stream(&self, request: ModelRequest, cancellation: ModelCancellation) -> BoxModelStream;
48}