visualize_memory_provenance() renders the ownership and data-flow story behind your memory — Tenant → User → Agent → Dataset → file, plus agent read/write access and agent-written sessions — to a self-contained HTML file.
Before you start:
- Complete Quickstart to understand basic operations
- Have some ingested data (the projection reads the relational database, so no graph backend is required)
Code in Action
include_memory=True to also fold in the extracted entities/relationships (from the relational nodes/edges tables) and link them back to the files they were extracted from.
Raw graph data
If you only need the projected graph data (in the same(nodes, edges) shape the renderer consumes) rather than HTML, call get_memory_provenance_graph():
Scoping in multi-tenant deployments
Both functions acceptscope_tenant_ids and scope_user_ids to restrict the projection to a tenant or user, and scope_dataset_ids to narrow it to the datasets the caller can read. In multi-tenant deployments you must pass a scope — an unscoped read returns every tenant’s actors, datasets, and files. A tenant scope alone still covers every dataset in the workspace, so for a tenant member who doesn’t administer the tenant also pass scope_dataset_ids; otherwise the graph shows datasets they hold no grant on, along with their files, agents, and sessions. When no scope is given the read is global, which is the intended behavior only for single-user / OSS installs where one user owns everything.
A third argument, scope_dataset_ids, narrows the projection further on top of whichever scope above applies. A tenant scope answers “which datasets exist in this workspace”, which is not the same question as “which datasets may this caller read” — every member of a tenant is in tenant scope. Pass the caller’s readable datasets (from get_all_user_permission_datasets(user, "read")) for any caller who does not administer the tenant:
scope_dataset_ids only ever narrows — it never widens a tenant or user scope, and an empty list means “this caller may read nothing”, which yields no dataset nodes rather than all of them. Everything the projection derives from datasets narrows with them: the files in those datasets, the ACL grant edges on them, the agents and sessions that worked on them, and the extracted memory when include_memory=True. It also narrows the actor layer — a role is kept only if it holds an ACL grant on an in-scope dataset, and a user only if they own an in-scope dataset, hold a direct grant on one, or belong to a role that does.
Passed without a tenant scope, scope_dataset_ids narrows the Tenant layer too: only the tenants the in-scope datasets belong to are projected, so an unrelated tenant’s name cannot appear in the graph.
Over HTTP
The HTTP endpointsGET /api/v1/schema/provenance (HTML) and GET /api/v1/schema/provenance/json (both take the query param include_memory) scope to the authenticated caller:
Full Example
This script ingests two documents into two datasets, then walks the ownership chain down to thementions edges that tie each memory node back to the file it came from, prints it as a tree, and renders the same projection to .artifacts/memory_provenance.html. Source: examples/guides/memory_provenance.py.
Memory provenance
Memory provenance
Graph Visualization
Render your knowledge graph to an interactive HTML file
Schema Inventory
Summarize the knowledge graph by semantic type