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}