pub mod client;
pub mod model;
pub mod splitter;
use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;
pub use crate::tools::ToolExecutor;
pub use client::{
image_to_data_uri, load_tools_file, parse_sse_delta, parse_sse_line, ContentBlock, FunctionDef,
ImageUrl, LlmClient, Message, MessageContent, SseDelta, Tool, ToolCall,
};
pub use splitter::ClauseSplitter;
use crate::error::Result;
pub trait LlmBackend: Send {
fn name(&self) -> &str;
fn stream_reply<'a>(
&'a mut self,
user: &'a str,
clauses: mpsc::Sender<String>,
cancel: CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;
fn clear_history(&mut self);
fn hold_music_flag(&self) -> Option<&Arc<AtomicBool>> {
None
}
}
impl LlmBackend for LlmClient {
fn name(&self) -> &str {
self.model_name()
}
fn stream_reply<'a>(
&'a mut self,
user: &'a str,
clauses: mpsc::Sender<String>,
cancel: CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>> {
Box::pin(LlmClient::stream_reply(self, user, clauses, cancel))
}
fn clear_history(&mut self) {
LlmClient::clear_history(self);
}
fn hold_music_flag(&self) -> Option<&Arc<AtomicBool>> {
self.hold_music_active.as_ref()
}
}