Skip to main content

smooth_operator/tools/
context.rs

1//! Shared context for the built-in tool catalog.
2//!
3//! The knowledge-grounded tools ([`KnowledgeSearchTool`](crate::tools::KnowledgeSearchTool))
4//! only need an `Arc<dyn KnowledgeBase>`, but the broader built-in catalog
5//! ([`builtin_tools`](crate::tools::builtin_tools)) needs more: the storage
6//! adapter (for `conversation_history`), the current conversation id, and an
7//! optional pluggable web-search provider. [`ToolContext`] bundles those so
8//! `builtin_tools(ctx)` can assemble the whole catalog from one value.
9
10use std::sync::Arc;
11
12use crate::adapter::StorageAdapter;
13use crate::tools::web_search::{NoopWebSearchProvider, WebSearchProvider};
14
15/// The context the built-in tool catalog is assembled from.
16///
17/// Cheap to clone — every field is `Arc`'d or a small owned value. Build one
18/// with [`ToolContext::new`] and refine it with the `with_*` setters, then hand
19/// it to [`builtin_tools`](crate::tools::builtin_tools).
20#[derive(Clone)]
21pub struct ToolContext {
22    /// The storage adapter — `conversation_history` reads the message log from
23    /// it.
24    pub storage: Arc<dyn StorageAdapter>,
25    /// The conversation the tools operate within. `conversation_history` reads
26    /// this conversation's recent messages.
27    pub conversation_id: String,
28    /// The web-search provider. Defaults to [`NoopWebSearchProvider`], which
29    /// returns an explanatory "no provider configured" result — so the
30    /// `web_search` tool is always present and never silently a no-op.
31    pub web_search: Arc<dyn WebSearchProvider>,
32}
33
34impl ToolContext {
35    /// Build a context over a storage adapter and conversation id, with the
36    /// no-op web-search provider as the default.
37    #[must_use]
38    pub fn new(storage: Arc<dyn StorageAdapter>, conversation_id: impl Into<String>) -> Self {
39        Self {
40            storage,
41            conversation_id: conversation_id.into(),
42            web_search: Arc::new(NoopWebSearchProvider),
43        }
44    }
45
46    /// Plug in a real web-search provider (e.g. a Brave/Bing/Tavily-backed
47    /// implementation). Replaces the default [`NoopWebSearchProvider`].
48    #[must_use]
49    pub fn with_web_search(mut self, provider: Arc<dyn WebSearchProvider>) -> Self {
50        self.web_search = provider;
51        self
52    }
53}