Expand description
LIFO scoped tool registry with shadow-stack semantics.
ScopedToolRegistry wraps a base ToolRegistry with a stack of
named scopes. Tools registered in higher scopes shadow those with the
same name in lower scopes. When a scope is popped, all tools registered
in that scope are removed, revealing any previously-shadowed tools.
§Scope model
Scope 2 (Turn) ── top
Scope 1 (Run)
Scope 0 (Agent) ── bottom
Base registry ── always presentResolution order: top scope → … → bottom scope → base registry. First match wins.
§Thread safety
The scope stack uses interior mutability (Mutex) so that scopes can
be pushed/popped through a shared reference. The base registry is
lock-free. Cloning captures the current scope snapshot; cloned copies
operate independently.
§Example
use behest_tool::{FunctionTool, ToolRegistry};
use behest_runtime::tool_scope::ScopedToolRegistry;
use serde_json::json;
let base = ToolRegistry::new();
let scoped = ScopedToolRegistry::new(base);
let scope = scoped.push_scope();
scoped.register_in_scope(scope, FunctionTool::new(
"my_tool", "desc", json!({}),
|args| async move { Ok(args) },
));
assert!(scoped.get("my_tool").is_some());
scoped.pop_scope(scope);
assert!(scoped.get("my_tool").is_none());Structs§
- Scope
Guard - RAII guard that pops a scope from a
ScopedToolRegistryon drop. - ScopeId
- Scope identifier returned by
ScopedToolRegistry::push_scope. - Scoped
Tool Registry - LIFO scoped tool registry with shadow-stack semantics.
Enums§
- Scope
Level - Well-known scope levels for documentation and ordering.