Skip to main content

adk_core/
callbacks.rs

1use crate::{CallbackContext, Content, LlmRequest, LlmResponse, ReadonlyContext, Result, Tool};
2use std::future::Future;
3use std::pin::Pin;
4use std::sync::Arc;
5
6// Agent callbacks
7/// Callback invoked before an agent runs. Return `Ok(Some(content))` to short-circuit.
8pub type BeforeAgentCallback = Box<
9    dyn Fn(
10            Arc<dyn CallbackContext>,
11        ) -> Pin<Box<dyn Future<Output = Result<Option<Content>>> + Send>>
12        + Send
13        + Sync,
14>;
15/// Callback invoked after an agent completes. Return `Ok(Some(content))` to override.
16pub type AfterAgentCallback = Box<
17    dyn Fn(
18            Arc<dyn CallbackContext>,
19        ) -> Pin<Box<dyn Future<Output = Result<Option<Content>>> + Send>>
20        + Send
21        + Sync,
22>;
23
24/// Result from a BeforeModel callback
25#[derive(Debug)]
26pub enum BeforeModelResult {
27    /// Continue with the (possibly modified) request
28    Continue(LlmRequest),
29    /// Skip the model call and use this response instead
30    Skip(LlmResponse),
31}
32
33// Model callbacks
34// BeforeModelCallback can modify the request or skip the model call entirely
35/// Callback invoked before a model call. Can modify the request or skip the call entirely.
36pub type BeforeModelCallback = Box<
37    dyn Fn(
38            Arc<dyn CallbackContext>,
39            LlmRequest,
40        ) -> Pin<Box<dyn Future<Output = Result<BeforeModelResult>> + Send>>
41        + Send
42        + Sync,
43>;
44/// Callback invoked after a model call. Return `Ok(Some(response))` to override.
45pub type AfterModelCallback = Box<
46    dyn Fn(
47            Arc<dyn CallbackContext>,
48            LlmResponse,
49        ) -> Pin<Box<dyn Future<Output = Result<Option<LlmResponse>>> + Send>>
50        + Send
51        + Sync,
52>;
53
54// Tool callbacks
55/// Callback invoked before a tool executes. Return `Ok(Some(content))` to skip execution.
56pub type BeforeToolCallback = Box<
57    dyn Fn(
58            Arc<dyn CallbackContext>,
59        ) -> Pin<Box<dyn Future<Output = Result<Option<Content>>> + Send>>
60        + Send
61        + Sync,
62>;
63/// Callback invoked after a tool executes. Return `Ok(Some(content))` to override the result.
64pub type AfterToolCallback = Box<
65    dyn Fn(
66            Arc<dyn CallbackContext>,
67        ) -> Pin<Box<dyn Future<Output = Result<Option<Content>>> + Send>>
68        + Send
69        + Sync,
70>;
71
72/// Rich after-tool callback that receives the tool, arguments, and response.
73///
74/// Aligned with the Python/Go ADK model where `after_tool_callback` receives
75/// the full tool execution context: the tool itself, the arguments it was
76/// called with, and the response it produced (or error JSON).
77///
78/// This is the V2 callback surface for first-class tool result handling.
79/// Unlike [`AfterToolCallback`] (which only receives `CallbackContext`),
80/// this callback can inspect and modify tool results without relying on
81/// `ToolOutcome` inspection.
82///
83/// Return `Ok(None)` to keep the original response, or `Ok(Some(value))`
84/// to replace the function response sent to the LLM.
85pub type AfterToolCallbackFull = Box<
86    dyn Fn(
87            Arc<dyn CallbackContext>,
88            Arc<dyn Tool>,
89            serde_json::Value, // args
90            serde_json::Value, // tool response (success result or error JSON)
91        ) -> Pin<Box<dyn Future<Output = Result<Option<serde_json::Value>>> + Send>>
92        + Send
93        + Sync,
94>;
95
96// Instruction providers - dynamic instruction generation
97/// Async function that generates dynamic instructions from context.
98pub type InstructionProvider = Box<
99    dyn Fn(Arc<dyn ReadonlyContext>) -> Pin<Box<dyn Future<Output = Result<String>> + Send>>
100        + Send
101        + Sync,
102>;
103/// Alias for [`InstructionProvider`] used at the global (runner) level.
104pub type GlobalInstructionProvider = InstructionProvider;
105
106// ===== Error Callbacks =====
107
108/// Callback invoked when a tool execution fails (after retries are exhausted).
109///
110/// This is the canonical, framework-level tool-error callback type shared by
111/// `adk-agent` (builder registration) and `adk-plugin` (plugin hooks).
112///
113/// Returns `Ok(Some(value))` to substitute a fallback result as the function
114/// response to the LLM, or `Ok(None)` to let the next callback (or the
115/// original error) propagate.
116pub type OnToolErrorCallback = Box<
117    dyn Fn(
118            Arc<dyn CallbackContext>,
119            Arc<dyn Tool>,
120            serde_json::Value, // args
121            String,            // error message
122        ) -> Pin<Box<dyn Future<Output = Result<Option<serde_json::Value>>> + Send>>
123        + Send
124        + Sync,
125>;
126
127// ===== Context Compaction =====
128
129use crate::Event;
130use async_trait::async_trait;
131
132/// Trait for summarizing events during context compaction.
133///
134/// Implementations receive a window of events and produce a single
135/// compacted event containing a summary. The runner calls this when
136/// the compaction interval is reached.
137#[async_trait]
138pub trait BaseEventsSummarizer: Send + Sync {
139    /// Summarize the given events into a single compacted event.
140    /// Returns `None` if no compaction is needed (e.g., empty input).
141    async fn summarize_events(&self, events: &[Event]) -> Result<Option<Event>>;
142}
143
144/// Configuration for automatic context compaction.
145///
146/// Mirrors ADK Python's `EventsCompactionConfig`:
147/// - `compaction_interval`: Number of invocations before triggering compaction
148/// - `overlap_size`: Events from the previous window to include in the next summary
149/// - `summarizer`: The strategy used to produce summaries
150#[derive(Clone)]
151pub struct EventsCompactionConfig {
152    /// Number of completed invocations that triggers compaction.
153    pub compaction_interval: u32,
154    /// How many events from the previous compacted window to include
155    /// in the next compaction for continuity.
156    pub overlap_size: u32,
157    /// The summarizer implementation (e.g., LLM-based).
158    pub summarizer: Arc<dyn BaseEventsSummarizer>,
159}