Refactor TUI message formatting: add role label toggle, improve indentation, and adjust role label styling logic. Optimize provider handling.

This commit is contained in:
2025-09-27 07:11:57 +02:00
parent 306104c5b4
commit 6ddc66d864
3 changed files with 24 additions and 13 deletions

View File

@@ -30,6 +30,11 @@ impl MessageFormatter {
self.wrap_width = width.max(20); self.wrap_width = width.max(20);
} }
/// Whether role labels should be shown alongside messages
pub fn show_role_labels(&self) -> bool {
self.show_role_labels
}
pub fn format_message(&self, message: &Message) -> Vec<String> { pub fn format_message(&self, message: &Message) -> Vec<String> {
// 1) Normalize line breaks to '\n' (handles CR, NEL, LS, PS) // 1) Normalize line breaks to '\n' (handles CR, NEL, LS, PS)
let normalized: String = message let normalized: String = message

View File

@@ -154,7 +154,7 @@ impl ChatApp {
self.models = all_models; self.models = all_models;
// Populate available_providers // Populate available_providers
let mut providers = self let providers = self
.models .models
.iter() .iter()
.map(|m| m.provider.clone()) .map(|m| m.provider.clone())
@@ -410,7 +410,7 @@ impl ChatApp {
self.models = all_models; self.models = all_models;
// Populate available_providers // Populate available_providers
let mut providers = self let providers = self
.models .models
.iter() .iter()
.map(|m| m.provider.clone()) .map(|m| m.provider.clone())

View File

@@ -68,27 +68,33 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &ChatApp) {
let mut lines: Vec<Line> = Vec::new(); let mut lines: Vec<Line> = Vec::new();
for (message_index, message) in conversation.messages.iter().enumerate() { for (message_index, message) in conversation.messages.iter().enumerate() {
let (prefix, color) = match message.role { let role = &message.role;
Role::User => ("👤 You:", Color::LightBlue), let prefix = match role {
Role::Assistant => ("🤖 Assistant:", Color::LightMagenta), Role::User => "👤 You:",
Role::System => ("⚙️ System:", Color::Cyan), Role::Assistant => "🤖 Assistant:",
Role::System => "⚙️ System:",
}; };
let mut formatted = formatter.format_message(message); let formatted = formatter.format_message(message);
let is_streaming = message let is_streaming = message
.metadata .metadata
.get("streaming") .get("streaming")
.and_then(|v| v.as_bool()) .and_then(|v| v.as_bool())
.unwrap_or(false); .unwrap_or(false);
lines.push(Line::from(Span::styled( let show_role_labels = formatter.show_role_labels();
prefix, let indent = if show_role_labels { " " } else { "" };
Style::default().fg(color).add_modifier(Modifier::BOLD),
))); if show_role_labels {
lines.push(Line::from(Span::styled(
prefix,
role_color(role).add_modifier(Modifier::BOLD),
)));
}
for (i, line) in formatted.iter().enumerate() { for (i, line) in formatted.iter().enumerate() {
let mut spans = Vec::new(); let mut spans = Vec::new();
spans.push(Span::raw(format!(" {}", line.clone()))); spans.push(Span::raw(format!("{indent}{line}")));
if i == formatted.len() - 1 && is_streaming { if i == formatted.len() - 1 && is_streaming {
spans.push(Span::styled("", Style::default().fg(Color::Magenta))); spans.push(Span::styled("", Style::default().fg(Color::Magenta)));
} }
@@ -359,7 +365,7 @@ fn centered_rect(percent_x: u16, percent_y: u16, area: Rect) -> Rect {
.split(vertical[1])[1] .split(vertical[1])[1]
} }
fn role_color(role: Role) -> Style { fn role_color(role: &Role) -> Style {
match role { match role {
Role::User => Style::default().fg(Color::LightBlue), Role::User => Style::default().fg(Color::LightBlue),
Role::Assistant => Style::default().fg(Color::LightMagenta), Role::Assistant => Style::default().fg(Color::LightMagenta),