pub struct Scratchpad { /* private fields */ }Expand description
A run-scoped, shared scratchpad passed to every hook via HookContext.
A type-map with interior mutability: cooperating hooks read and write typed
values keyed by type, sharing per-run state (a turn counter, a running
budget, a phase flag) without each rolling its own Arc<Mutex<…>>. Every
hook in a run receives the same HookContext by shared reference, so they
all see one scratchpad (and cloning a Scratchpad shares its storage too); a
fresh run starts with an empty one.
Hooks receive &HookContext (shared), so every accessor here takes &self
and mutates through an internal lock. Reads clone the stored value out (the
lock cannot hand out a borrow), so store cheaply-cloneable values.
§Concurrency
Most events are dispatched sequentially within a run, but at
tool_concurrency > 1 the
ToolCall / ToolResult
hooks for different tools in the same turn may run concurrently, all
sharing this one scratchpad. Each accessor (insert,
update, …) is race-free per operation (it holds the lock
for the whole read-modify-write), but the framework imposes no
deterministic ordering across those concurrent tool hooks — the order in
which two tools’ hooks touch the scratchpad depends on tool completion
timing. Prefer commutative / idempotent state (a counter, a set union), or
key per-tool state by the tool call id / internal call id, rather than
relying on the order of concurrent updates.
§Example
#[derive(Clone, Default)]
struct Calls(u32);
let pad = Scratchpad::default();
pad.update(|c: &mut Calls| c.0 += 1);
assert_eq!(pad.get::<Calls>().map(|c| c.0), Some(1));Implementations§
Source§impl Scratchpad
impl Scratchpad
Sourcepub fn insert<T: Clone + WasmCompatSend + WasmCompatSync + 'static>(
&self,
val: T,
) -> Option<T>
pub fn insert<T: Clone + WasmCompatSend + WasmCompatSync + 'static>( &self, val: T, ) -> Option<T>
Insert a typed value, returning the previous value of the same type.
Sourcepub fn get<T: Clone + WasmCompatSend + WasmCompatSync + 'static>(
&self,
) -> Option<T>
pub fn get<T: Clone + WasmCompatSend + WasmCompatSync + 'static>( &self, ) -> Option<T>
Get a clone of the stored value of type T, if present.
Sourcepub fn contains<T: WasmCompatSend + WasmCompatSync + 'static>(&self) -> bool
pub fn contains<T: WasmCompatSend + WasmCompatSync + 'static>(&self) -> bool
Whether a value of type T is present.
Sourcepub fn remove<T: Clone + WasmCompatSend + WasmCompatSync + 'static>(
&self,
) -> Option<T>
pub fn remove<T: Clone + WasmCompatSend + WasmCompatSync + 'static>( &self, ) -> Option<T>
Remove and return the stored value of type T, if present.
Sourcepub fn update<T, R>(&self, f: impl FnOnce(&mut T) -> R) -> R
pub fn update<T, R>(&self, f: impl FnOnce(&mut T) -> R) -> R
Read-modify-write the value of type T under one lock acquisition,
starting from Default when absent. The value is stored back and the
closure’s return value is returned.
The whole read-modify-write is atomic (no lost updates), but at
tool_concurrency > 1 it imposes no ordering across concurrent tool
hooks — see the type-level concurrency note.
This is the race-free way to bump a counter or accumulate:
pad.update(|t: &mut Total| t.0 += 10);Trait Implementations§
Source§impl Clone for Scratchpad
impl Clone for Scratchpad
Source§fn clone(&self) -> Scratchpad
fn clone(&self) -> Scratchpad
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for Scratchpad
impl Debug for Scratchpad
Source§impl Default for Scratchpad
impl Default for Scratchpad
Source§fn default() -> Scratchpad
fn default() -> Scratchpad
Auto Trait Implementations§
impl Freeze for Scratchpad
impl RefUnwindSafe for Scratchpad
impl Send for Scratchpad
impl Sync for Scratchpad
impl Unpin for Scratchpad
impl UnsafeUnpin for Scratchpad
impl UnwindSafe for Scratchpad
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneDebuggableStorage for Twhere
T: DebuggableStorage + Clone,
impl<T> CloneDebuggableStorage for Twhere
T: DebuggableStorage + Clone,
fn clone_storage(&self) -> Box<dyn CloneDebuggableStorage>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CloneableStorage for T
impl<T> CloneableStorage for T
fn clone_storage(&self) -> Box<dyn CloneableStorage>
impl<T> DebuggableStorage for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more