Standalone wisdom graph substrate for durable agent memory.
sophiagraph is a standalone wisdom graph substrate for durable agent memory.
The name comes from Greek Sophia (Σοφία), meaning wisdom; in this package it
frames durable knowledge as a graph of records, relations, provenance, trust,
and portable snapshots.
- Official GitHub:
https://github.com/openminion - Official website:
https://www.openminion.com - Official X account:
https://x.com/OpenMinion
sophiagraph has no official token, coin, NFT, airdrop, staking program,
treasury product, or investment offering. Any claim otherwise is unauthorized
and should be treated as a scam.
- Source code license:
Apache-2.0 - Brand/trademark grant:
none
The software license grants rights to use, modify, and redistribute the code. It does not grant rights to use the Sophiagraph, Sophiagraph Server, or OpenMinion names, logos, branding, website identity, or social identity except for truthful attribution. Forks, clones, and derivative distributions must not present themselves as the official Sophiagraph project or imply affiliation, endorsement, or maintenance by Sophiagraph or OpenMinion contributors unless that is actually true.
sophiagraph currently provides:
- canonical durable-memory models
- contract and provenance helpers
- query DTOs
- portability bundle models and codec helpers
- audit-event schemas
- trust and temporal primitives
- typed namespace DTOs for explicit tenant/user/agent/session isolation
- directed relation APIs with explicit incoming/outgoing/bidirectional lookup
- Obsidian-style structural document/link DTOs, Markdown/frontmatter adapter, addressable blocks, backlinks, outgoing links, local graph traversal, graph snapshots, deterministic graph algorithms, structural search DTOs, saved view evaluation, JSON Canvas DTOs, schema discovery, async facade helpers, and extension hooks
- a package-local SQLite durable engine
- a package-local in-memory backend for tests and ephemeral consumers
- a standalone smoke entrypoint for publish/install validation
- a typed vector-similarity metric registry (
cosine,L2,dot) and a backend-agnostic conformance harness (see docs/vector-conformance.md) - typed governance + observability event DTOs (write attempt/accepted,
retrieval, export, policy denial, lifecycle action, webhook delivery
attempt, retrieval explanation, quality eval signal) and deterministic
policy hook protocols in
sophiagraph.audit - typed lifecycle policy DTOs and a pure
evaluate_policy/apply_decision_to_record_metaengine for TTL, promotion, and archival transitions with cross-backendput_lifecycle_policy/get_lifecycle_policy/list_lifecycle_policies - typed
ArtifactRecordDTO + cross-backendput_artifact/get_artifact/list_artifactsfor multimodal artifact references with caller-supplied URI, sha256, MIME, source class, retention policy, and explicitderived_text_record_idlink (the package never OCRs, transcribes, or extracts claims from artifact content) - extended JSON Canvas DTOs (
CanvasNode.subpath/label,CanvasEdge.from_side/to_side/from_end/to_end) plus cross-backendput_canvas_board/get_canvas_board/list_canvas_boards/delete_canvas_boardwith deterministic changefeed emission; explicit caller-supplied relation-type policy for the optional canvas-edge → graph-relation mapping - local-first sync conflict DTOs, freshness ledger entries, and provider-neutral connector ingestion envelopes for idempotent replay
- shared memory-block attachment, mirror freshness, edit-conflict, and usage-audit primitives on top of the v1 memory-block store
- optional graph-backend adapter contracts with explicit export batches, capability discovery, normalized query results, and a provider-free fake adapter for conformance tests
- structural inspection reports and explicit repair candidates for unresolved links, orphan records, duplicate aliases, stale facts, broken source references, and open conflict queues
sophiagraph (this package) is the typed shape and deterministic
evaluator for governance and lifecycle. It exposes:
- typed event DTOs and audit recorder callbacks (
sophiagraph.audit.*), - deterministic policy hook evaluation (
evaluate_policy_hookswith short-circuit-on-first-deny semantics), - pure lifecycle policy evaluation (
evaluate_policyandapply_decision_to_record_meta), - typed
WebhookDeliveryAttemptEventso service/admin consumers can align on the event shape.
sophiagraph does NOT open HTTP connections, run cron schedulers,
or deliver webhooks. Those are the responsibility of
sophiagraph-server (the runtime service) and the host runtime. The
package supplies the typed contract; the service supplies the
operational behavior.
This package does not provide:
- application orchestration or gateway policy
- a full Obsidian clone, editor, sync service, or visual renderer
- provider/model routing
- session orchestration
- automatic link, tag, relation, entity, or summary inference from prose
- automatic file sync conflict resolution, connector payload interpretation, shared-block reconciliation, Text2Cypher generation, or semantic repair suggestions from prose
- implicit imports back into any host framework
- HTTP webhook delivery, scheduled job execution, or hosted admin UI
(those belong to
sophiagraph-serveror the host runtime) - semantic policy decisions inferred from freeform model output (policy
hooks must return typed
PolicyDecisioninstances with closed-enum reason codes)
Host frameworks remain the orchestrators. sophiagraph owns reusable durable
wisdom graph primitives and the standalone durable engine.
Editable install during local development:
python3.11 -m pip install -e .Wheel build:
python3.11 -m buildFresh-wheel smoke:
TMP_VENV="$(mktemp -d)/sophiagraph-venv"
python3.11 -m venv "$TMP_VENV"
"$TMP_VENV/bin/pip" install dist/sophiagraph-*.whl
"$TMP_VENV/bin/sophiagraph-smoke" --root /tmp/sophiagraph-release-smoke --seed --jsonSource-root smoke:
PYTHONPATH=src python3.11 -m sophiagraph --root /tmp/sophiagraph-smoke --seed --jsonInstalled-console-script smoke:
sophiagraph-smoke --root /tmp/sophiagraph-smoke --seed --jsonMinimal standalone flow for another framework or service:
from sophiagraph.models import MemoryNamespace, MemoryRecord
from sophiagraph.portability.models import MemoryBundleExportOptions, MemoryBundleImportOptions
from sophiagraph.query import ListQueryOptions, SearchQueryOptions
from sophiagraph.storage import create_memory_store, create_sqlite_store
store = create_sqlite_store("/tmp/sophiagraph-demo")
namespace = MemoryNamespace(
tenant_id="tenant-demo",
user_id="user-demo",
agent_id="demo",
graph_id="main",
)
store.put_record(
MemoryRecord(
id="rec-1",
scope="agent:demo",
type="fact",
key="project:apollo",
title="Apollo launch date",
content={"text": "Apollo launched in Q2"},
created_at="2026-05-22T00:00:00+00:00",
updated_at="2026-05-22T00:00:00+00:00",
source="validated",
confidence=0.95,
event_time="2026-05-22T00:00:00+00:00",
namespace=namespace,
)
)
namespace_filter = MemoryNamespace(agent_id="demo")
records = store.list_records(
ListQueryOptions(scopes=["agent:demo"], namespaces=[namespace_filter])
)
search_hits = store.search_records(
SearchQueryOptions(query="Apollo", scopes=["agent:demo"], namespaces=[namespace_filter])
)
snapshot = store.export_snapshot(
MemoryBundleExportOptions(scopes=["agent:demo"], namespaces=[namespace_filter])
)
import_store = create_memory_store()
import_store.import_snapshot(snapshot, MemoryBundleImportOptions())MCP-style host bridge without importing OpenMinion:
from dataclasses import asdict
from sophiagraph.adapters import McpMemoryRequest, SophiaGraphMcpAdapter
adapter = SophiaGraphMcpAdapter(store)
adapter.handle(McpMemoryRequest(operation="create", payload={"record": asdict(record)}))
adapter.handle(
McpMemoryRequest(
operation="search",
payload={"query": "Apollo", "scopes": ["agent:demo"], "limit": 5},
)
)Claude Code, Cursor, Windsurf, and other MCP hosts should wire this adapter
through their own MCP runtime package. sophiagraph supplies the structural
CRUD/search bridge; host-specific manifests, auth, process lifecycle, and
transport are owned by the host or an optional sibling adapter package.
Runnable example:
PYTHONPATH=src python3.11 examples/basic_usage.py
PYTHONPATH=src python3.11 examples/obsidian_substrate.pyThe SQLite backend configures each package-owned connection with:
PRAGMA journal_mode = walPRAGMA busy_timeout = 5000PRAGMA synchronous = normal
Writes use explicit transaction boundaries. This keeps a sibling reader, such as a local service process or a second host process, from blocking ordinary package writes under the common read-while-write SQLite case.
For production-like local use:
- create one store instance per process or worker, not one shared connection;
- expect SQLite's normal single-writer behavior even with WAL enabled;
- keep write transactions short and caller-owned payloads already structured;
- use
backup(...)for online copies instead of copying live*.sqlite3files.
SQLite backups are available through the store:
store = create_sqlite_store("/tmp/sophiagraph-demo")
store.backup("/tmp/sophiagraph-demo-backup.sqlite3")New durable tables should keep migrations deterministic, idempotent, and compatible with existing package stores.
Package stores expose append-only structural change events for durable mutation surfaces. Current events cover records, relations, links, candidates, tier transitions, and document blocks.
changes = store.list_changes(since_cursor=0, namespaces=[namespace_filter])
delta = store.export_delta(namespaces=[namespace_filter])
target_store.import_delta(delta)Change events carry caller-supplied structural payloads, namespace dimensions,
cursor order, and schema identifier strings such as node_label or
relation_type. sophiagraph does not infer event meaning from prose.
Records still accept the legacy scope string for compatibility. New
integrations can also attach typed namespace DTOs to records and use the same
typed dimensions for query/export/import boundaries:
from sophiagraph.models import MemoryNamespace
namespace = MemoryNamespace(
tenant_id="tenant-acme",
user_id="user-j",
agent_id="agent-codex",
session_id="session-123",
graph_id="main",
)
legacy_scope = namespace.to_scope("agent")
record = MemoryRecord(
id="rec-namespace",
scope=legacy_scope,
type="fact",
content={"text": "Namespace-safe records keep tenant and agent separate."},
created_at="2026-05-23T00:00:00+00:00",
updated_at="2026-05-23T00:00:00+00:00",
namespace=namespace,
)
records = store.list_records(
ListQueryOptions(scopes=[legacy_scope], namespaces=[MemoryNamespace(agent_id="agent-codex")])
)Namespace values must be explicit caller-provided identifiers. sophiagraph
does not infer tenant, user, project, or agent identity from prose. Existing
SQLite rows without namespace columns are migrated from their explicit legacy
scope value only; no content or title text is inspected.
Relations are explicit, typed, directed edges between records. Consumers can
list outgoing, incoming, or bidirectional edges through the direction option:
outgoing = store.list_relations("rec-1")
incoming = store.list_relations("rec-1", direction="in")
neighborhood = store.get_related_records(
"rec-1",
["agent:demo"],
direction="both",
)The package does not infer relation types from prose. Callers must submit relation records directly.
sophiagraph now has package-core surfaces for Obsidian-comparable structural
workflows:
KnowledgeDocumentwraps document-profileMemoryRecordnodes with path, title, aliases, content hash, namespace, timestamps, and provenance.StructuralLinkrepresents explicit wikilinks, Markdown links, embeds, property links, external URLs, unresolved targets, headings, and block refs.extract_markdown(...)parses frontmatter, aliases, tags, and explicit link syntax without modifying note prose.KnowledgeDocumentBlockrows represent explicit headings and^block-idanchors; stores exposeput_document_blocks(...)andlist_document_blocks(...).- Store backends expose
put_link(...),list_links(...),get_backlinks(...),get_outgoing_links(...),get_local_graph(...), andget_graph_snapshot(...). - SQLite structural search uses FTS5 record and block indexes when available and keeps a deterministic Python fallback for unsupported SQLite builds.
sophiagraph.queryexposes deterministic graph helpers for shortest paths, path evidence, connected components, and degree centrality over explicit graph snapshots.- Saved views evaluate deterministic filters, boolean groups, link predicates, grouping, sorting, projections, and summaries.
- JSON Canvas and extension hooks are package-local DTO/helper surfaces. They do not require a UI renderer or OpenMinion import.
Example:
from sophiagraph.adapters.markdown import extract_markdown
from sophiagraph.models import LinkResolutionCandidate, MemoryNamespace
from sophiagraph.query import LinkQueryOptions, LocalGraphOptions, shortest_path
namespace = MemoryNamespace(agent_id="demo", graph_id="main")
imported = extract_markdown(
"See [[Roadmap]].",
path="Index.md",
record_id="rec-index",
namespace=namespace,
resolver_candidates=[
LinkResolutionCandidate(
record_id="rec-roadmap",
path="Roadmap.md",
title="Roadmap",
namespace=namespace,
)
],
)
for link in imported.links:
store.put_link(link)
backlinks = store.list_links(LinkQueryOptions(record_id="rec-roadmap", direction="in"))
local_graph = store.get_local_graph(LocalGraphOptions(record_id="rec-index", depth=1))
path = shortest_path(local_graph, "rec-index", "rec-roadmap")The resolver contract is deliberately structural: explicit path first, then case-insensitive title/alias matching inside the namespace. Unresolved and ambiguous targets are preserved as first-class outcomes. Unlinked mentions are not persisted as graph edges.
Use sophiagraph.schema.describe_schema(...) to inspect current property-graph
labels, relation types, property keys, namespace dimensions, and property-type
conflicts from explicit records/relations/links/blocks.
The optional async facade wraps a sync store without adding provider or async database dependencies:
from sophiagraph.storage import async_store
async_facade = async_store(store)
record = await async_facade.get_record("rec-1")Current structural search uses deterministic matching with SQLite FTS5 candidate narrowing for record and block text when FTS5 is available. It is not yet a vector-backed or reranked retrieval engine. The hybrid retrieval roadmap owns the future vector/rerank design.
SophiaGraphSqliteStore opens a short-lived SQLite connection per method call.
That keeps alpha behavior simple and avoids hidden shared connection state. A
pooled or long-lived connection strategy should be introduced only with a
separate lifecycle/concurrency contract.
Some contract DTOs, including runtime snapshot/capsule/query shapes and
MemoryPatchResult, are retained for host-runtime adapters such as OpenMinion
and future service surfaces. They are compatibility contracts; package-local
stores are not required to instantiate every DTO.
sophiagraph must never import from host frameworks such as OpenMinion.
Dependency direction is one-way:
- allowed: host framework ->
sophiagraph - forbidden:
sophiagraph-> host framework
Stable top-level exports for external consumers:
sophiagraph.SophiaGraphSqliteStoresophiagraph.SophiaGraphMemoryStoresophiagraph.create_sqlite_store(...)sophiagraph.create_memory_store()sophiagraph.default_db_path(...)sophiagraph.auditsophiagraph.contractssophiagraph.portabilitysophiagraph.trustsophiagraph.coerce_temporal_dt
Supported import roots:
sophiagraphsophiagraph.modelssophiagraph.querysophiagraph.storagesophiagraph.portabilitysophiagraph.adapterssophiagraph.canvassophiagraph.extensionssophiagraph.viewssophiagraph.auditsophiagraph.trustsophiagraph.temporalsophiagraph.contracts
OpenMinion feeds typed, provenance-rich activity into Sophiagraph through a
direct-SDK submission path. The SubmissionEnvelope shape is pinned by
SUBMISSION_ENVELOPE_SCHEMA_VERSION = "openminion_sophiagraph_submission.v1"
so future MCP or REST transports can route the same payload without renaming
fields.
The direct-SDK path is the default OpenMinion integration; sophiagraph-server
service transports are opt-in for external clients or non-Python hosts.
Compatibility and deprecation policy:
API_COMPATIBILITY.md
Package-local release runbook:
RELEASING.mdscripts/release_check.py
