Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sessions

Sessions persist your conversation history so you can resume later. Each session is identified by a UUID and stored in a SQLite database.

How Sessions Work

  • A session is not created when agsh starts. It is created lazily when you send the first message.
  • When a session is created, its UUID is printed to stderr.
  • When you exit agsh (Ctrl+D), the session UUID is printed again so you can note it for later.
  • Sessions include the full message history: your inputs, the agent’s responses, and tool call results.

Resuming a Session

Continue Last Session

agsh -c

This resumes the most recently updated session.

By UUID

agsh -c 550e8400-e29b-41d4-a716-446655440000

The agent loads the previous conversation history and continues from where you left off.

Session Locking

Only one agsh instance can be attached to a session at a time. This prevents race conditions from concurrent writes.

  • If you try to resume a session that is locked by a running agsh process, you will get an error.
  • If the locking process has exited (crashed or was killed), agsh detects this and allows you to take over the lock.

Storage Location

Sessions are stored in a SQLite database at a platform-specific location:

PlatformPath
Linux~/.local/share/agsh/sessions.db ($XDG_DATA_HOME/agsh/sessions.db)
macOS~/Library/Application Support/agsh/sessions.db
Windows%APPDATA%\agsh\sessions.db

Database Schema

The database has three tables:

sessions – one row per session:

ColumnTypeDescription
idTEXT (UUID)Primary key
created_atTEXT (RFC 3339)When the session was created
updated_atTEXT (RFC 3339)When the session was last updated
locked_byTEXT (PID)PID of the process holding the lock, or NULL
metadataTEXTReserved for future use

messages – one row per message in a session:

ColumnTypeDescription
idINTEGERAuto-incrementing primary key
session_idTEXT (UUID)Foreign key to sessions.id
roleTEXTuser, assistant, or tool_results
contentTEXTMessage content (plain text or JSON)
created_atTEXT (RFC 3339)When the message was saved

tool_outputs – scratchpad entries, one row per entry:

ColumnTypeDescription
session_idTEXT (UUID)Part of composite primary key
nameTEXTPart of composite primary key
contentTEXTThe stored content
created_atTEXT (RFC 3339)When the entry was created

Scratchpad entries are scoped to a session. Two sessions can have entries with the same name. Entries are preserved across compaction but deleted when a session is deleted.

History Retention

agsh automatically manages session storage on startup with sensible defaults:

  • retention_days (default: 90) – deletes sessions whose updated_at is older than this many days.
  • max_storage_bytes (default: 52428800 / 50 MB) – when total message content exceeds this limit, the oldest sessions are deleted until the total is under the limit.

You can override these defaults in the config file under [session]:

[session]
retention_days = 30          # delete sessions not used in 30 days
max_storage_bytes = 10485760 # cap total storage at ~10 MB

See Config File for details.

Context Window Limiting

Long sessions can exceed the LLM’s context window or become expensive. The context_messages setting (default: 200) limits how many recent messages are sent to the API:

[session]
context_messages = 100

The full history remains in SQLite for resumption. Only the API payload is truncated. The truncation preserves tool call chains (it never splits a tool use from its result).

Compacting a Session

If a session becomes too long, you can use the /compact command to have the LLM summarize the conversation and replace older messages with a structured summary. Recent messages are preserved verbatim. The summary includes key files, decisions, errors, and user preferences.

Compaction preserves scratchpad entries and the todo list, and re-injects environment context so the agent isn’t disoriented after compaction.

Auto-Compact

When auto_compact is enabled (default: true), agsh automatically compacts the conversation when the input token count exceeds 80% of the context window. This runs between turns, not during tool loops.

[session]
auto_compact = true
context_window = 200000  # optional override

Listing Sessions

To see past sessions:

agsh list

This shows a table with each session’s ID, last update time, and a preview of the first message:

ID                                    Updated              Preview
550e8400-e29b-41d4-a716-446655440000  2026-03-14 12:00:00  How do I implement a binary search tree?
a1b2c3d4-e5f6-7890-abcd-ef1234567890  2026-03-13 09:30:00  Fix the login page CSS

By default the 20 most recent sessions are shown. Use -n to change:

agsh list -n 50

Exporting a Session

You can export any session as a Markdown file:

agsh export 550e8400-e29b-41d4-a716-446655440000

This writes session-550e8400-e29b-41d4-a716-446655440000.md in the current directory with the full conversation history. User and assistant messages are rendered as Markdown sections, while tool calls and results are wrapped in collapsible <details> blocks.

To write to a specific file:

agsh export 550e8400-e29b-41d4-a716-446655440000 -o conversation.md

To print to stdout (for piping):

agsh export 550e8400-e29b-41d4-a716-446655440000 -o -

Deleting Sessions

Delete specific sessions by UUID:

agsh delete 550e8400-e29b-41d4-a716-446655440000

Delete multiple sessions at once:

agsh delete 550e8400-e29b-41d4-a716-446655440000 a1b2c3d4-e5f6-7890-abcd-ef1234567890

Delete all sessions:

agsh delete --all

Managing Sessions via SQLite

You can also manage sessions directly through the SQLite database. For example, to list all sessions:

sqlite3 ~/.local/share/agsh/sessions.db \
  "SELECT id, created_at, updated_at FROM sessions ORDER BY updated_at DESC;"