use async_trait::async_trait;
use futures::stream::BoxStream;
use crate::error::Error;
use crate::provider::Provider;
use crate::providers::openai::OpenAiProvider;
use crate::stream_event::StreamEvent;
use crate::text::{Step, TextRequest};
macro_rules! openai_compatible_provider {
(
$(#[$doc:meta])*
feature = $feature:literal,
$struct_name:ident, $name:literal, $default_base_url:literal
) => {
$(#[$doc])*
#[cfg(feature = $feature)]
pub struct $struct_name {
inner: OpenAiProvider,
}
#[cfg(feature = $feature)]
impl $struct_name {
#[doc = concat!("`", $default_base_url, "`")]
pub fn new(api_key: impl Into<String>) -> Self {
Self::with_base_url(api_key, $default_base_url)
}
pub fn with_base_url(api_key: impl Into<String>, base_url: impl Into<String>) -> Self {
Self {
inner: OpenAiProvider::with_name_and_base_url($name, api_key, base_url),
}
}
pub fn with_client(mut self, client: reqwest_middleware::ClientWithMiddleware) -> Self {
self.inner = self.inner.with_client(client);
self
}
}
#[cfg(feature = $feature)]
#[async_trait]
impl Provider for $struct_name {
fn name(&self) -> &str {
$name
}
async fn text_step(&self, request: &TextRequest) -> Result<Step, Error> {
self.inner.text_step(request).await
}
async fn stream_text_once(
&self,
request: &TextRequest,
) -> Result<BoxStream<'static, Result<StreamEvent, Error>>, Error> {
self.inner.stream_text_once(request).await
}
}
};
}
openai_compatible_provider!(
feature = "groq",
GroqProvider,
"groq",
"https://api.groq.com/openai/v1"
);
openai_compatible_provider!(
feature = "deepseek",
DeepSeekProvider,
"deepseek",
"https://api.deepseek.com/v1"
);
openai_compatible_provider!(
feature = "mistral",
MistralProvider,
"mistral",
"https://api.mistral.ai/v1"
);
openai_compatible_provider!(
feature = "xai",
XaiProvider,
"xai",
"https://api.x.ai/v1"
);
openai_compatible_provider!(
feature = "openrouter",
OpenRouterProvider,
"openrouter",
"https://openrouter.ai/api/v1"
);
openai_compatible_provider!(
feature = "perplexity",
PerplexityProvider,
"perplexity",
"https://api.perplexity.ai"
);
openai_compatible_provider!(
feature = "zai",
ZaiProvider,
"zai",
"https://api.z.ai/api/paas/v4"
);