mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
docs: add session naming documentation across all doc files
- website/docs/user-guide/sessions.md: New 'Session Naming' section with /title usage, title rules, auto-lineage, gateway support. Updated 'Resume by Name' section, 'Rename a Session' subsection, updated sessions list output format, updated DB schema description. - website/docs/reference/cli-commands.md: Added -c "name" and --resume by title to Core Commands, sessions rename to Sessions table, /title to slash commands. - website/docs/user-guide/cli.md: Added -c "name" and --resume by title to resume options. - AGENTS.md: Added -c, --resume, sessions list/rename to CLI commands table. Added hermes_state.py to project structure. - CONTRIBUTING.md: Updated hermes_state.py and session persistence descriptions to mention titles. - hermes_cli/main.py: Fixed sessions help string to include 'rename'.
This commit is contained in:
@@ -58,6 +58,7 @@ hermes-agent/
|
|||||||
├── skills/ # Bundled skill sources
|
├── skills/ # Bundled skill sources
|
||||||
├── optional-skills/ # Official optional skills (not activated by default)
|
├── optional-skills/ # Official optional skills (not activated by default)
|
||||||
├── cli.py # Interactive CLI orchestrator (HermesCLI class)
|
├── cli.py # Interactive CLI orchestrator (HermesCLI class)
|
||||||
|
├── hermes_state.py # SessionDB — SQLite session store (schema, titles, FTS5 search)
|
||||||
├── run_agent.py # AIAgent class (core conversation loop)
|
├── run_agent.py # AIAgent class (core conversation loop)
|
||||||
├── model_tools.py # Tool orchestration (thin layer over tools/registry.py)
|
├── model_tools.py # Tool orchestration (thin layer over tools/registry.py)
|
||||||
├── toolsets.py # Tool groupings
|
├── toolsets.py # Tool groupings
|
||||||
@@ -226,6 +227,9 @@ The unified `hermes` command provides all functionality:
|
|||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `hermes` | Interactive chat (default) |
|
| `hermes` | Interactive chat (default) |
|
||||||
| `hermes chat -q "..."` | Single query mode |
|
| `hermes chat -q "..."` | Single query mode |
|
||||||
|
| `hermes -c` / `hermes --continue` | Resume the most recent session |
|
||||||
|
| `hermes -c "my project"` | Resume a session by name (latest in lineage) |
|
||||||
|
| `hermes --resume <session_id>` | Resume a specific session by ID or title |
|
||||||
| `hermes -w` / `hermes --worktree` | Start in isolated git worktree (for parallel agents) |
|
| `hermes -w` / `hermes --worktree` | Start in isolated git worktree (for parallel agents) |
|
||||||
| `hermes setup` | Configure API keys and settings |
|
| `hermes setup` | Configure API keys and settings |
|
||||||
| `hermes config` | View current configuration |
|
| `hermes config` | View current configuration |
|
||||||
@@ -240,6 +244,8 @@ The unified `hermes` command provides all functionality:
|
|||||||
| `hermes gateway` | Start gateway (messaging + cron scheduler) |
|
| `hermes gateway` | Start gateway (messaging + cron scheduler) |
|
||||||
| `hermes gateway setup` | Configure messaging platforms interactively |
|
| `hermes gateway setup` | Configure messaging platforms interactively |
|
||||||
| `hermes gateway install` | Install gateway as system service |
|
| `hermes gateway install` | Install gateway as system service |
|
||||||
|
| `hermes sessions list` | List past sessions (title, preview, last active) |
|
||||||
|
| `hermes sessions rename <id> <title>` | Rename/title a session |
|
||||||
| `hermes cron list` | View scheduled jobs |
|
| `hermes cron list` | View scheduled jobs |
|
||||||
| `hermes cron status` | Check if cron scheduler is running |
|
| `hermes cron status` | Check if cron scheduler is running |
|
||||||
| `hermes version` | Show version info |
|
| `hermes version` | Show version info |
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ hermes-agent/
|
|||||||
├── cli.py # HermesCLI class — interactive TUI, prompt_toolkit integration
|
├── cli.py # HermesCLI class — interactive TUI, prompt_toolkit integration
|
||||||
├── model_tools.py # Tool orchestration (thin layer over tools/registry.py)
|
├── model_tools.py # Tool orchestration (thin layer over tools/registry.py)
|
||||||
├── toolsets.py # Tool groupings and presets (hermes-cli, hermes-telegram, etc.)
|
├── toolsets.py # Tool groupings and presets (hermes-cli, hermes-telegram, etc.)
|
||||||
├── hermes_state.py # SQLite session database with FTS5 full-text search
|
├── hermes_state.py # SQLite session database with FTS5 full-text search, session titles
|
||||||
├── batch_runner.py # Parallel batch processing for trajectory generation
|
├── batch_runner.py # Parallel batch processing for trajectory generation
|
||||||
│
|
│
|
||||||
├── agent/ # Agent internals (extracted modules)
|
├── agent/ # Agent internals (extracted modules)
|
||||||
@@ -218,7 +218,7 @@ User message → AIAgent._run_agent_loop()
|
|||||||
|
|
||||||
- **Self-registering tools**: Each tool file calls `registry.register()` at import time. `model_tools.py` triggers discovery by importing all tool modules.
|
- **Self-registering tools**: Each tool file calls `registry.register()` at import time. `model_tools.py` triggers discovery by importing all tool modules.
|
||||||
- **Toolset grouping**: Tools are grouped into toolsets (`web`, `terminal`, `file`, `browser`, etc.) that can be enabled/disabled per platform.
|
- **Toolset grouping**: Tools are grouped into toolsets (`web`, `terminal`, `file`, `browser`, etc.) that can be enabled/disabled per platform.
|
||||||
- **Session persistence**: All conversations are stored in SQLite (`hermes_state.py`) with full-text search. JSON logs go to `~/.hermes/sessions/`.
|
- **Session persistence**: All conversations are stored in SQLite (`hermes_state.py`) with full-text search and unique session titles. JSON logs go to `~/.hermes/sessions/`.
|
||||||
- **Ephemeral injection**: System prompts and prefill messages are injected at API call time, never persisted to the database or logs.
|
- **Ephemeral injection**: System prompts and prefill messages are injected at API call time, never persisted to the database or logs.
|
||||||
- **Provider abstraction**: The agent works with any OpenAI-compatible API. Provider resolution happens at init time (Nous Portal OAuth, OpenRouter API key, or custom endpoint).
|
- **Provider abstraction**: The agent works with any OpenAI-compatible API. Provider resolution happens at init time (Nous Portal OAuth, OpenRouter API key, or custom endpoint).
|
||||||
- **Provider routing**: When using OpenRouter, `provider_routing` in config.yaml controls provider selection (sort by throughput/latency/price, allow/ignore specific providers, data retention policies). These are injected as `extra_body.provider` in API requests.
|
- **Provider routing**: When using OpenRouter, `provider_routing` in config.yaml controls provider selection (sort by throughput/latency/price, allow/ignore specific providers, data retention policies). These are injected as `extra_body.provider` in API requests.
|
||||||
|
|||||||
@@ -1724,7 +1724,7 @@ For more help on a command:
|
|||||||
# =========================================================================
|
# =========================================================================
|
||||||
sessions_parser = subparsers.add_parser(
|
sessions_parser = subparsers.add_parser(
|
||||||
"sessions",
|
"sessions",
|
||||||
help="Manage session history (list, export, prune, delete)",
|
help="Manage session history (list, rename, export, prune, delete)",
|
||||||
description="View and manage the SQLite session store"
|
description="View and manage the SQLite session store"
|
||||||
)
|
)
|
||||||
sessions_subparsers = sessions_parser.add_subparsers(dest="sessions_action")
|
sessions_subparsers = sessions_parser.add_subparsers(dest="sessions_action")
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ These are commands you run from your shell.
|
|||||||
| `hermes` | Start interactive chat (default) |
|
| `hermes` | Start interactive chat (default) |
|
||||||
| `hermes chat -q "Hello"` | Single query mode (non-interactive) |
|
| `hermes chat -q "Hello"` | Single query mode (non-interactive) |
|
||||||
| `hermes chat --continue` / `-c` | Resume the most recent session |
|
| `hermes chat --continue` / `-c` | Resume the most recent session |
|
||||||
| `hermes chat --resume <id>` / `-r <id>` | Resume a specific session |
|
| `hermes chat -c "my project"` | Resume a session by name (latest in lineage) |
|
||||||
|
| `hermes chat --resume <id>` / `-r <id>` | Resume a specific session by ID or title |
|
||||||
| `hermes chat --model <name>` | Use a specific model |
|
| `hermes chat --model <name>` | Use a specific model |
|
||||||
| `hermes chat --provider <name>` | Force a provider (`nous`, `openrouter`, `zai`, `kimi-coding`, `minimax`, `minimax-cn`) |
|
| `hermes chat --provider <name>` | Force a provider (`nous`, `openrouter`, `zai`, `kimi-coding`, `minimax`, `minimax-cn`) |
|
||||||
| `hermes chat --toolsets "web,terminal"` / `-t` | Use specific toolsets |
|
| `hermes chat --toolsets "web,terminal"` / `-t` | Use specific toolsets |
|
||||||
@@ -103,7 +104,8 @@ These are commands you run from your shell.
|
|||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `hermes sessions list` | Browse past sessions |
|
| `hermes sessions list` | Browse past sessions (shows title, preview, last active) |
|
||||||
|
| `hermes sessions rename <id> <title>` | Set or change a session's title |
|
||||||
| `hermes sessions export <id>` | Export a session |
|
| `hermes sessions export <id>` | Export a session |
|
||||||
| `hermes sessions delete <id>` | Delete a specific session |
|
| `hermes sessions delete <id>` | Delete a specific session |
|
||||||
| `hermes sessions prune` | Remove old sessions |
|
| `hermes sessions prune` | Remove old sessions |
|
||||||
@@ -154,6 +156,7 @@ Type `/` in the interactive CLI to see an autocomplete dropdown.
|
|||||||
| `/undo` | Remove the last user/assistant exchange |
|
| `/undo` | Remove the last user/assistant exchange |
|
||||||
| `/save` | Save the current conversation |
|
| `/save` | Save the current conversation |
|
||||||
| `/compress` | Manually compress conversation context |
|
| `/compress` | Manually compress conversation context |
|
||||||
|
| `/title [name]` | Set or show the current session's title |
|
||||||
| `/usage` | Show token usage for this session |
|
| `/usage` | Show token usage for this session |
|
||||||
| `/insights [--days N]` | Show usage insights and analytics (last 30 days) |
|
| `/insights [--days N]` | Show usage insights and analytics (last 30 days) |
|
||||||
|
|
||||||
|
|||||||
@@ -229,13 +229,15 @@ Resume options:
|
|||||||
```bash
|
```bash
|
||||||
hermes --continue # Resume the most recent CLI session
|
hermes --continue # Resume the most recent CLI session
|
||||||
hermes -c # Short form
|
hermes -c # Short form
|
||||||
|
hermes -c "my project" # Resume a named session (latest in lineage)
|
||||||
hermes --resume 20260225_143052_a1b2c3 # Resume a specific session by ID
|
hermes --resume 20260225_143052_a1b2c3 # Resume a specific session by ID
|
||||||
|
hermes --resume "refactoring auth" # Resume by title
|
||||||
hermes -r 20260225_143052_a1b2c3 # Short form
|
hermes -r 20260225_143052_a1b2c3 # Short form
|
||||||
```
|
```
|
||||||
|
|
||||||
Resuming restores the full conversation history from SQLite. The agent sees all previous messages, tool calls, and responses — just as if you never left.
|
Resuming restores the full conversation history from SQLite. The agent sees all previous messages, tool calls, and responses — just as if you never left.
|
||||||
|
|
||||||
Use `hermes sessions list` to browse past sessions.
|
Use `/title My Session Name` inside a chat to name the current session, or `hermes sessions rename <id> <title>` from the command line. Use `hermes sessions list` to browse past sessions.
|
||||||
|
|
||||||
### Session Logging
|
### Session Logging
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Every conversation — whether from the CLI, Telegram, Discord, WhatsApp, or Sla
|
|||||||
|
|
||||||
The SQLite database stores:
|
The SQLite database stores:
|
||||||
- Session ID, source platform, user ID
|
- Session ID, source platform, user ID
|
||||||
|
- **Session title** (unique, human-readable name)
|
||||||
- Model name and configuration
|
- Model name and configuration
|
||||||
- System prompt snapshot
|
- System prompt snapshot
|
||||||
- Full message history (role, content, tool calls, tool results)
|
- Full message history (role, content, tool calls, tool results)
|
||||||
@@ -54,6 +55,19 @@ hermes chat -c
|
|||||||
|
|
||||||
This looks up the most recent `cli` session from the SQLite database and loads its full conversation history.
|
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](#session-naming) below), you can resume it by name:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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 Specific Session
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -61,6 +75,9 @@ This looks up the most recent `cli` session from the SQLite database and loads i
|
|||||||
hermes --resume 20250305_091523_a1b2c3d4
|
hermes --resume 20250305_091523_a1b2c3d4
|
||||||
hermes -r 20250305_091523_a1b2c3d4
|
hermes -r 20250305_091523_a1b2c3d4
|
||||||
|
|
||||||
|
# Resume by title
|
||||||
|
hermes --resume "refactoring auth"
|
||||||
|
|
||||||
# Or with the chat subcommand
|
# Or with the chat subcommand
|
||||||
hermes chat --resume 20250305_091523_a1b2c3d4
|
hermes chat --resume 20250305_091523_a1b2c3d4
|
||||||
```
|
```
|
||||||
@@ -68,9 +85,53 @@ hermes chat --resume 20250305_091523_a1b2c3d4
|
|||||||
Session IDs are shown when you exit a CLI session, and can be found with `hermes sessions list`.
|
Session IDs are shown when you exit a CLI session, and can be found with `hermes sessions list`.
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
Session IDs follow the format `YYYYMMDD_HHMMSS_<8-char-hex>`, e.g. `20250305_091523_a1b2c3d4`. You only need to provide enough of the ID to be unique.
|
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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
## Session Management Commands
|
||||||
|
|
||||||
Hermes provides a full set of session management commands via `hermes sessions`:
|
Hermes provides a full set of session management commands via `hermes sessions`:
|
||||||
@@ -88,13 +149,23 @@ hermes sessions list --source telegram
|
|||||||
hermes sessions list --limit 50
|
hermes sessions list --limit 50
|
||||||
```
|
```
|
||||||
|
|
||||||
Output format:
|
When sessions have titles, the output shows titles, previews, and relative timestamps:
|
||||||
|
|
||||||
```
|
```
|
||||||
ID Source Model Messages Started
|
Title Preview Last Active ID
|
||||||
────────────────────────────────────────────────────────────────────────────────────────────────
|
────────────────────────────────────────────────────────────────────────────────────────────────
|
||||||
20250305_091523_a1b2c3d4 cli anthropic/claude-opus-4.6 24 2025-03-05 09:15
|
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
|
||||||
20250304_143022_e5f6g7h8 telegram anthropic/claude-opus-4.6 12 2025-03-04 14:30 (ended)
|
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 Sessions
|
||||||
@@ -122,6 +193,18 @@ hermes sessions delete 20250305_091523_a1b2c3d4
|
|||||||
hermes sessions delete 20250305_091523_a1b2c3d4 --yes
|
hermes sessions delete 20250305_091523_a1b2c3d4 --yes
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Rename a Session
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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
|
### Prune Old Sessions
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -233,7 +316,7 @@ The SQLite database uses WAL mode for concurrent readers and a single writer, wh
|
|||||||
|
|
||||||
Key tables in `state.db`:
|
Key tables in `state.db`:
|
||||||
|
|
||||||
- **sessions** — session metadata (id, source, user_id, model, timestamps, token counts)
|
- **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** — full message history (role, content, tool_calls, tool_name, token_count)
|
||||||
- **messages_fts** — FTS5 virtual table for full-text search across message content
|
- **messages_fts** — FTS5 virtual table for full-text search across message content
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user