Noēsis can persist episode facts into a long-term memory backend. You bring the storage (SQLite, Postgres, vector store, etc.), and expose it through the MemoryPort contract.
A fact is a small JSON-style record derived from an episode (task, outcome, tags, timestamps, and related metadata) that you can query later.
When to use
- You want episodes to leave behind a fact you can query later (e.g., for chat history, incident recall, eval traces).
- You need to link episodes to facts for audit/search.
- You want a minimal, schema-light way to store summaries without wiring a new service.
If you just need artifacts on disk, you can skip memory entirely.
Quick start: SQLite memory port
Use the built-in SQLite adapter for a lightweight, file-backed memory:
from pathlib import Path
from noesis.runtime.session import SessionBuilder
from noesis.infrastructure.memory.sqlite import SQLiteMemory
memory = SQLiteMemory(db_path=Path("memory/noesis.db"))
session = (
SessionBuilder.from_env()
.with_port("memory", memory, api=memory.__api_version__)
.build()
)
ep = session.run("Summarize incident INC-1234")
What happens:
- After the episode, Noēsis builds a fact from
summary.json (task, episode ID, metrics, tags) and persists it into SQLite.
- The memory event records status (persisted/skipped/error) in
events.jsonl.
- Episodes are linked to fact IDs for later lookup.
In multi-service or multi-tenant environments, consider using a separate database, schema, or table prefix per app/tenant so facts stay isolated.
Querying memory
You can query the memory port directly:
from noesis.interfaces.memory import MemoryQuery
results = memory.query(MemoryQuery(text="incident"), k=5)
for fact in results:
print(fact.id, fact.content)
Facts include id, content, and metadata (e.g., tags, artifacts, timestamps).
Implement your own memory port
Implement the MemoryPort protocol if you want Postgres, a vector store, or another backend:
from dataclasses import dataclass
from typing import Sequence
from noesis.interfaces.memory import Fact, MemoryPort, MemoryQuery
@dataclass
class PostgresMemory(MemoryPort):
__api_version__ = "memory/1.1"
def supports(self, capability: str) -> bool:
# Capabilities Noēsis checks today
return capability in {"write_fact", "query", "episode_links", "long_term_memory"}
def write_fact(self, fact: Fact) -> None:
# persist fact.content + fact.metadata
...
def query(self, query: MemoryQuery, *, k: int = 5) -> Sequence[Fact]:
# return top-k matching facts
...
def link_episode(self, episode_id: str, fact_ids: Sequence[str]) -> None:
# link episodes to fact IDs
...
Then register it on your session:
memory = PostgresMemory(...)
session = (
SessionBuilder.from_env()
.with_port("memory", memory, api=memory.__api_version__)
.build()
)
Capabilities and behavior
- The memory port must return
True for supports("long_term_memory") to receive persisted facts.
- On each run, Noēsis builds a fact from
summary.json, calls write_fact, and then link_episode.
- Success/errors are logged as
memory events in events.jsonl.
Avoid storing sensitive payloads verbatim. Use metadata or hashed IDs when needed; Noēsis does not enforce PII handling for you.