Skip to main content

adk_plugin/
hook_result.rs

1//! Hook result types for the enhanced plugin system.
2//!
3//! These enums define the return types for plugin hooks, enabling
4//! continue/short-circuit semantics in the plugin pipeline.
5//!
6//! # Overview
7//!
8//! Each hook type has a corresponding result enum:
9//!
10//! - [`BeforeToolCallResult`] — returned by `before_tool_call` hooks
11//! - [`AfterToolCallResult`] — returned by `after_tool_call` hooks
12//! - [`BeforeModelCallResult`] — returned by `before_model_call` hooks
13//! - [`AfterModelCallResult`] — returned by `after_model_call` hooks
14//!
15//! "Before" hooks support short-circuiting (skipping the underlying operation),
16//! while "after" hooks only support continuing with a (possibly modified) result.
17
18use adk_core::{LlmRequest, LlmResponse};
19
20/// Result from a `before_tool_call` hook invocation.
21///
22/// Determines whether tool execution continues with (possibly modified) arguments,
23/// or is short-circuited with a synthetic result.
24///
25/// # Examples
26///
27/// ## Continuing with modified arguments
28///
29/// ```rust
30/// use adk_plugin::BeforeToolCallResult;
31/// use serde_json::json;
32///
33/// // Pass through arguments unchanged
34/// let args = json!({"query": "hello"});
35/// let result = BeforeToolCallResult::Continue(args);
36///
37/// // Or modify arguments before passing to the tool
38/// let sanitized = json!({"query": "hello", "safe_mode": true});
39/// let result = BeforeToolCallResult::Continue(sanitized);
40/// ```
41///
42/// ## Short-circuiting tool execution
43///
44/// ```rust
45/// use adk_plugin::BeforeToolCallResult;
46/// use serde_json::json;
47///
48/// // Skip tool execution and return a cached result
49/// let cached = json!({"data": "cached response"});
50/// let result = BeforeToolCallResult::ShortCircuit(cached);
51/// ```
52#[derive(Debug)]
53pub enum BeforeToolCallResult {
54    /// Continue execution with (possibly modified) arguments.
55    ///
56    /// The contained value will be passed to the next plugin in the chain,
57    /// and ultimately to the tool execution if this is the last plugin.
58    Continue(serde_json::Value),
59
60    /// Short-circuit: skip tool execution and use this synthetic result.
61    ///
62    /// When returned, no further plugins in the chain are invoked,
63    /// the tool is not executed, and this value is used as the tool output.
64    ShortCircuit(serde_json::Value),
65}
66
67/// Result from an `after_tool_call` hook invocation.
68///
69/// After-tool hooks can only continue with a (possibly modified) result.
70/// Short-circuiting is not supported for after-hooks since the operation
71/// has already completed.
72///
73/// # Examples
74///
75/// ```rust
76/// use adk_plugin::AfterToolCallResult;
77/// use serde_json::json;
78///
79/// // Pass through the tool result unchanged
80/// let tool_output = json!({"status": "success", "data": [1, 2, 3]});
81/// let result = AfterToolCallResult::Continue(tool_output);
82///
83/// // Or modify the result (e.g., add metadata)
84/// let enriched = json!({"status": "success", "data": [1, 2, 3], "cached": false});
85/// let result = AfterToolCallResult::Continue(enriched);
86/// ```
87#[derive(Debug)]
88pub enum AfterToolCallResult {
89    /// Continue with (possibly modified) result.
90    ///
91    /// The contained value will be passed to the next plugin in the chain,
92    /// and ultimately returned to the agent as the tool output.
93    Continue(serde_json::Value),
94}
95
96/// Result from a `before_model_call` hook invocation.
97///
98/// Determines whether the model call continues with a (possibly modified) request,
99/// or is short-circuited with a synthetic response.
100///
101/// # Examples
102///
103/// ## Continuing with a modified request
104///
105/// ```rust,ignore
106/// use adk_plugin::BeforeModelCallResult;
107/// use adk_core::LlmRequest;
108///
109/// // Modify the request (e.g., inject a system instruction)
110/// let mut request = LlmRequest::default();
111/// request.model = "gemini-2.5-flash".to_string();
112/// let result = BeforeModelCallResult::Continue(request);
113/// ```
114///
115/// ## Short-circuiting with a cached response
116///
117/// ```rust,ignore
118/// use adk_plugin::BeforeModelCallResult;
119/// use adk_core::LlmResponse;
120///
121/// // Return a cached response without calling the model
122/// let cached_response = LlmResponse::default();
123/// let result = BeforeModelCallResult::ShortCircuit(cached_response);
124/// ```
125#[derive(Debug)]
126pub enum BeforeModelCallResult {
127    /// Continue execution with (possibly modified) LLM request.
128    ///
129    /// The contained request will be passed to the next plugin in the chain,
130    /// and ultimately to the LLM provider if this is the last plugin.
131    Continue(LlmRequest),
132
133    /// Short-circuit: skip the model call and use this synthetic response.
134    ///
135    /// When returned, no further plugins in the chain are invoked,
136    /// the LLM is not called, and this response is used as the model output.
137    ShortCircuit(LlmResponse),
138}
139
140/// Result from an `after_model_call` hook invocation.
141///
142/// After-model hooks can only continue with a (possibly modified) response.
143/// Short-circuiting is not supported for after-hooks since the model call
144/// has already completed.
145///
146/// # Examples
147///
148/// ```rust,ignore
149/// use adk_plugin::AfterModelCallResult;
150/// use adk_core::LlmResponse;
151///
152/// // Pass through the model response unchanged
153/// let response = LlmResponse::default();
154/// let result = AfterModelCallResult::Continue(response);
155/// ```
156#[derive(Debug)]
157pub enum AfterModelCallResult {
158    /// Continue with (possibly modified) LLM response.
159    ///
160    /// The contained response will be passed to the next plugin in the chain,
161    /// and ultimately returned to the agent as the model output.
162    Continue(LlmResponse),
163}