mem_save
Firma
mem.mem_save(
user_id: str,
content: str,
*,
type: str, # uno de: profile, preference, decision, discovery, pattern
title: str,
topic_key: str | None = None,
) -> SaveResult
Guarda una observación para user_id. El privacy strip se aplica a ambos title y content antes del hashing y la persistencia (Braess #1) — todo lo que esté dentro de <private>...</private> queda como [REDACTED]. La sesión activa se toca en cada llamada, incluso en dedup.
Parámetros
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
user_id | str | sí | Dueño de la observación. Tiene que matchear el user_id de la sesión activa. |
content | str | sí | Contenido Markdown. Puede contener tags <private>...</private> — el contenido adentro se va a strippear a [REDACTED] ANTES del hashing/persistencia. |
type | str (Literal) | sí | Uno de profile, preference, decision, discovery, pattern. El tipo summary está reservado — pasarlo levanta ValueError (usá mem_session_summary). Si Config.observation_types está seteado, solo se permiten esos valores. |
title | str | sí | Corto, searchable. Verbo + objeto (ej. "Fixed FTS5 syntax error", "Chose SQLite over Postgres"). |
topic_key | str | None | no (default None) | Key opcional estable (ej. "architecture/auth"). Mismo key + mismo user_id → upsert in place. Tópicos distintos DEBEN usar keys distintas (sino sobrescriben). Ver Conceptos: Topic keys. |
Returns
SaveResult (modelo Pydantic frozen):
id(int) — id de la observación.outcome(Literal["created", "updated", "deduped"]) — qué pasó.session_id(str) — sesión a la que se atribuye este save.topic_key(str | None) — devuelto si lo pasaste.
Levanta
ValueError—typeinválido (reservado o fuera deconfig.allowed_types),content/title/user_idvacío, etc.RuntimeError— falla del storage.
Ejemplos
- Save básico
- Privacy strip
- Upsert idempotente vía topic_key
- Sin topic_key (one-off)
mem.mem_save(
user_id="alice",
content="Cambiamos de Postgres a SQLite por simplicidad en v0.1.",
type="decision",
title="Elección de DB para 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 rotada",
)
# Cuando se recupera después, content lee: "API key: [REDACTED]"
# Primera llamada — crea
mem.mem_save(user_id="alice", content="Usar React.", type="decision",
title="Stack frontend", topic_key="architecture/frontend")
# Segunda llamada — actualiza la MISMA observación in place
mem.mem_save(user_id="alice", content="Usar React + Tauri.", type="decision",
title="Stack frontend v2", topic_key="architecture/frontend")
mem.mem_save(
user_id="alice",
content="Escribí integration tests para el fallback de LIKE en FTS5.",
type="discovery",
title="Fallback de FTS5 cubierto por tests",
)
# Sin topic_key → nunca upsertea; contenido idéntico en la misma sesión se dedupea por hash.