Slater Gets full-text BM25 indexing and Graphiti Support

rickkjp1 pts1 comments

GitHub - Hikari-Systems/graphiti-slater: Run Graphiti's temporal knowledge graph on Slater: the FalkorDB dialect, transported over Bolt. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search/

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

Uh oh!

There was an error while loading. Please reload this page.

Hikari-Systems

graphiti-slater

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

develop

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>6 Commits<br>6 Commits

docker-example

docker-example

src/graphiti_slater

src/graphiti_slater

tests

tests

.dockerignore

.dockerignore

.gitignore

.gitignore

README.md

README.md

pyproject.toml

pyproject.toml

View all files

Repository files navigation

graphiti-slater

Run Graphiti's temporal knowledge graph on<br>Slater.

Graphiti branches every query on driver.provider. Slater's Cypher surface is far<br>closer to FalkorDB's than to Neo4j's — it borrowed FalkorDB's vecf32(),<br>vec.cosineDistance() and db.idx.* namespace — so this adapter reports the<br>FalkorDB dialect and transports it over Bolt . Graphiti's own query strings run<br>unchanged; the adapter touches none of them.

from graphiti_core import Graphiti<br>from graphiti_slater import SlaterDriver

graphiti = Graphiti(graph_driver=SlaterDriver('bolt://slater:7687', 'graphiti', '…'))

For the stock Graphiti MCP server , which constructs its driver by name and offers no<br>hook, put a sitecustomize.py on PYTHONPATH:

from graphiti_slater import install<br>install()

and configure the server with database.provider: "neo4j" pointing at Slater. It builds<br>a SlaterDriver with no forking.

What the adapter actually does

Almost nothing, which is the point. Graphiti's writes come from<br>models/{nodes,edges}/*_db_queries.py and have no extension point, so anything Slater<br>cannot accept has to be fixed in Slater rather than papered over here. It has been. What<br>remains is five things.

Why

provider = FALKORDB<br>selects the branch whose Cypher Slater already speaks

SlaterSession<br>on the FalkorDB branch the bulk node save is a list of (query, params), which no Bolt session understands; and execute_write must not retry, because embeddings are generated inside the unit of work

search_interface<br>routes node similarity to the vector index (see below)

graph_operations_interface<br>respells node deletes for the writable layer (see below)

build_indices_and_constraints<br>verifies the schema instead of creating it

The FalkorDB operations classes are reused as-is. Nothing under<br>graphiti_core/driver/falkordb/operations/ imports the falkordb package — every<br>method does records, _, _ = await executor.execute_query(...) then dict access, which<br>neo4j.EagerResult and neo4j.Record both satisfy. The falkordb pip package is<br>deliberately not a dependency; FalkorDriver is never imported, because it hard-imports<br>that package at module scope.

Why node similarity is rerouted

Graphiti's FalkorDB node-similarity leg is a label scan that reads n.name_embedding as<br>a column and scores it inline. On Slater an indexed embedding is routed out of the<br>property record into the vector store, so a column read returns Null and that leg finds<br>nothing — measured, not assumed. db.idx.vector.queryNodes finds the same vectors<br>immediately, including ones written through the write delta moments earlier, so node<br>similarity goes through the index. It is also strictly faster than the scan it replaces.

The score scales differ and the conversion happens in the query: Slater's score is the<br>distance under the index metric, ascending; Graphiti's is (2 - cosineDistance) / 2,<br>descending.

The index ranks before the filters (group id, labels, timestamps) are applied, so the<br>adapter over-fetches (OVERSAMPLE) to keep recall. That cannot make a shortfall<br>impossible — it is inherent to index-then-filter — so very selective filters may still<br>return short.

Edge similarity is left alone. Slater's vector indexes are node-only, so an edge's<br>fact_embedding stays an ordinary column that reads back verbatim, and Graphiti's inline<br>vec.cosineDistance leg works exactly as written.

Fulltext: delegated, not overridden

Slater implements db.idx.fulltext.query{Nodes,Relationships} with the FalkorDB contract<br>Graphiti expects — the same two-argument call, the same YIELD node|relationship, score,<br>and score as BM25 ordered descending, which is what Graphiti's ORDER BY score DESC<br>relies on. So all four fulltext legs run Graphiti's own query unchanged, and hybrid search<br>fuses a real BM25 list with the similarity one.

Every leg sees writes immediately, with no consolidation in between. That needs Slater<br>>= 0.25.1 : relationships...

graphiti slater falkordb node query similarity

Related Articles