pub mod anthropic;
pub mod openai;
use crate::error::GatewayError;
use crate::model::{ChatRequest, ChatResponse};
use async_trait::async_trait;
use bytes::Bytes;
use futures::stream::BoxStream;
pub type ChatStream = BoxStream<'static, crate::error::Result<Bytes>>;
#[derive(Clone, Debug, Default)]
pub struct Caps {
pub tools: bool,
pub vision: bool,
pub streaming: bool,
}
impl Caps {
pub fn from_list(list: &[String]) -> Self {
Self {
tools: list.iter().any(|c| c == "tools"),
vision: list.iter().any(|c| c == "vision"),
streaming: true,
}
}
}
#[async_trait]
pub trait Provider: Send + Sync {
fn id(&self) -> &str;
fn caps(&self) -> &Caps;
fn price(&self, prompt_tokens: u32, completion_tokens: u32) -> f64;
async fn chat(&self, req: ChatRequest) -> crate::error::Result<ChatResponse>;
async fn chat_stream(&self, _req: ChatRequest) -> crate::error::Result<ChatStream> {
Err(GatewayError::UpstreamUnavailable(format!(
"streaming is not supported by provider '{}'",
self.id()
)))
}
async fn embed(&self, _input: serde_json::Value) -> crate::error::Result<serde_json::Value> {
Err(GatewayError::UpstreamUnavailable(format!(
"embeddings are not supported by provider '{}'",
self.id()
)))
}
}