use acktor::Message;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::llm::Embedding;
use crate::memory::error::{IndexError, MemoryError, StorageError};
#[derive(Debug)]
pub struct Chunk {
pub text: String,
pub start_line: u32,
pub end_line: u32,
pub embedding: Embedding,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResult {
pub path: String,
pub start_line: u32,
pub end_line: u32,
pub score: f32,
pub snippet: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), StorageError>)]
pub struct StorageWrite {
pub path: String,
pub content: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<Option<String>, StorageError>)]
pub struct StorageRead {
pub path: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), StorageError>)]
pub struct StorageDelete {
pub path: String,
}
#[derive(Debug, Message)]
#[result_type(Result<(), IndexError>)]
pub struct IndexInsert {
pub path: String,
pub source: String,
pub size: u64,
pub model: String,
pub chunks: Vec<Chunk>,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), IndexError>)]
pub struct IndexDelete {
pub path: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), IndexError>)]
pub struct EnsureVecReady {
pub dim: usize,
}
#[derive(Debug, Message)]
#[result_type(Result<Vec<SearchResult>, IndexError>)]
pub struct IndexSearch {
pub embeddings: Vec<Embedding>,
pub username: String,
pub agent_id: Uuid,
pub limit: usize,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), MemoryError>)]
pub struct FileOpWrite {
pub username: String,
pub agent_id: Uuid,
pub filename: String,
pub content: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<Option<String>, MemoryError>)]
pub struct FileOpRead {
pub username: String,
pub agent_id: Uuid,
pub filename: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<(), MemoryError>)]
pub struct FileOpDelete {
pub username: String,
pub agent_id: Uuid,
pub filename: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(Result<Vec<SearchResult>, MemoryError>)]
pub struct Search {
pub username: String,
pub agent_id: Uuid,
pub query: String,
}
#[derive(Debug, Clone, Message)]
#[result_type(())]
pub struct FileChanged {
pub rel_path: String,
}
#[cfg(test)]
mod tests {
use super::*;
use uuid::Uuid;
#[test]
fn storage_write_msg_fields() {
let msg = StorageWrite {
path: "alice/agent1/2026-03-31.md".to_string(),
content: "hello".to_string(),
};
assert_eq!(msg.path, "alice/agent1/2026-03-31.md");
assert_eq!(msg.content, "hello");
}
#[test]
fn file_op_write_msg_fields() {
let msg = FileOpWrite {
username: "alice".to_string(),
agent_id: Uuid::new_v4(),
filename: "2026-03-31.md".to_string(),
content: "hello".to_string(),
};
assert_eq!(msg.username, "alice");
}
#[test]
fn search_result_fields() {
let sr = SearchResult {
path: "alice/agent1/2026-03-31.md".to_string(),
start_line: 1,
end_line: 10,
score: 0.95,
snippet: "hello world".to_string(),
};
assert!(sr.score > 0.9);
}
#[test]
fn file_changed_msg_fields() {
let msg = FileChanged {
rel_path: "alice/agent1/x.md".to_string(),
};
assert_eq!(msg.rel_path, "alice/agent1/x.md");
}
#[test]
fn chunk_fields() {
use crate::llm::Embedding;
let chunk = Chunk {
text: "some text".to_string(),
start_line: 1,
end_line: 5,
embedding: Embedding(vec![0.0; 128]),
};
assert_eq!(chunk.start_line, 1);
assert_eq!(chunk.embedding.0.len(), 128);
}
}