use async_trait::async_trait;
use std::sync::Arc;
use super::run_tree::RunTree;
use lc_schema::Message;
#[async_trait]
pub trait CallbackHandler: Send + Sync {
async fn on_run_start(&self, run: &RunTree);
async fn on_run_end(&self, run: &RunTree);
async fn on_run_error(&self, run: &RunTree, error: &str);
async fn on_llm_start(&self, run: &RunTree, _messages: &[Message]) {
self.on_run_start(run).await;
}
async fn on_llm_end(&self, run: &RunTree, _response: &str) {
self.on_run_end(run).await;
}
async fn on_llm_new_token(&self, _run: &RunTree, _token: &str) {
}
async fn on_llm_thinking(&self, _run: &RunTree, _thinking: &str) {
}
async fn on_llm_error(&self, run: &RunTree, error: &str) {
self.on_run_error(run, error).await;
}
async fn on_chain_start(&self, run: &RunTree, _inputs: &serde_json::Value) {
self.on_run_start(run).await;
}
async fn on_chain_end(&self, run: &RunTree, _outputs: &serde_json::Value) {
self.on_run_end(run).await;
}
async fn on_chain_error(&self, run: &RunTree, error: &str) {
self.on_run_error(run, error).await;
}
async fn on_tool_start(&self, run: &RunTree, _tool_name: &str, _input: &str) {
self.on_run_start(run).await;
}
async fn on_tool_end(&self, run: &RunTree, _output: &str) {
self.on_run_end(run).await;
}
async fn on_tool_error(&self, run: &RunTree, error: &str) {
self.on_run_error(run, error).await;
}
async fn on_retriever_start(&self, run: &RunTree, _query: &str) {
self.on_run_start(run).await;
}
async fn on_retriever_end(&self, run: &RunTree, _documents: &[serde_json::Value]) {
self.on_run_end(run).await;
}
async fn on_retriever_error(&self, run: &RunTree, error: &str) {
self.on_run_error(run, error).await;
}
}
pub struct CallbackManager {
inner: Arc<CallbackManagerInner>,
}
struct CallbackManagerInner {
handlers: Vec<Arc<dyn CallbackHandler>>,
}
impl std::fmt::Debug for CallbackManager {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CallbackManager")
.field("handlers_count", &self.inner.handlers.len())
.finish()
}
}
impl CallbackManager {
pub fn new() -> Self {
Self {
inner: Arc::new(CallbackManagerInner {
handlers: Vec::new(),
}),
}
}
pub fn add_handler(self, handler: Arc<dyn CallbackHandler>) -> Self {
let mut handlers = self.inner.handlers.clone();
handlers.push(handler);
Self {
inner: Arc::new(CallbackManagerInner { handlers }),
}
}
pub fn handlers(&self) -> &[Arc<dyn CallbackHandler>] {
&self.inner.handlers
}
pub fn is_empty(&self) -> bool {
self.inner.handlers.is_empty()
}
}
impl Default for CallbackManager {
fn default() -> Self {
Self::new()
}
}
impl Clone for CallbackManager {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl CallbackManager {
pub async fn dispatch_chain_start(&self, run: &RunTree, inputs: &serde_json::Value) {
for handler in &self.inner.handlers {
handler.on_chain_start(run, inputs).await;
}
}
pub async fn dispatch_chain_end(&self, run: &RunTree, outputs: &serde_json::Value) {
for handler in &self.inner.handlers {
handler.on_chain_end(run, outputs).await;
}
}
pub async fn dispatch_chain_error(&self, run: &RunTree, error: &str) {
for handler in &self.inner.handlers {
handler.on_chain_error(run, error).await;
}
}
pub async fn dispatch_llm_start(&self, run: &RunTree, messages: &[lc_schema::Message]) {
for handler in &self.inner.handlers {
handler.on_llm_start(run, messages).await;
}
}
pub async fn dispatch_llm_end(&self, run: &RunTree, response: &str) {
for handler in &self.inner.handlers {
handler.on_llm_end(run, response).await;
}
}
pub async fn dispatch_llm_error(&self, run: &RunTree, error: &str) {
for handler in &self.inner.handlers {
handler.on_llm_error(run, error).await;
}
}
pub async fn dispatch_llm_new_token(&self, run: &RunTree, token: &str) {
for handler in &self.inner.handlers {
handler.on_llm_new_token(run, token).await;
}
}
pub async fn dispatch_tool_start(&self, run: &RunTree, tool_name: &str, input: &str) {
for handler in &self.inner.handlers {
handler.on_tool_start(run, tool_name, input).await;
}
}
pub async fn dispatch_tool_end(&self, run: &RunTree, output: &str) {
for handler in &self.inner.handlers {
handler.on_tool_end(run, output).await;
}
}
pub async fn dispatch_tool_error(&self, run: &RunTree, error: &str) {
for handler in &self.inner.handlers {
handler.on_tool_error(run, error).await;
}
}
pub async fn dispatch_retriever_start(&self, run: &RunTree, query: &str) {
for handler in &self.inner.handlers {
handler.on_retriever_start(run, query).await;
}
}
pub async fn dispatch_retriever_end(&self, run: &RunTree, documents: &[serde_json::Value]) {
for handler in &self.inner.handlers {
handler.on_retriever_end(run, documents).await;
}
}
pub async fn dispatch_retriever_error(&self, run: &RunTree, error: &str) {
for handler in &self.inner.handlers {
handler.on_retriever_error(run, error).await;
}
}
}