mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-27 01:11:40 +00:00
Merge pull request #1495 from NousResearch/fix/814-group-session-isolation
fix(gateway): default group sessions to per-user isolation
This commit is contained in:
commit
9cf7e2f0af
11 changed files with 307 additions and 29 deletions
|
|
@ -848,6 +848,21 @@ voice:
|
|||
|
||||
Use `/voice on` in the CLI to enable microphone mode, `record_key` to start/stop recording, and `/voice tts` to toggle spoken replies. See [Voice Mode](/docs/user-guide/features/voice-mode) for end-to-end setup and platform-specific behavior.
|
||||
|
||||
## Group Chat Session Isolation
|
||||
|
||||
Control whether shared chats keep one conversation per room or one conversation per participant:
|
||||
|
||||
```yaml
|
||||
group_sessions_per_user: true # true = per-user isolation in groups/channels, false = one shared session per chat
|
||||
```
|
||||
|
||||
- `true` is the default and recommended setting. In Discord channels, Telegram groups, Slack channels, and similar shared contexts, each sender gets their own session when the platform provides a user ID.
|
||||
- `false` reverts to the old shared-room behavior. That can be useful if you explicitly want Hermes to treat a channel like one collaborative conversation, but it also means users share context, token costs, and interrupt state.
|
||||
- Direct messages are unaffected. Hermes still keys DMs by chat/DM ID as usual.
|
||||
- Threads stay isolated from their parent channel either way; with `true`, each participant also gets their own session inside the thread.
|
||||
|
||||
For the behavior details and examples, see [Sessions](/docs/user-guide/sessions) and the [Discord guide](/docs/user-guide/messaging/discord).
|
||||
|
||||
## Quick Commands
|
||||
|
||||
Define custom commands that run shell commands without invoking the LLM — zero token usage, instant execution. Especially useful from messaging platforms (Telegram, Discord, etc.) for quick server checks or utility scripts.
|
||||
|
|
|
|||
|
|
@ -14,15 +14,71 @@ Before setup, here's the part most people want to know: how Hermes behaves once
|
|||
|
||||
| Context | Behavior |
|
||||
|---------|----------|
|
||||
| **DMs** | Hermes responds to every message. No `@mention` needed. |
|
||||
| **DMs** | Hermes responds to every message. No `@mention` needed. Each DM has its own session. |
|
||||
| **Server channels** | By default, Hermes only responds when you `@mention` it. If you post in a channel without mentioning it, Hermes ignores the message. |
|
||||
| **Free-response channels** | You can make specific channels mention-free with `DISCORD_FREE_RESPONSE_CHANNELS`, or disable mentions globally with `DISCORD_REQUIRE_MENTION=false`. |
|
||||
| **Threads** | Hermes replies in the same thread. Mention rules still apply unless that thread or its parent channel is configured as free-response. |
|
||||
| **Threads** | Hermes replies in the same thread. Mention rules still apply unless that thread or its parent channel is configured as free-response. Threads stay isolated from the parent channel for session history. |
|
||||
| **Shared channels with multiple users** | By default, Hermes isolates session history per user inside the channel for safety and clarity. Two people talking in the same channel do not share one transcript unless you explicitly disable that. |
|
||||
|
||||
:::tip
|
||||
If you want a normal shared bot channel where people can talk to Hermes without tagging it every time, add that channel to `DISCORD_FREE_RESPONSE_CHANNELS`.
|
||||
If you want a normal bot-help channel where people can talk to Hermes without tagging it every time, add that channel to `DISCORD_FREE_RESPONSE_CHANNELS`.
|
||||
:::
|
||||
|
||||
### Discord Gateway Model
|
||||
|
||||
Hermes on Discord is not a webhook that replies statelessly. It runs through the full messaging gateway, which means each incoming message goes through:
|
||||
|
||||
1. authorization (`DISCORD_ALLOWED_USERS`)
|
||||
2. mention / free-response checks
|
||||
3. session lookup
|
||||
4. session transcript loading
|
||||
5. normal Hermes agent execution, including tools, memory, and slash commands
|
||||
6. response delivery back to Discord
|
||||
|
||||
That matters because behavior in a busy server depends on both Discord routing and Hermes session policy.
|
||||
|
||||
### Session Model in Discord
|
||||
|
||||
By default:
|
||||
|
||||
- each DM gets its own session
|
||||
- each server thread gets its own session namespace
|
||||
- each user in a shared channel gets their own session inside that channel
|
||||
|
||||
So if Alice and Bob both talk to Hermes in `#research`, Hermes treats those as separate conversations by default even though they are using the same visible Discord channel.
|
||||
|
||||
This is controlled by `config.yaml`:
|
||||
|
||||
```yaml
|
||||
group_sessions_per_user: true
|
||||
```
|
||||
|
||||
Set it to `false` only if you explicitly want one shared conversation for the entire room:
|
||||
|
||||
```yaml
|
||||
group_sessions_per_user: false
|
||||
```
|
||||
|
||||
Shared sessions can be useful for a collaborative room, but they also mean:
|
||||
|
||||
- users share context growth and token costs
|
||||
- one person's long tool-heavy task can bloat everyone else's context
|
||||
- one person's in-flight run can interrupt another person's follow-up in the same room
|
||||
|
||||
### Interrupts and Concurrency
|
||||
|
||||
Hermes tracks running agents by session key.
|
||||
|
||||
With the default `group_sessions_per_user: true`:
|
||||
|
||||
- Alice interrupting her own in-flight request only affects Alice's session in that channel
|
||||
- Bob can keep talking in the same channel without inheriting Alice's history or interrupting Alice's run
|
||||
|
||||
With `group_sessions_per_user: false`:
|
||||
|
||||
- the whole room shares one running-agent slot for that channel/thread
|
||||
- follow-up messages from different people can interrupt or queue behind each other
|
||||
|
||||
This guide walks you through the full setup process — from creating your bot on Discord's Developer Portal to sending your first message.
|
||||
|
||||
## Step 1: Create a Discord Application
|
||||
|
|
@ -175,13 +231,25 @@ Add the following to your `~/.hermes/.env` file:
|
|||
|
||||
```bash
|
||||
# Required
|
||||
DISCORD_BOT_TOKEN=your-bot-token-from-developer-portal
|
||||
DISCORD_BOT_TOKEN=your-bot-token
|
||||
DISCORD_ALLOWED_USERS=284102345871466496
|
||||
|
||||
# Multiple allowed users (comma-separated)
|
||||
# DISCORD_ALLOWED_USERS=284102345871466496,198765432109876543
|
||||
```
|
||||
|
||||
Optional behavior settings in `~/.hermes/config.yaml`:
|
||||
|
||||
```yaml
|
||||
discord:
|
||||
require_mention: true
|
||||
|
||||
group_sessions_per_user: true
|
||||
```
|
||||
|
||||
- `discord.require_mention: true` keeps Hermes quiet in normal server traffic unless mentioned
|
||||
- `group_sessions_per_user: true` keeps each participant's context isolated inside shared channels and threads
|
||||
|
||||
### Start the Gateway
|
||||
|
||||
Once configured, start the Discord gateway:
|
||||
|
|
@ -265,6 +333,18 @@ For the full setup and operational guide, see:
|
|||
|
||||
**Fix**: Add your User ID to `DISCORD_ALLOWED_USERS` in `~/.hermes/.env` and restart the gateway.
|
||||
|
||||
### People in the same channel are sharing context unexpectedly
|
||||
|
||||
**Cause**: `group_sessions_per_user` is disabled, or the platform cannot provide a user ID for the messages in that context.
|
||||
|
||||
**Fix**: Set this in `~/.hermes/config.yaml` and restart the gateway:
|
||||
|
||||
```yaml
|
||||
group_sessions_per_user: true
|
||||
```
|
||||
|
||||
If you intentionally want a shared room conversation, leave it off — just expect shared transcript history and shared interrupt behavior.
|
||||
|
||||
## Security
|
||||
|
||||
:::warning
|
||||
|
|
|
|||
|
|
@ -299,17 +299,32 @@ The agent is prompted to use session search automatically:
|
|||
|
||||
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 |
|
||||
| Chat Type | Default Key Format | Behavior |
|
||||
|-----------|--------------------|----------|
|
||||
| Telegram DM | `agent:main:telegram:dm:<chat_id>` | One session per DM chat |
|
||||
| Discord DM | `agent:main:discord:dm:<chat_id>` | One session per DM chat |
|
||||
| WhatsApp DM | `agent:main:whatsapp:dm:<chat_id>` | One session per DM chat |
|
||||
| Group chat | `agent:main:<platform>:group:<chat_id>:<user_id>` | Per-user inside the group when the platform exposes a user ID |
|
||||
| Group thread/topic | `agent:main:<platform>:group:<chat_id>:<thread_id>:<user_id>` | Per-user inside that thread/topic |
|
||||
| Channel | `agent:main:<platform>:channel:<chat_id>:<user_id>` | Per-user inside the channel when the platform exposes a user ID |
|
||||
|
||||
:::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.
|
||||
:::
|
||||
When Hermes cannot get a participant identifier for a shared chat, it falls back to one shared session for that room.
|
||||
|
||||
### Shared vs Isolated Group Sessions
|
||||
|
||||
By default, Hermes uses `group_sessions_per_user: true` in `config.yaml`. That means:
|
||||
|
||||
- Alice and Bob can both talk to Hermes in the same Discord channel without sharing transcript history
|
||||
- one user's long tool-heavy task does not pollute another user's context window
|
||||
- interrupt handling also stays per-user because the running-agent key matches the isolated session key
|
||||
|
||||
If you want one shared "room brain" instead, set:
|
||||
|
||||
```yaml
|
||||
group_sessions_per_user: false
|
||||
```
|
||||
|
||||
That reverts groups/channels to a single shared session per room, which preserves shared conversational context but also shares token costs, interrupt state, and context growth.
|
||||
|
||||
### Session Reset Policies
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue