use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::OnceLock;
static TOOL_ID_COUNTER: AtomicU64 = AtomicU64::new(1);
pub(crate) fn next_tool_id() -> String {
format!("tool_{}", TOOL_ID_COUNTER.fetch_add(1, Ordering::Relaxed))
}
pub mod fs;
pub mod hint_accumulator;
pub mod server;
pub mod shared_utils;
static SESSION_WORKDIR: OnceLock<PathBuf> = OnceLock::new();
thread_local! {
static CURRENT_WORKDIR: std::cell::RefCell<Option<PathBuf>> = const { std::cell::RefCell::new(None) };
}
pub fn set_session_working_directory(path: PathBuf) {
SESSION_WORKDIR.set(path).ok(); }
pub fn set_thread_working_directory(path: PathBuf) {
CURRENT_WORKDIR.with(|w| {
*w.borrow_mut() = Some(path);
});
}
pub fn get_thread_working_directory() -> PathBuf {
CURRENT_WORKDIR.with(|w| {
w.borrow().clone().unwrap_or_else(|| {
SESSION_WORKDIR
.get()
.cloned()
.unwrap_or_else(|| std::env::current_dir().unwrap_or_default())
})
})
}
pub fn get_thread_original_working_directory() -> PathBuf {
SESSION_WORKDIR
.get()
.cloned()
.unwrap_or_else(|| std::env::current_dir().unwrap_or_default())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct McpToolCall {
pub tool_name: String,
pub parameters: Value,
#[serde(default)]
pub tool_id: String,
}