pub mod accumulator;
pub mod agentic;
pub mod context;
pub mod executor;
pub mod registry;
pub mod result_handler;
pub mod smart_code_review;
pub mod types;
pub use accumulator::{
finalize_tool_calls, update_partial_tool_call, PartialToolCall, ToolCallAccumulator,
};
pub use agentic::{
convert_from_standard_result, convert_to_standard_result, AgenticContext, AgenticTool,
AgenticToolExecutor, AgenticToolResult, Interaction, InteractionRole, ToolGoal,
};
pub use context::ToolExecutionContext;
pub use executor::{execute_tool_call, execute_tool_call_with_context, ToolError, ToolExecutor};
pub use registry::{
global_registry, normalize_tool_name, RegistryError, SharedTool, Tool, ToolRegistry,
};
pub use result_handler::{
execute_sub_actions, handle_tool_result_with_agentic_support, parse_tool_args,
parse_tool_args_best_effort, send_clarification_request, try_parse_agentic_result,
ToolHandlingOutcome, MAX_SUB_ACTIONS,
};
pub use smart_code_review::SmartCodeReviewTool;
pub use types::{FunctionCall, FunctionSchema, ToolCall, ToolResult, ToolSchema};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ToolMutability {
ReadOnly,
Mutating,
}
const READ_ONLY_TOOLS: &[&str] = &[
"Read",
"GetFileInfo",
"Glob",
"Grep",
"WebFetch",
"WebSearch",
"Workspace",
"BashOutput",
"session_note",
"memory_note",
"recall",
"session_inspector",
"compact_context",
"Sleep",
];
pub fn classify_tool(tool_name: &str) -> ToolMutability {
if READ_ONLY_TOOLS
.iter()
.any(|&t| t.eq_ignore_ascii_case(tool_name))
{
ToolMutability::ReadOnly
} else {
ToolMutability::Mutating
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classify_compact_context_as_read_only() {
assert_eq!(classify_tool("compact_context"), ToolMutability::ReadOnly);
}
#[test]
fn classify_compact_context_case_insensitive() {
assert_eq!(classify_tool("Compact_Context"), ToolMutability::ReadOnly);
assert_eq!(classify_tool("COMPACT_CONTEXT"), ToolMutability::ReadOnly);
}
#[test]
fn classify_write_as_mutating() {
assert_eq!(classify_tool("Write"), ToolMutability::Mutating);
}
#[test]
fn classify_unknown_as_mutating() {
assert_eq!(
classify_tool("totally_unknown_tool"),
ToolMutability::Mutating
);
}
#[test]
fn classify_all_read_only_tools() {
for name in READ_ONLY_TOOLS {
assert_eq!(
classify_tool(name),
ToolMutability::ReadOnly,
"{name} should be classified as read-only"
);
}
}
}