- add code-derived reference pages for slash commands, tools, toolsets, bundled skills, and official optional skills - document the skin system and link visual theming separately from conversational personality - refresh quickstart, configuration, environment variable, and messaging docs to match current provider, gateway, and browser behavior - fix stale command, session, and Home Assistant configuration guidance
13 KiB
sidebar_position, title, description
| sidebar_position | title | description |
|---|---|---|
| 7 | Sessions | Session persistence, resume, search, management, and per-platform session tracking |
Sessions
Hermes Agent automatically saves every conversation as a session. Sessions enable conversation resume, cross-session search, and full conversation history management.
How Sessions Work
Every conversation — whether from the CLI, Telegram, Discord, WhatsApp, or Slack — is stored as a session with full message history. Sessions are tracked in two complementary systems:
- SQLite database (
~/.hermes/state.db) — structured session metadata with FTS5 full-text search - JSONL transcripts (
~/.hermes/sessions/) — raw conversation transcripts including tool calls (gateway)
The SQLite database stores:
- Session ID, source platform, user ID
- Session title (unique, human-readable name)
- Model name and configuration
- System prompt snapshot
- Full message history (role, content, tool calls, tool results)
- Token counts (input/output)
- Timestamps (started_at, ended_at)
- Parent session ID (for compression-triggered session splitting)
Session Sources
Each session is tagged with its source platform:
| Source | Description |
|---|---|
cli |
Interactive CLI (hermes or hermes chat) |
telegram |
Telegram messenger |
discord |
Discord server/DM |
whatsapp |
WhatsApp messenger |
slack |
Slack workspace |
CLI Session Resume
Resume previous conversations from the CLI using --continue or --resume:
Continue Last Session
# Resume the most recent CLI session
hermes --continue
hermes -c
# Or with the chat subcommand
hermes chat --continue
hermes chat -c
This looks up the most recent cli session from the SQLite database and loads its full conversation history.
Resume by Name
If you've given a session a title (see Session Naming below), you can resume it by name:
# Resume a named session
hermes -c "my project"
# If there are lineage variants (my project, my project #2, my project #3),
# this automatically resumes the most recent one
hermes -c "my project" # → resumes "my project #3"
Resume Specific Session
# Resume a specific session by ID
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4
# Resume by title
hermes --resume "refactoring auth"
# Or with the chat subcommand
hermes chat --resume 20250305_091523_a1b2c3d4
Session IDs are shown when you exit a CLI session, and can be found with hermes sessions list.
Conversation Recap on Resume
When you resume a session, Hermes displays a compact recap of the previous conversation in a styled panel before the input prompt:
╭─────────────────────────── Previous Conversation ────────────────────────────╮
│ ● You: What is Python? │
│ ◆ Hermes: Python is a high-level programming language. │
│ ● You: How do I install it? │
│ ◆ Hermes: [3 tool calls: web_search, web_extract, terminal] │
│ ◆ Hermes: You can download Python from python.org... │
╰──────────────────────────────────────────────────────────────────────────────╯
The recap:
- Shows user messages (gold
●) and assistant responses (green◆) - Truncates long messages (300 chars for user, 200 chars / 3 lines for assistant)
- Collapses tool calls to a count with tool names (e.g.,
[3 tool calls: terminal, web_search]) - Hides system messages, tool results, and internal reasoning
- Caps at the last 10 exchanges with a "... N earlier messages ..." indicator
- Uses dim styling to distinguish from the active conversation
To disable the recap and keep the minimal one-liner behavior, set in ~/.hermes/config.yaml:
display:
resume_display: minimal # default: full
:::tip
Session IDs follow the format YYYYMMDD_HHMMSS_<8-char-hex>, e.g. 20250305_091523_a1b2c3d4. You can resume by ID or by title — both work with -c and -r.
:::
Session Naming
Give sessions human-readable titles so you can find and resume them easily.
Setting a Title
Use the /title slash command inside any chat session (CLI or gateway):
/title my research project
The title is applied immediately. If the session hasn't been created in the database yet (e.g., you run /title before sending your first message), it's queued and applied once the session starts.
You can also rename existing sessions from the command line:
hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"
Title Rules
- Unique — no two sessions can share the same title
- Max 100 characters — keeps listing output clean
- Sanitized — control characters, zero-width chars, and RTL overrides are stripped automatically
- Normal Unicode is fine — emoji, CJK, accented characters all work
Auto-Lineage on Compression
When a session's context is compressed (manually via /compress or automatically), Hermes creates a new continuation session. If the original had a title, the new session automatically gets a numbered title:
"my project" → "my project #2" → "my project #3"
When you resume by name (hermes -c "my project"), it automatically picks the most recent session in the lineage.
/title in Messaging Platforms
The /title command works in all gateway platforms (Telegram, Discord, Slack, WhatsApp):
/title My Research— set the session title/title— show the current title
Session Management Commands
Hermes provides a full set of session management commands via hermes sessions:
List Sessions
# List recent sessions (default: last 20)
hermes sessions list
# Filter by platform
hermes sessions list --source telegram
# Show more sessions
hermes sessions list --limit 50
When sessions have titles, the output shows titles, previews, and relative timestamps:
Title Preview Last Active ID
────────────────────────────────────────────────────────────────────────────────────────────────
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
my project #3 Can you check the test failures? yesterday 20250304_143022_e
— What's the weather in Las Vegas? 3d ago 20250303_101500_f
When no sessions have titles, a simpler format is used:
Preview Last Active Src ID
──────────────────────────────────────────────────────────────────────────────────────
Help me refactor the auth module please 2h ago cli 20250305_091523_a
What's the weather in Las Vegas? 3d ago tele 20250303_101500_f
Export Sessions
# Export all sessions to a JSONL file
hermes sessions export backup.jsonl
# Export sessions from a specific platform
hermes sessions export telegram-history.jsonl --source telegram
# Export a single session
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4
Exported files contain one JSON object per line with full session metadata and all messages.
Delete a Session
# Delete a specific session (with confirmation)
hermes sessions delete 20250305_091523_a1b2c3d4
# Delete without confirmation
hermes sessions delete 20250305_091523_a1b2c3d4 --yes
Rename a Session
# Set or change a session's title
hermes sessions rename 20250305_091523_a1b2c3d4 "debugging auth flow"
# Multi-word titles don't need quotes in the CLI
hermes sessions rename 20250305_091523_a1b2c3d4 debugging auth flow
If the title is already in use by another session, an error is shown.
Prune Old Sessions
# Delete ended sessions older than 90 days (default)
hermes sessions prune
# Custom age threshold
hermes sessions prune --older-than 30
# Only prune sessions from a specific platform
hermes sessions prune --source telegram --older-than 60
# Skip confirmation
hermes sessions prune --older-than 30 --yes
:::info Pruning only deletes ended sessions (sessions that have been explicitly ended or auto-reset). Active sessions are never pruned. :::
Session Statistics
hermes sessions stats
Output:
Total sessions: 142
Total messages: 3847
cli: 89 sessions
telegram: 38 sessions
discord: 15 sessions
Database size: 12.4 MB
For deeper analytics — token usage, cost estimates, tool breakdown, and activity patterns — use hermes insights.
Session Search Tool
The agent has a built-in session_search tool that performs full-text search across all past conversations using SQLite's FTS5 engine.
How It Works
- FTS5 searches matching messages ranked by relevance
- Groups results by session, takes the top N unique sessions (default 3)
- Loads each session's conversation, truncates to ~100K chars centered on matches
- Sends to a fast summarization model for focused summaries
- Returns per-session summaries with metadata and surrounding context
FTS5 Query Syntax
The search supports standard FTS5 query syntax:
- Simple keywords:
docker deployment - Phrases:
"exact phrase" - Boolean:
docker OR kubernetes,python NOT java - Prefix:
deploy*
When It's Used
The agent is prompted to use session search automatically:
"When the user references something from a past conversation or you suspect relevant prior context exists, use session_search to recall it before asking them to repeat themselves."
Per-Platform Session Tracking
Gateway Sessions
On messaging platforms, sessions are keyed by a deterministic session key built from the message source:
| Chat Type | Key Format | Example |
|---|---|---|
| Telegram DM | agent:main:telegram:dm |
One session per bot |
| Discord DM | agent:main:discord:dm |
One session per bot |
| WhatsApp DM | agent:main:whatsapp:dm:<chat_id> |
Per-user (multi-user) |
| Group chat | agent:main:<platform>:group:<chat_id> |
Per-group |
| Channel | agent:main:<platform>:channel:<chat_id> |
Per-channel |
:::info WhatsApp DMs include the chat ID in the session key because multiple users can DM the bot. Other platforms use a single DM session since the bot is configured per-user via allowlists. :::
Session Reset Policies
Gateway sessions are automatically reset based on configurable policies:
- idle — reset after N minutes of inactivity
- daily — reset at a specific hour each day
- both — reset on whichever comes first (idle or daily)
- none — never auto-reset
Before a session is auto-reset, the agent is given a turn to save any important memories or skills from the conversation.
Sessions with active background processes are never auto-reset, regardless of policy.
Storage Locations
| What | Path | Description |
|---|---|---|
| SQLite database | ~/.hermes/state.db |
All session metadata + messages with FTS5 |
| Gateway transcripts | ~/.hermes/sessions/ |
JSONL transcripts per session + sessions.json index |
| Gateway index | ~/.hermes/sessions/sessions.json |
Maps session keys to active session IDs |
The SQLite database uses WAL mode for concurrent readers and a single writer, which suits the gateway's multi-platform architecture well.
Database Schema
Key tables in state.db:
- sessions — session metadata (id, source, user_id, model, title, timestamps, token counts). Titles have a unique index (NULL titles allowed, only non-NULL must be unique).
- messages — full message history (role, content, tool_calls, tool_name, token_count)
- messages_fts — FTS5 virtual table for full-text search across message content
Session Expiry and Cleanup
Automatic Cleanup
- Gateway sessions auto-reset based on the configured reset policy
- Before reset, the agent saves memories and skills from the expiring session
- Ended sessions remain in the database until pruned
Manual Cleanup
# Prune sessions older than 90 days
hermes sessions prune
# Delete a specific session
hermes sessions delete <session_id>
# Export before pruning (backup)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes
:::tip The database grows slowly (typical: 10-15 MB for hundreds of sessions). Pruning is mainly useful for removing old conversations you no longer need for search recall. :::