Refactor IPC and DTO structures; remove unused code and streamline message handling

- Removed unused structs and methods from `response.rs`, `usage.rs`, and `client.rs`.
- Simplified `Connection` handling in `conn.rs` to only support Unix sockets.
- Updated `IpcServer` to exclusively use Unix sockets and removed TCP handling.
- Cleaned up `editlog.rs` by removing loading and recent entry methods.
- Refactored `memory.rs` to eliminate unused functions related to lesson promotion and retrospective creation.
- Enhanced `search.rs` to support multiple search providers and improved error handling.
- Updated chat view logic to simplify message display and improve user experience.
- Removed deprecated modules and constants from various files to streamline the codebase.
This commit is contained in:
asepharyana
2026-07-11 23:45:13 +07:00
parent 93d1bbb7c1
commit fcef85a327
51 changed files with 1431 additions and 1246 deletions
+6 -36
View File
@@ -40,24 +40,6 @@ impl EditLog {
Ok(())
}
pub fn load(path: &std::path::Path) -> std::io::Result<Self> {
let content = std::fs::read_to_string(path)?;
let entries: Vec<EditLogEntry> = content
.lines()
.filter_map(|l| serde_json::from_str(l).ok())
.collect();
Ok(EditLog {
entries,
path: path.to_path_buf(),
})
}
pub fn recent(&self, n: usize) -> &[EditLogEntry] {
let len = self.entries.len();
let start = len.saturating_sub(n);
&self.entries[start..]
}
pub fn len(&self) -> usize {
self.entries.len()
}
@@ -73,7 +55,6 @@ mod tests {
let _ = std::fs::create_dir_all(&dir);
let log = EditLog::new(&dir);
assert_eq!(log.len(), 0);
assert_eq!(log.recent(5).len(), 0);
let _ = std::fs::remove_dir_all(&dir);
}
@@ -94,19 +75,10 @@ mod tests {
};
log.append(entry.clone()).unwrap();
assert_eq!(log.len(), 1);
let loaded = EditLog::load(&log.path).unwrap();
assert_eq!(loaded.len(), 1);
assert_eq!(loaded.entries[0].reason, "test reason");
assert_eq!(loaded.entries[0].tool, "write");
assert_eq!(loaded.entries[0].path, "test.txt");
let recent = log.recent(1);
assert_eq!(recent.len(), 1);
assert_eq!(recent[0].bytes_delta, 42);
let empty = log.recent(0);
assert_eq!(empty.len(), 0);
assert_eq!(log.entries[0].reason, "test reason");
assert_eq!(log.entries[0].tool, "write");
assert_eq!(log.entries[0].path, "test.txt");
assert_eq!(log.entries[0].bytes_delta, 42);
let _ = std::fs::remove_dir_all(&dir);
}
@@ -128,10 +100,8 @@ mod tests {
}).unwrap();
}
assert_eq!(log.len(), 5);
let recent = log.recent(3);
assert_eq!(recent.len(), 3);
assert_eq!(recent[0].reason, "reason 2");
assert_eq!(recent[2].reason, "reason 4");
assert_eq!(log.entries[0].reason, "reason 0");
assert_eq!(log.entries[4].reason, "reason 4");
let _ = std::fs::remove_dir_all(&dir);
}
}
-84
View File
@@ -1,8 +1,6 @@
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use super::session::Session;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Memory {
pub name: String,
@@ -129,16 +127,6 @@ impl Memory {
})
.collect()
}
pub fn load_index(memory_dir: &Path) -> Vec<String> {
let index_path = memory_dir.join("MEMORY.md");
let content = std::fs::read_to_string(index_path).unwrap_or_default();
content.lines().filter_map(|l| {
let l = l.trim();
if l.is_empty() || l.starts_with('#') { return None; }
l.split(']').next().and_then(|s| s.split('[').nth(1)).map(|s| s.to_string())
}).collect()
}
}
pub fn slug_path(memory_dir: &Path, raw: &str) -> PathBuf {
@@ -159,26 +147,6 @@ pub fn export_lessons(memory_dir: &Path, output: &Path) -> std::io::Result<()> {
std::fs::write(output, data)?;
Ok(())
}
pub fn promote_with_consensus(global_dir: &Path, lesson: &Memory) -> std::io::Result<bool> {
let global_path = global_dir.join("memory");
std::fs::create_dir_all(&global_path)?;
let existing = Memory::list(&global_path);
let slug = Memory::slugify(&lesson.name).unwrap_or_default();
if existing.contains(&slug) {
return Ok(true);
}
let consensus = lesson.outcome.as_deref() == Some("verified");
if consensus {
let mut promoted = lesson.clone();
promoted.scope = Some("global".to_string());
promoted.write(&global_path)?;
Ok(true)
} else {
Ok(false)
}
}
pub fn import_lessons(memory_dir: &Path, input: &Path) -> std::io::Result<usize> {
let data = std::fs::read_to_string(input)?;
let lessons: Vec<Memory> = serde_json::from_str(&data)
@@ -194,30 +162,6 @@ pub fn import_lessons(memory_dir: &Path, input: &Path) -> std::io::Result<usize>
}
Ok(imported)
}
pub fn auto_create_retrospective(session_dir: &Path, session: &Session) -> std::io::Result<Option<Memory>> {
let now = chrono::Utc::now().timestamp_millis();
let session_age_ms = now.saturating_sub(session.created_at);
if session_age_ms < 60_000 {
return Ok(None);
}
let retro_name = format!("retrospective-{}", session.id);
let retro_path = Memory::path(session_dir, &retro_name);
if retro_path.exists() {
return Ok(None);
}
let lessons: Vec<Memory> = Memory::list(session_dir)
.iter()
.filter_map(|n| Memory::read(session_dir, n).ok())
.filter(|m| m.kind == "lesson")
.collect();
if lessons.is_empty() {
return Ok(None);
}
let retrospective = create_retrospective(session_dir, session, &lessons)?;
Ok(Some(retrospective))
}
#[cfg(test)]
mod tests {
@@ -386,31 +330,3 @@ mod tests {
let _ = std::fs::remove_file(&export_path);
}
}
pub fn create_retrospective(session_dir: &Path, session: &Session, lessons: &[Memory]) -> std::io::Result<Memory> {
let now = chrono::Utc::now().timestamp_millis();
let lessons_content: String = lessons.iter()
.map(|l| format!("- {}: {}", l.name, l.description))
.collect::<Vec<_>>()
.join("\n");
let content = format!(
"# Session Retrospective\n\nSession: {}\nCreated: {}\nLessons learned:\n{}\n",
session.title, now, lessons_content,
);
let memory = Memory {
name: format!("retrospective-{}", session.id),
description: format!("End-of-session retrospective for {}", session.title),
content,
kind: "retrospective".to_string(),
created_at: now,
updated_at: now,
outcome: None,
lifecycle: "new".to_string(),
scope: Some("project".to_string()),
before_snippet: None,
after_snippet: None,
provenances: vec![],
};
memory.write(session_dir)?;
Ok(memory)
}
-4
View File
@@ -1,10 +1,6 @@
pub mod agent_def;
pub mod app_config;
pub mod conversation;
pub mod editlog;
pub mod memory;
pub mod msglog;
pub mod session;
pub mod session_lock;
pub mod settings;
pub mod store;
+12 -2
View File
@@ -1,4 +1,14 @@
pub mod blobs;
pub mod query;
pub mod schema;
pub mod summary;
pub use query::insert_message;
pub fn open_or_create(session_dir: &std::path::Path) -> anyhow::Result<rusqlite::Connection> {
let path = session_dir.join("messages.sqlite");
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let conn = rusqlite::Connection::open(&path)?;
schema::init_schema(&conn)?;
Ok(conn)
}
-44
View File
@@ -22,47 +22,3 @@ pub fn insert_message(conn: &Connection, session_id: &str, msg: &ChatMessage) ->
)?;
Ok(conn.last_insert_rowid())
}
pub fn query_messages(conn: &Connection, session_id: &str, limit: usize, offset: usize) -> Result<Vec<ChatMessage>> {
let mut stmt = conn.prepare(
"SELECT role, content, tool_call_id, tool_name, tool_arguments FROM messages WHERE session_id = ?1 ORDER BY id ASC LIMIT ?2 OFFSET ?3"
)?;
let rows = stmt.query_map(params![session_id, limit as i64, offset as i64], |row| {
let role_str: String = row.get(0)?;
let content: Option<String> = row.get(1)?;
let tool_call_id: Option<String> = row.get(2)?;
let tool_name: Option<String> = row.get(3)?;
let tool_arguments: Option<String> = row.get(4)?;
let role = match role_str.as_str() {
"user" => Role::User,
"assistant" => Role::Assistant,
"system" => Role::System,
"tool" => Role::Tool,
_ => Role::User,
};
let tool_calls = tool_arguments.and_then(|args| {
serde_json::from_str(&args).ok()
});
Ok(ChatMessage {
role,
content,
tool_calls,
tool_call_id,
name: tool_name,
})
})?;
let mut messages = Vec::new();
for row in rows {
messages.push(row?);
}
Ok(messages)
}
pub fn count_messages(conn: &Connection, session_id: &str) -> Result<i64> {
let count: i64 = conn.query_row(
"SELECT COUNT(*) FROM messages WHERE session_id = ?1",
params![session_id],
|row| row.get(0),
)?;
Ok(count)
}
-8
View File
@@ -41,14 +41,6 @@ impl Session {
self.session_dir(base_dir).join("conversation.json")
}
pub fn edit_log_path(&self, base_dir: &Path) -> PathBuf {
self.session_dir(base_dir).join("edits.jsonl")
}
pub fn msglog_path(&self, base_dir: &Path) -> PathBuf {
self.session_dir(base_dir).join("msglog.db")
}
pub fn save(&self, base_dir: &Path) -> std::io::Result<()> {
let dir = self.session_dir(base_dir);
std::fs::create_dir_all(&dir)?;