Overview
The bot is single-user, so it maintains exactly one main session at a time. When the bot starts (or reconnects after a crash), it loads the stored session ID and resumes the previous conversation. If no session ID exists, a fresh conversation begins. Session persistence is handled bysessions.py. The underlying SDK manages
conversation history — ollim-bot only needs to track the session ID.
Session persistence
The main session ID is stored at~/.ollim-bot/state/sessions.json (~ is
your home directory).
The bot reads, writes, and deletes this file at key moments:
| Action | What happens |
|---|---|
| Load | Reads the session ID from disk, or returns nothing if the file is missing or empty |
| Save | Writes the new session ID safely (crash-proof). Also detects lifecycle events like creation and compaction |
| Delete | Removes the file — used when clearing the session |
Writes are crash-safe — the bot writes to a temporary file first, then
moves it into place. This prevents corruption if the bot stops mid-write.
Session lifecycle events
Every session transition is recorded in~/.ollim-bot/state/session_history.jsonl. Each line contains:
| Field | Description |
|---|---|
session_id | The session ID involved in this event |
event | One of the event types below |
timestamp | When the event occurred (in the configured timezone) |
parent_session_id | The session this one branched from (for forks, compaction, swaps) — absent for standalone events |
Event types
| Event | When it’s logged |
|---|---|
created | A brand-new session starts (no prior session on disk) |
compacted | The conversation is compacted — either manually via /compact or automatically when context grows too large |
swapped | A fork is promoted to the main session |
cleared | You run /clear to start fresh |
interactive_fork | An interactive fork begins receiving responses |
bg_fork | A background fork session starts |
isolated_bg | An isolated background fork (no parent session) starts |
restarting | Bot is restarting (recorded before exit) |
Developer reference
Developer reference
save_session_id() automatically detects created and compacted events
by comparing the new ID against the current one on disk. During
swap_client(), a _swap_in_progress flag suppresses this auto-detection
so that the swap is logged as swapped rather than compacted.Compaction
When a conversation grows too long, context compaction summarizes the history to free up space. This happens through two paths:- Manual (
/compact): You run the command, the bot compacts the conversation, and returns productivity stats — turns taken, session age, and how much context was freed. - Automatic: The bot may auto-compact during normal conversation when context reaches its limit. When this happens, the bot re-sends your original message against the freshly compacted context so the agent produces a response without you needing to repeat yourself.
compacted event to the session history, linking the new
session to the previous one.
The /clear lifecycle
When you run /clear, the bot executes the following sequence:
Fork session tracking
When a fork sends messages to Discord, the bot tracks which fork sent which message. Both background and interactive fork messages are tracked. This enables the reply-to-fork feature — replying to any fork message resumes that fork’s conversation as an interactive fork. When you reply to a fork message, the bot looks up the message and returns one of three outcomes:| Outcome | What happens |
|---|---|
| Live fork found | Resumes the fork as an interactive fork |
| Expired fork (past 7 days) | The bot tells you the fork has expired |
| Unknown message | Not a fork message — no action taken |
~/.ollim-bot/state/fork_messages.json. Each record links a Discord message ID to the fork session that sent it, along with the parent main session and a timestamp.
Developer reference
Developer reference
Tracking uses a collector pattern in
sessions.py:| Function | Purpose |
|---|---|
start_message_collector() | Initializes a collector before a background fork runs |
track_message(message_id) | Records a Discord message ID during the fork’s run |
flush_message_collector(fork_id, parent_id) | Writes collected IDs to fork_messages.json |
cancel_message_collector() | Discards collected IDs without writing |
lookup_fork_session(message_id) | Looks up which fork sent a given Discord message |
Files reference
| File | Purpose |
|---|---|
~/.ollim-bot/state/sessions.json | Current main session ID |
~/.ollim-bot/state/session_history.jsonl | Lifecycle event log |
~/.ollim-bot/state/fork_messages.json | Discord message to fork session mapping |
Next steps
Context flow
How context flows between main sessions, forks, and background forks.
Forks
Interactive and background forks, exit strategies, and idle timeout.
Streaming
How agent responses stream to Discord with throttled edits.
Data directory
Full layout of the ~/.ollim-bot/ directory.
Development guide
How to modify session management and other core modules.
