Skip to main content

Memory Rules

A memory store's ingestion policy: which completed agent turns feed it, and who decides what is worth keeping.

Overview​

A memory rule lives on the destination store, because the question it answers — what feeds this corpus? — is a property of the store, not of any one agent. One store can carry several rules, one agent can feed two stores under different rules, and "what feeds this store?" is one listing rather than a sweep over every agent in the project.

That makes it the opposite half of the write_memory tool an agent gets from knowledge_config.write_memory_store_id:

write_memory toolmemory rule
Who decidesthe agent, mid-turn, at its discretionthe platform, after every completed turn
What it isa capability grantan ingestion policy
Readsthe agent's whole contextexactly one turn's transcript
Lives onthe agentthe memory store

Give an agent long-term memory uses a rule; Limit what an agent may do uses the tool.

This module is a verbatim mirror of the runtime: every field, method, status code and error shape is the runtime's own, re-rooted under the project in the path.

See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Memory Rules.

Data Model​

MemoryRule​

FieldTypeDescription
idstringPublic memory rule ID (mrule_ prefix).
memory_store_idstringThe destination store, and the rule's owning scope. Deleting the store deletes its rules.
project_idstringThe store's project.
onstringThe event the rule reads — see Which turns a rule reads.
source_agent_idsarray of string, nullableAgents whose turns it reads. null is every agent in the project.
agent_idstring, nullableHandler agent. Mutually exclusive with tool_id.
tool_idstring, nullableHandler tool. Mutually exclusive with agent_id.
actionstring, nullableOperation id, for a tool handler.
preset_parametersobject, nullableMerged into a tool handler's input. The turn's own fields are reserved and win.
promptstring, nullableReplaces the built-in extractor's task instructions.
ai_provider_idstring, nullableProvider override for the built-in extractor.
modelstring, nullableModel override for the built-in extractor.
enabledbooleanA disabled rule is kept and never fires.
created_atstring (date-time)
updated_atstring (date-time)

Key Concepts​

Which turns a rule reads​

onFiresFit
agents.generation.completedonce per completed turn — conversation or bare, streaming or notturn-level extraction, and the only event the built-in extractor may bind to
conversations.message.generatedonce per persisted assistant replyconversation-backed only; for a custom handler

source_agent_ids narrows further. Leave it out and every agent in the project feeds the store. Give an agent long-term memory binds one agent on agents.generation.completed.

Handlers propose, the store decides​

A handler reads one turn's transcript and answers with candidate facts:

{ "facts": [{ "content": "Customer prefers email", "tags": { "kind": "preference" } }] }
HandlerSetBehaviour
built-in extractorneither agent_id nor tool_ida tool-less completion over the transcript, asking for atomic facts. prompt, ai_provider_id and model tune it
agentagent_idthe agent is generated against the transcript and its reply is parsed as the contract above
tooltool_id (+ action)the tool is called with the turn's context plus preset_parameters, and its output is parsed as the contract above

The three built-in extractor fields cannot be combined with a handler: a handler makes its own model call, or none, so they would be accepted and ignored.

Every candidate then goes through the store's own write algorithm on its effective thresholds, and each write appends an assertion with mechanism: "rule". A handler can propose garbage and cannot corrupt the store. A rule never blocks or fails the turn it reads: a handler that throws, times out or answers with nonsense contributes nothing.

Firings on agents.generation.completed also record a summary on the originating generation's extraction field, keyed by rule id — a store can carry several rules, so one flat pair of counts could not say which produced them. Give an agent long-term memory reads both: the fact the built-in extractor stored and the turn's extraction.

Who may do what​

Every route needs any project member. Every route is authorized against the store the rule belongs to.

Examples​

Add a rule to a store​

naturali create-memory-rule \
--project-id proj_V1StGXR8Z5jdHi6B \
--memory-store-id mstore_V1StGXR8Z5jdHi6B \
--on agents.generation.completed \
--source-agent-ids agent_V1StGXR8Z5jdHi6B

Read one store's policy​

naturali list-memory-rules \
--project-id proj_V1StGXR8Z5jdHi6B \
--memory-store-id mstore_V1StGXR8Z5jdHi6B

Turn a rule off without losing it​

naturali update-memory-rule \
--project-id proj_V1StGXR8Z5jdHi6B \
--memory-rule-id mrule_V1StGXR8Z5jdHi6B \
--enabled false