| 1 | use super::CommandResult; |
| 2 | use super::DebugAction as AppAction; |
| 3 | use crate::diagnostics_reports::{render_tool_snapshot_json, render_tool_snapshot_text}; |
| 4 | use codewhale_command_contract::handler::{CommandCapabilities, CommandContexts, CommandHandler}; |
| 5 | use codewhale_command_contract::metadata::{ |
| 6 | CommandInfo as ContractInfo, RegisterCommand as ContractRegisterCommand, |
| 7 | }; |
| 8 | |
| 9 | pub(in crate::commands) struct ToolsCmd; |
| 10 | |
| 11 | const CONTRACT_INFO: ContractInfo = ContractInfo { |
| 12 | name: "tools", |
| 13 | aliases: &["tool-studio"], |
| 14 | usage: "/tools [text|json]", |
| 15 | description_key: "cmd_tools_description", |
| 16 | }; |
| 17 | |
| 18 | impl ContractRegisterCommand<CommandResult> for ToolsCmd { |
| 19 | fn info() -> &'static ContractInfo { |
| 20 | &CONTRACT_INFO |
| 21 | } |
| 22 | |
| 23 | fn handler() -> CommandHandler<CommandResult> { |
| 24 | CommandHandler::Contextual { |
| 25 | capabilities: CommandCapabilities::DEBUG_DIAGNOSTICS, |
| 26 | handler: tools, |
| 27 | } |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | pub(super) fn tools(contexts: CommandContexts<'_>, arg: Option<&str>) -> CommandResult { |
| 32 | let mut parts = contexts.into_parts(); |
| 33 | let Some(diagnostics) = parts.debug_diagnostics.as_deref_mut() else { |
| 34 | return CommandResult::error("Command capability unavailable: debug_diagnostics"); |
| 35 | }; |
| 36 | // The original availability check precedes format validation. No prior |
| 37 | // request differs from an observed empty prepared catalog. |
| 38 | let Some(snapshot) = diagnostics.tool_snapshot() else { |
| 39 | return CommandResult::message( |
| 40 | "Tool request snapshot unavailable — no model request has been captured for the latest turn.", |
| 41 | ); |
| 42 | }; |
| 43 | match arg.unwrap_or("text").trim() { |
| 44 | "" | "text" => CommandResult::action(AppAction::OpenTextPager { |
| 45 | title: "Prepared Tool Request".to_string(), |
| 46 | content: render_tool_snapshot_text(&snapshot), |
| 47 | }), |
| 48 | "json" => match render_tool_snapshot_json(&snapshot) { |
| 49 | Ok(output) => CommandResult::action(AppAction::OpenTextPager { |
| 50 | title: "Prepared Tool Request (JSON)".to_string(), |
| 51 | content: output, |
| 52 | }), |
| 53 | Err(error) => CommandResult::error(format!( |
| 54 | "tool request snapshot could not be serialized: {error}" |
| 55 | )), |
| 56 | }, |
| 57 | _ => CommandResult::error("usage: /tools [text|json]"), |
| 58 | } |
| 59 | } |
| 60 |