agntz
RuntimeHostedSelf-hostDocsChangelog
Sign inQuickstart
Documentation
View .mdOptimized for LLMs — paste directly into ChatGPT, Claude, or Cursor.

Memory with memrez

memrez is the durable memory resource for agntz agents. It stores tagged facts, preferences, events, and summaries under namespace scopes, then exposes memory to LLM agents through the generic resources: system.

It is not session history. It is not the legacy contextIds scratchpad. memrez is long-lived resource state guarded by runtime context namespace grants.

Install

pnpm add @agntz/memrez

The TypeScript package is published as @agntz/memrez. The Python package exports matching core storage and provider primitives from agntz.memrez, agntz.memrez_llm_reasoner, agntz.memrez_sqlite, agntz.memrez_postgres, and agntz.memrez_provider.

Declare a memory resource

agents/support-with-memory.yaml
id: support-with-memory
name: Support with Memory
kind: llm
model:
  provider: openai
  name: gpt-5.4
instruction: |
  Help the user. Use memory when it is relevant, and write only stable facts or preferences.
resources:
  memory:
    mode: read-write
    autoScan: true

When this agent runs, the memory provider can add visible topic summaries to the prompt and expose tools named memory_read and memory_write.

Use mode: read when an agent may read memory but must not write it. In read mode, the write tool is not registered.

Wire the provider

index.ts
import { agntz } from "@agntz/sdk";
import { createMemrez, SqliteMemoryStore } from "@agntz/memrez";

const memrez = createMemrez({
  store: new SqliteMemoryStore("./memory.db"),
});

const client = await agntz({
  agents: "./agents",
  resources: { memory: memrez.provider() },
});

The key in resources: { memory: ... } is the provider kind. It must match the manifest resource kind. If the manifest omits kind, the resource name is used as the kind.

Run with namespace grants

Pass context from trusted application code. Do not ask the model to pick a namespace.

await client.agents.run({
  agentId: "support-with-memory",
  input: "Remember that I prefer metric units.",
  context: ["app/user/" + userId],
});

The memory tools receive the normalized grant list. A write can only land inside a writable scope allowed by those grants and the memory write policy.

Read and write directly

You can also use memrez outside an agent, which is useful for tests, backfills, and admin jobs.

const grants = ["app/user/" + userId];

await memrez.write(grants, "Prefers metric units.", {
  topicsHint: ["preferences"],
});

const entries = await memrez.read(grants, "preferences", { limit: 10 });

Direct calls use the same grant validation as resource tool calls.

Storage options

StoreTypeScriptPythonUse case
In-memoryInMemoryMemoryStoredefault create_memrez() storeTests and demos
SQLiteSqliteMemoryStoreSqliteMemoryStoreLocal apps and single-node deployments
PostgresPostgresMemoryStorePostgresMemoryStoreMulti-process and hosted deployments
import { createMemrez, PostgresMemoryStore } from "@agntz/memrez";

const memrez = createMemrez({
  store: new PostgresMemoryStore(process.env.DATABASE_URL!),
});

Auto-scan

autoScan: true lets the provider inject a small list of visible memory topics before the model starts tool calling.

## Resource: memory
Memory topics visible to this run:
- preferences (3) - durable user preferences
- billing (1)

Set autoScan: false when you want the model to discover memory only through explicit memory_read calls.

Preload

Agent resource config controls what memory is inlined into the run context. Topic taxonomy and reasoner policy belong to Memrez-level configuration, not the agent manifest.

resources:
  memory:
    kind: memory
    mode: read-write

    preload:
      core: true
      topics: [goals, equipment]
      limit: 30
      maxChars: 10000
      types: [fact, preference, summary]

Omit preload when you only want topic summaries and explicit memory_read calls. Use preload.core: true to include the Memrez core topic, and preload.topics for additional topic slices. preload.limit caps entries, preload.maxChars caps rendered context, and preload.types filters entry types.

The shorthands preload: true, preload: all, and preload: [goals, equipment] are still supported. Prefer the object form for new agents.

Do not set resources.memory.topics in an agent manifest. The memrez resource provider rejects agent-level topic taxonomy config; agents should choose preload slices, while memrez owns tagging policy.

Write policy

By default, memrez writes to the current grant or one of its descendants. It does not promote writes to ancestors unless configured.

resources:
  memory:
    mode: read-write
    writePolicy:
      descendants: true
      ancestorPromotion: none

Use ancestor promotion only for trusted agents that are designed to curate shared memory. Normal user-facing agents should receive narrow grants such as app/user/u_123.

Reasoning layer

memrez uses a reasoner to organize memory writes — choosing topics, entry type, normalized content, and target namespace — and to curate scopes. By default createMemrez({ store }) and create_memrez(store=...) wire a built-in LLM reasoner that makes direct model calls, keyed from your provider env var (e.g. OPENAI_API_KEY). That is why the agent's memory_write tool takes content only: filing the entry is memrez's job, not the agent's.

Override the reasoner when you want different models, or no LLM at all for tests / emergency fallback:

import {
  createMemrez,
  llmReasoner,
  DeterministicReasoner,
} from "@agntz/memrez";

createMemrez({ store, reasoner: llmReasoner({ taggerModel: { provider: "anthropic", name: "claude-haiku-4-5" } }) });
createMemrez({ store, reasoner: new DeterministicReasoner() }); // no LLM (tests / kill-switch)
from agntz.memrez import DeterministicReasoner, create_memrez
from agntz.memrez_llm_reasoner import ReasonerModelConfig, llm_reasoner

create_memrez(
    store=store,
    reasoner=llm_reasoner(
        tagger_model=ReasonerModelConfig(provider="anthropic", name="claude-haiku-4-5")
    ),
)
create_memrez(store=store, reasoner=DeterministicReasoner())  # no LLM (tests / kill-switch)

memrez does not run its tagger or curator through the agntz agent loop yet. Those steps are bounded structured model calls owned by memrez, which avoids circular setups where memory writes invoke agents that can themselves use memory.

The reasoner may propose a namespace, but memrez validates it before writing. The model cannot bypass the grant boundary.

Curation

Curation is a memrez capability, not an agent manifest feature. Embedded apps can call memrez.curate(grants) directly or inspect dirty work with memrez.store.listDirtyTopics(). The Agntz worker can run periodic sweeps when MEMREZ_CURATE_INTERVAL is set, for example 30m or 1h. Leave that env var unset when you want to trigger curation from your own scheduler or admin job.

Hosted use

Hosted workers accept the same run-time context field over the HTTP API and hosted clients. The deployment decides which resource providers are wired into the worker. When using a hosted memory provider, mint grants from authenticated server-side state and pass them with the run request.

Where to go next

← Previous
MCP tools
Next →
Agent-as-tool