pub mod anthropic;
pub mod frame;
pub mod google_genai;
mod json;
pub mod ollama_chat;
pub mod openai;
pub mod openai_responses;
pub mod sse;
mod synth;
use crate::canonical::{CanonicalError, CanonicalRequest, Event};
use crate::transport::Timeouts;
pub use frame::{DecodeState, Decoder, Frame, Framing, OpenBlock};
pub(crate) use json::{decode_models, http_error};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ModelsShape {
pub path: &'static str,
pub array_key: &'static str,
pub id_key: &'static str,
pub strip: &'static str,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Method {
#[default]
Post,
Get,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct WireRequest {
pub method: Method,
pub url: String,
pub headers: Vec<(String, String)>,
pub body: Vec<u8>,
pub timeouts: Timeouts,
}
impl WireRequest {
pub fn new(url: impl Into<String>, body: Vec<u8>) -> Self {
WireRequest {
method: Method::Post,
url: url.into(),
headers: Vec::new(),
body,
timeouts: Timeouts::default(),
}
}
pub fn get(url: impl Into<String>) -> Self {
WireRequest {
method: Method::Get,
url: url.into(),
headers: Vec::new(),
body: Vec::new(),
timeouts: Timeouts::default(),
}
}
pub fn set_header(&mut self, name: &str, value: &str) {
if let Some(slot) = self
.headers
.iter_mut()
.find(|(n, _)| n.eq_ignore_ascii_case(name))
{
slot.1 = value.to_owned();
} else {
self.headers.push((name.to_owned(), value.to_owned()));
}
}
pub fn header(&self, name: &str) -> Option<&str> {
self.headers
.iter()
.find(|(n, _)| n.eq_ignore_ascii_case(name))
.map(|(_, v)| v.as_str())
}
}
pub struct ProviderCtx<'a> {
pub base_url: &'a str,
pub model: &'a str,
pub beta_headers: &'a [(&'a str, &'a str)],
}
pub trait Protocol: Send + Sync {
fn encode(
&self,
req: &CanonicalRequest,
ctx: &ProviderCtx,
) -> Result<WireRequest, CanonicalError>;
fn path(&self, ctx: &ProviderCtx) -> String;
fn content_type(&self) -> &str;
fn decode(&self, frame: Frame, state: &mut DecodeState) -> Result<Vec<Event>, CanonicalError>;
fn decode_full(
&self,
body: &[u8],
state: &mut DecodeState,
) -> Result<Vec<Event>, CanonicalError>;
fn framing(&self) -> Framing;
fn models_shape(&self) -> ModelsShape;
}