Skip to content

feat: Integrate VecLite as a native vector storage backend - #51

Merged
laxmanclo merged 10 commits into
vektori-ai:mainfrom
rithulkamesh:main
Apr 17, 2026
Merged

feat: Integrate VecLite as a native vector storage backend#51
laxmanclo merged 10 commits into
vektori-ai:mainfrom
rithulkamesh:main

Conversation

@rithulkamesh

@rithulkamesh rithulkamesh commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR introduces VecLite (via the veclite-db Python package) as a native Database Storage Provider for Vektori. This enables users to leverage VecLite's fast, embedded vector search capabilities seamlessly within the Vektori ecosystem.

Key Changes

  • New Storage Backend (veclite_backend.py): Implemented the VecLiteBackend which satisfies the StorageBackend interface. It utilizes veclite.VecLite() instances for fast vector similarity search (sentences.db, facts.db, episodes.db) while maintaining metadata state.
  • Factory Resolution (factory.py): Updated the storage factory to automatically resolve and initialize the VecLite backend when the configuration specifies storage_backend="veclite" or uses a veclite://<path> connection string.
  • Dependencies: Added veclite-db>=1.0.9 as an optional dependency in pyproject.toml.
  • Testing:
    • Added tests/unit/test_veclite_backend.py to verify vector insertion and cosine similarity search behavior.
    • Updated tests/unit/test_new_backends_factory.py to validate correct routing and path parsing for VecLite URLs.

How to test

You can now initialize a Vektori client using VecLite by passing the appropriate config:

from vektori.config import VektoriConfig
from vektori.storage.factory import create_storage
config = VektoriConfig(database_url="veclite://my_veclite_data")
backend = await create_storage(config)

Summary by CodeRabbit

  • New Features

    • Added support for a VecLite storage backend for vector search and persistence across sentences, facts, sessions and episodes.
  • Tests

    • Added unit tests for backend selection (config/URL) and core VecLite operations (initialize, upsert, search, lifecycle).
  • Chores

    • New optional install extra "veclite" (included in "all"); CI updated to install extras to enable VecLite.

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new VecLite storage backend implementation and tests, registers it in the storage factory, declares a veclite optional extra (veclite-db>=1.1.1), and updates CI to install extras including all.

Changes

Cohort / File(s) Summary
Dependency manifest
pyproject.toml
Added optional extra veclite = ["veclite-db>=1.1.1"] and included veclite-db>=1.1.1 in the all extra.
New backend implementation
vektori/storage/veclite_backend.py
Added VecLiteBackend implementing async persistence across multiple veclite DB files, in-memory joins, CRUD and vector search for sentences/facts/episodes, session/edge/episode↔fact management, user deletion, and datetime restoration; raises ImportError if veclite is missing.
Factory routing
vektori/storage/factory.py
Extended create_storage to instantiate VecLiteBackend when storage_backend == "veclite" or database_url starts with veclite://, deriving base path from the URL (defaults to veclite_data).
Unit tests
tests/unit/test_new_backends_factory.py, tests/unit/test_veclite_backend.py
Added tests for factory routing by name and URL (patching initialization) and an async integration-style test for sentence upsert/search that skips if veclite is unavailable.
CI workflow
.github/workflows/ci.yml
Changed install step to pip install -e ".[dev,all]" so CI installs expanded extras.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Factory
    participant VecLiteBackend as "VecLiteBackend\n(vektori/storage)"
    participant VecLiteDB as "veclite DB files"

    Client->>Factory: create_storage(config)
    Factory->>VecLiteBackend: instantiate(path)
    VecLiteBackend->>VecLiteDB: initialize() (open/create DB files)
    Client->>VecLiteBackend: upsert_sentences / insert_fact / search_*
    VecLiteBackend->>VecLiteDB: write embeddings/records / similarity query
    VecLiteDB-->>VecLiteBackend: results
    VecLiteBackend-->>Client: result objects
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

