feat: royal blue tool names in agent mode + fix README heading display
- Add set_agent_mode() to UiWriter trait for visual mode differentiation - ConsoleUiWriter uses royal blue (ANSI 256 color 69) for tool names in agent mode - Fix extract_readme_heading() to search only README section of combined content (was incorrectly showing AGENTS.md heading instead of README heading)
This commit is contained in:
@@ -768,6 +768,8 @@ async fn run_agent_mode(
|
|||||||
|
|
||||||
// Create agent with custom system prompt
|
// Create agent with custom system prompt
|
||||||
let ui_writer = ConsoleUiWriter::new();
|
let ui_writer = ConsoleUiWriter::new();
|
||||||
|
// Set agent mode on UI writer for visual differentiation (royal blue tool names)
|
||||||
|
ui_writer.set_agent_mode(true);
|
||||||
let mut agent = Agent::new_with_custom_prompt(
|
let mut agent = Agent::new_with_custom_prompt(
|
||||||
config,
|
config,
|
||||||
ui_writer,
|
ui_writer,
|
||||||
@@ -1407,11 +1409,20 @@ fn read_project_readme(workspace_dir: &Path) -> Option<String> {
|
|||||||
|
|
||||||
/// Extract the main heading or title from README content
|
/// Extract the main heading or title from README content
|
||||||
fn extract_readme_heading(readme_content: &str) -> Option<String> {
|
fn extract_readme_heading(readme_content: &str) -> Option<String> {
|
||||||
// Process the content line by line, skipping the prefix line if present
|
// Find the README section in the combined content
|
||||||
let lines_iter = readme_content.lines();
|
// The README section starts with "📚 Project README (from"
|
||||||
let mut content_lines = Vec::new();
|
let readme_start = readme_content.find("📚 Project README (from");
|
||||||
|
|
||||||
for line in lines_iter {
|
// If we can't find the README marker, the content might be just README
|
||||||
|
// or might not contain README at all
|
||||||
|
let content_to_search = match readme_start {
|
||||||
|
Some(pos) => &readme_content[pos..],
|
||||||
|
None => readme_content,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process the content line by line, skipping the prefix line
|
||||||
|
let mut content_lines = Vec::new();
|
||||||
|
for line in content_to_search.lines() {
|
||||||
// Skip the "📚 Project README (from ...):" line
|
// Skip the "📚 Project README (from ...):" line
|
||||||
if line.starts_with("📚 Project README") {
|
if line.starts_with("📚 Project README") {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub struct ConsoleUiWriter {
|
|||||||
current_tool_args: std::sync::Mutex<Vec<(String, String)>>,
|
current_tool_args: std::sync::Mutex<Vec<(String, String)>>,
|
||||||
current_output_line: std::sync::Mutex<Option<String>>,
|
current_output_line: std::sync::Mutex<Option<String>>,
|
||||||
output_line_printed: std::sync::Mutex<bool>,
|
output_line_printed: std::sync::Mutex<bool>,
|
||||||
|
is_agent_mode: std::sync::Mutex<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsoleUiWriter {
|
impl ConsoleUiWriter {
|
||||||
@@ -18,6 +19,7 @@ impl ConsoleUiWriter {
|
|||||||
current_tool_args: std::sync::Mutex::new(Vec::new()),
|
current_tool_args: std::sync::Mutex::new(Vec::new()),
|
||||||
current_output_line: std::sync::Mutex::new(None),
|
current_output_line: std::sync::Mutex::new(None),
|
||||||
output_line_printed: std::sync::Mutex::new(false),
|
output_line_printed: std::sync::Mutex::new(false),
|
||||||
|
is_agent_mode: std::sync::Mutex::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +111,11 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
// Reset output_line_printed at the start of a new tool output
|
// Reset output_line_printed at the start of a new tool output
|
||||||
// This ensures the header isn't cleared by update_tool_output_line
|
// This ensures the header isn't cleared by update_tool_output_line
|
||||||
*self.output_line_printed.lock().unwrap() = false;
|
*self.output_line_printed.lock().unwrap() = false;
|
||||||
// Now print the tool header with the most important arg in bold green
|
// Now print the tool header with the most important arg
|
||||||
|
// Use royal blue in agent mode, bold green otherwise
|
||||||
|
let is_agent_mode = *self.is_agent_mode.lock().unwrap();
|
||||||
|
// Royal blue: \x1b[38;5;69m, Bold green: \x1b[1;32m
|
||||||
|
let tool_color = if is_agent_mode { "\x1b[1;38;5;69m" } else { "\x1b[1;32m" };
|
||||||
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
||||||
let args = self.current_tool_args.lock().unwrap();
|
let args = self.current_tool_args.lock().unwrap();
|
||||||
|
|
||||||
@@ -162,14 +168,14 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Print with bold green tool name, purple (non-bold) for pipe and args
|
// Print with tool name in color (royal blue for agent mode, green otherwise)
|
||||||
println!(
|
println!(
|
||||||
"┌─\x1b[1;32m {}\x1b[0m\x1b[35m | {}{}\x1b[0m",
|
"┌─{} {}\x1b[0m\x1b[35m | {}{}\x1b[0m",
|
||||||
tool_name, display_value, header_suffix
|
tool_color, tool_name, display_value, header_suffix
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Print with bold green formatting using ANSI escape codes
|
// Print with tool name in color
|
||||||
println!("┌─\x1b[1;32m {}\x1b[0m", tool_name);
|
println!("┌─{} {}\x1b[0m", tool_color, tool_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,4 +367,8 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
// Reset the filter state for a new response
|
// Reset the filter state for a new response
|
||||||
reset_json_tool_state();
|
reset_json_tool_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_agent_mode(&self, is_agent_mode: bool) {
|
||||||
|
*self.is_agent_mode.lock().unwrap() = is_agent_mode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ pub trait UiWriter: Send + Sync {
|
|||||||
/// Called at the start of a new response to clear any partial state.
|
/// Called at the start of a new response to clear any partial state.
|
||||||
/// Default implementation does nothing.
|
/// Default implementation does nothing.
|
||||||
fn reset_json_filter(&self) {}
|
fn reset_json_filter(&self) {}
|
||||||
|
|
||||||
|
/// Set whether the UI is in agent mode.
|
||||||
|
/// When in agent mode, tool names may be displayed differently (e.g., different color).
|
||||||
|
/// Default implementation does nothing.
|
||||||
|
fn set_agent_mode(&self, _is_agent_mode: bool) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A no-op implementation for when UI output is not needed
|
/// A no-op implementation for when UI output is not needed
|
||||||
|
|||||||
Reference in New Issue
Block a user