use anybytes::View;
use triblespace::core::blob::{Blob, BlobEncoding, TryFromBlob};
use triblespace::core::id::ExclusiveId;
use triblespace::core::inline::{Encodes, InlineEncoding};
use triblespace::core::metadata::{self, MetaDescribe};
use triblespace::core::trible::Fragment;
use triblespace::macros::id_hex;
use triblespace::prelude::*;
use triblespace_search::hnsw::HNSWBuilder;
use triblespace_search::schemas::{put_embedding, Embedding};
pub const DIM: usize = 768;
pub const DEFAULT_SCOPE_ID: Id = id_hex!("F6BE4C16A56001FEA03A5927C6ED3814");
pub mod golden {
use triblespace::prelude::*;
attributes! {
"18AD4630637E03D4A8214A7464D06AAC" as text_embedding: inlineencodings::Handle<super::Embedding768>;
"7415B83D46A1EDD8EE02BE1EBCEE6304" as image_embedding: inlineencodings::Handle<super::Embedding768>;
}
}
#[derive(Debug)]
pub enum EmbeddingDimError {
WrongLen { expected: usize, got: usize },
View(anybytes::view::ViewError),
}
impl std::fmt::Display for EmbeddingDimError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::WrongLen { expected, got } => {
write!(f, "embedding has {got} floats, expected {expected}")
}
Self::View(e) => write!(f, "embedding view: {e}"),
}
}
}
impl std::error::Error for EmbeddingDimError {}
pub struct Embedding768;
impl BlobEncoding for Embedding768 {}
impl MetaDescribe for Embedding768 {
fn describe() -> Fragment {
let id = id_hex!("D135AA8404D09D112E5BD206494190C4");
entity! { ExclusiveId::force_ref(&id) @
metadata::name: "Embedding768",
metadata::description: "768-d [f32] LE embedding blob in the shared nomic text+vision space (nomic-embed-{text,vision}-v1.5). L2-normalized; length-validated on read so it can never be mixed with another embedding dimension in one HNSW index.",
metadata::tag: metadata::KIND_BLOB_ENCODING,
}
}
}
impl TryFromBlob<Embedding768> for View<[f32]> {
type Error = EmbeddingDimError;
fn try_from_blob(b: Blob<Embedding768>) -> Result<Self, Self::Error> {
let floats = b.bytes.len() / 4;
if floats != DIM {
return Err(EmbeddingDimError::WrongLen {
expected: DIM,
got: floats,
});
}
b.bytes.view().map_err(EmbeddingDimError::View)
}
}
impl Encodes<Vec<f32>> for Embedding768
where
inlineencodings::Handle<Embedding768>: InlineEncoding,
{
type Output = Blob<Embedding768>;
fn encode(source: Vec<f32>) -> Blob<Embedding768> {
let mut bytes = Vec::with_capacity(source.len() * 4);
for v in &source {
bytes.extend_from_slice(&v.to_le_bytes());
}
Blob::new(bytes.into())
}
}
pub mod attr {
use super::*;
attributes! {
"BCDCA79081A84E7428A2D06A7F222313" unsafe as embedding: inlineencodings::Handle<super::Embedding768>;
}
}
pub const DIM_3584: usize = 3584;
pub struct Embedding3584;
impl BlobEncoding for Embedding3584 {}
impl MetaDescribe for Embedding3584 {
fn describe() -> Fragment {
let id = id_hex!("3A11703C58FD2E7DB78846565E8FEABB");
entity! { ExclusiveId::force_ref(&id) @
metadata::name: "Embedding3584",
metadata::description: "3584-d [f32] LE embedding blob in the nomic-embed-multimodal-7b dense space (Qwen2.5-VL LoRA; last-token pool, L2-normalized). Length-validated on read so it can never be mixed with another embedding dimension in one HNSW index.",
metadata::tag: metadata::KIND_BLOB_ENCODING,
}
}
}
impl TryFromBlob<Embedding3584> for View<[f32]> {
type Error = EmbeddingDimError;
fn try_from_blob(b: Blob<Embedding3584>) -> Result<Self, Self::Error> {
let floats = b.bytes.len() / 4;
if floats != DIM_3584 {
return Err(EmbeddingDimError::WrongLen {
expected: DIM_3584,
got: floats,
});
}
b.bytes.view().map_err(EmbeddingDimError::View)
}
}
impl Encodes<Vec<f32>> for Embedding3584
where
inlineencodings::Handle<Embedding3584>: InlineEncoding,
{
type Output = Blob<Embedding3584>;
fn encode(source: Vec<f32>) -> Blob<Embedding3584> {
let mut bytes = Vec::with_capacity(source.len() * 4);
for v in &source {
bytes.extend_from_slice(&v.to_le_bytes());
}
Blob::new(bytes.into())
}
}
pub mod attr_mm7b {
use super::*;
attributes! {
"1BFC43C63FE8A38BC09DB3144859F3FC" unsafe as embedding: inlineencodings::Handle<super::Embedding3584>;
}
}
pub fn nearest(
pairs: &[(Id, Vec<f32>)],
query: &[f32],
floor: f32,
) -> anyhow::Result<Vec<(f32, Id)>> {
type LocalHandle = Inline<inlineencodings::Handle<Embedding>>;
if pairs.is_empty() {
return Ok(Vec::new());
}
let dim = query.len();
let mut store = MemoryBlobStore::new();
let mut builder = HNSWBuilder::new(dim).with_seed(42);
let mut by_handle: std::collections::HashMap<LocalHandle, (Vec<Id>, Vec<f32>)> =
std::collections::HashMap::new();
for (eid, v) in pairs {
let lh = put_embedding(&mut store, v.clone())
.map_err(|e| anyhow::anyhow!("stage embedding: {e:?}"))?;
let is_new = !by_handle.contains_key(&lh);
let entry = by_handle
.entry(lh)
.or_insert_with(|| (Vec::new(), v.clone()));
entry.0.push(*eid);
if is_new {
builder
.insert(lh, v.clone())
.map_err(|e| anyhow::anyhow!("hnsw insert: {e:?}"))?;
}
}
let local_query = put_embedding(&mut store, query.to_vec())
.map_err(|e| anyhow::anyhow!("stage query: {e:?}"))?;
let idx = builder.build();
let reader = store
.snapshot()
.map_err(|e| anyhow::anyhow!("blob reader: {e:?}"))?;
let view = idx.attach(&reader);
let candidates = view
.candidates_above(local_query, floor)
.map_err(|e| anyhow::anyhow!("similarity search: {e:?}"))?;
let mut rows: Vec<(f32, Id)> = candidates
.into_iter()
.flat_map(|h| {
by_handle.get(&h).into_iter().flat_map(|(ids, v)| {
let cos: f32 = query.iter().zip(v.iter()).map(|(a, b)| a * b).sum();
ids.iter().copied().map(move |id| (cos, id))
})
})
.collect();
rows.sort_by(|a, b| {
b.0.partial_cmp(&a.0)
.unwrap_or(std::cmp::Ordering::Equal)
.then_with(|| a.1.cmp(&b.1))
});
Ok(rows)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn embedding768_roundtrips_and_rejects_wrong_dim() {
let v: Vec<f32> = (0..DIM).map(|i| i as f32 * 0.001).collect();
let blob = <Embedding768 as Encodes<Vec<f32>>>::encode(v.clone());
let back: View<[f32]> =
<View<[f32]> as TryFromBlob<Embedding768>>::try_from_blob(blob).unwrap();
assert_eq!(back.as_ref(), v.as_slice(), "768-d round-trips byte-exact");
let wrong: Vec<f32> = vec![0.0; 512];
let blob = <Embedding768 as Encodes<Vec<f32>>>::encode(wrong);
let err = <View<[f32]> as TryFromBlob<Embedding768>>::try_from_blob(blob);
assert!(
matches!(
err,
Err(EmbeddingDimError::WrongLen {
expected: 768,
got: 512
})
),
"wrong dimension is rejected on read"
);
}
#[test]
fn embedding3584_roundtrips_and_rejects_wrong_dim() {
let v: Vec<f32> = (0..DIM_3584).map(|i| i as f32 * 0.0001).collect();
let blob = <Embedding3584 as Encodes<Vec<f32>>>::encode(v.clone());
let back: View<[f32]> =
<View<[f32]> as TryFromBlob<Embedding3584>>::try_from_blob(blob).unwrap();
assert_eq!(back.as_ref(), v.as_slice(), "3584-d round-trips byte-exact");
let wrong: Vec<f32> = vec![0.0; DIM];
let blob = <Embedding3584 as Encodes<Vec<f32>>>::encode(wrong);
let err = <View<[f32]> as TryFromBlob<Embedding3584>>::try_from_blob(blob);
assert!(
matches!(
err,
Err(EmbeddingDimError::WrongLen {
expected: 3584,
got: 768
})
),
"wrong dimension is rejected on read"
);
}
fn unit(mut v: Vec<f32>) -> Vec<f32> {
let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
if n > 0.0 {
for x in &mut v {
*x /= n;
}
}
v
}
#[test]
fn nearest_ranks_by_cosine_and_respects_floor() {
let a = Id::new([1u8; 16]).unwrap();
let b = Id::new([2u8; 16]).unwrap();
let c = Id::new([3u8; 16]).unwrap();
let pairs = vec![
(a, unit(vec![1.0, 0.0, 0.0])),
(b, unit(vec![0.0, 1.0, 0.0])),
(c, unit(vec![0.9, 0.1, 0.0])),
];
let query = unit(vec![1.0, 0.0, 0.0]);
let ranked = nearest(&pairs, &query, 0.0).unwrap();
assert_eq!(ranked.first().unwrap().1, a, "A is the nearest");
let high = nearest(&pairs, &query, 0.5).unwrap();
assert!(
high.iter().all(|(_, id)| *id != b),
"floor drops orthogonal b"
);
assert!(high.iter().any(|(_, id)| *id == a), "floor keeps near a");
}
#[test]
fn nearest_preserves_duplicate_vectors_and_orders_ties_by_entity() {
let low = Id::new([1u8; 16]).unwrap();
let high = Id::new([2u8; 16]).unwrap();
let vector = unit(vec![1.0, 0.0, 0.0]);
let ranked = nearest(
&[(high, vector.clone()), (low, vector.clone())],
&vector,
0.0,
)
.unwrap();
assert_eq!(ranked, vec![(1.0, low), (1.0, high)]);
}
#[test]
fn nearest_empty_is_empty() {
let q = unit(vec![1.0, 0.0, 0.0]);
assert!(nearest(&[], &q, 0.0).unwrap().is_empty());
}
}