Skip to content

session

session

Session manager — markdown-based session persistence with per-turn metadata.

SessionManager

Markdown-based session persistence with per-turn metadata.

Stores conversation sessions as structured markdown files in a sessions directory. Each session file contains metadata (title, timestamps, axes) and individual turns with prompts, responses, RAG chunks, tool calls, and cited sources.

Supports session creation, loading by ID or numeric index, turn appending, listing, deletion, and preview generation.

This is the legacy persistence layer — new deployments use SQLSessionManager backed by SQLite.

turn_count property

turn_count: int

Return the number of turns in the session.

__init__

__init__(
    sessions_dir: str | Path, axes: dict | None = None
)

Initialize the markdown session manager.

Creates the sessions directory if it does not exist.

Parameters:

Name Type Description Default
sessions_dir str | Path

Path to the directory where session markdown files are stored.

required
axes dict | None

Initial political axes dict with keys "ethical", "alignment", "social". Defaults to ethical=-1.0, alignment=+1.0, social=+1.0.

None

get_preview

get_preview(session_id: str) -> dict | None

Get a lightweight preview of a session for listing UIs.

Returns first 3 turns with truncated prompt (300 chars) and response (500 chars), plus session metadata.

Parameters:

Name Type Description Default
session_id str

Session ID to look up (supports prefix matching).

required

Returns:

Type Description
dict | None

Dictionary with session metadata and preview turns, or None

dict | None

if the session is not found.

start_new

start_new(first_prompt: str) -> str

Create a new session file and set it as current.

Parameters:

Name Type Description Default
first_prompt str

The user's first prompt text, used for the session title and slug in the session ID.

required

Returns:

Type Description
str

The generated session ID string.

load

load(session_id_or_index: str | int) -> list[dict]

Load a session by ID or numeric index.

When given an int, resolves to the nth session in the list_sessions() output (1-based). When given a string, resolves by session ID with prefix matching.

Parameters:

Name Type Description Default
session_id_or_index str | int

Session ID string or 1-based index.

required

Returns:

Type Description
list[dict]

List of turn dictionaries parsed from the session file.

Raises:

Type Description
FileNotFoundError

If the session ID or index is not found.

IndexError

If the numeric index is out of range.

add_turn

add_turn(turn_data: dict) -> None

Append a conversation turn to the current session.

Parameters:

Name Type Description Default
turn_data dict

Dictionary with keys: prompt, response, timestamp, chunks, tools_called, cited_sources.

required

Raises:

Type Description
RuntimeError

If no active session (start_new() not called).

list_sessions

list_sessions() -> list[dict]

List all sessions ordered by most recent first.

Returns:

Type Description
list[dict]

List of metadata dicts with keys: id, title, created,

list[dict]

updated, axes, turns, path.

delete

delete(session_id: str) -> None

Delete a session file.

If the deleted session is the currently active one, clears the current state.

Parameters:

Name Type Description Default
session_id str

Session ID to delete (supports prefix matching).

required

set_axes

set_axes(axes: dict) -> None

Update the political axes for the current session.

Parameters:

Name Type Description Default
axes dict

Dict with keys "ethical", "alignment", "social" and float values in range [-1.0, 1.0].

required

get_title

get_title() -> str

Get the title of the current session.

Returns:

Type Description
str

First 60 characters of the first turn's prompt, or empty

str

string if no active session.

SQLSessionManager

SQLite-backed session persistence with per-user isolation.

Each method opens its own connection via aiosqlite.connect (connection-per-operation pattern to avoid shared connection issues). All queries are parameterized per T-03-01.

__init__

__init__(db_path: str)

Initialize the SQLite session manager.

Parameters:

Name Type Description Default
db_path str

Path to the SQLite database file (typically DATABASE_URL from config).

required

list_sessions async

list_sessions(
    user_id: str, role: str = "user"
) -> list[dict]

List sessions for a user, ordered by most recent update.

For non-admin users, sessions older than 30 minutes are filtered out. Admin users see all sessions regardless of age.

Parameters:

Name Type Description Default
user_id str

The user's UUID.

required
role str

The user's role ('admin', 'user', 'guest').

'user'

Returns:

Type Description
list[dict]

List of session dicts with id, title, timestamps, axes, turns.

get_session async

get_session(session_id: str, user_id: str) -> dict | None

Get a full session by ID with ownership check.

Returns the complete session including all messages (turns) with their tool calls, cited sources, and RAG chunks.

Parameters:

Name Type Description Default
session_id str

UUID of the session to retrieve.

required
user_id str

UUID of the requesting user for ownership validation.

required

Returns:

Type Description
dict | None

Session dict with id, title, timestamps, axes, and a messages

dict | None

list containing full turn data. Returns None if the session

dict | None

does not exist or belongs to a different user.

get_session_preview async

get_session_preview(
    session_id: str, user_id: str
) -> dict | None

Get session preview with the first 3 turns.

Returns truncated prompt/response text suitable for sidebar hover previews. Prompts are capped at 300 chars, responses at 500 chars.

Parameters:

Name Type Description Default
session_id str

UUID of the session.

required
user_id str

UUID of the requesting user.

required

Returns:

Type Description
dict | None

Preview dict with id, title, timestamps, axes, total turn

dict | None

count, and a preview list of the first 3 turns (truncated).

dict | None

Returns None if session not found or not owned by user.

delete_session async

delete_session(session_id: str, user_id: str) -> bool

Delete a session and all its messages.

Verifies ownership before deletion. Deletes messages first (foreign key cascade), then the session record.

Parameters:

Name Type Description Default
session_id str

UUID of the session to delete.

required
user_id str

UUID of the requesting user for ownership check.

required

Returns:

Type Description
bool

True if a session was deleted, False if not found or

bool

not owned by the user.

start_new_session async

start_new_session(
    user_id: str,
    session_id: str,
    title: str,
    axes: str = "{}",
) -> None

Create a new session record for a user.

Parameters:

Name Type Description Default
user_id str

UUID of the user who owns this session.

required
session_id str

UUID for the new session.

required
title str

Display title (typically first prompt, truncated).

required
axes str

JSON string of the axes configuration at creation time.

'{}'

add_turn async

add_turn(session_id: str, turn_data: dict) -> None

Add a conversation turn (prompt + response pair) to a session.

Inserts two message rows (user prompt and assistant response) with the next sequential turn number. Updates the session's updated_at timestamp. JSON-serializes tool calls, cited sources, and chunk metadata.

Parameters:

Name Type Description Default
session_id str

UUID of the session.

required
turn_data dict

Dict with prompt, response, tools_called, cited_sources, chunks, and timestamp keys.

required