I’m a rabbit in code, nose twitching with glee,
Burrows of vectors now nested for me,
Sentences, facts, and episodes stored tight,
Hopping through searches by day and by night,
Hop—store—test—repeat: VecLite feels just right. 🐇✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: integrating VecLite as a native vector storage backend, which is reflected across all modified files including the new backend implementation, factory integration, tests, and dependency updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pyproject.toml`:
- Around line 33-39: Remove test-only packages "pytest" and "pytest-asyncio" and
the optional backend "veclite-db" from the core dependencies list (the top-level
dependencies array) so they are not installed for every user; ensure "pytest"
and "pytest-asyncio" remain only in the dev extras and "veclite-db" remains
under the [project.optional-dependencies] -> veclite extra. If you intend an
"all" extra to install every backend, add "veclite-db>=1.0.9" to that extra as
well so backends are optional unless explicitly requested.

In `@tests/unit/test_veclite_backend.py`:
- Around line 1-3: Remove the unused stdlib imports and stray whitespace-only
blank lines at the top of the test module: delete the unused imports (datetime,
timezone, os) from the import block and keep only the used import(s) like
pytest, and remove any blank lines that contain only spaces so there are no
trailing whitespace-only lines (also apply the same cleanup to the similar
import/blank-line region around lines 15-29).

In `@vektori/storage/factory.py`:
- Around line 78-86: The code currently checks URL heuristics before honoring an
explicit backend_key, so storage_backend="veclite" can be ignored when
database_url matches an earlier scheme; update the logic so that an explicit
backend_key wins: either move the branch that tests backend_key == "veclite" to
run before any database_url scheme checks, or split the condition so that if
backend_key == "veclite" you always instantiate VecLiteBackend(path) regardless
of database_url; reference backend_key, database_url and VecLiteBackend when
making the change so the explicit-key path is evaluated first.

In `@vektori/storage/veclite_backend.py`:
- Around line 105-111: The current stubbed method find_sentences_by_similarity
returns an empty list which silently disables paraphrase matching; replace that
behavior by either implementing a real fallback or raising a clear error: if
VecLite backend cannot perform paraphrase/similarity lookups yet, change
find_sentences_by_similarity to raise NotImplementedError (or a custom
BackendNotSupportedError) with a concise message like "VecLite backend does not
support paraphrase similarity lookups"; otherwise implement the fallback inside
find_sentences_by_similarity by computing embeddings for the input quotes,
querying the VecLite similarity/index API for matches above the threshold, and
returning the matched sentence strings — reference the
find_sentences_by_similarity method to locate where to make this change.
- Around line 438-445: delete_user currently only removes in-memory dict entries
(_sentences, _facts, _episodes, _sessions) but leaves persisted VecLite vectors
and related mappings (_edges, _fact_sources, _episode_facts) on disk; update
delete_user to collect all vector ids associated with the user, remove those ids
from the VecLite indices (call the VecLite index client/delete API or mark them
deleted), and delete entries from _edges, _fact_sources, and _episode_facts that
reference those ids; after removals, persist or flush the index and any
file-backed stores so on-disk state matches the in-memory deletions and return
the total removed count.
- Around line 30-53: The backend currently keeps metadata only in memory
(_sentences, _facts, _edges, _fact_sources, _sessions, _episodes,
_episode_facts) and never persists or reloads it in initialize() / close(),
causing lost joins across restarts; fix by serializing these structures to disk
(e.g., JSON files like sentences.json, facts.json, edges.json,
fact_sources.json, sessions.json, episodes.json, episode_facts.json inside
self.base_path) whenever closing or mutating, and load/validate them in
initialize() before using self._vec_sentences / self._vec_facts /
self._vec_episodes so IDs line up; ensure atomic writes (tmp file + rename) and
graceful handling of missing/corrupt files (recreate empty structures) and keep
file names and keys matching the in-memory dict/list shapes used by methods that
reference _sentences, _facts, _edges, _fact_sources, _sessions, _episodes, and
_episode_facts.
- Around line 89-103: The code currently calls _vec_sentences.search and then
post-filters results by user_id/agent_id/session_id/subject (using
_sentences.get and checks) which can drop most matches if the shared index's
top-N is dominated by other tenants; update the search logic in this method (and
the similar blocks at the other ranges you noted) to either (a) perform
per-scope partitioned searches when possible (e.g., call the vector index with a
tenant/agent/session-specific partition or namespace) or (b) implement an
iterative-expand-and-rerank strategy: repeatedly call _vec_sentences.search with
increasing candidate limits (or fetch all candidates) and accumulate filtered
matches from _sentences until you reach the desired limit or exhaust the index;
ensure you reference and preserve the existing distance computation (1.0 - sim)
and break when results length >= limit to avoid returning incomplete scoped
results.
- Around line 217-229: get_active_facts currently ignores the optional agent_id,
causing cross-agent reads; update get_active_facts (and the other fact-reading
method get_all_facts) to filter facts by agent when agent_id is provided by
adding a condition like (agent_id is None or f.get("agent_id") == agent_id) to
the list comprehension (while keeping the existing user_id and is_active checks)
so slicing/limit/offset behavior remains unchanged.
- Around line 57-65: In upsert_sentences, add a pre-loop check that sentences
and embeddings have the same length and fail fast if they don't: compare
len(sentences) and len(embeddings) before the for loop and raise a clear
exception (e.g., ValueError) including both lengths and any identifying context
(user_id/agent_id) so mismatched responses are not silently truncated by zip;
keep the rest of the logic (count, loop over sent/emb) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 76b83555-1b5e-4892-ba76-30511c3f74f9

📥 Commits

Reviewing files that changed from the base of the PR and between 2500816 and 791da2e.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • pyproject.toml
  • tests/unit/test_new_backends_factory.py
  • tests/unit/test_veclite_backend.py
  • vektori/storage/factory.py
  • vektori/storage/veclite_backend.py

Comment thread pyproject.toml Outdated
Comment thread tests/unit/test_veclite_backend.py Outdated
Comment thread vektori/storage/factory.py Outdated
Comment thread vektori/storage/veclite_backend.py Outdated
Comment thread vektori/storage/veclite_backend.py
Comment thread vektori/storage/veclite_backend.py Outdated
Comment thread vektori/storage/veclite_backend.py Outdated
Comment thread vektori/storage/veclite_backend.py
Comment thread vektori/storage/veclite_backend.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
vektori/storage/veclite_backend.py (2)

454-457: insert_fact_source lacks deduplication, unlike insert_episode_fact.

This method always appends without checking for existing links, while the similar insert_episode_fact method (lines 403-409) properly deduplicates. This inconsistency could lead to duplicate fact-source entries on retries.

♻️ Proposed fix for consistency with insert_episode_fact
     async def insert_fact_source(self, fact_id: str, sentence_id: str) -> None:
+        for link in self._fact_sources:
+            if link["fact_id"] == fact_id and link["sentence_id"] == sentence_id:
+                return
         link = {"fact_id": fact_id, "sentence_id": sentence_id}
         self._fact_sources.append(link)
         self._sync_relation(f"fs:{uuid.uuid4()}", link)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vektori/storage/veclite_backend.py` around lines 454 - 457, The
