Skip to main content
ollim-bot remembers your conversation across restarts. A session ID stored on disk lets the bot pick up where it left off. Every lifecycle transition — creation, compaction, clearing, forking — is recorded in a history log for debugging and review.

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 by sessions.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:
ActionWhat happens
LoadReads the session ID from disk, or returns nothing if the file is missing or empty
SaveWrites the new session ID safely (crash-proof). Also detects lifecycle events like creation and compaction
DeleteRemoves 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.
On reconnect, the bot loads the session ID and creates a new client that resumes the previous conversation. If no session ID is found, a fresh session starts instead.

Session lifecycle events

Every session transition is recorded in ~/.ollim-bot/state/session_history.jsonl. Each line contains:
FieldDescription
session_idThe session ID involved in this event
eventOne of the event types below
timestampWhen the event occurred (in the configured timezone)
parent_session_idThe session this one branched from (for forks, compaction, swaps) — absent for standalone events

Event types

EventWhen it’s logged
createdA brand-new session starts (no prior session on disk)
compactedThe conversation is compacted — either manually via /compact or automatically when context grows too large
swappedA fork is promoted to the main session
clearedYou run /clear to start fresh
interactive_forkAn interactive fork begins receiving responses
bg_forkA background fork session starts
isolated_bgAn isolated background fork (no parent session) starts
restartingBot is restarting (recorded before exit)
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.
The bot also shows a context usage warning after responses when context exceeds 60% of the window — escalating at 80% — so you can compact proactively before auto-compaction kicks in. Both paths log a 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:
1

Reset permissions

Clears any tool permissions you’ve granted during the session.
2

Exit any active fork

If an interactive fork is active, exits and discards it cleanly.
3

Log the cleared event

Records a cleared event to the session history.
4

Disconnect

Shuts down the current session connection.
5

Delete the session file

Removes ~/.ollim-bot/state/sessions.json. The next message starts a fresh session.

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:
OutcomeWhat happens
Live fork foundResumes the fork as an interactive fork
Expired fork (past 7 days)The bot tells you the fork has expired
Unknown messageNot a fork message — no action taken
The mapping is stored in ~/.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.
Records older than 7 days are automatically pruned on read.
Tracking uses a collector pattern in sessions.py:
FunctionPurpose
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

FilePurpose
~/.ollim-bot/state/sessions.jsonCurrent main session ID
~/.ollim-bot/state/session_history.jsonlLifecycle event log
~/.ollim-bot/state/fork_messages.jsonDiscord 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.