use anyhow::Result;
use futures_core::Stream;
pub use limits::default_context_limit;
pub use message::{Message, MessageBuilder, Role, estimate_tokens};
pub use request::Request;
pub use response::{
Choice, CompletionMeta, CompletionTokensDetails, Delta, FinishReason, Response, Usage,
};
pub use stream::StreamChunk;
pub use tool::{FunctionCall, Tool, ToolCall, ToolChoice};
mod limits;
mod message;
mod request;
mod response;
mod stream;
mod tool;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_model;
pub trait Model: Sized + Clone {
fn send(&self, request: &Request) -> impl Future<Output = Result<Response>> + Send;
fn stream(&self, request: Request) -> impl Stream<Item = Result<StreamChunk>> + Send;
fn context_limit(&self, model: &str) -> usize {
default_context_limit(model)
}
fn active_model(&self) -> String;
}
impl Model for () {
async fn send(&self, _request: &Request) -> Result<Response> {
panic!("NoopModel::send called — not intended for real LLM calls");
}
#[allow(unreachable_code)]
fn stream(&self, _request: Request) -> impl Stream<Item = Result<StreamChunk>> + Send {
panic!("NoopModel::stream called — not intended for real LLM calls");
async_stream::stream! {
yield Err(anyhow::anyhow!("not implemented"));
}
}
fn context_limit(&self, _model: &str) -> usize {
0
}
fn active_model(&self) -> String {
String::new()
}
}