use std::sync::Arc;
use async_trait::async_trait;
use futures::stream::BoxStream;
use crate::audio::{
AudioResponse, SpeechToTextRequest, TextToSpeechRequest, TranscriptionResponse,
};
use crate::embeddings::{EmbeddingsRequest, EmbeddingsResponse};
use crate::error::Error;
use crate::images::{ImagesRequest, ImagesResponse};
use crate::moderation::{ModerationRequest, ModerationResponse};
use crate::provider::Provider;
use crate::rerank::{RerankRequest, RerankResponse};
use crate::stream_event::StreamEvent;
use crate::structured::{StructuredRequest, StructuredResponse};
use crate::text::{Step, TextRequest};
#[async_trait]
pub trait ProviderMiddleware: Send + Sync {
async fn text_step(&self, request: TextRequest, next: &dyn Provider) -> Result<Step, Error> {
next.text_step(&request).await
}
async fn stream_text_once(
&self,
request: TextRequest,
next: &dyn Provider,
) -> Result<BoxStream<'static, Result<StreamEvent, Error>>, Error> {
next.stream_text_once(&request).await
}
async fn structured(
&self,
request: StructuredRequest,
next: &dyn Provider,
) -> Result<StructuredResponse, Error> {
next.structured(request).await
}
async fn moderation(
&self,
request: ModerationRequest,
next: &dyn Provider,
) -> Result<ModerationResponse, Error> {
next.moderation(request).await
}
async fn embeddings(
&self,
request: EmbeddingsRequest,
next: &dyn Provider,
) -> Result<EmbeddingsResponse, Error> {
next.embeddings(request).await
}
async fn rerank(
&self,
request: RerankRequest,
next: &dyn Provider,
) -> Result<RerankResponse, Error> {
next.rerank(request).await
}
async fn images(
&self,
request: ImagesRequest,
next: &dyn Provider,
) -> Result<ImagesResponse, Error> {
next.images(request).await
}
async fn text_to_speech(
&self,
request: TextToSpeechRequest,
next: &dyn Provider,
) -> Result<AudioResponse, Error> {
next.text_to_speech(request).await
}
async fn speech_to_text(
&self,
request: SpeechToTextRequest,
next: &dyn Provider,
) -> Result<TranscriptionResponse, Error> {
next.speech_to_text(request).await
}
}
pub struct MiddlewareProvider {
inner: Arc<dyn Provider>,
middleware: Arc<dyn ProviderMiddleware>,
}
impl MiddlewareProvider {
pub fn new(inner: Arc<dyn Provider>, middleware: impl ProviderMiddleware + 'static) -> Self {
Self {
inner,
middleware: Arc::new(middleware),
}
}
}
#[async_trait]
impl Provider for MiddlewareProvider {
fn name(&self) -> &str {
self.inner.name()
}
async fn text_step(&self, request: &TextRequest) -> Result<Step, Error> {
self.middleware
.text_step(request.clone(), self.inner.as_ref())
.await
}
async fn stream_text_once(
&self,
request: &TextRequest,
) -> Result<BoxStream<'static, Result<StreamEvent, Error>>, Error> {
self.middleware
.stream_text_once(request.clone(), self.inner.as_ref())
.await
}
async fn structured(&self, request: StructuredRequest) -> Result<StructuredResponse, Error> {
self.middleware
.structured(request, self.inner.as_ref())
.await
}
async fn moderation(&self, request: ModerationRequest) -> Result<ModerationResponse, Error> {
self.middleware
.moderation(request, self.inner.as_ref())
.await
}
async fn embeddings(&self, request: EmbeddingsRequest) -> Result<EmbeddingsResponse, Error> {
self.middleware
.embeddings(request, self.inner.as_ref())
.await
}
async fn rerank(&self, request: RerankRequest) -> Result<RerankResponse, Error> {
self.middleware.rerank(request, self.inner.as_ref()).await
}
async fn images(&self, request: ImagesRequest) -> Result<ImagesResponse, Error> {
self.middleware.images(request, self.inner.as_ref()).await
}
async fn text_to_speech(&self, request: TextToSpeechRequest) -> Result<AudioResponse, Error> {
self.middleware
.text_to_speech(request, self.inner.as_ref())
.await
}
async fn speech_to_text(
&self,
request: SpeechToTextRequest,
) -> Result<TranscriptionResponse, Error> {
self.middleware
.speech_to_text(request, self.inner.as_ref())
.await
}
}