Sessions
A session is a logical unit of work for a user_id. It has a started_at, an optional ended_at, an optional summary, and a status of active or completed. Observations belong to the session that wrote them last (Braess #4).
Lifecycle
1. Open or reuse
mem_session_start(user_id) returns a SessionStartResponse. If the user has an active, non-expired session, it is reused (is_new=False). Otherwise a new session is created (is_new=True).
2. Save observations
Every mem_save and mem_session_summary call touches the active session — its last_activity_at advances. The timeout window is reset.
3. Close (manual or auto)
Call mem_session_end(user_id, summary=...) to close the session with a human-written summary. If you forget and the timeout elapses, the next mem_session_start will auto-close the stale session with a rudimentary summary marked is_auto_generated=true and open a new one.
What mem_session_start returns
from ilab_memory import ILabMemory
mem = ILabMemory.from_path("./mem.db")
resp = mem.mem_session_start(user_id="alice")
print(resp.session_id) # uuid string
print(resp.is_new) # True if newly created, False if reused
print(len(resp.sessions_context)) # past session summaries (up to 5)
print(len(resp.memories)) # recent ObservationCompacts (up to ~10)
The response is a frozen SessionStartResponse with four fields:
| Field | What it is | Used for |
|---|---|---|
session_id | uuid string | Pass it as a header / context anchor in your app. |
is_new | bool | Tell the agent whether to greet vs continue. |
sessions_context | list[SessionSummaryCompact] | Recent past session summaries — show or feed to LLM. |
memories | list[ObservationCompact] | Recent observations scored with ContextScore. |
memories[] are scored with ContextScore, not SearchScore. The two are not comparable — see Scoring and Architecture / Braess #5.
Session reuse — no spurious sessions
The default timeout is 24 hours of inactivity. As long as the user keeps interacting (or your app keeps calling mem_session_start within that window), the same session is reused.
Calling mem_session_start is idempotent and cheap — call it on every "user appears" event in your app. You will not get duplicate sessions.
Auto-close on timeout
When you call mem_session_start and the user's last session has been inactive longer than session_timeout_hours, the library:
- Closes the stale session with a synthetic summary like
Memorias registradas: [type] title, [type] title, ...(built from the observations recorded in that session). - Marks
Session.is_auto_generated = Trueso downstream code can distinguish auto vs human summaries (Braess #2). - Opens a new session and returns it.
Distinguish auto vs narrative summaries before showing them to the user. The auto summary is a list of fragments, not a story — it exists so the next session has something to hydrate from.
Implicit session creation
If you call mem_save (or mem_session_summary) without calling mem_session_start first, the library creates an active session implicitly. This is by design — embeddable mode should not punish callers for skipping the handshake.
That said, calling mem_session_start explicitly is recommended because it is the only way to retrieve sessions_context and memories for hydration before responding to the user.
Manual close with mem_session_end
closed = mem.mem_session_end(
user_id="alice",
summary="Captured Alice's preferred greeting and confirmed the agent will use 'Ali'.",
)
print(closed.id)
print(closed.ended_at) # ISO 8601, UTC
print(closed.is_auto_generated) # False — this is a human-written summary
If there is no active session for user_id, mem_session_end raises LookupError. That maps to a 404 in the HTTP layer.
Next
- Observations — what lives inside sessions.
- Privacy — what happens to
<private>blocks across the lifecycle. - Architecture — Braess #2 (auto vs narrative) and #4 (session_id of last update) explained.