Skip to content

Commit addc62f

Browse files
committed
feat(tui): add config option to hide message source labels
Add [tui] config section with show_source_labels option (default: false). When disabled, role prefixes like [user], [zeph], [bash] are hidden since message colors already distinguish roles. Closes #488
1 parent d92ddb5 commit addc62f

File tree

6 files changed

+51
-9
lines changed

6 files changed

+51
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
1212
- Duplicate `ToolEvent::Completed` emission in shell executor before filtering was applied (#480)
1313

1414
### Added
15+
- TUI `[tui]` config section with `show_source_labels` option to hide `[user]`/`[zeph]`/`[tool]` prefixes (#488)
1516
- Syntax-highlighted diff view for write/edit tool output in TUI (#451)
1617
- Diff rendering with green/red backgrounds for added/removed lines
1718
- Word-level change highlighting within modified lines

config/default.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,7 @@ embedding_seconds = 30
320320
a2a_seconds = 30
321321
# Maximum number of tool calls to execute in parallel
322322
max_parallel_tools = 8
323+
324+
[tui]
325+
# Show role prefix labels ([user], [zeph], etc.) in chat messages
326+
show_source_labels = false

crates/zeph-core/src/config/types.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ pub struct Config {
3939
pub daemon: DaemonConfig,
4040
#[serde(default)]
4141
pub scheduler: SchedulerConfig,
42+
#[serde(default)]
43+
pub tui: TuiConfig,
4244
#[serde(skip)]
4345
pub secrets: ResolvedSecrets,
4446
}
@@ -917,6 +919,12 @@ pub struct SchedulerConfig {
917919
pub tasks: Vec<ScheduledTaskConfig>,
918920
}
919921

922+
#[derive(Debug, Clone, Copy, Default, Deserialize)]
923+
pub struct TuiConfig {
924+
#[serde(default)]
925+
pub show_source_labels: bool,
926+
}
927+
920928
#[derive(Debug, Clone, Deserialize)]
921929
pub struct ScheduledTaskConfig {
922930
pub name: String,
@@ -990,6 +998,7 @@ impl Config {
990998
gateway: GatewayConfig::default(),
991999
daemon: DaemonConfig::default(),
9921000
scheduler: SchedulerConfig::default(),
1001+
tui: TuiConfig::default(),
9931002
secrets: ResolvedSecrets::default(),
9941003
}
9951004
}

crates/zeph-tui/src/app.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub struct App {
5858
active_panel: Panel,
5959
tool_expanded: bool,
6060
compact_tools: bool,
61+
show_source_labels: bool,
6162
status_label: Option<String>,
6263
throbber_state: throbber_widgets_tui::ThrobberState,
6364
confirm_state: Option<ConfirmState>,
@@ -89,6 +90,7 @@ impl App {
8990
active_panel: Panel::Chat,
9091
tool_expanded: false,
9192
compact_tools: false,
93+
show_source_labels: false,
9294
status_label: None,
9395
throbber_state: throbber_widgets_tui::ThrobberState::default(),
9496
confirm_state: None,
@@ -198,6 +200,15 @@ impl App {
198200
self.compact_tools
199201
}
200202

203+
#[must_use]
204+
pub fn show_source_labels(&self) -> bool {
205+
self.show_source_labels
206+
}
207+
208+
pub fn set_show_source_labels(&mut self, v: bool) {
209+
self.show_source_labels = v;
210+
}
211+
201212
#[must_use]
202213
pub fn status_label(&self) -> Option<&str> {
203214
self.status_label.as_deref()

crates/zeph-tui/src/widgets/chat.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ pub fn render(app: &mut App, frame: &mut Frame, area: Rect) -> usize {
3838

3939
let msg_start = lines.len();
4040

41+
let show_labels = app.show_source_labels();
4142
if msg.role == MessageRole::Tool {
42-
render_tool_message(msg, app, &theme, wrap_width, &mut lines);
43+
render_tool_message(msg, app, &theme, wrap_width, show_labels, &mut lines);
4344
} else {
44-
render_chat_message(msg, &theme, wrap_width, &mut lines);
45+
render_chat_message(msg, &theme, wrap_width, show_labels, &mut lines);
4546
}
4647

4748
for line in &mut lines[msg_start..] {
@@ -111,13 +112,23 @@ fn render_chat_message(
111112
msg: &crate::app::ChatMessage,
112113
theme: &Theme,
113114
wrap_width: usize,
115+
show_labels: bool,
114116
lines: &mut Vec<Line<'static>>,
115117
) {
116-
let (prefix, base_style) = match msg.role {
117-
MessageRole::User => ("[user] ", theme.user_message),
118-
MessageRole::Assistant => ("[zeph] ", theme.assistant_message),
119-
MessageRole::System => ("[system] ", theme.system_message),
120-
MessageRole::Tool => unreachable!(),
118+
let (prefix, base_style) = if show_labels {
119+
match msg.role {
120+
MessageRole::User => ("[user] ", theme.user_message),
121+
MessageRole::Assistant => ("[zeph] ", theme.assistant_message),
122+
MessageRole::System => ("[system] ", theme.system_message),
123+
MessageRole::Tool => unreachable!(),
124+
}
125+
} else {
126+
match msg.role {
127+
MessageRole::User => ("", theme.user_message),
128+
MessageRole::Assistant => ("", theme.assistant_message),
129+
MessageRole::System => ("", theme.system_message),
130+
MessageRole::Tool => unreachable!(),
131+
}
121132
};
122133

123134
let indent = " ".repeat(prefix.len());
@@ -219,10 +230,15 @@ fn render_tool_message(
219230
app: &App,
220231
theme: &Theme,
221232
wrap_width: usize,
233+
show_labels: bool,
222234
lines: &mut Vec<Line<'static>>,
223235
) {
224-
let name = msg.tool_name.as_deref().unwrap_or("tool");
225-
let prefix = format!("[{name}] ");
236+
let prefix = if show_labels {
237+
let name = msg.tool_name.as_deref().unwrap_or("tool");
238+
format!("[{name}] ")
239+
} else {
240+
String::new()
241+
};
226242
let content_lines: Vec<&str> = msg.content.lines().collect();
227243

228244
// First line is always the command ($ ...)

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ async fn main() -> anyhow::Result<()> {
399399
std::thread::spawn(move || reader.run());
400400

401401
let mut tui_app = App::new(tui_handle.user_tx, tui_handle.agent_rx);
402+
tui_app.set_show_source_labels(config.tui.show_source_labels);
402403

403404
let history: Vec<(&str, &str)> = agent
404405
.context_messages()

0 commit comments

Comments
 (0)