Merge pull request 'docs(clawhdf5): document DType variants, fix unresolved doc links' (#17) from sdlc-docs/clawhdf5-types-20260514-165210 into main
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
//! Search and agents_md methods for HDF5Memory.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::bm25;
|
||||
use crate::hybrid;
|
||||
use crate::{HDF5Memory, MemoryError, Result, SearchResult};
|
||||
|
||||
impl HDF5Memory {
|
||||
/// Perform hybrid search combining cosine vector similarity and BM25 keyword search.
|
||||
pub fn hybrid_search(
|
||||
&mut self,
|
||||
query_embedding: &[f32],
|
||||
query_text: &str,
|
||||
vector_weight: f32,
|
||||
keyword_weight: f32,
|
||||
k: usize,
|
||||
) -> Vec<SearchResult> {
|
||||
let bm25 = bm25::BM25Index::build(&self.cache.chunks, &self.cache.tombstones);
|
||||
let scored = hybrid::hybrid_search(
|
||||
query_embedding,
|
||||
query_text,
|
||||
&self.cache.embeddings,
|
||||
&self.cache.chunks,
|
||||
&self.cache.tombstones,
|
||||
&bm25,
|
||||
vector_weight,
|
||||
keyword_weight,
|
||||
k,
|
||||
);
|
||||
let mut results: Vec<SearchResult> = scored
|
||||
.into_iter()
|
||||
.map(|(idx, score)| {
|
||||
let w = self.cache.activation_weights[idx];
|
||||
SearchResult {
|
||||
score: score * w.sqrt(),
|
||||
chunk: self.cache.chunks[idx].clone(),
|
||||
index: idx,
|
||||
timestamp: self.cache.timestamps[idx],
|
||||
source_channel: self.cache.source_channels[idx].clone(),
|
||||
activation: w,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
results.sort_by(|a, b| {
|
||||
b.score
|
||||
.partial_cmp(&a.score)
|
||||
.unwrap_or(std::cmp::Ordering::Equal)
|
||||
});
|
||||
|
||||
let hit_indices: Vec<usize> = results.iter().map(|r| r.index).collect();
|
||||
self.apply_hebbian_boost(&hit_indices);
|
||||
self.flush().ok();
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
fn apply_hebbian_boost(&mut self, hit_indices: &[usize]) {
|
||||
for &idx in hit_indices {
|
||||
self.cache.activation_weights[idx] += self.config.hebbian_boost;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the chunk text for a memory entry by index.
|
||||
pub fn get_chunk(&self, index: usize) -> Option<&str> {
|
||||
if index < self.cache.chunks.len() && self.cache.tombstones[index] == 0 {
|
||||
Some(&self.cache.chunks[index])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate an AGENTS.md string from current memory state.
|
||||
pub fn generate_agents_md(&self) -> String {
|
||||
crate::agents_md::generate(&self.config, &self.cache, &self.sessions, &self.knowledge)
|
||||
}
|
||||
|
||||
/// Write AGENTS.md to disk alongside the .h5 file.
|
||||
pub fn write_agents_md(&self) -> Result<()> {
|
||||
let md = self.generate_agents_md();
|
||||
let md_path = self.config.path.with_extension("agents.md");
|
||||
std::fs::write(&md_path, md).map_err(MemoryError::Io)
|
||||
}
|
||||
|
||||
/// Read AGENTS.md from disk (if it exists).
|
||||
pub fn read_agents_md(path: &Path) -> Result<String> {
|
||||
let md_path = path.with_extension("agents.md");
|
||||
std::fs::read_to_string(&md_path).map_err(MemoryError::Io)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user