Skip to main content

rig_core/tool/
managed.rs

1//! Registry contracts for refreshable external tool sources.
2//! Generation tokens protect newer registrations from stale refreshes, while
3//! [`DynamicTool::is_live`] reports disconnection without tool execution.
4//!
5//! ```
6//! use rig_core::tool::ManagedToolToken;
7//!
8//! let token = ManagedToolToken::new();
9//! assert_eq!(token, token.clone());
10//! assert_ne!(token, ManagedToolToken::new());
11//! ```
12
13use std::collections::HashMap;
14use std::sync::Arc;
15
16use super::DynamicTool;
17
18/// Opaque identity for one managed registry generation.
19///
20/// Minted by a [`ManagedToolSink`] when it installs a tool; two tokens are
21/// equal only if they are the same generation.
22#[derive(Clone, Debug)]
23pub struct ManagedToolToken(Arc<()>);
24
25impl ManagedToolToken {
26    /// Mint a fresh generation. Only sinks should call this.
27    pub fn new() -> Self {
28        Self(Arc::new(()))
29    }
30}
31
32impl Default for ManagedToolToken {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl PartialEq for ManagedToolToken {
39    fn eq(&self, other: &Self) -> bool {
40        Arc::ptr_eq(&self.0, &other.0)
41    }
42}
43
44impl Eq for ManagedToolToken {}
45
46/// A tool registry that accepts tools from an external, refreshable source.
47pub trait ManagedToolSink {
48    /// Atomically install the initial tools owned by one source.
49    /// Last-registration-wins: an existing name is replaced. Tools that
50    /// report `!is_live()` are skipped. Returns one generation token per
51    /// installed name, to hand back to [`Self::reconcile_managed_tools`].
52    fn add_managed_tools(&self, tools: Vec<DynamicTool>) -> HashMap<String, ManagedToolToken>;
53
54    /// Atomically reconcile one source's registrations with a refreshed tool
55    /// list. Existing names change only while their `expected` generation is
56    /// still current (newer local or peer-source registrations win); names
57    /// missing from `tools` and still owned by this source are removed.
58    /// Returns the new generation tokens.
59    fn reconcile_managed_tools(
60        &self,
61        expected: HashMap<String, ManagedToolToken>,
62        tools: Vec<DynamicTool>,
63    ) -> HashMap<String, ManagedToolToken>;
64}