chore: fix clippy warnings, add embedding/omni_patch, update telemetry, and ignore temp files
This commit is contained in:
1 parent
495304f3fa
commit
98a1716ac8
23 files changed
+2253
-75
No files matched your search
@@ -11,6 +11,7 @@ mod mcp;
|
||||
mod models;
|
||||
mod router;
|
||||
mod search;
|
||||
pub mod embedding;
|
||||
mod state;
|
||||
mod store;
|
||||
mod tools;
|
||||
@@ -89,6 +90,28 @@ pub struct AppState {
|
||||
next_id: AtomicUsize,
|
||||
}
|
||||
|
||||
async fn ttl_sweeper_worker(state: Arc<MemoryState>) {
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_secs(3600)).await;
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
|
||||
state.tasks.modify(|tasks| {
|
||||
tasks.retain(|t| t.expires_at.is_none_or(|exp| exp > now));
|
||||
});
|
||||
state.sticky.modify(|notes| {
|
||||
notes.retain(|n| n.expires_at.is_none_or(|exp| exp > now));
|
||||
});
|
||||
state.handoff_memos.modify(|memos| {
|
||||
memos.retain(|m| m.expires_at.is_none_or(|exp| exp > now));
|
||||
});
|
||||
state.session_summaries.modify(|summaries| {
|
||||
summaries.retain(|s| s.expires_at.is_none_or(|exp| exp > now));
|
||||
});
|
||||
}
|
||||
}
|
||||
async fn index_committer_worker(state: Arc<MemoryState>) {
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
@@ -103,6 +126,7 @@ async fn index_committer_worker(state: Arc<MemoryState>) {
|
||||
async fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
state.rebuild_index().await;
|
||||
tokio::spawn(index_committer_worker(Arc::clone(&state)));
|
||||
tokio::spawn(ttl_sweeper_worker(Arc::clone(&state)));
|
||||
let app_state = Arc::new(AppState {
|
||||
handler: Arc::new(MemoryHandler::new(Arc::clone(&state))),
|
||||
clients: RwLock::new(HashMap::new()),
|
||||
@@ -132,6 +156,102 @@ async fn run_server(state: Arc<MemoryState>) -> Result<(), Box<dyn std::error::E
|
||||
}
|
||||
});
|
||||
|
||||
// UDP Telemetry Listener on port 3001
|
||||
let udp_state = Arc::clone(&app_state);
|
||||
tokio::spawn(async move {
|
||||
if let Ok(socket) = tokio::net::UdpSocket::bind("127.0.0.1:3001").await {
|
||||
let mut buf = [0; 4096];
|
||||
loop {
|
||||
if let Ok((len, _addr)) = socket.recv_from(&mut buf).await
|
||||
&& let Ok(payload) = serde_json::from_slice::<crate::models::TerminalHistory>(&buf[..len])
|
||||
{
|
||||
udp_state.handler.state.terminal_history.modify(|history| {
|
||||
history.push_front(payload.clone());
|
||||
if history.len() > 100 {
|
||||
history.pop_back();
|
||||
}
|
||||
});
|
||||
|
||||
let ws_msg = serde_json::json!({
|
||||
"type": "terminal_telemetry",
|
||||
"data": payload
|
||||
});
|
||||
let msg_str = ws_msg.to_string();
|
||||
|
||||
let senders: Vec<_> = udp_state
|
||||
.clients
|
||||
.read()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.values()
|
||||
.cloned()
|
||||
.collect();
|
||||
for tx in senders {
|
||||
let _ = tx.try_send(msg_str.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// UDP Neovim Telemetry Listener on port 3002
|
||||
let nvim_udp_state = Arc::clone(&app_state);
|
||||
tokio::spawn(async move {
|
||||
if let Ok(socket) = tokio::net::UdpSocket::bind("127.0.0.1:3002").await {
|
||||
let mut buf = [0; 4096];
|
||||
loop {
|
||||
if let Ok((len, _addr)) = socket.recv_from(&mut buf).await
|
||||
&& let Ok(payload) = serde_json::from_slice::<crate::api::telemetry::NvimTelemetry>(&buf[..len])
|
||||
{
|
||||
// 1. Legacy disk write for active_nvim.txt
|
||||
if payload.event == "FocusGained" || payload.event == "BufEnter" || payload.event == "VimEnter" {
|
||||
let session = &payload.session_id;
|
||||
let is_unix_socket = session.starts_with('/') || session.starts_with('~');
|
||||
if is_unix_socket {
|
||||
let wsl_path = "\\\\wsl.localhost\\Ubuntu\\home\\riz\\.gemini\\active_nvim.txt";
|
||||
let _ = tokio::fs::write(wsl_path, session).await;
|
||||
} else {
|
||||
let profile = std::env::var("USERPROFILE").unwrap_or_else(|_| "C:\\Users\\reazul.ashraf".into());
|
||||
let win_path = format!("{}\\.gemini\\active_nvim.txt", profile);
|
||||
let _ = tokio::fs::write(&win_path, session).await;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Broadcast to UI
|
||||
let ws_msg = serde_json::json!({
|
||||
"type": "nvim_telemetry",
|
||||
"data": payload
|
||||
});
|
||||
let msg_str = ws_msg.to_string();
|
||||
|
||||
let senders: Vec<_> = nvim_udp_state
|
||||
.clients
|
||||
.read()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.values()
|
||||
.cloned()
|
||||
.collect();
|
||||
for tx in senders {
|
||||
let _ = tx.try_send(msg_str.clone());
|
||||
}
|
||||
|
||||
// 3. Event bus trigger for auto-save hook
|
||||
if payload.event == "BufWritePost"
|
||||
&& let Some(ref file_path) = payload.file
|
||||
{
|
||||
let normalized_file = file_path.replace("\\", "/");
|
||||
let topic = format!("nvim:save:{}", normalized_file);
|
||||
let event = crate::state::GenericEvent {
|
||||
topic,
|
||||
session_id: Some(payload.session_id.clone()),
|
||||
payload: serde_json::json!(&payload),
|
||||
};
|
||||
let _ = nvim_udp_state.handler.state.event_bus_tx.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let app = api::setup::create_router(app_state);
|
||||
|
||||
tracing::info!("MCP Memory Server running on http://127.0.0.1:3000/ws");
|
||||
|
||||
Reference in new issue
Block a user