use anyhow::Result;
use rag_module::RagModule;
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.init();
println!("đ Testing Local Estate Search\n");
println!("{}", "=".repeat(60));
let home = std::env::var("HOME").expect("HOME environment variable not set");
let base_path = format!("{}/.escher", home);
let user_id = "a4d8c418-90e1-702a-64e8-604fc7b72f72";
println!("\nđ Path: {}", base_path);
println!("đ¤ User ID: {}", user_id);
println!("\nđĻ Step 1: Initializing RAG Module...");
let rag = RagModule::new(&base_path).await?;
rag.initialize().await?;
rag.set_user_context(user_id).await?;
println!(" â
RAG Module initialized");
println!(" đ Storage Mode: Dual (Embedded + Server Sync)");
println!(" đ Local: Fast searches from embedded storage");
println!(" đĄ Server: Automatic backup on writes");
println!("\nđ Step 2: Listing collections...");
let collections = rag.vector_store.list_collections().await?;
println!(" Found {} collections:", collections.len());
for collection in &collections {
println!(" - {}", collection);
}
let collection_name = "core_estate";
println!("\nđĻ Step 2.5: Ensuring '{}' collection exists...", collection_name);
if !collections.contains(&collection_name.to_string()) {
println!(" Creating collection '{}'...", collection_name);
rag.vector_store.create_collection(collection_name, 1024).await?;
println!(" â
Collection created/loaded");
} else {
println!(" â
Collection already exists");
}
println!("\nđ Step 3: Checking '{}' collection info...", collection_name);
if let Some(info) = rag.vector_store.get_collection_info(collection_name).await? {
println!(" â
Collection exists:");
println!(" - Name: {}", info.name);
println!(" - Vector size: {}", info.vector_size);
println!(" - Points count: {}", info.points_count);
} else {
println!(" â Collection '{}' not found!", collection_name);
return Ok(());
}
println!("\nđ Step 4: Listing documents from '{}'...", collection_name);
let docs = rag.vector_store.list_documents(collection_name, Some(5), None).await?;
println!(" Found {} documents (showing first 5):", docs.len());
for (i, doc) in docs.iter().enumerate() {
println!(" {}. ID: {}", i + 1, doc.id);
if let Some(metadata) = &doc.metadata.get("service") {
println!(" Service: {}", metadata);
}
}
println!("\nđ Step 5: Searching estate resources...");
let query = "list my ec2 instances";
println!(" Query: '{}'", query);
println!(" Collection: '{}'", collection_name);
let estate_options = rag_module::services::search_service::EstateSearchOptions {
resource_types: None, account_ids: None,
regions: None,
services: None, states: None,
environment: None,
application: None,
synced_after: None,
limit: Some(5),
score_threshold: Some(0.5),
include_metadata: true,
use_anonymous_ids: false,
};
let results = rag.search_service.search_estate_resources(
collection_name,
query,
estate_options,
None, user_id,
).await?;
println!("\nđ Search Results:");
println!("{}", "=".repeat(60));
if results.is_empty() {
println!("â No results found!");
} else {
println!("â
Found {} results:\n", results.len());
for (i, result) in results.iter().enumerate() {
println!("{}. Result:", i + 1);
if let Some(obj) = result.as_object() {
if let Some(id) = obj.get("id").and_then(|v| v.as_str()) {
println!(" ID: {}", id);
}
if let Some(score) = obj.get("score").and_then(|v| v.as_f64()) {
println!(" Score: {:.4}", score);
}
if let Some(service) = obj.get("service").and_then(|v| v.as_str()) {
println!(" Service: {}", service);
}
if let Some(resource_type) = obj.get("resourceType").and_then(|v| v.as_str()) {
println!(" Resource Type: {}", resource_type);
}
if let Some(region) = obj.get("region").and_then(|v| v.as_str()) {
println!(" Region: {}", region);
}
if let Some(account_id) = obj.get("accountId").and_then(|v| v.as_str()) {
println!(" Account: {}", account_id);
}
}
println!();
}
}
println!("{}", "=".repeat(60));
println!("\nđ Step 6: Verifying Dual Mode Architecture...");
if let Some(_dual_store) = rag.vector_store.as_any().downcast_ref::<rag_module::db::DualVectorStore>() {
println!(" â
Confirmed: Using DualVectorStore");
println!(" đ Search executed through search_estate_resources():");
println!(" â Query preprocessing & spell correction");
println!(" â BGE-M3 embedding generation");
println!(" â Vector search in LOCAL embedded storage (fast)");
println!(" â Privacy filtering & IAM checks");
println!(" â Results formatted as JSON");
println!("\n đž Write operations (if any):");
println!(" â Local embedded storage (immediate)");
println!(" â Remote server sync (automatic backup)");
} else if let Some(_embedded_store) = rag.vector_store.as_any().downcast_ref::<rag_module::db::EmbeddedQdrantVectorStore>() {
println!(" âšī¸ Using EmbeddedQdrantVectorStore only");
} else if let Some(_server_store) = rag.vector_store.as_any().downcast_ref::<rag_module::db::QdrantServerVectorStore>() {
println!(" âšī¸ Using QdrantServerVectorStore only");
} else {
println!(" â ī¸ Unknown vector store type");
}
println!("\n{}", "=".repeat(60));
println!("â
Test complete!");
println!("\nđĄ Summary:");
println!(" - Method: search_estate_resources() (user-facing API)");
println!(" - Storage: Dual mode (embedded + server sync)");
println!(" - Searches: Local embedded storage (milliseconds)");
println!(" - Writes: Dual (local + server backup)");
println!(" - Collections: Auto-discovered from filesystem");
println!(" - Results: {} matching resources", results.len());
Ok(())
}