pub trait ProviderBackend:
Send
+ Sync
+ 'static {
type Model: ModelBackend;
Show 14 methods
// Required methods
fn model(&self, id: ModelId) -> Result<Self::Model, KitError>;
fn shutdown(&self) -> impl Future<Output = Result<(), KitError>> + Send + '_;
// Provided methods
fn list_models(
&self,
_request: ModelListRequest,
) -> impl Future<Output = Result<ModelPage, KitError>> + Send + '_ { ... }
fn model_info(
&self,
_id: ModelId,
) -> impl Future<Output = Result<ModelSummary, KitError>> + Send + '_ { ... }
fn upload_file(
&self,
_request: FileUploadRequest,
) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_ { ... }
fn list_files(
&self,
_request: FileListRequest,
) -> impl Future<Output = Result<FilePage, KitError>> + Send + '_ { ... }
fn file_info(
&self,
_id: String,
) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_ { ... }
fn delete_file(
&self,
_id: String,
) -> impl Future<Output = Result<(), KitError>> + Send + '_ { ... }
fn download_file(
&self,
_id: String,
_max_bytes: NonZeroUsize,
) -> impl Future<Output = Result<Vec<u8>, KitError>> + Send + '_ { ... }
fn batch_status(
&self,
_id: String,
) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_ { ... }
fn cancel_batch(
&self,
_id: String,
) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_ { ... }
fn batch_results(
&self,
_id: String,
_max_bytes: NonZeroUsize,
) -> impl Future<Output = Result<Vec<BatchResult<<Self::Model as ModelBackend>::Continuation>>, KitError>> + Send + '_ { ... }
fn list_batches(
&self,
_request: BatchListRequest,
) -> impl Future<Output = Result<BatchPage, KitError>> + Send + '_ { ... }
fn health(
&self,
) -> impl Future<Output = Result<HealthStatus, KitError>> + Send + '_ { ... }
}Expand description
Public implementation contract for one provider root.
Provider and Model clones share one lifecycle. Shutdown seals model admission, drains accepted work, and publishes one terminal result to every waiter; cancelling a waiter cannot cancel owned cleanup. Models have no independent shutdown. Caller implementations retain their concrete associated children directly.
§Examples
use providers_kit::{
ModelBackend, ModelId, Provider, ProviderBackend, ProviderConfig,
config::{OllamaConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::Ollama(OllamaConfig::local()),
TransportConfig::default(),
))?;
let model = provider.model(ModelId::new("exact-model")?)?;
assert_eq!(model.model_id().as_str(), "exact-model");
provider.shutdown().await?;
§Implement a concrete local hierarchy
This runnable caller implementation is a deliberately limited, in-process text echo service, not a language model or proof of any supplied provider. It supports one text message with default settings and text-only Sessions. Optional operations retain their Unsupported defaults. Its work is synchronous and finite: there is no transport, spawned task or asynchronous resource to drain. A real network implementation must additionally own admitted work and shutdown cleanup.
The continuation is caller-owned, cloneable, and deliberately has no serialization contract. Finite streams yield on demand without a forwarding task. Shared closure seals the root and existing children; consuming Session close releases its local queue.
use std::{collections::VecDeque, sync::{Arc, atomic::{AtomicBool, Ordering}}};
use futures_util::{stream, StreamExt};
use providers_kit::{ProviderBackend, ModelBackend, SessionBackend, ModelId, KitError};
use providers_kit::error::{ErrorKind, ErrorPhase, Operation};
use providers_kit::generation::{ContentPart, FinishReason, GenerateEvent,
GenerateEventStream, GenerateRequest, GenerateResponse, GenerationConfig, Message, Role, Usage};
use providers_kit::session::{SessionConfig, SessionEvent, SessionInput};
#[derive(Clone, Default)]
struct EchoProvider { closed: Arc<AtomicBool> }
#[derive(Clone)]
struct EchoContinuation(Arc<()>);
struct EchoModel { id: ModelId, root: EchoProvider, replay: EchoContinuation }
struct EchoSession { model: ModelId, root: EchoProvider, events: VecDeque<SessionEvent> }
impl EchoProvider {
fn check(&self, operation: Operation) -> Result<(), KitError> {
if self.closed.load(Ordering::SeqCst) {
return Err(KitError::new(ErrorKind::Closed, operation, ErrorPhase::Lifecycle));
}
Ok(())
}
}
impl ProviderBackend for EchoProvider {
type Model = EchoModel;
fn model(&self, id: ModelId) -> Result<EchoModel, KitError> {
self.check(Operation::Generate)?;
if id.as_str() != "local-echo" {
return Err(KitError::new(ErrorKind::Unsupported, Operation::Generate,
ErrorPhase::InputValidation));
}
Ok(EchoModel { id, root: self.clone(), replay: EchoContinuation(Arc::new(())) })
}
async fn shutdown(&self) -> Result<(), KitError> {
// No await: sealing and this resource-free cleanup complete together.
self.closed.store(true, Ordering::SeqCst);
Ok(())
}
}
impl EchoModel {
fn response(&self, request: &GenerateRequest<EchoContinuation>)
-> Result<GenerateResponse<EchoContinuation>, KitError>
{
self.root.check(Operation::Generate)?;
let unsupported = || KitError::new(ErrorKind::Unsupported,
Operation::Generate, ErrorPhase::InputValidation);
if !request.tools().is_empty() || request.reasoning().is_some()
|| request.response_format().is_some()
|| request.generation() != &GenerationConfig::default()
|| request.messages().len() != 1 {
return Err(unsupported());
}
let message = &request.messages()[0];
if message.role() != Role::User { return Err(unsupported()); }
let [ContentPart::Text { text }] = message.content() else {
return Err(unsupported());
};
if text.len() > 64 * 1024 { return Err(unsupported()); }
Ok(GenerateResponse {
model: self.id.clone(),
message: Message::assistant_text(text.clone())?
.with_continuation(self.replay.clone())?,
finish_reason: Some(FinishReason::Stop),
citations: Vec::new(), artifacts: Vec::new(), hosted_tool_outputs: Vec::new(),
usage: Usage::default(), // No token accounting is invented.
})
}
}
impl ModelBackend for EchoModel {
type Continuation = EchoContinuation;
type Session = EchoSession;
fn model_id(&self) -> &ModelId { &self.id }
async fn generate(&self, request: &GenerateRequest<EchoContinuation>)
-> Result<GenerateResponse<EchoContinuation>, KitError> { self.response(request) }
async fn generate_stream(&self, request: &GenerateRequest<EchoContinuation>)
-> Result<GenerateEventStream<EchoContinuation>, KitError>
{
let response = self.response(request)?;
let text: String = response.message.content().iter().filter_map(|part| match part {
ContentPart::Text { text } => Some(text.as_str()), _ => None,
}).collect();
Ok(GenerateEventStream::new(stream::iter([
Ok(GenerateEvent::Started { model: self.id.clone() }),
Ok(GenerateEvent::ContentDelta { delta: text }),
Ok(GenerateEvent::Completed(Box::new(response))),
])))
}
async fn open_session(&self, config: SessionConfig) -> Result<EchoSession, KitError> {
self.root.check(Operation::OpenSession)?;
if config != SessionConfig::default() {
return Err(KitError::new(ErrorKind::Unsupported, Operation::OpenSession,
ErrorPhase::InputValidation));
}
Ok(EchoSession { model: self.id.clone(), root: self.root.clone(), events: VecDeque::new() })
}
}
impl SessionBackend for EchoSession {
fn id(&self) -> &str { "local-echo-session" }
fn model_id(&self) -> &ModelId { &self.model }
async fn send(&mut self, input: SessionInput) -> Result<(), KitError> {
self.root.check(Operation::SessionSend)?;
if !self.events.is_empty() {
return Err(KitError::new(ErrorKind::InvalidState, Operation::SessionSend,
ErrorPhase::Lifecycle));
}
match input {
SessionInput::Text { text } if !text.trim().is_empty() && text.len() <= 64 * 1024 => {
self.events.push_back(SessionEvent::TextDelta { delta: text });
self.events.push_back(SessionEvent::Completed);
Ok(())
}
_ => Err(KitError::new(ErrorKind::Unsupported, Operation::SessionSend,
ErrorPhase::InputValidation)),
}
}
async fn recv(&mut self) -> Result<SessionEvent, KitError> {
self.root.check(Operation::SessionReceive)?;
self.events.pop_front().ok_or_else(|| KitError::new(ErrorKind::InvalidState,
Operation::SessionReceive, ErrorPhase::Lifecycle))
}
async fn close(self) -> Result<(), KitError> { Ok(()) }
}
let provider = EchoProvider::default();
let model = provider.model(ModelId::new("local-echo")?)?;
let request = GenerateRequest::new(vec![Message::user_text("hello")?])?;
let response = model.generate(&request).await?;
assert!(matches!(response.message.content(), [ContentPart::Text { text }] if text == "hello"));
assert!(Arc::ptr_eq(&response.message.continuation().unwrap().0, &model.replay.0));
let mut events = model.generate_stream(&request).await?;
assert!(matches!(events.next().await.transpose()?, Some(GenerateEvent::Started { .. })));
assert!(
matches!(events.next().await.transpose()?, Some(GenerateEvent::ContentDelta { delta }) if delta == "hello")
);
assert!(matches!(events.next().await.transpose()?, Some(GenerateEvent::Completed(_))));
assert!(events.next().await.is_none());
let mut session = model.open_session(SessionConfig::default()).await?;
session.send(SessionInput::Text { text: "hello again".into() }).await?;
assert!(
matches!(session.recv().await?, SessionEvent::TextDelta { delta } if delta == "hello again")
);
assert_eq!(session.recv().await?, SessionEvent::Completed);
session.close().await?;
provider.shutdown().await?;
assert_eq!(model.generate(&request).await.err().unwrap().kind(), ErrorKind::Closed);
provider.shutdown().await?; // Replays the same resource-free terminal result.Required Associated Types§
Sourcetype Model: ModelBackend
type Model: ModelBackend
Exact model child returned by this provider.
Required Methods§
Sourcefn model(&self, id: ModelId) -> Result<Self::Model, KitError>
fn model(&self, id: ModelId) -> Result<Self::Model, KitError>
Selects one exact provider-local model.
§Errors
Returns an error when root admission is closed or the selected implementation cannot construct this exact model. Selection never silently falls back to another model.
See crate::ProviderBackend for a complete example.
Sourcefn shutdown(&self) -> impl Future<Output = Result<(), KitError>> + Send + '_
fn shutdown(&self) -> impl Future<Output = Result<(), KitError>> + Send + '_
Shuts down backend-owned resources.
Retain cleanup independently of each borrowed waiter. Repeated and concurrent calls replay the same terminal result; last-handle drop is not an async cleanup API.
§Errors
Returns the shared backend cleanup failure, if any. A cancelled waiter does not reset shutdown or abandon cleanup.
§Examples
use providers_kit::{
ModelBackend, ModelId, Provider, ProviderBackend, ProviderConfig,
config::{OllamaConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::Ollama(OllamaConfig::local()),
TransportConfig::default(),
))?;
let clone = provider.clone();
provider.shutdown().await?;
clone.shutdown().await?;
assert!(clone.model(ModelId::new("exact-model")?).is_err());
Provided Methods§
Sourcefn list_models(
&self,
_request: ModelListRequest,
) -> impl Future<Output = Result<ModelPage, KitError>> + Send + '_
fn list_models( &self, _request: ModelListRequest, ) -> impl Future<Output = Result<ModelPage, KitError>> + Send + '_
Lists provider-visible models.
This example requires a real configured service, valid credentials, and any exact resource ids shown. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.list_models(providers_kit::models::ModelListRequest::default()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let page = result?;
cleanup?;
for model in page.models {
println!("{}", model.id.as_str());
}
Sourcefn model_info(
&self,
_id: ModelId,
) -> impl Future<Output = Result<ModelSummary, KitError>> + Send + '_
fn model_info( &self, _id: ModelId, ) -> impl Future<Output = Result<ModelSummary, KitError>> + Send + '_
Fetches descriptive metadata for one exact provider-local model.
This example requires a real configured service, valid credentials, and any exact resource ids shown. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.model_info(providers_kit::ModelId::new("your-exact-model-id")?).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn upload_file(
&self,
_request: FileUploadRequest,
) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_
fn upload_file( &self, _request: FileUploadRequest, ) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_
Uploads one provider-managed file.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider
.upload_file(providers_kit::files::FileUploadRequest::new(
"notes.txt",
"text/plain",
b"notes".to_vec(),
)?)
.await;
let deletion = match &result {
Ok(file) => provider.delete_file(file.id.clone()).await,
Err(_) => Ok(()),
};
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
deletion?;
cleanup?;
Sourcefn list_files(
&self,
_request: FileListRequest,
) -> impl Future<Output = Result<FilePage, KitError>> + Send + '_
fn list_files( &self, _request: FileListRequest, ) -> impl Future<Output = Result<FilePage, KitError>> + Send + '_
Lists provider-managed files.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.list_files(providers_kit::files::FileListRequest::default()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn file_info(
&self,
_id: String,
) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_
fn file_info( &self, _id: String, ) -> impl Future<Output = Result<FileObject, KitError>> + Send + '_
Fetches metadata for one provider-managed file.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.file_info("owned-file-id".into()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn delete_file(
&self,
_id: String,
) -> impl Future<Output = Result<(), KitError>> + Send + '_
fn delete_file( &self, _id: String, ) -> impl Future<Output = Result<(), KitError>> + Send + '_
Deletes one provider-managed file.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.delete_file("owned-file-id".into()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn download_file(
&self,
_id: String,
_max_bytes: NonZeroUsize,
) -> impl Future<Output = Result<Vec<u8>, KitError>> + Send + '_
fn download_file( &self, _id: String, _max_bytes: NonZeroUsize, ) -> impl Future<Output = Result<Vec<u8>, KitError>> + Send + '_
Downloads one provider-managed file under the caller’s byte limit.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider
.download_file(
"owned-file-id".into(),
std::num::NonZeroUsize::new(1024 * 1024).unwrap(),
)
.await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn batch_status(
&self,
_id: String,
) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_
fn batch_status( &self, _id: String, ) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_
Fetches one batch job.
Supplied OpenAI status reads opt into the configured bounded transport
retries; every attempt shares the original absolute request deadline.
This does not retry decoding or successful-response body failures. The
lookup used by batch_results is excluded. See the batch workflow.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.batch_status("owned-batch-id".into()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn cancel_batch(
&self,
_id: String,
) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_
fn cancel_batch( &self, _id: String, ) -> impl Future<Output = Result<BatchJob, KitError>> + Send + '_
Requests cancellation of one batch job.
Acknowledgement is not terminality: the returned job may still be running. Observe its status until terminal before cleaning up owned input files; see the bounded batch workflow.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.cancel_batch("owned-batch-id".into()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn batch_results(
&self,
_id: String,
_max_bytes: NonZeroUsize,
) -> impl Future<Output = Result<Vec<BatchResult<<Self::Model as ModelBackend>::Continuation>>, KitError>> + Send + '_
fn batch_results( &self, _id: String, _max_bytes: NonZeroUsize, ) -> impl Future<Output = Result<Vec<BatchResult<<Self::Model as ModelBackend>::Continuation>>, KitError>> + Send + '_
Downloads and normalizes batch result rows under the caller’s byte limit.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported. The byte bound covers the downloaded result; each terminal row must be inspected independently. Row failures are result data, while download/normalization failures are outer errors.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider
.batch_results(
"owned-batch-id".into(),
std::num::NonZeroUsize::new(1024 * 1024).unwrap(),
)
.await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn list_batches(
&self,
_request: BatchListRequest,
) -> impl Future<Output = Result<BatchPage, KitError>> + Send + '_
fn list_batches( &self, _request: BatchListRequest, ) -> impl Future<Output = Result<BatchPage, KitError>> + Send + '_
Lists provider batch jobs.
This example requires a real configured service, valid credentials, and any exact resource ids shown. Only delete or cancel resources the caller owns. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.list_batches(providers_kit::batch::BatchListRequest::default()).await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Sourcefn health(
&self,
) -> impl Future<Output = Result<HealthStatus, KitError>> + Send + '_
fn health( &self, ) -> impl Future<Output = Result<HealthStatus, KitError>> + Send + '_
Probes provider runtime health.
This example requires a real configured service, valid credentials, and any exact resource ids shown. The default trait implementation returns Unsupported.
§Errors
Returns KitError classified as Unsupported when unavailable, Closed after sealing, or the owning input, transport, deadline, service-rejection, or response-validation category. Inspect kind() and context() rather than diagnostic prose.
§Examples
use providers_kit::{
Provider, ProviderBackend, ProviderConfig,
config::{ApiKey, OpenAiConfig, ProviderKind, TransportConfig},
};
let provider = Provider::from_config(ProviderConfig::new(
ProviderKind::OpenAi(OpenAiConfig::new(ApiKey::new("replace-with-your-key")?)),
TransportConfig::default(),
))?;
let result = provider.health().await;
let cleanup = provider.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _value = result?;
cleanup?;
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".