use parking_lot::Mutex;
use std::collections::HashMap;
use tokio::sync::oneshot;
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ToolApprovalResult {
Approved,
Denied,
}
struct PendingEntry {
tool_name: String,
sender: oneshot::Sender<ToolApprovalResult>,
}
#[derive(Default)]
pub struct PendingToolApprovals {
inner: Mutex<HashMap<Uuid, PendingEntry>>,
}
impl PendingToolApprovals {
pub fn new() -> Self {
Self::default()
}
pub fn register(&self, tool_name: String) -> (Uuid, oneshot::Receiver<ToolApprovalResult>) {
let id = Uuid::new_v4();
let (tx, rx) = oneshot::channel();
self.inner.lock().insert(
id,
PendingEntry {
tool_name,
sender: tx,
},
);
(id, rx)
}
pub fn resolve(&self, id: Uuid, result: ToolApprovalResult) -> Option<String> {
let entry = self.inner.lock().remove(&id)?;
let _ = entry.sender.send(result);
Some(entry.tool_name)
}
pub fn cancel_all(&self) {
let mut guard = self.inner.lock();
for (_, entry) in guard.drain() {
let _ = entry.sender.send(ToolApprovalResult::Denied);
}
}
}