> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ollim.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Session management

> Learn how sessions persist across restarts, compact when context grows, and recover from /clear.

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:

| 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                                                          |

<Note>
  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.
</Note>

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:

| 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)                                                                     |

<Accordion title="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`.
</Accordion>

## 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](/core-usage/conversations#context-and-memory) 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:

<Steps>
  <Step title="Reset permissions">
    Clears any tool permissions you've granted during the session.
  </Step>

  <Step title="Exit any active fork">
    If an interactive fork is active, exits and discards it cleanly.
  </Step>

  <Step title="Log the cleared event">
    Records a `cleared` event to the session history.
  </Step>

  <Step title="Disconnect">
    Shuts down the current session connection.
  </Step>

  <Step title="Delete the session file">
    Removes `~/.ollim-bot/state/sessions.json`. The next message starts a fresh session.
  </Step>
</Steps>

## 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    |

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.

<Tip>Records older than 7 days are automatically pruned on read.</Tip>

<Accordion title="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      |
</Accordion>

## 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

<Columns cols={2}>
  <Card title="Context flow" icon="arrows-split-up-and-left" href="/architecture/context-flow">
    How context flows between main sessions, forks, and background forks.
  </Card>

  <Card title="Forks" icon="code-branch" href="/core-usage/forks">
    Interactive and background forks, exit strategies, and idle timeout.
  </Card>

  <Card title="Streaming" icon="wave-pulse" href="/architecture/streaming">
    How agent responses stream to Discord with throttled edits.
  </Card>

  <Card title="Data directory" icon="folder-open" href="/configuration/data-directory">
    Full layout of the \~/.ollim-bot/ directory.
  </Card>

  <Card title="Development guide" icon="code" href="/development/guide">
    How to modify session management and other core modules.
  </Card>
</Columns>
