Enhance TUI thinking panel: add dynamic height calculation, implement real-time updates from assistant messages, and refine thinking content rendering logic.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use crate::types::Message;
|
||||
use textwrap::{wrap, Options};
|
||||
|
||||
/// Formats messages for display across different clients.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -38,4 +37,55 @@ impl MessageFormatter {
|
||||
pub fn format_message(&self, message: &Message) -> Vec<String> {
|
||||
message.content.trim().lines().map(|s| s.to_string()).collect()
|
||||
}
|
||||
|
||||
/// Extract thinking content from <think> tags, returning (content_without_think, thinking_content)
|
||||
/// This handles both complete and incomplete (streaming) think tags.
|
||||
pub fn extract_thinking(&self, content: &str) -> (String, Option<String>) {
|
||||
let mut result = String::new();
|
||||
let mut thinking = String::new();
|
||||
let mut current_pos = 0;
|
||||
|
||||
while let Some(start_pos) = content[current_pos..].find("<think>") {
|
||||
let abs_start = current_pos + start_pos;
|
||||
|
||||
// Add content before <think> tag to result
|
||||
result.push_str(&content[current_pos..abs_start]);
|
||||
|
||||
// Find closing tag
|
||||
if let Some(end_pos) = content[abs_start..].find("</think>") {
|
||||
let abs_end = abs_start + end_pos;
|
||||
let think_content = &content[abs_start + 7..abs_end]; // 7 = len("<think>")
|
||||
|
||||
if !thinking.is_empty() {
|
||||
thinking.push_str("\n\n");
|
||||
}
|
||||
thinking.push_str(think_content.trim());
|
||||
|
||||
current_pos = abs_end + 8; // 8 = len("</think>")
|
||||
} else {
|
||||
// Unclosed tag - this is streaming content
|
||||
// Extract everything after <think> as thinking content
|
||||
let think_content = &content[abs_start + 7..]; // 7 = len("<think>")
|
||||
|
||||
if !thinking.is_empty() {
|
||||
thinking.push_str("\n\n");
|
||||
}
|
||||
thinking.push_str(think_content);
|
||||
|
||||
current_pos = content.len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add remaining content
|
||||
result.push_str(&content[current_pos..]);
|
||||
|
||||
let thinking_result = if thinking.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(thinking)
|
||||
};
|
||||
|
||||
(result, thinking_result)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user