MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / vault_embed

Method vault_embed

atomic-repository/src/repository/vault_embeddings.rs:51–143  ·  view source on GitHub ↗

Embed a single vault entry using the provided embedding function. Chunks the content by heading/paragraph, computes embeddings via `embed_fn`, and stores them in redb. Returns the number of chunks stored. Staleness detection: skips re-embedding if the content hash matches the existing stored hash.

(
        &self,
        path: &str,
        embed_fn: &F,
        config: &EmbedConfig,
    )

Source from the content-addressed store, hash-verified

49 /// Staleness detection: skips re-embedding if the content hash matches
50 /// the existing stored hash.
51 pub fn vault_embed<F>(
52 &self,
53 path: &str,
54 embed_fn: &F,
55 config: &EmbedConfig,
56 ) -> Result<usize, RepositoryError>
57 where
58 F: Fn(&str) -> Vec<f32>,
59 {
60 let entry = self
61 .vault_retrieve(path)?
62 .ok_or_else(|| RepositoryError::FileNotFound {
63 path: std::path::PathBuf::from(path),
64 })?;
65
66 let content = String::from_utf8_lossy(&entry.content_bytes);
67 let content_hash = entry.content_hash;
68
69 // Check staleness — if first chunk has same hash, skip
70 {
71 let txn = self
72 .pristine
73 .read_txn()
74 .map_err(|e| RepositoryError::Database(e.to_string()))?;
75 let still_current = txn
76 .get_vault_entry(path)
77 .map_err(|e| RepositoryError::Database(e.to_string()))?
78 .is_some_and(|current| {
79 current.entry_type == entry.entry_type
80 && current.content_hash == content_hash
81 && current.introduced_by == entry.introduced_by
82 });
83 if !still_current {
84 return Ok(0);
85 }
86 if let Ok(Some(existing)) = txn.get_embedding(path, 0) {
87 if existing.content_hash == content_hash {
88 return Ok(0); // Content unchanged, skip
89 }
90 }
91 }
92
93 // Chunk the content
94 let chunks = chunk_by_heading(&content, config.max_chunk_tokens);
95
96 // Compute vectors before opening the write transaction. This keeps the
97 // database lock short and gives us one final source validation before
98 // atomically replacing all derived chunks.
99 let mut records = Vec::new();
100 for (idx, chunk) in chunks.iter().enumerate() {
101 if chunk.text.trim().is_empty() {
102 continue;
103 }
104
105 let record = EmbeddingRecord {
106 vector: embed_fn(&chunk.text),
107 content_hash,
108 introduced_by: entry.introduced_by,

Callers 5

runMethod · 0.80
vault_embed_allMethod · 0.80
vault_auto_indexMethod · 0.80

Calls 13

chunk_by_headingFunction · 0.85
vault_retrieveMethod · 0.80
read_txnMethod · 0.80
write_txnMethod · 0.80
del_embeddingsMethod · 0.80
put_embeddingMethod · 0.80
commitMethod · 0.80
get_vault_entryMethod · 0.45
get_embeddingMethod · 0.45
iterMethod · 0.45
is_emptyMethod · 0.45
pushMethod · 0.45

Tested by 2