Skip to content

[Feature]: Per-topic/per-chat configuration overrides (topic_configs) for gateway sessions #4431

@Chrisr6records

Description

@Chrisr6records

Summary

When running the Hermes gateway with multiple Telegram groups (or Discord servers), every session gets the same personality, system prompt, CLAUDE.md, and working directory. There's no way to specialize the agent per group or per forum topic.

Use case: I run two Telegram groups through one gateway:

  • A project group (horse racing ML project) — needs a domain-specific personality, project CLAUDE.md loaded, and CWD set to the project directory
  • A personal assistant group — needs a warm/practical personality, no project context, home directory CWD

Currently the only option is the global /personality command or agent.system_prompt, which applies to ALL sessions simultaneously.

Proposed Solution: topic_configs in config.yaml

A new config section that maps chat/topic identifiers to per-session overrides:

topic_configs:
  # Match by platform:chat_id (applies to all topics in a group)
  "telegram:-1001234567890":
    personality: coding        # lookup from agent.personalities
    claude_md: ~/projects/myapp/CLAUDE.md
    cwd: ~/projects/myapp
  
  # Match by platform:chat_id:thread_id (specific forum topic)
  "telegram:-1001234567890:42":
    personality: devops
    
  # Different group, different config
  "telegram:-1009876543210":
    system_prompt: "You are a helpful personal assistant..."
    cwd: "~"
    
  # Works for Discord too
  "discord:987654321":
    personality: casual

Fields (all optional, inherits from global when absent)

  • personality — name from agent.personalities dict
  • system_prompt — raw system prompt text (overrides personality)
  • claude_md — explicit path to a CLAUDE.md/context file to load
  • cwd — working directory override for terminal commands

Resolution order (most specific first)

  1. platform:chat_id:thread_id (specific topic/thread)
  2. platform:chat_id (group/channel level)
  3. Global defaults (existing behavior, unchanged)

Implementation

I've implemented this as a working patch. The changes are minimal and purely additive — no existing behavior is affected when topic_configs is absent.

Files changed:

  1. gateway/config.py — New TopicConfig dataclass + topic_configs field on GatewayConfig, parsed from config.yaml
  2. gateway/run.py_resolve_topic_config(source) does the key lookup. _resolve_topic_system_prompt() resolves personality name → prompt text. Per-topic CWD override. Topic config included in agent cache signature.
  3. agent/prompt_builder.pybuild_context_files_prompt() accepts claude_md_override param to load a specific file instead of CWD-based discovery
  4. run_agent.pyAIAgent.__init__ accepts and threads claude_md_override to the prompt builder

The patch hooks into run_sync() in _run_agent() where combined_ephemeral is built — topic config overrides the global _ephemeral_system_prompt when present, otherwise falls through to existing behavior.

I'm happy to submit this as a PR if there's interest. Running it in production on my setup now.

Why This Matters

Multi-group users are effectively locked into one-size-fits-all behavior. The personality system exists but is global. This is the missing piece for anyone running Hermes as a gateway across multiple contexts — project management in one group, personal assistant in another, team support in a third.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havearea/configConfig system, migrations, profilescomp/gatewayGateway runner, session dispatch, deliveryplatform/discordDiscord bot adapterplatform/telegramTelegram bot adaptertype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions