use super::{Arc, BTreeMap, Error, ModelBinding, Mutex, Result, ToolBinding};
#[derive(Debug, Clone, Default)]
pub(crate) struct ToolCallCounts {
inner: Arc<Mutex<BTreeMap<String, u64>>>,
}
impl ToolCallCounts {
#[must_use]
pub(crate) fn new(aliases: impl IntoIterator<Item = String>) -> Self {
let map: BTreeMap<String, u64> = aliases.into_iter().map(|a| (a, 0)).collect();
Self {
inner: Arc::new(Mutex::new(map)),
}
}
fn lock(&self) -> Result<std::sync::MutexGuard<'_, BTreeMap<String, u64>>> {
self.inner
.lock()
.map_err(|_| Error::Lua("tool call counts mutex was poisoned".to_owned()))
}
pub(crate) fn ensure(&self, alias: &str) -> Result<()> {
let mut map = self.lock()?;
map.entry(alias.to_owned()).or_insert(0);
Ok(())
}
pub(crate) fn increment(&self, alias: &str) -> Result<()> {
let mut map = self.lock()?;
let count = map.get_mut(alias).ok_or_else(|| {
Error::Lua(format!(
"tool call counts: alias {alias:?} was not pre-seeded"
))
})?;
*count += 1;
Ok(())
}
pub(crate) fn get(&self, alias: &str) -> Result<Option<u64>> {
Ok(self.lock()?.get(alias).copied())
}
pub(crate) fn aliases(&self) -> Result<Vec<String>> {
Ok(self.lock()?.keys().cloned().collect())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct ToolScope {
pub(crate) bindings: Vec<ToolBinding>,
}
impl ToolScope {
#[must_use]
pub(crate) fn from_bindings(bindings: Vec<ToolBinding>) -> Self {
Self { bindings }
}
#[must_use]
pub(crate) fn bindings(&self) -> &[ToolBinding] {
&self.bindings
}
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct ClosedScopes {
pub(crate) tools: ToolScope,
pub(crate) model: Option<ModelBinding>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ToolPhase {
H2,
Closed,
}
#[derive(Debug)]
pub(crate) struct ToolRuntime {
pub(crate) phase: ToolPhase,
pub(crate) added: Vec<String>,
pub(crate) description_overrides: BTreeMap<String, String>,
pub(crate) generation: u64,
}
impl ToolRuntime {
#[must_use]
pub(crate) fn generation(&self) -> u64 {
self.generation
}
}