mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
fix(cli): handle Reasoning content and fix streaming thinking display (#7296)
Signed-off-by: rabi <ramishra@redhat.com>
This commit is contained in:
@@ -967,6 +967,7 @@ impl CliSession {
|
||||
let mut progress_bars = output::McpSpinners::new();
|
||||
let cancel_token_clone = cancel_token.clone();
|
||||
let mut markdown_buffer = streaming_buffer::MarkdownBuffer::new();
|
||||
let mut thinking_header_shown = false;
|
||||
|
||||
use futures::StreamExt;
|
||||
loop {
|
||||
@@ -1039,7 +1040,7 @@ impl CliSession {
|
||||
if is_stream_json_mode {
|
||||
emit_stream_event(&StreamEvent::Message { message: message.clone() });
|
||||
} else if !is_json_mode {
|
||||
output::render_message_streaming(&message, &mut markdown_buffer, self.debug);
|
||||
output::render_message_streaming(&message, &mut markdown_buffer, &mut thinking_header_shown, self.debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Error, IsTerminal, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use std::time::Duration;
|
||||
|
||||
use super::streaming_buffer::MarkdownBuffer;
|
||||
@@ -238,16 +238,9 @@ pub fn render_message(message: &Message, debug: bool) {
|
||||
MessageContent::Image(image) => {
|
||||
println!("Image: [data: {}, type: {}]", image.data, image.mime_type);
|
||||
}
|
||||
MessageContent::Thinking(thinking) => {
|
||||
if std::env::var("GOOSE_CLI_SHOW_THINKING").is_ok()
|
||||
&& std::io::stdout().is_terminal()
|
||||
{
|
||||
println!("\n{}", style("Thinking:").dim().italic());
|
||||
print_markdown(&thinking.thinking, theme);
|
||||
}
|
||||
}
|
||||
MessageContent::Thinking(t) => render_thinking(&t.thinking, theme),
|
||||
MessageContent::Reasoning(r) => render_thinking(&r.text, theme),
|
||||
MessageContent::RedactedThinking(_) => {
|
||||
// For redacted thinking, print thinking was redacted
|
||||
println!("\n{}", style("Thinking:").dim().italic());
|
||||
print_markdown("Thinking was redacted", theme);
|
||||
}
|
||||
@@ -276,10 +269,22 @@ pub fn render_message(message: &Message, debug: bool) {
|
||||
|
||||
/// Render a streaming message, using a buffer to accumulate text content
|
||||
/// and only render when markdown constructs are complete.
|
||||
pub fn render_message_streaming(message: &Message, buffer: &mut MarkdownBuffer, debug: bool) {
|
||||
pub fn render_message_streaming(
|
||||
message: &Message,
|
||||
buffer: &mut MarkdownBuffer,
|
||||
thinking_header_shown: &mut bool,
|
||||
debug: bool,
|
||||
) {
|
||||
let theme = get_theme();
|
||||
|
||||
for content in &message.content {
|
||||
if !matches!(
|
||||
content,
|
||||
MessageContent::Thinking(_) | MessageContent::Reasoning(_)
|
||||
) {
|
||||
*thinking_header_shown = false;
|
||||
}
|
||||
|
||||
match content {
|
||||
MessageContent::Text(text) => {
|
||||
if let Some(safe_content) = buffer.push(&text.text) {
|
||||
@@ -312,14 +317,11 @@ pub fn render_message_streaming(message: &Message, buffer: &mut MarkdownBuffer,
|
||||
flush_markdown_buffer(buffer, theme);
|
||||
println!("Image: [data: {}, type: {}]", image.data, image.mime_type);
|
||||
}
|
||||
MessageContent::Thinking(thinking) => {
|
||||
if std::env::var("GOOSE_CLI_SHOW_THINKING").is_ok()
|
||||
&& std::io::stdout().is_terminal()
|
||||
{
|
||||
flush_markdown_buffer(buffer, theme);
|
||||
println!("\n{}", style("Thinking:").dim().italic());
|
||||
print_markdown(&thinking.thinking, theme);
|
||||
}
|
||||
MessageContent::Thinking(t) => {
|
||||
render_thinking_streaming(&t.thinking, buffer, thinking_header_shown, theme);
|
||||
}
|
||||
MessageContent::Reasoning(r) => {
|
||||
render_thinking_streaming(&r.text, buffer, thinking_header_shown, theme);
|
||||
}
|
||||
MessageContent::RedactedThinking(_) => {
|
||||
flush_markdown_buffer(buffer, theme);
|
||||
@@ -410,6 +412,38 @@ pub fn goose_mode_message(text: &str) {
|
||||
println!("\n{}", style(text).yellow(),);
|
||||
}
|
||||
|
||||
static SHOW_THINKING: LazyLock<bool> = LazyLock::new(|| {
|
||||
std::env::var("GOOSE_CLI_SHOW_THINKING").is_ok() && std::io::stdout().is_terminal()
|
||||
});
|
||||
|
||||
fn should_show_thinking() -> bool {
|
||||
*SHOW_THINKING
|
||||
}
|
||||
|
||||
fn render_thinking(text: &str, theme: Theme) {
|
||||
if should_show_thinking() {
|
||||
println!("\n{}", style("Thinking:").dim().italic());
|
||||
print_markdown(text, theme);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_thinking_streaming(
|
||||
text: &str,
|
||||
buffer: &mut MarkdownBuffer,
|
||||
header_shown: &mut bool,
|
||||
theme: Theme,
|
||||
) {
|
||||
if should_show_thinking() {
|
||||
flush_markdown_buffer(buffer, theme);
|
||||
if !*header_shown {
|
||||
println!("\n{}", style("Thinking:").dim().italic());
|
||||
*header_shown = true;
|
||||
}
|
||||
print!("{}", style(text).dim());
|
||||
let _ = std::io::stdout().flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn render_tool_request(req: &ToolRequest, theme: Theme, debug: bool) {
|
||||
match &req.tool_call {
|
||||
Ok(call) => match call.name.to_string().as_str() {
|
||||
|
||||
Reference in New Issue
Block a user