use std::{future::Future, pin::Pin};
use crate::{
error::Result,
generic::{GenericChatCompletionResponse, GenericFunctionSpec, GenericMessage},
model::Model,
};
use futures_core::stream::Stream;
pub trait ChatCompletionProvider: Send + Sync {
type Message: Send + Sync + 'static;
fn chat_complete<'p, M>(
&self,
params: ChatCompleteParameters<M>,
) -> Pin<
Box<dyn Future<Output = Result<GenericChatCompletionResponse<GenericMessage>>> + Send + 'p>,
>
where
M: Into<Self::Message> + Send + Sync + 'p;
}
pub trait StreamingChatProvider: ChatCompletionProvider {
type Delta<'s>: Stream<Item = Result<String>> + Send + 's
where
Self: 's;
fn chat_complete_stream<'p, M>(&self, params: ChatCompleteParameters<M>) -> Self::Delta<'p>
where
M: Into<Self::Message> + Send + Sync + 'p;
}
#[derive(Debug, Clone)]
pub struct ChatCompleteParameters<M> {
pub messages: Vec<M>,
pub model: Model,
pub tools: Option<Vec<GenericFunctionSpec>>,
pub temperature: Option<f64>,
pub response_format: Option<serde_json::Value>,
}
impl<M> ChatCompleteParameters<M> {
pub fn new(messages: Vec<M>, model: Model) -> Self {
Self {
messages,
model,
tools: None,
temperature: None,
response_format: None,
}
}
pub fn messages(&self) -> &Vec<M> {
&self.messages
}
pub fn model(&self) -> Model {
self.model.clone()
}
pub fn tools(&self) -> Option<&Vec<GenericFunctionSpec>> {
self.tools.as_ref()
}
pub fn with_temperature(mut self, temperature: f64) -> Self {
self.temperature = Some(temperature);
self
}
pub fn with_response_format(mut self, response_format: serde_json::Value) -> Self {
self.response_format = Some(response_format);
self
}
pub fn with_tools(mut self, tools: Vec<GenericFunctionSpec>) -> Self {
self.tools = Some(tools);
self
}
}