Entity Graph

Feature 6 min read Updated May 2026

Plain text search is great for "find me everything about Q2 fundraising". But sometimes you need to ask who depends on X? or which decisions reference the new pricing? — questions that are about relationships between entities, not about matching words.

GrooveOS keeps an entity graph alongside your team's memory. Every time something gets written to memory — a chat message, a meeting summary, a Drive document — the system extracts the entities mentioned (people, projects, decisions, dates) and the relationships between them. You query the graph from chat or from the API.

What's in the graph

The graph is built from two kinds of things:

The graph is team-scoped. Team A's graph is completely separate from Team B's — same isolation guarantees as the rest of GrooveOS.

Why a graph and not just search?

Some examples of questions a graph answers cleanly that plain search can't:

Search can hint at these answers; the graph gives you a clean, structured result. Behind the scenes, GrooveOS uses graphiti, an open-source temporal-graph engine on top of Neo4j.

How it gets built

You don't curate the graph. It builds itself, fail-soft:

  1. You (or the system) write something to memory — a chat message, a clip, a meeting summary.
  2. GrooveOS sends the content to the graph engine in the background.
  3. The engine extracts entities and relationships, resolves contradictions against existing facts, and saves time-bounded edges to your team's graph partition.

Graph ingest is never blocking

If the graph engine is slow or temporarily unavailable, your memory write still succeeds — the graph just catches up later. Plain-text search in memory works regardless of the graph state. The graph is an enrichment layer.

Querying from chat

The fastest way to use the graph is to ask a question naturally in LibreChat or Open WebUI. The chat surface routes graph-style questions to the right backend automatically:

You: who currently leads engineering at Acme?
xbrain: Bob has been Tech Lead of Acme Engineering since June 1, 2025.
        (Alice was Tech Lead from January to May 2025.)

You: which projects depend on the database migration?
xbrain: Three projects depend on it: payment-flow, audit-log, and crm-sync.
        The migration is owned by Alice and scheduled for July.

You don't need to mention "graph" — xbrain figures out when to use the graph and when to fall back to plain memory search.

Querying from the API

For programmatic use, the API exposes GET /v1/graph/neighbors. Given an entity name, it returns all directly-connected entities with the type and validity window of each relationship:

curl "https://api.grooveos.app/v1/graph/neighbors?entity=Alice" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Team-Scope: your-team"

# Returns:
{
  "entity": "Alice",
  "team_scope": "your-team",
  "neighbors": [
    {
      "name": "Acme.Engineering",
      "relationship": "WAS_TECH_LEAD",
      "valid_from": "2025-01-15",
      "valid_until": "2025-05-31"
    },
    {
      "name": "Q2-Fundraising",
      "relationship": "CONTRIBUTED_TO",
      "valid_from": "2025-03-01",
      "valid_until": null
    }
  ]
}

Pass ?depth=2 to also include neighbors-of-neighbors. The default is depth 1 (max 3).

Time-aware facts

A common knowledge-graph problem is that "Alice is the Tech Lead" eventually becomes wrong, but the old answer is still useful for past questions. GrooveOS handles this by giving every relationship a validity window (valid_from and valid_until):

// Two facts that look contradictory:
"Alice is Tech Lead." (recorded 2025-01-15)
"Bob is now Tech Lead. Alice moved to product." (recorded 2025-06-01)

// What the graph stores:
Alice -[WAS_TECH_LEAD: 2025-01-15 → 2025-05-31]→ Acme.Engineering
Bob   -[IS_TECH_LEAD:  2025-06-01 → now]→ Acme.Engineering

// Querying:
"who was Tech Lead in March 2025?" → Alice
"who is Tech Lead now?"            → Bob

Both facts coexist forever. The graph picks the one that matches the time you're asking about.

FAQ

Do I need to do anything to enable the graph?

No — it's on by default for every team. The first few memory writes after sign-up populate the graph automatically. You'll see the graph answer chat questions within minutes of getting started.

Can I see a visualisation of my team's graph?

A graph-explorer UI ships in v1.5 (under /account/teams/.../graph/). For now, the API surface and the chat questions are the supported entry points.

Can I edit graph entities directly?

Not yet. The graph is rebuilt from your memory items, so the way to "edit" it is to write a corrective memory item — e.g. promote a memory item to CANONICAL stating "Alice is the Tech Lead, not Bob". The next graph pass will create a corrective time-bounded edge.

Are entities shared across teams?

No. Each team has its own graph partition. Even if two teams both mention "Acme Corp", those are separate nodes — Team A's "Acme Corp" cannot reveal anything about Team B's.

What's next

Open-source graph engine

Under the hood, GrooveOS uses the open-source graphiti engine on top of Neo4j. Self-hosters can run the same setup from the xbrain Docker Compose stack — no managed-cloud dependency.