Skip to main content

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:

FieldWhat it isUsed for
session_iduuid stringPass it as a header / context anchor in your app.
is_newboolTell the agent whether to greet vs continue.
sessions_contextlist[SessionSummaryCompact]Recent past session summaries — show or feed to LLM.
memorieslist[ObservationCompact]Recent observations scored with ContextScore.
note

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.

tip

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:

  1. Closes the stale session with a synthetic summary like Memorias registradas: [type] title, [type] title, ... (built from the observations recorded in that session).
  2. Marks Session.is_auto_generated = True so downstream code can distinguish auto vs human summaries (Braess #2).
  3. Opens a new session and returns it.
warning

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.