Skip to main content

mem_save

Signature

mem.mem_save(
user_id: str,
content: str,
*,
type: str, # one of: profile, preference, decision, discovery, pattern
title: str,
topic_key: str | None = None,
) -> SaveResult

Saves an observation for user_id. Privacy strip is applied to both title and content before hashing and persistence (Braess #1) — anything inside <private>...</private> becomes [REDACTED]. The active session is touched on every call, even on dedup.

Parameters

ParámetroTipoRequeridoDescripción
user_idstrOwner of the observation. Must match the active session's user_id.
contentstrMarkdown content. May contain <private>...</private> tags — content inside will be stripped to [REDACTED] BEFORE hashing/persistence.
typestr (Literal)One of profile, preference, decision, discovery, pattern. The summary type is reserved — passing it raises ValueError (use mem_session_summary instead). If Config.observation_types is set, only those values are allowed.
titlestrShort, searchable. Verb + object (e.g. "Fixed FTS5 syntax error", "Chose SQLite over Postgres").
topic_keystr | Noneno (default None)Optional stable key (e.g. "architecture/auth"). Same key + same user_id → upserts in place. Different topics MUST use different keys (would overwrite). See Concepts: Topic keys.

Returns

SaveResult (frozen Pydantic model):

  • id (int) — observation id.
    • outcome (Literal["created", "updated", "deduped"]) — what happened.
    • session_id (str) — session this save was attributed to.
    • topic_key (str | None) — echoed back if provided.

Raises

  • ValueError — invalid type (reserved or not in config.allowed_types), empty content / title / user_id, etc.
  • RuntimeError — storage failure.

Examples

mem.mem_save(
user_id="alice",
content="Switched from Postgres to SQLite for simplicity in v0.1.",
type="decision",
title="DB choice for v0.1",
topic_key="architecture/db",
)

See also