Lifei/sub recipe desktop temp (#3576)
This commit is contained in:
@@ -2,6 +2,7 @@ use goose::agents::subagent_execution_tool::lib::TaskStatus;
|
||||
use goose::agents::subagent_execution_tool::notification_events::{
|
||||
TaskExecutionNotificationEvent, TaskInfo,
|
||||
};
|
||||
use goose::utils::safe_truncate;
|
||||
use serde_json::Value;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
@@ -18,7 +19,7 @@ static INITIAL_SHOWN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
fn format_result_data_for_display(result_data: &Value) -> String {
|
||||
match result_data {
|
||||
Value::String(s) => strip_ansi_codes(s),
|
||||
Value::String(s) => s.to_string(),
|
||||
Value::Object(obj) => {
|
||||
if let Some(partial_output) = obj.get("partial_output").and_then(|v| v.as_str()) {
|
||||
format!("Partial output: {}", partial_output)
|
||||
@@ -45,53 +46,7 @@ fn process_output_for_display(output: &str) -> String {
|
||||
};
|
||||
|
||||
let clean_output = recent_lines.join(" ... ");
|
||||
let stripped = strip_ansi_codes(&clean_output);
|
||||
truncate_with_ellipsis(&stripped, OUTPUT_PREVIEW_LENGTH)
|
||||
}
|
||||
|
||||
fn truncate_with_ellipsis(text: &str, max_len: usize) -> String {
|
||||
if text.len() > max_len {
|
||||
let mut end = max_len.saturating_sub(3);
|
||||
while end > 0 && !text.is_char_boundary(end) {
|
||||
end -= 1;
|
||||
}
|
||||
format!("{}...", &text[..end])
|
||||
} else {
|
||||
text.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_ansi_codes(text: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut chars = text.chars();
|
||||
|
||||
while let Some(ch) = chars.next() {
|
||||
if ch == '\x1b' {
|
||||
if let Some(next_ch) = chars.next() {
|
||||
if next_ch == '[' {
|
||||
// This is an ANSI escape sequence, consume until alphabetic character
|
||||
loop {
|
||||
match chars.next() {
|
||||
Some(c) if c.is_ascii_alphabetic() => break,
|
||||
Some(_) => continue,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not an ANSI sequence, keep both characters
|
||||
result.push(ch);
|
||||
result.push(next_ch);
|
||||
}
|
||||
} else {
|
||||
// End of string after \x1b
|
||||
result.push(ch);
|
||||
}
|
||||
} else {
|
||||
result.push(ch);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
safe_truncate(&clean_output, OUTPUT_PREVIEW_LENGTH)
|
||||
}
|
||||
|
||||
pub fn format_task_execution_notification(
|
||||
@@ -233,7 +188,7 @@ fn format_task_display(task: &TaskInfo) -> String {
|
||||
|
||||
if matches!(task.status, TaskStatus::Failed) {
|
||||
if let Some(error) = &task.error {
|
||||
let error_preview = truncate_with_ellipsis(error, 80);
|
||||
let error_preview = safe_truncate(error, 80);
|
||||
task_display.push_str(&format!(
|
||||
" ⚠️ {}{}\n",
|
||||
error_preview.replace('\n', " "),
|
||||
|
||||
@@ -4,34 +4,6 @@ use goose::agents::subagent_execution_tool::notification_events::{
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_strip_ansi_codes() {
|
||||
assert_eq!(strip_ansi_codes("hello world"), "hello world");
|
||||
assert_eq!(strip_ansi_codes("\x1b[31mred text\x1b[0m"), "red text");
|
||||
assert_eq!(
|
||||
strip_ansi_codes("\x1b[1;32mbold green\x1b[0m"),
|
||||
"bold green"
|
||||
);
|
||||
assert_eq!(
|
||||
strip_ansi_codes("normal\x1b[33myellow\x1b[0mnormal"),
|
||||
"normalyellownormal"
|
||||
);
|
||||
assert_eq!(strip_ansi_codes("\x1bhello"), "\x1bhello");
|
||||
assert_eq!(strip_ansi_codes("hello\x1b"), "hello\x1b");
|
||||
assert_eq!(strip_ansi_codes(""), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_with_ellipsis() {
|
||||
assert_eq!(truncate_with_ellipsis("hello", 10), "hello");
|
||||
assert_eq!(truncate_with_ellipsis("hello", 5), "hello");
|
||||
assert_eq!(truncate_with_ellipsis("hello world", 8), "hello...");
|
||||
assert_eq!(truncate_with_ellipsis("hello", 3), "...");
|
||||
assert_eq!(truncate_with_ellipsis("hello", 2), "...");
|
||||
assert_eq!(truncate_with_ellipsis("hello", 1), "...");
|
||||
assert_eq!(truncate_with_ellipsis("", 5), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_output_for_display() {
|
||||
assert_eq!(process_output_for_display("hello world"), "hello world");
|
||||
@@ -49,20 +21,15 @@ fn test_process_output_for_display() {
|
||||
assert!(result.len() <= 100);
|
||||
assert!(result.ends_with("..."));
|
||||
|
||||
let ansi_output = "\x1b[31mred line 1\x1b[0m\n\x1b[32mgreen line 2\x1b[0m";
|
||||
let result = process_output_for_display(ansi_output);
|
||||
assert_eq!(result, "red line 1 ... green line 2");
|
||||
|
||||
assert_eq!(process_output_for_display(""), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_result_data_for_display() {
|
||||
let string_val = json!("hello world");
|
||||
assert_eq!(format_result_data_for_display(&string_val), "hello world");
|
||||
|
||||
let ansi_string = json!("\x1b[31mred text\x1b[0m");
|
||||
assert_eq!(format_result_data_for_display(&ansi_string), "red text");
|
||||
assert_eq!(
|
||||
format_result_data_for_display(&json!("red text")),
|
||||
"red text"
|
||||
);
|
||||
|
||||
assert_eq!(format_result_data_for_display(&json!(true)), "true");
|
||||
assert_eq!(format_result_data_for_display(&json!(false)), "false");
|
||||
|
||||
Reference in New Issue
Block a user