mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-09-02 17:49:20 +00:00
refactor: replace LanceDB Database decorator with VectorStore composition
Instead of wrapping all ~80 Database trait methods in a 664-line decorator (lancedb_wrapper.rs), introduce a 4-method VectorStore trait that any vector backend can implement. Workspace composes FTS from the database with vector search from the external store via RRF fusion. - Add src/workspace/vector_store.rs with VectorStore trait - Rewrite lancedb_store.rs to implement VectorStore (not wrap Database) - Delete src/db/lancedb_wrapper.rs (664 lines removed) - Remove get_chunk_by_id from Database trait and all backends - Workspace gains with_vector_store() builder for optional composition - Fix LanceDB tests: bypass_vector_index() for brute-force search - Fix integration tests: use temp file DB (libSQL :memory: is per-connection) - Merge duplicate mod tests in config.rs Net: -724 lines. Adding a new vector backend requires 4 methods, not 80. Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
+12
-12
@@ -378,7 +378,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
#[cfg(feature = "libsql")]
|
||||
let mut libsql_db: Option<std::sync::Arc<libsql::Database>> = None;
|
||||
|
||||
let mut inner_db: Option<Arc<dyn ironclaw::db::Database>> = if cli.no_db {
|
||||
let db: Option<Arc<dyn ironclaw::db::Database>> = if cli.no_db {
|
||||
tracing::warn!("Running without database connection");
|
||||
None
|
||||
} else {
|
||||
@@ -435,8 +435,8 @@ async fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
// Optionally wrap with LanceDB vector store for workspace semantic search
|
||||
let db: Option<Arc<dyn ironclaw::db::Database>> = if let Some(inner) = inner_db.take() {
|
||||
// Create optional external vector store for workspace semantic search
|
||||
let vector_store: Option<Arc<dyn ironclaw::workspace::VectorStore>> = {
|
||||
#[cfg(feature = "lancedb")]
|
||||
{
|
||||
if config.database.vector_backend == ironclaw::config::VectorBackend::LanceDb {
|
||||
@@ -449,12 +449,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("LanceDB: {}", e))?;
|
||||
tracing::info!("LanceDB vector store connected for workspace search");
|
||||
Some(Arc::new(ironclaw::db::lancedb_wrapper::DbWithLanceVectorStore::new(
|
||||
inner,
|
||||
Arc::new(store),
|
||||
)) as Arc<dyn ironclaw::db::Database>)
|
||||
Some(Arc::new(store) as Arc<dyn ironclaw::workspace::VectorStore>)
|
||||
} else {
|
||||
Some(inner)
|
||||
None
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "lancedb"))]
|
||||
@@ -463,12 +460,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
anyhow::bail!(
|
||||
"VECTOR_BACKEND=lancedb requires the 'lancedb' feature. Build with: cargo build --features lancedb"
|
||||
);
|
||||
} else {
|
||||
Some(inner)
|
||||
}
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Post-init operations using the database
|
||||
@@ -761,6 +755,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
if let Some(ref emb) = embeddings {
|
||||
workspace = workspace.with_embeddings(emb.clone());
|
||||
}
|
||||
if let Some(ref vs) = vector_store {
|
||||
workspace = workspace.with_vector_store(vs.clone());
|
||||
}
|
||||
let workspace = Arc::new(workspace);
|
||||
tools.register_memory_tools(workspace);
|
||||
}
|
||||
@@ -1265,6 +1262,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
if let Some(ref emb) = embeddings {
|
||||
ws = ws.with_embeddings(emb.clone());
|
||||
}
|
||||
if let Some(ref vs) = vector_store {
|
||||
ws = ws.with_vector_store(vs.clone());
|
||||
}
|
||||
Some(Arc::new(ws))
|
||||
} else {
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user