insert_fact_source method currently always appends a new link and can create
duplicates on retries; update insert_fact_source to mirror insert_episode_fact
by building the link {"fact_id": fact_id, "sentence_id": sentence_id"}, checking
if that link already exists in self._fact_sources before appending, and only
call self._sync_relation(f"fs:{uuid.uuid4()}", link) when you actually added the
link to avoid duplicate entries and duplicate sync calls. Ensure you reference
insert_fact_source and insert_episode_fact so the deduplication logic is
consistent between them.

346-350: insert_edges lacks deduplication.

The base interface contract specifies "ON CONFLICT DO NOTHING" but this implementation always appends, potentially creating duplicate edges. While edges are typically inserted once per session, repeated processing or retries could accumulate duplicates.

♻️ Proposed fix to add deduplication
     async def insert_edges(self, edges: list[dict[str, Any]]) -> int:
+        existing = {(e.get("source"), e.get("target"), e.get("type")) for e in self._edges}
+        count = 0
         for edge in edges:
+            key = (edge.get("source"), edge.get("target"), edge.get("type"))
+            if key in existing:
+                continue
             self._edges.append(edge)
+            existing.add(key)
             self._sync_relation(f"edge:{uuid.uuid4()}", edge)
-        return len(edges)
+            count += 1
+        return count
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vektori/storage/veclite_backend.py` around lines 346 - 350, insert_edges
currently always appends every edge (and calls _sync_relation with a fresh
uuid), causing duplicate edges; change it to deduplicate before appending by
computing a canonical representation (e.g., json.dumps(edge, sort_keys=True) or
equivalent) and tracking seen representations in a set, only appending and
calling _sync_relation for edges whose representation is not already present in
self._edges; also use a stable/deterministic key for _sync_relation (derived
from the canonical representation, e.g., a hash or uuid5) instead of
uuid.uuid4(), and return the number of edges actually inserted (unique adds)
rather than the input length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@vektori/storage/veclite_backend.py`:
- Around line 561-579: delete_user currently filters in-memory lists (_edges,
_fact_sources, _episode_facts) but does not remove corresponding persisted
entries in _vec_relations, leaving orphaned relation rows; fix by, after
collecting sentence_ids, fact_ids, episode_ids and after the existing in-memory
filters in delete_user, iterate through self._vec_relations.get_all() (guarded
by hasattr(self._vec_relations, "delete")), parse each meta JSON, and call
self._vec_relations.delete(rid) for relation ids whose prefix is "edge:", "fs:"
or "ef:" and whose parsed fields (source/target for edges, fact_id/sentence_id
for fs, episode_id/fact_id for ef) match the deleted id sets so persisted
relations are removed when their referenced entities were deleted.
- Around line 29-31: The test imports VecLiteBackend even when the optional
veclite-db package isn't installed; update the test to call
pytest.importorskip("veclite") before importing VecLiteBackend so the test is
skipped when the veclite module is missing, ensuring the import of
vektori.storage.veclite_backend.VecLiteBackend only happens after the
skip-check.

---

Nitpick comments:
In `@vektori/storage/veclite_backend.py`:
- Around line 454-457: The insert_fact_source method currently always appends a
new link and can create duplicates on retries; update insert_fact_source to
mirror insert_episode_fact by building the link {"fact_id": fact_id,
"sentence_id": sentence_id"}, checking if that link already exists in
self._fact_sources before appending, and only call
self._sync_relation(f"fs:{uuid.uuid4()}", link) when you actually added the link
to avoid duplicate entries and duplicate sync calls. Ensure you reference
insert_fact_source and insert_episode_fact so the deduplication logic is
consistent between them.
- Around line 346-350: insert_edges currently always appends every edge (and
calls _sync_relation with a fresh uuid), causing duplicate edges; change it to
deduplicate before appending by computing a canonical representation (e.g.,
json.dumps(edge, sort_keys=True) or equivalent) and tracking seen
representations in a set, only appending and calling _sync_relation for edges
whose representation is not already present in self._edges; also use a
stable/deterministic key for _sync_relation (derived from the canonical
representation, e.g., a hash or uuid5) instead of uuid.uuid4(), and return the
number of edges actually inserted (unique adds) rather than the input length.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b09253bd-0808-4422-a784-3fd5b91b4df6

📥 Commits

Reviewing files that changed from the base of the PR and between 791da2e and ed9b66b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • pyproject.toml
  • tests/unit/test_veclite_backend.py
  • vektori/storage/factory.py
  • vektori/storage/veclite_backend.py
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (2)
  • vektori/storage/factory.py
  • tests/unit/test_veclite_backend.py

Comment thread vektori/storage/veclite_backend.py
Comment thread vektori/storage/veclite_backend.py
@laxmanclo

Copy link
Copy Markdown
Contributor

Hey @rithulkamesh, thanks so much for this contribution! The code looks really solid and the integration with the factory pattern and StorageBackend interface is super clean.

there is one minor issues that should be fixed before merging:
I looked into the CodeRabbit warning and it's definitely a valid edge case. Since the relations (like _edges) are only removed from the in-memory lists but not the physical _vec_relations database, they'll magically reload as ghost data if the Vektori server restarts. We need to make sure those get swept from the physical .db file too so user data is permanently deleted.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
vektori/storage/veclite_backend.py (1)

319-328: ⚠️ Potential issue | 🟠 Major

find_fact_by_text still ignores agent_id.

get_active_facts was updated at line 300 to filter by agent_id, but this method — which is used for write-time dedup — was not. Two agents writing the same fact text for the same user will dedupe against each other, breaking (user_id, agent_id) isolation and causing one agent to silently adopt the other agent's fact row.

🔐 Suggested fix
     async def find_fact_by_text(
         self,
         user_id: str,
         text: str,
         agent_id: str | None = None,
     ) -> dict[str, Any] | None:
         for f in self._facts.values():
-            if f.get("user_id") == user_id and f.get("text") == text and f.get("is_active", True):
+            if (
+                f.get("user_id") == user_id
+                and f.get("text") == text
+                and f.get("is_active", True)
+                and (agent_id is None or f.get("agent_id") == agent_id)
+            ):
                 return f
         return None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vektori/storage/veclite_backend.py` around lines 319 - 328, The
find_fact_by_text method currently ignores agent_id and thus can dedupe facts
across agents; update the loop in find_fact_by_text to also compare
f.get("agent_id") (treating None appropriately) against the agent_id parameter
and only return when user_id, text, is_active, and agent_id match; ensure the
function signature (find_fact_by_text) and callers that pass agent_id still work
and that agent_id=None behavior mirrors get_active_facts' filtering logic.
🧹 Nitpick comments (1)
tests/unit/test_veclite_backend.py (1)

1-44: Add tests for the two fixes this PR advertises.

The PR description highlights (1) durability via VecLite-backed metadata and (2) the ghost-data fix where relation deletes are now swept from relations.db on delete_user. Neither is exercised here — the only test covers the happy-path of upsert_sentences + search_sentences. Without regression coverage, a future refactor can silently reintroduce the exact bugs this PR closed.

Worth adding, at minimum:

  • A restart-persistence test: open VecLiteBackend(path), upsert sentences/facts/edges, close(), open a fresh instance at the same path, call initialize(), assert _sentences / _facts / _edges / _fact_sources / _episode_facts are repopulated and search_sentences still returns the record.
  • A delete_user cascade test: seed sentences + facts + an edge + a fact_source + an episode_fact, call delete_user, then reopen the backend and assert there are no ghost edge: / fs: / ef: / sess: rows in _vec_relations.get_all().

Want me to draft those two tests?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/test_veclite_backend.py` around lines 1 - 44, Add two new async
tests using VecLiteBackend: (1) restart-persistence: create
VecLiteBackend(path=temp_dir), call initialize(), upsert
sentences/facts/edges/fact_sources/episode_facts using existing methods (e.g.
upsert_sentences and whatever upsert_* helpers exist), close() then create a
fresh VecLiteBackend at same path, call initialize(), and assert internal maps
_sentences/_facts/_edges/_fact_sources/_episode_facts are repopulated and
search_sentences returns the previously inserted sentence; (2) delete_user
cascade: seed sentences, facts, an edge, a fact_source and an episode_fact for a
user, call delete_user(user_id), then reopen backend (initialize()) and assert
_vec_relations.get_all() contains no rows starting with the relation prefixes
"edge:", "fs:", "ef:", or "sess:" (and that corresponding
_edges/_fact_sources/_episode_facts/_sentences entries are removed). Ensure
tests use the same temp_dir fixture and close() between reopenings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@vektori/storage/veclite_backend.py`:
- Around line 587-608: The loop mutates self._vec_relations while iterating
self._vec_relations.get_all(), which can invalidate the iterator; instead, first
build a list/set of relation IDs to remove by iterating get_all() and checking
the same conditions (use sentence_ids, fact_ids, episode_ids ->
sent_set/fact_set/ep_set and inspect rid, meta_str, data), then after the
iteration complete call self._vec_relations.delete(rid) for each collected id;
keep the same rid prefixes ("edge:", "fs:", "ef:") and JSON parsing logic but
perform deletions only after collecting matching rids.

---

Duplicate comments:
In `@vektori/storage/veclite_backend.py`:
- Around line 319-328: The find_fact_by_text method currently ignores agent_id
and thus can dedupe facts across agents; update the loop in find_fact_by_text to
also compare f.get("agent_id") (treating None appropriately) against the
agent_id parameter and only return when user_id, text, is_active, and agent_id
match; ensure the function signature (find_fact_by_text) and callers that pass
agent_id still work and that agent_id=None behavior mirrors get_active_facts'
filtering logic.

---

Nitpick comments:
In `@tests/unit/test_veclite_backend.py`:
- Around line 1-44: Add two new async tests using VecLiteBackend: (1)
restart-persistence: create VecLiteBackend(path=temp_dir), call initialize(),
upsert sentences/facts/edges/fact_sources/episode_facts using existing methods
(e.g. upsert_sentences and whatever upsert_* helpers exist), close() then create
a fresh VecLiteBackend at same path, call initialize(), and assert internal maps
_sentences/_facts/_edges/_fact_sources/_episode_facts are repopulated and
search_sentences returns the previously inserted sentence; (2) delete_user
cascade: seed sentences, facts, an edge, a fact_source and an episode_fact for a
user, call delete_user(user_id), then reopen backend (initialize()) and assert
_vec_relations.get_all() contains no rows starting with the relation prefixes
"edge:", "fs:", "ef:", or "sess:" (and that corresponding
_edges/_fact_sources/_episode_facts/_sentences entries are removed). Ensure
tests use the same temp_dir fixture and close() between reopenings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fdaf656b-e6b2-477a-988a-8c35a2c11d90

📥 Commits

Reviewing files that changed from the base of the PR and between 830258a and db132ba.

📒 Files selected for processing (2)
  • tests/unit/test_veclite_backend.py
  • vektori/storage/veclite_backend.py

Comment thread vektori/storage/veclite_backend.py
Comment thread vektori/storage/veclite_backend.py Outdated
@laxmanclo
laxmanclo merged commit 0cace05 into vektori-ai:main Apr 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants