Python API
The primary Python entry point is zaxy.core.MemoryFabric. It wires the event log, session manager, graph store, query router, embedding provider, metrics, and tracer. The MCP server uses the same underlying orchestration, so Python and MCP callers share behavior.
For the maintained classification of MCP tools, Python exports, CLI commands, Eventloom events, projection backend contracts, and benchmark artifact schemas (first frozen at v0.9 and kept current through 2.0), see API Inventory.
Create a fabric:
from zaxy import MemoryFabric
fabric = MemoryFabric()
await fabric.connect()
Append an event:
event = await fabric.append(
event_type="goal.created",
actor="planner",
payload={"title": "Ship memory integration"},
session_id="agent-1",
)
Initialize a workspace session with a durable genesis profile:
profile = await fabric.initialize_session(".", session_id="zaxy-default")
Query memory:
context = await fabric.query(
"Ship memory integration",
temporal_filter=None,
limit=5,
session_id="agent-1",
)
Returned context metadata includes Eventloom citations when available and score_explanation details for retrieval debugging. Score explanations include source weights, the matched query, query-expansion weights when applicable, and temporal scoring fields for as-of queries.
Query exact source chunks:
sources = await fabric.query_verbatim(
"Which transcript turn mentioned identity-preserving chunks?",
session_id="agent-1",
limit=5,
)
query_verbatim() reads the Eventloom log directly and does not require Neo4j. It returns raw document, transcript, or event payload chunks with eventloom://... citations and source metadata. Use it when the agent needs the exact text that produced a memory rather than a compact graph summary.
Ingest local project documents:
count = await fabric.ingest_documents(
"docs",
session_id="agent-1",
max_lines=80,
)
Document ingestion currently supports Markdown, plain text, and reStructuredText files. It skips hidden directories, chunks content by line range, writes document.indexed Eventloom events, and projects each chunk as a document entity. Retrieved document chunks cite their original file and starting line with file://path:line citations.
Document and transcript projection also emits a role-neutral neutral_substrate graph record with actor, artifact, action, time, source, quote, uncertainty, permission scope, candidate claim, and Eventloom source backpointer. Purpose-specific meanings such as legal_obligation, roadmap_commitment, customer_escalation, or churn_risk are projection views rebuilt from that neutral record, not labels written by ingestion.
Ingest a sanitized transcript:
count = await fabric.ingest_transcript(
[
{"role": "user", "content": "What did we decide?"},
{"role": "assistant", "content": "Use MMR for diversity."},
],
source="codex",
session_id="agent-1",
)
Transcript ingestion writes one transcript.turn event per non-empty turn. Secret-looking content is redacted before the event is appended, and redaction paths are retained on the event payload for auditability.
Assemble prompt-ready context:
assembly = await fabric.assemble_context(
"What did we decide about retrieval?",
session_id="agent-1",
replay_from_seq=1,
limit=5,
)
print(assembly.prompt)
Context assembly combines recent replayed events, ranked graph retrieval, and a reserved verbatim Eventloom source-recall lane. It is the first lifecycle API for building an LLM context window from durable session history, temporal graph memory, and exact cited source chunks. Returned context metadata includes assembly_lane so clients can distinguish graph context from verbatim source recall. The prompt begins with # Active Memory Working Set, a bounded deterministic projection of goals, decisions, tasks, artifacts, blockers, and cited source anchors. This gives the model task-relevant memory structure without injecting the whole event log or graph. assembly.assembly_policy records the policy in force for the call, and assembly.context_counts records graph, verbatim, and replay counts for observability. assembly.working_set exposes the same working-set items as structured data.
Run lifecycle hooks after a turn or subagent handoff:
next_context = await fabric.after_turn(
role="assistant",
content="Use MMR for diversity.",
session_id="agent-1",
query="retrieval decisions",
max_recent_events=20,
)
handoff = await fabric.handoff_bundle(
session_id="agent-1",
query="current goals and open tasks",
)
subagent = await fabric.cleanup_subagent(
parent_session_id="main",
subagent_session_id="worker-1",
summary="Indexed retrieval docs and found no blockers.",
)
after_turn preserves the turn as a transcript.turn event before assembling bounded context. handoff_bundle includes summary data, prompt-ready context, and Eventloom integrity status. cleanup_subagent records subagent.cleaned in the subagent session and returns a bundle the parent can import or inspect.
Record feedback for retrieved context:
contexts = await fabric.query("retention decisions", session_id="agent-1")
await fabric.record_context_feedback(
contexts[:2],
feedback="used",
session_id="agent-1",
actor="assistant",
importance=0.8,
)
Positive feedback (used or helpful) appends memory.reinforced events for the retrieved entity. Negative feedback (irrelevant) appends audit-only memory.feedback events and does not delete or decay existing memory. Feedback for packet_memory context preserves the packet projection citation plus source packet sequence/hash, provider path, and model when available.
Persist synthesis answer artifacts from Memory Checkout:
checkout = await fabric.checkout_memory(
"How much did I spend on bike expenses in total?",
session_id="agent-1",
purpose="review",
)
artifact_event = await fabric.record_synthesis_artifact(checkout, actor="assistant")
candidate = checkout.diagnostics["synthesis"]["answer_candidates"][0]
await fabric.record_synthesis_candidate(
checkout,
candidate=candidate,
outcome="used",
actor="assistant",
)
checkout_memory(..., purpose=...) accepts a preset name such as coding, review, release, security, research, support, product, sales, legal, executive, or coordinate, or a purpose object with role, task, risk, time horizon, expected action, evidence policy, retention policy, and ontology lens fields. The normalized profile is returned in the checkout payload and diagnostics so downstream feedback can distinguish memory that was useful for a release review from memory that was useful for implementation. The broader support/product/sales/legal/executive presets are project-local agent-work policies; they do not imply enterprise connectors, global permissions, or a full Company Brain product category. Checkout also enforces purpose suppress rules before projection: for example, coordinate checkout excludes worker-local pending, rejected, and stale unpromoted rows from current facts while reporting the suppressed counts and reasons in diagnostics.purpose_policy. Non-general purpose profiles also condition retrieval before projection. Zaxy adds deterministic emphasis terms from the profile's ontology lens, required evidence, expected action, and retention policy, selects a purpose-appropriate scoring profile, and raises the internal recall budget without increasing the visible prompt limit. The applied policy is reported in diagnostics.purpose_retrieval_policy, including the profile, emphasis terms, scoring profile, base recall limit, and resolved recall limit. Feedback templates produced by checkout include the normalized purpose profile when the profile is not general, and both record_context_feedback(..., purpose=..., outcome=...) and MCP memory_feedback(..., purpose, outcome) preserve that useful-for-what metadata in Eventloom. Reinforced memory projection keeps compact purpose and authority fields so future retrieval can distinguish accepted Coordinate state that supported a handoff from the same fact used for a code review or implementation step.
Operators can inspect that purpose layer without starting a graph backend:
zaxy memory purpose status --eventloom-path .eventloom
zaxy memory purpose lanes --eventloom-path .eventloom --json
zaxy memory purpose feedback --eventloom-path .eventloom --profile coordinate
These commands replay Eventloom only. They report the active purpose profile, checkout evidence-policy status, suppressed row counts and reasons, stale or missing evidence refresh suggestions, retained positive/negative consequence history, and Coordinate accepted parent state versus worker-local diagnostics. The same replay-only summary powers the local dashboard /api/purpose/status, /api/purpose/lanes, /api/purpose/feedback routes and the static Eventloom viewer Purpose panel.
record_synthesis_artifact appends memory.synthesis.artifact.created with a deterministic synthesis_artifact_v1 payload: query, checkout quality, purpose profile, slot plan, answer candidates, auditable ledger rows, support citations, source groups, snippets, and verification warnings. record_synthesis_candidate writes outcome events such as memory.synthesis.used, memory.synthesis.rejected, or memory.synthesis.corrected without mutating the source memory. Candidate and row-level evidence feedback also preserve the purpose profile that conditioned the checkout.
MCP clients use the same contract through memory_synthesis_artifact. The tool accepts the Memory Checkout payload directly. If a selected candidate is provided, outcome must be provided in the same call; helpful normalizes to used, while excluded records memory.evidence.excluded. Selected candidates are validated against diagnostics.synthesis.answer_candidates and persisted from the canonical checkout candidate so support ids cannot drift from the artifact. MCP clients can also call memory_synthesis_evidence for one diagnostics.synthesis.ledger_rows item when a specific cited row was used or excluded, preserving the row fact id, source group, citation, selected candidate, and reason as row-level feedback. Synthesis artifacts, answer candidates, ledger rows, and outcome feedback are projected into graph memory as typed entities and edges for later traversal.
For Coordinate, treat the same artifact as the proof packet for accepted-state composition:
coordinate_state = await fabric.coordinate_checkout(
"release-rc1",
include_diagnostics=True,
)
checkout = await fabric.checkout_memory(
"Compose the accepted release-rc1 findings into the handoff answer.",
session_id="release-rc1",
)
proof = await fabric.coordinate_record_synthesis_artifact(
"release-rc1",
checkout,
decision_scope="handoff",
handoff_id="release-rc1:handoff:9",
actor="coordinator",
)
The Coordinate checkout should show which rows are authoritative before the coordinator records a mission-scoped proof packet. It carries the coordinate purpose profile, which requires accepted parent state and treats worker-local pending findings as diagnostic unless explicitly included. The proof packet links the generic synthesis artifact to accepted findings, review events, promotion events, worker source events, optional handoff event refs, diagnostic pending rows, conflicts, and excluded duplicate, stale, or conflicting rows before promotion or handoff. Handoff-scoped proof packets require handoff_id and cite the matching handoff event sequence and hash.
Render first-run integration payloads:
from zaxy import render_agent_integration_template, render_handoff_adapter, render_mcp_client_config
config = render_mcp_client_config("claude-desktop", eventloom_path=".eventloom")
handoff_payload = render_handoff_adapter(handoff, "langgraph")
template = render_agent_integration_template("langgraph", session_id="agent-1")
render_mcp_client_config() supports claude-desktop, cursor, and vscode JSON fragments for local MCP setup. render_handoff_adapter() supports generic, langgraph, crewai, and autogen payload shapes without importing those frameworks.
Customize retrieval policy:
from zaxy.query import HTTPReranker, LateInteractionHTTPReranker, LexicalReranker, QueryRouter
router = QueryRouter(
fabric.graph,
scoring_profile="precision",
reranker=LexicalReranker(),
)
chunks = await router.query("auth decision rationale", session_id="agent-1")
Built-in scoring profiles are balanced, precision, recall, and temporal. Rerankers implement an async rerank(query, results, limit=...) method and receive fused, deduplicated graph candidates before final truncation. Use LexicalReranker for deterministic local reranking, HTTPReranker for local/self-hosted model endpoints, LateInteractionHTTPReranker for ColBERT-style token-interaction endpoints, or OpenAICompatibleReranker for OpenAI-compatible chat-completions reranking.
Replay a session:
replay = fabric.replay(session_id="agent-1", from_seq=0)
Invalidate a graph fact:
await fabric.invalidate(
entity_name="Ship memory integration",
entity_type="Goal",
invalid_at="2026-05-06T12:00:00Z",
)
Always close long-lived clients:
await fabric.close()
MemoryFabric validates inputs before writing events or querying the graph. Session IDs are passed through the same safety rules used by MCP. Payload size, query length, traversal depth, and limits are bounded in src/zaxy/security.py. At the durable EventLog.append boundary, payloads are also classified and common secret fields or secret-looking values are redacted before the event hash is sealed.
Lower-level modules are public enough for advanced integration but should be used carefully: EventLog for direct JSONL operations, extract for rule-based projection, projection backends for graph operations, QueryRouter for retrieval, and MemoryTracer for Pathlight spans. The plain install uses embedded LadybugDB; install zaxy-memory[neo4j] for the optional Neo4j sidecar and zaxy-memory[pathlight] for Pathlight tracing. Prefer MemoryFabric unless you are building tests, migrations, or specialized tooling.
For extractor and schema authoring, use the CLI helpers before editing production code:
zaxy extractor-template decision.recorded --entity-type decision --name-key title
zaxy schema-plan
Extractor templates validate event names and identifiers before rendering code. Schema migrations are named, checksum-addressed, and still applied through GraphStore.init_schema() so existing callers keep the same lifecycle.
Errors should be treated as operational signals. Validation errors normally mean the caller sent an unsafe session ID, oversized payload, invalid limit, or empty query. Graph errors usually mean the selected projection backend is unavailable, indexes are missing, or backend credentials are wrong. Event log errors usually mean filesystem permissions, lock contention, or integrity verification failed. In all cases, the Eventloom log should remain the recovery anchor: fix the environment, replay the log, and rebuild projections rather than inventing graph state by hand.
For long-running processes, create one fabric per service process and reuse it. Avoid constructing a new fabric for every query because each instance owns graph and tracer clients. Tests can instantiate directly with mocks, but production callers should use the lifecycle methods consistently.
Configuration comes from configuration.md. MCP behavior is in mcp.md. Graph details are in graph-schema.md. The quick install path is in README.md, and the public product overview is site/index.html.