"""Vector storage and retrieval with USearch.""" import numpy as np from usearch.index import Index def embedding_store_usearch(path: str, ids: list, embeddings: list, dim: int = 384) -> int: """Crea o sobreescribe un indice USearch con los embeddings dados. Args: path: Path del archivo .usearch para persistir el indice. ids: Lista de IDs (int) para cada embedding. embeddings: Lista de arrays numpy float32. dim: Dimension de los embeddings (default 384 para e5-small). Returns: Numero de embeddings insertados. Raises: OSError: Si no se puede escribir en el path. """ index = Index(ndim=dim, metric="ip", dtype="f32") keys = np.array(ids, dtype=np.uint64) vecs = np.array(embeddings, dtype=np.float32) index.add(keys, vecs) index.save(path) return len(ids) def embedding_search_usearch(path: str, query_embedding: list, k: int = 10, dim: int = 384) -> list: """Busca los k vecinos mas cercanos en un indice USearch persistido. Args: path: Path del archivo .usearch. query_embedding: Array numpy float32 del query. k: Numero de resultados a retornar. dim: Dimension de los embeddings. Returns: Lista de dicts con 'key' y 'distance' ordenados por cercania. Raises: OSError: Si el archivo no existe. """ index = Index(ndim=dim, metric="ip", dtype="f32") index.load(path) q = np.asarray(query_embedding, dtype=np.float32) results = index.search(q, k) keys = np.atleast_1d(results.keys) distances = np.atleast_1d(results.distances) return [{"key": int(keys[i]), "distance": float(distances[i])} for i in range(len(keys))]