mod models;
mod request;
mod response;
#[cfg(test)]
mod tests;
use actix_web::{web, HttpResponse};
use bamboo_agent_core::tools::ToolExecutionContext;
use crate::app_state::AppState;
use crate::error::AppError;
pub use models::{
ToolExecutionRequest, ToolExecutionResponse, ToolExecutionResultPayload, ToolParameter,
};
pub async fn execute_tool(
app_state: web::Data<AppState>,
payload: web::Json<ToolExecutionRequest>,
) -> Result<HttpResponse, AppError> {
let ToolExecutionRequest {
tool_name,
parameters,
session_id,
} = payload.into_inner();
let canonical_tool_name = request::canonical_tool_name_or_error(&tool_name)?;
let session_id = request::trimmed_session_id(session_id.as_deref());
request::validate_session_context_requirement(&canonical_tool_name, session_id)?;
let args = request::parse_arguments(parameters);
let call = request::build_tool_call(canonical_tool_name, args)?;
let root_tools = app_state.tools_for(crate::tools::ToolSurface::Root);
let available_tool_schemas = root_tools.list_tools();
let result = root_tools
.execute_with_context(
&call,
ToolExecutionContext {
session_id,
tool_call_id: &call.id,
event_tx: None,
available_tool_schemas: Some(available_tool_schemas.as_slice()),
},
)
.await
.map_err(|err| AppError::ToolExecutionError(err.to_string()))?;
let response = response::build_execution_response(tool_name, result)?;
Ok(HttpResponse::Ok().json(response))
}
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.route("/tools/execute", web::post().to(execute_tool));
}