Skip to main content

adk_tool/
simple_context.rs

1//! Lightweight [`ToolContext`] implementation for use outside the agent loop.
2//!
3//! [`SimpleToolContext`] provides sensible defaults for all trait methods so
4//! that callers in MCP server mode, testing, or sub-agent delegation can
5//! invoke tools without constructing a full invocation context.
6//!
7//! # Example
8//!
9//! ```rust,no_run
10//! use adk_tool::SimpleToolContext;
11//! use std::sync::Arc;
12//!
13//! let ctx = SimpleToolContext::new("my-caller");
14//! let ctx: Arc<dyn adk_core::ToolContext> = Arc::new(ctx);
15//! ```
16
17use adk_core::context::{Artifacts, CallbackContext, MemoryEntry, ReadonlyContext};
18use adk_core::types::Content;
19use adk_core::{EventActions, Result, ToolContext};
20use async_trait::async_trait;
21use std::sync::{Arc, Mutex};
22
23/// A lightweight [`ToolContext`] with sensible defaults for non-agent callers.
24///
25/// Implements [`ReadonlyContext`], [`CallbackContext`], and [`ToolContext`]
26/// with minimal configuration. Construct via [`SimpleToolContext::new`] with
27/// a caller name; all other fields use safe defaults.
28pub struct SimpleToolContext {
29    caller_name: String,
30    invocation_id: String,
31    function_call_id: String,
32    user_content: Content,
33    actions: Mutex<EventActions>,
34}
35
36impl SimpleToolContext {
37    /// Create a new context with the given caller name.
38    ///
39    /// Generates unique UUIDs for `invocation_id` and `function_call_id`.
40    /// The caller name is returned by both [`agent_name()`](ReadonlyContext::agent_name)
41    /// and [`app_name()`](ReadonlyContext::app_name).
42    pub fn new(caller_name: impl Into<String>) -> Self {
43        Self {
44            caller_name: caller_name.into(),
45            invocation_id: uuid::Uuid::new_v4().to_string(),
46            function_call_id: uuid::Uuid::new_v4().to_string(),
47            user_content: Content::new("user"),
48            actions: Mutex::new(EventActions::default()),
49        }
50    }
51
52    /// Override the default function call ID.
53    ///
54    /// By default a UUID is generated at construction. Use this builder
55    /// method to provide a specific ID instead.
56    pub fn with_function_call_id(mut self, id: impl Into<String>) -> Self {
57        self.function_call_id = id.into();
58        self
59    }
60}
61
62#[async_trait]
63impl ReadonlyContext for SimpleToolContext {
64    fn invocation_id(&self) -> &str {
65        &self.invocation_id
66    }
67
68    fn agent_name(&self) -> &str {
69        &self.caller_name
70    }
71
72    fn user_id(&self) -> &str {
73        "anonymous"
74    }
75
76    fn app_name(&self) -> &str {
77        &self.caller_name
78    }
79
80    fn session_id(&self) -> &str {
81        ""
82    }
83
84    fn branch(&self) -> &str {
85        ""
86    }
87
88    fn user_content(&self) -> &Content {
89        &self.user_content
90    }
91}
92
93#[async_trait]
94impl CallbackContext for SimpleToolContext {
95    fn artifacts(&self) -> Option<Arc<dyn Artifacts>> {
96        None
97    }
98}
99
100#[async_trait]
101impl ToolContext for SimpleToolContext {
102    fn function_call_id(&self) -> &str {
103        &self.function_call_id
104    }
105
106    fn actions(&self) -> EventActions {
107        self.actions.lock().unwrap().clone()
108    }
109
110    fn set_actions(&self, actions: EventActions) {
111        *self.actions.lock().unwrap() = actions;
112    }
113
114    async fn search_memory(&self, _query: &str) -> Result<Vec<MemoryEntry>> {
115        Ok(vec![])
116    }
117}