use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;
use futures::Stream;
use serde::{Deserialize, Serialize};
use crate::error::PeError;
use crate::message::{AiMessage, Message};
pub type StreamFuture<'a> = Pin<
Box<
dyn Future<Output = Result<Pin<Box<dyn Stream<Item = StreamChunk> + Send>>, PeError>>
+ Send
+ 'a,
>,
>;
pub trait LlmProvider: Send + Sync + 'static {
fn complete(
&self,
messages: &[Message],
tools: &[ToolSchema],
) -> Pin<Box<dyn Future<Output = Result<LlmResponse, PeError>> + Send + '_>>;
fn stream(&self, messages: &[Message], tools: &[ToolSchema]) -> StreamFuture<'_>;
fn embed(
&self,
text: &str,
) -> Pin<Box<dyn Future<Output = Result<Vec<f32>, PeError>> + Send + '_>>;
fn provider_name(&self) -> &'static str;
}
#[derive(Debug, Clone)]
pub struct LlmResponse {
pub message: AiMessage,
pub provider_metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum StreamChunk {
Token(String),
Done(LlmResponse),
Error(PeError),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolSchema {
pub name: String,
pub description: String,
pub parameters: serde_json::Value,
#[serde(default)]
pub strict: bool,
}