steer_tui/tui/widgets/formatters/
mod.rs1use crate::tui::theme::Theme;
2use lazy_static::lazy_static;
3use ratatui::text::Line;
4use serde_json::Value;
5use std::collections::HashMap;
6use steer_core::app::conversation::ToolResult;
7
8pub mod astgrep;
9pub mod bash;
10pub mod default;
11pub mod dispatch_agent;
12pub mod edit;
13pub mod external;
14pub mod fetch;
15pub mod glob;
16pub mod grep;
17pub mod helpers;
18pub mod ls;
19pub mod replace;
20pub mod todo;
21pub mod view;
22
23use self::astgrep::AstGrepFormatter;
25use self::bash::BashFormatter;
26use self::default::DefaultFormatter;
27use self::dispatch_agent::DispatchAgentFormatter;
28use self::edit::EditFormatter;
29use self::external::ExternalFormatter;
30use self::fetch::FetchFormatter;
31use self::glob::GlobFormatter;
32use self::grep::GrepFormatter;
33use self::ls::LsFormatter;
34use self::replace::ReplaceFormatter;
35
36use self::todo::{TodoReadFormatter, TodoWriteFormatter};
37use self::view::ViewFormatter;
38
39pub trait ToolFormatter: Send + Sync {
41 fn compact(
43 &self,
44 params: &Value,
45 result: &Option<ToolResult>,
46 wrap_width: usize,
47 theme: &Theme,
48 ) -> Vec<Line<'static>>;
49
50 fn detailed(
52 &self,
53 params: &Value,
54 result: &Option<ToolResult>,
55 wrap_width: usize,
56 theme: &Theme,
57 ) -> Vec<Line<'static>>;
58
59 fn approval(&self, params: &Value, wrap_width: usize, theme: &Theme) -> Vec<Line<'static>> {
61 self.compact(params, &None, wrap_width, theme)
63 }
64}
65
66lazy_static! {
67 static ref FORMATTERS: HashMap<&'static str, Box<dyn ToolFormatter>> = {
68 use steer_tools::tools::*;
69
70 let mut map: HashMap<&'static str, Box<dyn ToolFormatter>> = HashMap::new();
71
72 map.insert(BASH_TOOL_NAME, Box::new(BashFormatter));
73 map.insert(GREP_TOOL_NAME, Box::new(GrepFormatter));
74 map.insert(LS_TOOL_NAME, Box::new(LsFormatter));
75 map.insert(GLOB_TOOL_NAME, Box::new(GlobFormatter));
76 map.insert(VIEW_TOOL_NAME, Box::new(ViewFormatter));
77 map.insert(EDIT_TOOL_NAME, Box::new(EditFormatter));
78 map.insert(edit::multi_edit::MULTI_EDIT_TOOL_NAME, Box::new(EditFormatter)); map.insert(REPLACE_TOOL_NAME, Box::new(ReplaceFormatter));
80 map.insert(TODO_READ_TOOL_NAME, Box::new(TodoReadFormatter));
81 map.insert(TODO_WRITE_TOOL_NAME, Box::new(TodoWriteFormatter));
82 map.insert(AST_GREP_TOOL_NAME, Box::new(AstGrepFormatter));
83 map.insert(steer_core::tools::fetch::FETCH_TOOL_NAME, Box::new(FetchFormatter));
84 map.insert(steer_core::tools::dispatch_agent::DISPATCH_AGENT_TOOL_NAME, Box::new(DispatchAgentFormatter));
85
86 map
89 };
90
91 static ref DEFAULT_FORMATTER: Box<dyn ToolFormatter> = Box::new(DefaultFormatter);
92 static ref EXTERNAL_FORMATTER: Box<dyn ToolFormatter> = Box::new(ExternalFormatter);
93}
94
95pub fn get_formatter(tool_name: &str) -> &'static dyn ToolFormatter {
96 if let Some(fmt) = FORMATTERS.get(tool_name) {
97 fmt.as_ref()
98 } else if tool_name.starts_with("mcp__") {
99 EXTERNAL_FORMATTER.as_ref()
100 } else {
101 DEFAULT_FORMATTER.as_ref()
102 }
103}