use async_trait::async_trait;
use serde_json::Value;
use crate::error::ProviderError;
use crate::message::{CacheControl, Content, Message, StopReason, Usage};
use crate::stream::ProviderEventStream;
#[derive(Debug, Clone)]
pub struct ToolDefinition {
pub name: String,
pub description: String,
pub input_schema: Value,
pub cache_control: Option<CacheControl>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SystemBlock {
pub text: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cache_control: Option<CacheControl>,
}
impl SystemBlock {
pub fn text(s: impl Into<String>) -> Self {
Self {
text: s.into(),
cache_control: None,
}
}
pub fn cached(s: impl Into<String>) -> Self {
Self {
text: s.into(),
cache_control: Some(CacheControl::ephemeral()),
}
}
pub fn cached_1h(s: impl Into<String>) -> Self {
Self {
text: s.into(),
cache_control: Some(CacheControl::ephemeral_1h()),
}
}
}
#[derive(Debug, Clone)]
pub struct Request {
pub model: String,
pub system: Option<Vec<SystemBlock>>,
pub messages: Vec<Message>,
pub tools: Vec<ToolDefinition>,
pub max_tokens: u32,
pub temperature: Option<f32>,
}
#[derive(Debug, Clone)]
pub struct Response {
pub content: Vec<Content>,
pub stop_reason: StopReason,
pub usage: Usage,
}
#[async_trait]
pub trait LlmProvider: Send + Sync {
async fn complete(&self, request: Request) -> Result<Response, ProviderError>;
async fn stream(&self, request: Request) -> Result<ProviderEventStream, ProviderError>;
}