Skip to main content

steer_tui/tui/widgets/formatters/
default.rs

1use super::{
2    ToolFormatter,
3    helpers::{separator_line, truncate_lines},
4};
5use crate::tui::theme::{Component, Theme};
6use ratatui::text::{Line, Span};
7use serde_json::Value;
8use steer_grpc::client_api::ToolResult;
9
10pub struct DefaultFormatter;
11
12impl ToolFormatter for DefaultFormatter {
13    fn compact(
14        &self,
15        _params: &Value,
16        _result: &Option<ToolResult>,
17        _wrap_width: usize,
18        theme: &Theme,
19    ) -> Vec<Line<'static>> {
20        vec![Line::from(Span::styled(
21            "Unknown tool",
22            theme.style(Component::ErrorText),
23        ))]
24    }
25
26    fn detailed(
27        &self,
28        params: &Value,
29        result: &Option<ToolResult>,
30        wrap_width: usize,
31        theme: &Theme,
32    ) -> Vec<Line<'static>> {
33        let mut lines = Vec::new();
34
35        lines.push(Line::from(Span::styled(
36            "Tool Parameters:",
37            theme.style(Component::ToolCallHeader),
38        )));
39
40        // Show parameters as pretty-printed JSON
41        let pretty_params = serde_json::to_string_pretty(params).unwrap_or_default();
42        for line in pretty_params.lines() {
43            let wrapped_lines = textwrap::wrap(line, wrap_width);
44            for wrapped_line in wrapped_lines {
45                lines.push(Line::from(Span::styled(
46                    wrapped_line.to_string(),
47                    theme.style(Component::DimText),
48                )));
49            }
50        }
51
52        // Show result if available
53        if let Some(result) = result {
54            lines.push(separator_line(wrap_width, theme.style(Component::DimText)));
55
56            // Show the result as pretty-printed JSON
57            match serde_json::to_string_pretty(result) {
58                Ok(pretty_result) => {
59                    const MAX_LINES: usize = 10;
60                    let (output_lines, truncated) = truncate_lines(&pretty_result, MAX_LINES);
61
62                    for line in output_lines {
63                        for wrapped in textwrap::wrap(line, wrap_width) {
64                            lines.push(Line::from(Span::raw(wrapped.to_string())));
65                        }
66                    }
67
68                    if truncated {
69                        lines.push(Line::from(Span::styled(
70                            format!(
71                                "... ({} more lines)",
72                                pretty_result.lines().count() - MAX_LINES
73                            ),
74                            theme
75                                .style(Component::DimText)
76                                .add_modifier(ratatui::style::Modifier::ITALIC),
77                        )));
78                    }
79                }
80                Err(_) => {
81                    lines.push(Line::from(Span::styled(
82                        "(Unable to display result)",
83                        theme
84                            .style(Component::DimText)
85                            .add_modifier(ratatui::style::Modifier::ITALIC),
86                    )));
87                }
88            }
89        }
90
91        lines
92    }
93}