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:
asepharyana
2026-07-12 01:25:52 +07:00
parent fcef85a327
commit 18a41aad48
28 changed files with 838 additions and 98 deletions
+15
View File
@@ -53,6 +53,11 @@ fn run_single_process() -> Result<()> {
let session_dir = store.base_dir.join("sessions").join(&session_id);
std::fs::create_dir_all(&session_dir)?;
let session_lock = model::session_lock::SessionLock::new(&session_dir);
if !session_lock.try_lock()? {
anyhow::bail!("session already active (another zesdex process holds the lock for this session directory)");
}
let workspace_roots = vec![std::env::current_dir()?];
let mut state = app::state::rest::AppStateRest::new(
workspace_roots.clone(),
@@ -60,6 +65,9 @@ fn run_single_process() -> Result<()> {
store.memory_dir,
);
state.sessions = model::session::Session::list(&store.base_dir);
if state.settings.api_key.is_none() {
state.misc.overlay = app::state::types::Overlay::Onboard;
}
let _rt = tokio::runtime::Runtime::new()?;
@@ -82,6 +90,7 @@ fn run_single_process() -> Result<()> {
}
let _ = state.settings.save();
session_lock.unlock();
Ok(())
}
@@ -255,6 +264,11 @@ fn run_daemon() -> Result<()> {
let session_dir = store.base_dir.join("sessions").join(&session_id);
std::fs::create_dir_all(&session_dir)?;
let session_lock = model::session_lock::SessionLock::new(&session_dir);
if !session_lock.try_lock()? {
anyhow::bail!("session already active (another zesdex process holds the lock for this session directory)");
}
let workspace_roots = vec![std::env::current_dir()?];
let mut state = app::state::rest::AppStateRest::new(
workspace_roots.clone(),
@@ -336,6 +350,7 @@ fn run_daemon() -> Result<()> {
let _ = std::fs::remove_file(&socket_path);
let _ = state.settings.save();
session_lock.unlock();
Ok(())
}