Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Callbacks

Synaptic provides an event-driven callback system for observing agent execution. The CallbackHandler trait receives RunEvent values at key lifecycle points -- when a run starts, when the LLM is called, when tools are executed, and when the run finishes or fails.

The CallbackHandler Trait

The trait is defined in synaptic_core:

#[async_trait]
pub trait CallbackHandler: Send + Sync {
    async fn on_event(&self, event: RunEvent) -> Result<(), SynapticError>;
}

A single method receives all event types. Handlers are Send + Sync so they can be shared across async tasks.

RunEvent Variants

The RunEvent enum covers the full agent lifecycle:

VariantFieldsWhen It Fires
RunStartedrun_id, session_idAt the beginning of an agent run
RunSteprun_id, stepAt each iteration of the agent loop
LlmCalledrun_id, message_countWhen the LLM is invoked with messages
ToolCalledrun_id, tool_nameWhen a tool is executed
RunFinishedrun_id, outputWhen the agent produces a final answer
RunFailedrun_id, errorWhen the agent run fails with an error

RunEvent implements Clone, so handlers can store copies of events for later inspection.

Built-in Handlers

Synaptic ships with four callback handlers:

HandlerPurpose
RecordingCallbackRecords all events in memory for later inspection
TracingCallbackEmits structured tracing spans and events
StdOutCallbackHandlerPrints events to stdout (with optional verbose mode)
CompositeCallbackDispatches events to multiple handlers

Implementing a Custom Handler

You can implement CallbackHandler to add your own observability:

use async_trait::async_trait;
use synaptic::core::{CallbackHandler, RunEvent, SynapticError};

struct MetricsCallback;

#[async_trait]
impl CallbackHandler for MetricsCallback {
    async fn on_event(&self, event: RunEvent) -> Result<(), SynapticError> {
        match event {
            RunEvent::LlmCalled { message_count, .. } => {
                // Record to your metrics system
                println!("LLM called with {message_count} messages");
            }
            RunEvent::ToolCalled { tool_name, .. } => {
                println!("Tool executed: {tool_name}");
            }
            _ => {}
        }
        Ok(())
    }
}

Guides