use async_trait::async_trait;
use futures::Stream;
use thiserror::Error;
use crate::model::{Message, Response};
use crate::options::{ModelOptions, TransportOptions};
use rmcp::model::Tool;
#[derive(Error, Debug)]
pub enum ClientError {
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("JSON parse error: {0}")]
Parse(#[from] serde_json::Error),
#[error("Provider error: {0}")]
ProviderError(String),
#[error("Stream cancelled")]
StreamCancelled,
#[error("Configuration error: {0}")]
Config(String),
}
#[async_trait]
pub trait Client: Send + Sync {
type ModelProvider: Send + Sync;
async fn request(
&self,
messages: Vec<Message>,
tools: Vec<Tool>,
) -> Result<Response, ClientError>;
fn model_options(&self) -> &ModelOptions<Self::ModelProvider>;
fn transport_options(&self) -> &TransportOptions;
}
#[async_trait]
pub trait StreamingClient: Client {
async fn request_stream(
&self,
messages: Vec<Message>,
tools: Vec<Tool>,
) -> Result<
std::pin::Pin<Box<dyn Stream<Item = Result<Response, ClientError>> + Send>>,
ClientError,
>;
}