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ámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
user_id | str | sí | Owner of the observation. Must match the active session's user_id. |
content | str | sí | Markdown content. May contain <private>...</private> tags — content inside will be stripped to [REDACTED] BEFORE hashing/persistence. |
type | str (Literal) | sí | 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. |
title | str | sí | Short, searchable. Verb + object (e.g. "Fixed FTS5 syntax error", "Chose SQLite over Postgres"). |
topic_key | str | None | no (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— invalidtype(reserved or not inconfig.allowed_types), emptycontent/title/user_id, etc.RuntimeError— storage failure.
Examples
- Basic save
- Privacy strip
- Idempotent upsert via topic_key
- Without topic_key (one-off)
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",
)
result = mem.mem_save(
user_id="alice",
content="API key: <private>sk-abc123def456</private>",
type="discovery",
title="OpenAI key rotated",
)
# When retrieved later, content reads: "API key: [REDACTED]"
# First call — creates
mem.mem_save(user_id="alice", content="Use React.", type="decision",
title="Frontend stack", topic_key="architecture/frontend")
# Second call — updates the SAME observation in place
mem.mem_save(user_id="alice", content="Use React + Tauri.", type="decision",
title="Frontend stack v2", topic_key="architecture/frontend")
mem.mem_save(
user_id="alice",
content="Wrote integration tests for the FTS5 LIKE fallback.",
type="discovery",
title="FTS5 fallback covered by tests",
)
# No topic_key → never upserts; identical content in the same session is deduped via hash.