steer_tui/tui/handlers/
approval.rs1use crate::error::Error;
2use crate::error::Result;
3use crate::tui::Tui;
4use ratatui::crossterm::event::{KeyCode, KeyEvent};
5use steer_grpc::client_api::ApprovalDecision;
6use steer_tools::tools::BASH_TOOL_NAME;
7use steer_tools::tools::bash::BashParams;
8use tracing::debug;
9
10impl Tui {
11 pub async fn handle_approval_mode(&mut self, key: KeyEvent) -> Result<bool> {
12 if let Some((request_id, tool_call)) = self.current_tool_approval.take() {
13 match key.code {
14 KeyCode::Char('y' | 'Y') => {
15 self.client
16 .approve_tool(request_id.to_string(), ApprovalDecision::Once)
17 .await?;
18 self.input_mode = self.default_input_mode();
19 }
20 KeyCode::Char('a' | 'A') => {
21 debug!(target: "handle_approval_mode", "Approving tool call with request_id '{:?}' and name '{}'", request_id, tool_call.name);
22 if tool_call.name == BASH_TOOL_NAME {
23 debug!(target: "handle_approval_mode", "(Always) Approving bash command with request_id '{:?}'", request_id);
24 let bash_params: BashParams =
25 serde_json::from_value(tool_call.parameters.clone()).map_err(|e| {
26 Error::CommandProcessing(format!(
27 "Invalid bash params for approval: {e}"
28 ))
29 })?;
30 self.client
31 .approve_tool(
32 request_id.to_string(),
33 ApprovalDecision::AlwaysBashPattern(bash_params.command.clone()),
34 )
35 .await?;
36 } else {
37 self.client
38 .approve_tool(request_id.to_string(), ApprovalDecision::AlwaysTool)
39 .await?;
40 }
41 self.input_mode = self.default_input_mode();
42 }
43 KeyCode::Char('l' | 'L') => {
44 if tool_call.name == BASH_TOOL_NAME {
45 self.client
46 .approve_tool(request_id.to_string(), ApprovalDecision::AlwaysTool)
47 .await?;
48 self.input_mode = self.default_input_mode();
49 } else {
50 self.current_tool_approval = Some((request_id, tool_call));
51 }
52 }
53 KeyCode::Char('n' | 'N') | KeyCode::Esc => {
54 self.client
55 .approve_tool(request_id.to_string(), ApprovalDecision::Deny)
56 .await?;
57 self.input_mode = self.default_input_mode();
58 }
59 _ => {
60 self.current_tool_approval = Some((request_id, tool_call));
61 }
62 }
63 } else {
64 self.input_mode = self.default_input_mode();
65 }
66 Ok(false)
67 }
68}