use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use machi_types::{AgentId, Deadline, SessionId};
use tokio_util::sync::CancellationToken;
pub const EXTRA_SPAWN_DEPTH: &str = "machi.spawn_depth";
#[derive(Debug, Clone)]
pub struct ToolCallContext {
pub cancel: CancellationToken,
pub deadline: Option<Deadline>,
pub cwd: Option<PathBuf>,
pub session_id: Option<SessionId>,
pub agent_id: Option<AgentId>,
pub extras: Arc<HashMap<String, String>>,
}
impl Default for ToolCallContext {
fn default() -> Self {
Self {
cancel: CancellationToken::new(),
deadline: None,
cwd: None,
session_id: None,
agent_id: None,
extras: Arc::new(HashMap::new()),
}
}
}
impl ToolCallContext {
#[must_use]
pub fn with_cancel(mut self, cancel: CancellationToken) -> Self {
self.cancel = cancel;
self
}
#[must_use]
pub fn with_deadline(mut self, deadline: Deadline) -> Self {
self.deadline = Some(deadline);
self
}
#[must_use]
pub fn with_extras(mut self, extras: HashMap<String, String>) -> Self {
self.extras = Arc::new(extras);
self
}
#[must_use]
pub fn spawn_depth(&self) -> Option<u32> {
self.extras
.get(EXTRA_SPAWN_DEPTH)
.and_then(|s| s.parse().ok())
}
#[must_use]
pub fn is_cancelled(&self) -> bool {
self.cancel.is_cancelled() || self.deadline.is_some_and(|d| d.is_expired())
}
}