mnesis.session¶
session
¶
Mnesis Session — the primary public API entry point.
MnesisSession
¶
MnesisSession(
session_id: str,
model: str,
model_info: ModelInfo,
config: MnesisConfig,
system_prompt: str,
agent: str,
store: ImmutableStore,
dag_store: SummaryDAGStore,
context_builder: ContextBuilder,
compaction_engine: CompactionEngine,
token_estimator: TokenEstimator,
event_bus: EventBus,
)
A single Mnesis session managing a conversation with an LLM.
Handles the complete lifecycle: message persistence, context assembly, streaming, compaction, and cleanup.
Usage::
# Preferred: open() returns an async context manager directly
async with MnesisSession.open(model="anthropic/claude-opus-4-6") as session:
result = await session.send("Hello!")
print(result.text)
# Alternative: create() + async with (equivalent, for explicit lifecycle)
async with await MnesisSession.create(model="anthropic/claude-opus-4-6") as session:
result = await session.send("Hello!")
# Manual lifecycle (no context manager)
session = await MnesisSession.create(model="anthropic/claude-opus-4-6")
result = await session.send("Hello!")
await session.close()
BYO-LLM (bring-your-own LLM client)
If you manage LLM calls yourself (Anthropic SDK, OpenAI SDK, Gemini, etc.)
and only want Mnesis for memory management, use :meth:record together
with :meth:context_for_next_turn::
session = await MnesisSession.create(model="anthropic/claude-opus-4-6")
# Get the compaction-aware context window for your LLM call
messages = await session.context_for_next_turn()
response = your_client.chat(messages=messages, system=your_system_prompt)
# Persist the completed turn so Mnesis tracks tokens and compaction
await session.record(
user_message="Explain quantum entanglement.",
assistant_response=response.text,
tokens=TokenUsage(input=response.usage.input, output=response.usage.output),
)
See docs/byo-llm.md and examples/06_byo_llm.py for a full walkthrough.
token_usage
property
¶
Cumulative token usage across all turns in this session.
compaction_in_progress
property
¶
True while a background compaction task is running.
event_bus
property
¶
The event bus for this session. Subscribe to monitor events.
create
async
classmethod
¶
create(
*,
model: str,
agent: str = "default",
parent_id: str | None = None,
config: MnesisConfig | None = None,
system_prompt: str = "You are a helpful assistant.",
db_path: str | None = None,
pool: StorePool | None = None,
) -> MnesisSession
Create a new Mnesis session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
LLM model string in litellm format (e.g. |
required |
agent
|
str
|
Agent role name for multi-agent setups. |
'default'
|
parent_id
|
str | None
|
Parent session ID for sub-sessions (AgenticMap). |
None
|
config
|
MnesisConfig | None
|
Mnesis configuration. Defaults to |
None
|
system_prompt
|
str
|
System prompt for all turns in this session. |
'You are a helpful assistant.'
|
db_path
|
str | None
|
Override database path (useful for testing). Raises |
None
|
pool
|
StorePool | None
|
Optional shared connection pool. When provided, all sessions
pointing at the same |
None
|
Returns:
| Type | Description |
|---|---|
MnesisSession
|
An initialized MnesisSession ready to receive messages. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
Error
|
If the database cannot be initialized. |
open
async
classmethod
¶
open(
*,
model: str,
agent: str = "default",
parent_id: str | None = None,
config: MnesisConfig | None = None,
system_prompt: str = "You are a helpful assistant.",
db_path: str | None = None,
pool: StorePool | None = None,
) -> AsyncGenerator[MnesisSession, None]
Create a new session and use it as an async context manager.
This is the preferred idiom for most callers — it avoids the
await ... async with double-ceremony of :meth:create::
async with MnesisSession.open(model="anthropic/claude-opus-4-6") as session:
result = await session.send("Hello!")
All parameters are identical to :meth:create. The session is
automatically closed (pending compaction awaited, DB connection
released) when the async with block exits, even on exception.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
LLM model string in litellm format. |
required |
agent
|
str
|
Agent role name for multi-agent setups. |
'default'
|
parent_id
|
str | None
|
Parent session ID for sub-sessions (AgenticMap). |
None
|
config
|
MnesisConfig | None
|
Mnesis configuration. Defaults to |
None
|
system_prompt
|
str
|
System prompt for all turns in this session. |
'You are a helpful assistant.'
|
db_path
|
str | None
|
Override database path. |
None
|
pool
|
StorePool | None
|
Optional shared connection pool (see :meth: |
None
|
Yields:
| Type | Description |
|---|---|
AsyncGenerator[MnesisSession, None]
|
An initialized MnesisSession. |
Note
To receive operator events (LLMMap, AgenticMap), pass
event_bus=session.event_bus when constructing operators.
load
async
classmethod
¶
load(
session_id: str,
config: MnesisConfig | None = None,
db_path: str | None = None,
pool: StorePool | None = None,
) -> MnesisSession
Load an existing session from the store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
The session ID to load. |
required |
config
|
MnesisConfig | None
|
Optional config override. |
None
|
db_path
|
str | None
|
Override database path. |
None
|
pool
|
StorePool | None
|
Optional shared connection pool (see |
None
|
Returns:
| Type | Description |
|---|---|
MnesisSession
|
An MnesisSession wrapping the existing session. |
Raises:
| Type | Description |
|---|---|
SessionNotFoundError
|
If the session does not exist. |
send
async
¶
send(
message: str | list[MessagePart],
*,
tools: list[Any] | None = None,
on_part: Callable[[MessagePart], None | Awaitable[None]]
| None = None,
system_prompt: str | None = None,
) -> TurnResult
Send a user message and receive a streaming assistant response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | list[MessagePart]
|
User message text or list of MessagePart objects. |
required |
tools
|
list[Any] | None
|
Optional list of tool definitions (litellm format dicts). |
None
|
on_part
|
Callable[[MessagePart], None | Awaitable[None]] | None
|
Optional callback invoked for each streamed |
None
|
system_prompt
|
str | None
|
Override the session system prompt for this turn only. Note: not all providers support per-turn system prompt overrides — check your provider's documentation before relying on this. |
None
|
Returns:
| Type | Description |
|---|---|
TurnResult
|
TurnResult with the assistant's text, token usage, and status. |
Raises:
| Type | Description |
|---|---|
MnesisStoreError
|
If message persistence fails. |
record
async
¶
record(
user_message: str | list[MessagePart],
assistant_response: str | list[MessagePart],
*,
tokens: TokenUsage | None = None,
finish_reason: str = "stop",
) -> RecordResult
Persist a completed user/assistant turn without making an LLM call.
Use this when you manage LLM calls yourself (e.g. using the Anthropic, OpenAI, or Gemini SDKs directly) and only want mnesis to handle memory, context assembly, and compaction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str | list[MessagePart]
|
The user message text or parts to record. |
required |
assistant_response
|
str | list[MessagePart]
|
The assistant reply text or parts to record. |
required |
tokens
|
TokenUsage | None
|
Token usage for the turn. Estimated from text if omitted. |
None
|
finish_reason
|
str
|
The finish reason from your LLM response (e.g.
|
'stop'
|
Returns:
| Type | Description |
|---|---|
RecordResult
|
RecordResult with the persisted message IDs and token usage. |
Example::
import anthropic
from mnesis import MnesisSession
from mnesis.models.message import TokenUsage
client = anthropic.Anthropic()
session = await MnesisSession.create(model="anthropic/claude-opus-4-6")
user_text = "Explain quantum entanglement."
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": user_text}],
)
result = await session.record(
user_message=user_text,
assistant_response=response.content[0].text,
tokens=TokenUsage(
input=response.usage.input_tokens,
output=response.usage.output_tokens,
),
)
messages
async
¶
Return the full message history for this session.
The returned list includes all stored rows:
- Regular user and assistant turns.
- Compaction summary messages (
m.is_summary == True). - Messages whose parts contain :class:
~mnesis.models.message.CompactionMarkerParttombstones (tool outputs pruned by the compaction engine).
To get only the conversational turns, use :meth:conversation_messages
or filter manually with [m for m in msgs if not m.is_summary].
Returns:
| Type | Description |
|---|---|
list[MessageWithParts]
|
List of MessageWithParts in chronological order. |
conversation_messages
async
¶
Return only the conversational turns, excluding compaction summaries.
Convenience wrapper around :meth:messages that filters out summary
messages produced by the compaction engine (is_summary == True).
Tombstoned tool outputs within regular messages are still included —
only top-level summary rows are removed.
Returns:
| Type | Description |
|---|---|
list[MessageWithParts]
|
List of non-summary MessageWithParts in chronological order. |
context_for_next_turn
async
¶
Return the compaction-aware context window for the next LLM call.
Intended for BYO-LLM callers who manage their own LLM client but
want Mnesis to handle context assembly and compaction. The returned
list is in the format expected by most chat completion APIs
([{"role": "user"|"assistant", "content": "..."}, ...]).
Summaries injected by the compaction engine are included as assistant messages at the correct position, so the context is always accurate even after one or more compaction cycles.
After calling your LLM, persist the completed turn with
:meth:record so Mnesis can track token usage and trigger compaction
when needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_prompt
|
str | None
|
Override the session system prompt for this turn.
Defaults to the system prompt set at :meth: |
None
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
Ordered list of |
list[dict[str, Any]]
|
ready to pass to any chat completion API. |
Example::
messages = await session.context_for_next_turn()
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": my_system_prompt}, *messages],
)
await session.record(
user_message=my_user_text,
assistant_response=response.choices[0].message.content,
)
compact
async
¶
Manually trigger synchronous compaction.
Blocks until compaction completes. Useful for checkpointing before complex operations or for testing.
The compaction result is stored internally so that the next
:meth:send or :meth:record call will include it in its
:class:~mnesis.models.snapshot.TurnSnapshot via the
compact_result field.
Returns:
| Type | Description |
|---|---|
CompactionResult
|
CompactionResult describing the compaction outcome. |
close
async
¶
Clean up session resources.
If background compaction is in progress, close() waits for it to
finish before releasing the database connection. This guarantees that
no in-flight write is interrupted and that the compaction summary is
fully persisted before the DB handle is closed.
Publishes :attr:~mnesis.events.bus.MnesisEvent.SESSION_CLOSED after
cleanup.
subscribe
¶
Register an event handler on this session's event bus.
Convenience wrapper for session.event_bus.subscribe().
history
¶
Return the accumulated per-turn context snapshots.
Each entry corresponds to one completed turn — one :meth:send call or
one :meth:record call. Entries are appended in turn order and the
list grows monotonically; it is never reordered or truncated.
Typical use-cases:
- Debugging — inspect the exact context composition at each turn to diagnose unexpected compaction or budget overflows.
- Research — plot sawtooth token-usage curves, compute compaction level distributions, or analyse information retention across compaction boundaries.
Returns:
| Type | Description |
|---|---|
list[TurnSnapshot]
|
A list of :class: |
list[TurnSnapshot]
|
chronological order. Returns an empty list if no turns have |
list[TurnSnapshot]
|
completed yet. |
Example::
async with MnesisSession.open(model="anthropic/claude-opus-4-6") as session:
await session.send("Hello!")
await session.send("Tell me about Paris.")
for snap in session.history():
print(
f"Turn {snap.turn_index}: "
f"{snap.context_tokens.total} tokens "
f"(summary={snap.context_tokens.summary})"
)
make_id
¶
Generate a ULID-based sortable identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Short prefix for readability (e.g. |
required |
Returns:
| Type | Description |
|---|---|
str
|
ID string in the format |