feat: add editing and MCP command handling, enhance SSE streaming with usage tracking
- Implemented `Edit` and `McpAdd` commands in the command parser and handler. - Added a new `stream` module to the runtime for handling streaming events. - Enhanced `SseParser` to parse usage information from SSE events. - Introduced `ToolCallAccumulator` for tracking tool calls independently. - Updated `AppStateRest` to include `app_config` and `MiscState` to track `effort_level` and `selected_index`. - Modified `LlmClient` to support streaming responses with usage tracking. - Improved error handling and retry logic in the streaming API calls. - Added tests for new features and improved markdown rendering in the chat view.
This commit is contained in:
+3
-4
@@ -74,10 +74,9 @@ pub fn draw_chat(frame: &mut Frame, area: Rect, state: &crate::app::state::rest:
|
||||
} else {
|
||||
msg.content.clone()
|
||||
};
|
||||
let content_line = Line::from(vec![
|
||||
Span::styled(format!("{} ", prefix), Style::default().fg(role_color)),
|
||||
Span::styled(content_str, Style::default().fg(Theme::TEXT)),
|
||||
]);
|
||||
let mut content_spans = vec![Span::styled(format!("{} ", prefix), Style::default().fg(role_color))];
|
||||
content_spans.extend(super::markdown::render_markdown(&content_str, area.width));
|
||||
let content_line = Line::from(content_spans);
|
||||
|
||||
display_lines.push(header);
|
||||
display_lines.push(content_line);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use ratatui::text::Span;
|
||||
|
||||
pub fn render_markdown<'a>(text: &'a str, width: u16) -> Vec<Span<'a>> {
|
||||
pub fn render_markdown(text: &str, width: u16) -> Vec<Span<'static>> {
|
||||
let mut spans = Vec::new();
|
||||
let parser = pulldown_cmark::Parser::new(text);
|
||||
let mut in_code_block = false;
|
||||
@@ -122,6 +122,7 @@ pub fn render_markdown<'a>(text: &'a str, width: u16) -> Vec<Span<'a>> {
|
||||
let mut spans_out = Vec::new();
|
||||
let mut line_len = 0;
|
||||
for span in &spans {
|
||||
let style = span.style;
|
||||
let s = span.content.clone();
|
||||
let text = s.as_ref();
|
||||
let remaining = text.len();
|
||||
@@ -129,7 +130,7 @@ pub fn render_markdown<'a>(text: &'a str, width: u16) -> Vec<Span<'a>> {
|
||||
spans_out.push(Span::raw("\n"));
|
||||
line_len = 0;
|
||||
}
|
||||
spans_out.push(Span::raw(text.to_string()));
|
||||
spans_out.push(Span::styled(text.to_string(), style));
|
||||
if !text.contains('\n') {
|
||||
line_len += remaining;
|
||||
} else {
|
||||
|
||||
+4
-7
@@ -1,4 +1,5 @@
|
||||
pub mod chat;
|
||||
pub mod markdown;
|
||||
pub mod status;
|
||||
pub mod theme;
|
||||
pub mod workflow;
|
||||
@@ -148,7 +149,7 @@ fn render_overlay(frame: &mut Frame, area: Rect, overlay: crate::app::state::typ
|
||||
Style::default(),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
"Press Ctrl+Q again to confirm, Esc to cancel.",
|
||||
"Press Enter to confirm, Esc to cancel.",
|
||||
Style::default().fg(Theme::DIM),
|
||||
)),
|
||||
];
|
||||
@@ -254,12 +255,8 @@ fn render_overlay(frame: &mut Frame, area: Rect, overlay: crate::app::state::typ
|
||||
}
|
||||
crate::app::state::types::Overlay::Effort => {
|
||||
let block = block.title(" Effort Level ");
|
||||
let levels = ["low", "medium", "high", "xhigh", "max"];
|
||||
let current_idx = if state.settings.temperature > 0.8 { 0usize }
|
||||
else if state.settings.temperature > 0.5 { 1 }
|
||||
else if state.settings.temperature > 0.3 { 2 }
|
||||
else if state.settings.max_tokens > 4000 { 3 }
|
||||
else { 4 };
|
||||
let levels = crate::app::mode::effort::EFFORT_LEVELS;
|
||||
let current_idx = crate::app::mode::effort::current_effort(state);
|
||||
let mut lines: Vec<Line> = levels.iter().enumerate().map(|(i, l)| {
|
||||
let selected = i == current_idx;
|
||||
Line::from(Span::styled(
|
||||
|
||||
Reference in New Issue
Block a user