Coverage for src/lilbee/data/extract/backends/embedding.py: 100%
17 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-14 11:46 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-14 11:46 +0000
1"""lilbee's embedder exposed as a xberg plugin embedding backend.
3xberg's semantic chunker needs embeddings to detect topic boundaries. This routes
4them to lilbee's own embedder, so the same model vectorizes and splits chunks;
5without it xberg falls back to its bundled ONNX preset.
6"""
8from __future__ import annotations
10from typing import TYPE_CHECKING
12from lilbee.data.types import EmbeddingBackendName
14from .registry import BackendKind, XbergBinding, register_binding
16if TYPE_CHECKING:
17 from collections.abc import Callable
19 from lilbee.core.vectors import Vector
22class LilbeeEmbeddingBackend:
23 """Routes xberg's boundary-detection embeddings to lilbee's embedder.
25 ``embed_fn``/``dim_fn`` are read live, so an embedding-model swap needs no
26 re-registration. xberg calls these sync methods on its own worker threads.
27 """
29 def __init__(
30 self,
31 *,
32 embed_fn: Callable[[list[str]], list[Vector]],
33 dim_fn: Callable[[], int],
34 ) -> None:
35 self._embed_fn = embed_fn
36 self._dim_fn = dim_fn
38 def name(self) -> str:
39 return EmbeddingBackendName.LILBEE
41 def initialize(self) -> None: ...
43 def shutdown(self) -> None: ...
45 def dimensions(self) -> int:
46 return self._dim_fn()
48 def embed(self, texts: list[str]) -> list[Vector]:
49 return self._embed_fn(texts)
52register_binding(
53 XbergBinding(
54 kind=BackendKind.EMBEDDING,
55 name=EmbeddingBackendName.LILBEE,
56 enabled=lambda cfg: True,
57 make=lambda provider, cfg: LilbeeEmbeddingBackend(
58 embed_fn=provider.embed, dim_fn=lambda: cfg.embedding_dim
59 ),
60 )
61)