fix(transcribe): show tool results by default with truncation

Remove the opts.include.output gate in render_entry_text so tool results
are always visible. Truncated to 200 chars by default; uncapped with
--verbose.

Closes claudbg-zy1p

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Elijah Voigt 2 months ago
parent dbffc151fb
commit 1455859825

@ -1,10 +1,11 @@
--- ---
# claudbg-zy1p # claudbg-zy1p
title: Tool results hidden by default in transcriptions — should show with truncation title: Tool results hidden by default in transcriptions — should show with truncation
status: todo status: completed
type: bug type: bug
priority: normal
created_at: 2026-03-30T04:44:18Z created_at: 2026-03-30T04:44:18Z
updated_at: 2026-03-30T04:44:18Z updated_at: 2026-03-30T05:12:16Z
parent: claudbg-8vpb parent: claudbg-8vpb
--- ---
@ -41,3 +42,7 @@ Also apply the same change to the `--verbose` path: when `opts.verbose` is true,
- `src/commands/sessions.rs``render_entry_text`, `ToolResult` branch (~line 113131) - `src/commands/sessions.rs``render_entry_text`, `ToolResult` branch (~line 113131)
- `src/commands/agents.rs``render_entry_text`, same branch (~line 7492) - `src/commands/agents.rs``render_entry_text`, same branch (~line 7492)
## Summary of Changes
Removed opts.include.output gate in render_entry_text in both sessions.rs and agents.rs. Tool results now always shown, truncated at 200 chars by default, uncapped with --verbose.

@ -44,7 +44,7 @@ fn content_preview(entry: &crate::models::session::RawEntry, max_len: usize) ->
/// Render a single entry to stdout in human-readable text format. /// Render a single entry to stdout in human-readable text format.
/// ///
/// Thinking blocks are shown only when `opts.include.thinking` is set. /// Thinking blocks are shown only when `opts.include.thinking` is set.
/// Tool result blocks are shown only when `opts.include.output` is set. /// Tool result blocks are always shown, truncated to 200 chars unless `opts.verbose`.
fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli::GlobalOpts) { fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli::GlobalOpts) {
let Some(msg) = &entry.message else { return }; let Some(msg) = &entry.message else { return };
let role = msg.role.as_deref().unwrap_or("?"); let role = msg.role.as_deref().unwrap_or("?");
@ -74,18 +74,20 @@ fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli
crate::models::session::ContentBlock::ToolResult { crate::models::session::ContentBlock::ToolResult {
content, is_error, .. content, is_error, ..
} => { } => {
if opts.include.output { let err_flag = if is_error.unwrap_or(false) {
let err_flag = if is_error.unwrap_or(false) { " (error)"
" (error)" } else {
} else { ""
"" };
}; let preview = content
let preview = content .as_ref()
.as_ref() .and_then(|c| c.as_str().map(|s| s.to_string()))
.and_then(|c| c.as_str().map(|s| s.to_string())) .unwrap_or_else(|| {
.unwrap_or_else(|| { content.as_ref().map(|c| c.to_string()).unwrap_or_default()
content.as_ref().map(|c| c.to_string()).unwrap_or_default() });
}); if opts.verbose {
println!("[tool_result{err_flag}]: {preview}");
} else {
let boundary = preview.floor_char_boundary(200); let boundary = preview.floor_char_boundary(200);
let short = &preview[..boundary]; let short = &preview[..boundary];
println!("[tool_result{err_flag}]: {short}"); println!("[tool_result{err_flag}]: {short}");
@ -696,9 +698,9 @@ mod tests {
render_entry_text(&entry, &opts); // must not panic render_entry_text(&entry, &opts); // must not panic
} }
/// `render_entry_text` does not panic when tool results are present but gated off. /// `render_entry_text` always shows tool results (truncated by default) without panicking.
#[test] #[test]
fn render_entry_text_tool_result_gated() { fn render_entry_text_tool_result_always_shown() {
let entry = make_raw_entry( let entry = make_raw_entry(
"user", "user",
"user", "user",
@ -708,7 +710,7 @@ mod tests {
is_error: Some(false), is_error: Some(false),
}]), }]),
); );
let opts = default_opts(); let opts = default_opts(); // verbose = false → truncated at 200 chars
render_entry_text(&entry, &opts); // must not panic render_entry_text(&entry, &opts); // must not panic
} }
} }

@ -83,7 +83,7 @@ fn content_preview(entry: &crate::models::session::RawEntry, max_len: usize) ->
/// Render a single entry to stdout in human-readable text format. /// Render a single entry to stdout in human-readable text format.
/// ///
/// Thinking blocks are shown only when `opts.include.thinking` is set. /// Thinking blocks are shown only when `opts.include.thinking` is set.
/// Tool result blocks are shown only when `opts.include.output` is set. /// Tool result blocks are always shown, truncated to 200 chars unless `opts.verbose`.
fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli::GlobalOpts) { fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli::GlobalOpts) {
let Some(msg) = &entry.message else { return }; let Some(msg) = &entry.message else { return };
let role = msg.role.as_deref().unwrap_or("?"); let role = msg.role.as_deref().unwrap_or("?");
@ -113,18 +113,20 @@ fn render_entry_text(entry: &crate::models::session::RawEntry, opts: &crate::cli
crate::models::session::ContentBlock::ToolResult { crate::models::session::ContentBlock::ToolResult {
content, is_error, .. content, is_error, ..
} => { } => {
if opts.include.output { let err_flag = if is_error.unwrap_or(false) {
let err_flag = if is_error.unwrap_or(false) { " (error)"
" (error)" } else {
} else { ""
"" };
}; let preview = content
let preview = content .as_ref()
.as_ref() .and_then(|c| c.as_str().map(|s| s.to_string()))
.and_then(|c| c.as_str().map(|s| s.to_string())) .unwrap_or_else(|| {
.unwrap_or_else(|| { content.as_ref().map(|c| c.to_string()).unwrap_or_default()
content.as_ref().map(|c| c.to_string()).unwrap_or_default() });
}); if opts.verbose {
println!("[tool_result{err_flag}]: {preview}");
} else {
let boundary = preview.floor_char_boundary(200); let boundary = preview.floor_char_boundary(200);
let short = &preview[..boundary]; let short = &preview[..boundary];
println!("[tool_result{err_flag}]: {short}"); println!("[tool_result{err_flag}]: {short}");
@ -917,9 +919,9 @@ mod tests {
assert_eq!(result[2][0], "5-6"); assert_eq!(result[2][0], "5-6");
} }
/// `render_entry_text` does not print tool results when `include.output` is false. /// `render_entry_text` always shows tool results (truncated by default) without panicking.
#[test] #[test]
fn render_entry_text_tool_result_gated() { fn render_entry_text_tool_result_always_shown() {
let entry = make_raw_entry( let entry = make_raw_entry(
"user", "user",
"user", "user",
@ -929,7 +931,7 @@ mod tests {
is_error: Some(false), is_error: Some(false),
}]), }]),
); );
let opts = default_opts(); // include.output = false let opts = default_opts(); // verbose = false → truncated at 200 chars
render_entry_text(&entry, &opts); // must not panic render_entry_text(&entry, &opts); // must not panic
} }
} }

Loading…
Cancel
Save