Skip to content

Feature: Single-Daemon Multi-Agent with Per-Topic Workspace & Memory Isolation #9514

@willy-scr

Description

@willy-scr

Overview

Hermes currently requires one profile (and one gateway process) per agent. If you want a coding assistant, a CS bot, and a personal assistant — each with its own workspace, memory, and personality — you run three separate gateway processes. Each one eats memory, has its own event loop, and maintains separate platform connections.

OpenClaw solves this with a single daemon that hosts multiple agents, each with isolated workspaces and memory, routing messages by session key (including per-topic in groups). This issue proposes bringing a similar architecture to Hermes.

What OpenClaw Does

OpenClaw runs one Node.js Gateway daemon that owns all state and connections. Multiple agents live inside it:

  • Per-agent workspace: Each agent gets its own directory (~/.openclaw/agents/<id>/workspace/) with separate MEMORY.md, SOUL.md, daily logs, skills, and state files
  • Per-topic session keys: Session routing includes topic ID for Telegram forums: agent::<name>::<platform>::group::<id>::topic:<id>. Each topic in a group gets its own conversation context and memory
  • Shared daemon: One process, one set of platform connections (one Telegram bot token, one Discord bot), one event loop
  • Memory isolation: Agent A's memory is never visible to Agent B unless explicitly shared via sharedPaths
  • Resource efficiency: No duplicate event loops, no duplicate API connections, no per-process overhead

The key architectural insight: the Gateway is the only process that holds messaging sessions — exactly one Telegram session, one Discord session, etc. Agents are logical tenants inside the daemon, not separate processes.

Current State in Hermes

Profile system (hermes -p <name>):

  • Each profile gets its own ~/.hermes/profiles/<name>/ directory (config, memory, sessions, skills, cron, logs)
  • Each profile runs a separate gateway process
  • Each profile needs its own platform credentials (bot token, Discord token)
  • Profiles cannot share a single Telegram bot connection

What works well:

  • Complete isolation — profiles never interfere with each other
  • Simple mental model — one process per agent
  • Independent lifecycle — restart one agent without affecting others
  • Profile migration is straightforward (hermes profile migrate)

What's missing:

  • No way to run multiple agents behind one gateway process
  • No per-topic workspace/memory isolation within a single group
  • No way for one Telegram bot to serve different "personalities" in different topics
  • Running N agents = N gateway processes = N× memory overhead
  • Each agent needs its own platform credentials (can't share a bot token)

Proposed Architecture

Agent-as-Tenant Model

Instead of one profile = one process, introduce agents as tenants within a single gateway:

Gateway (single process)
├── Platform connections (1 Telegram bot, 1 Discord bot, etc.)
├── Agent Router
│   ├── Agent "coding" (workspace: profiles/coding/)
│   │   ├── SOUL.md, MEMORY.md, skills/
│   │   ├── Session: telegram:topic:chat1:101 → coding agent
│   │   └── Session: telegram:topic:chat1:102 → coding agent
│   ├── Agent "cs-bot" (workspace: profiles/cs-bot/)
│   │   ├── SOUL.md, MEMORY.md, skills/
│   │   └── Session: telegram:topic:chat1:201 → cs-bot agent
│   └── Agent "personal" (workspace: profiles/personal/)
│       ├── SOUL.md, MEMORY.md, skills/
│       └── Session: telegram:dm:user1 → personal agent
└── Shared resources (event loop, platform adapters, tool registries)

Per-Topic Session Routing

Extend session key resolution to include topic-level granularity with agent assignment:

Session key format:
  telegram:topic:<chat_id>:<topic_id>  →  routes to agent X
  telegram:group:<chat_id>:<user_id>   →  routes to agent Y
  telegram:dm:<user_id>                →  routes to agent Z

Each topic in a Telegram forum group maps to a specific agent. That agent gets its own:

  • Conversation history
  • Memory (MEMORY.md scoped to that agent)
  • Skills and toolsets
  • System prompt / personality

Agent Routing Config

agents:
  - id: coding
    workspace: profiles/coding/
    topics:
      - telegram:-100XXXX:101    # coding-fork topic → coding agent
      - telegram:-100XXXX:102    # coding-help topic → coding agent
    dm_scope: per-peer
    model: anthropic/claude-opus-4.6

  - id: cs-bot
    workspace: profiles/cs-bot/
    topics:
      - telegram:-100XXXX:201    # support topic → cs-bot agent
    model: openai/gpt-5.4

  - id: personal
    workspace: profiles/personal/
    dm:
      - telegram:12345678        # DMs from owner → personal agent
    model: anthropic/claude-opus-4.6

Workspace Isolation

Each agent tenant reads/writes to its own workspace directory:

  • profiles/<id>/config.yaml — agent-specific config (model, tools, skills)
  • profiles/<id>/memories/MEMORY.md — agent-specific long-term memory
  • profiles/<id>/skills/ — agent-specific skills
  • profiles/<id>/cron/ — agent-specific scheduled jobs
  • profiles/<id>/state.db — agent-specific session database

No cross-agent memory leakage. An agent in topic 101 cannot see or write to the workspace of the agent in topic 201.

Implementation Phases

Phase 1: Multi-Agent Routing in Single Gateway

  • Add agent router to gateway that maps session keys to agent configs
  • Extend gateway/run.py to load multiple agent definitions from config
  • Each agent gets its own AIAgent instance with isolated workspace
  • Platform adapters dispatch messages to the correct agent based on routing rules
  • Effort: Medium-High
  • Dependencies: None

Phase 2: Per-Topic Memory & Workspace

  • Extend session key to include topic ID for Telegram forums
  • Each topic-session writes to its assigned agent's workspace
  • Memory tool reads/writes scoped to the active agent's workspace
  • Skills loaded per-agent (not per-gateway)
  • Effort: Medium
  • Dependencies: Phase 1

Phase 3: Shared Resources & Cross-Agent Communication

  • Agents share platform connections (one bot token for all)
  • Optional shared memory paths (like OpenClaw's sharedPaths)
  • Inter-agent messaging (agent A can send context to agent B)
  • Shared tool registries to reduce memory footprint
  • Effort: High
  • Dependencies: Phase 1 + 2

Phase 4: Hot-Reload & Agent Lifecycle

  • Add/remove agents without restarting the gateway
  • Per-agent restart (reset conversation, reload skills)
  • Per-agent health monitoring
  • Agent-level resource limits (token budgets, rate limits)
  • Effort: Medium-High
  • Dependencies: Phase 1

Pros & Cons

Pros

  • 10× resource savings — one process instead of N for N agents
  • One bot token serves all agents — no need for separate Telegram bots
  • Per-topic specialization — different agents handle different topics in the same group
  • Memory isolation — no cross-contamination between agent workspaces
  • Backward compatible — single-profile mode works exactly as today
  • Simpler ops — one process to monitor, one log stream, one restart

Cons / Risks

  • Single point of failure — one crash kills all agents (mitigated by Phase 4 hot-reload)
  • Resource contention — one agent's heavy task could slow others (mitigated by resource limits)
  • Config complexity — routing rules add a new config surface to learn
  • Testing difficulty — multi-tenant routing has more edge cases than single-profile
  • Migration path — existing multi-profile users need migration guidance

Open Questions

  1. Should agents share a single state.db or have separate databases? Separate is simpler and more isolated. Shared enables cross-agent session search.
  2. How to handle cron jobs? Each agent gets its own cron schedule, or a unified cron with agent routing?
  3. Tool registry sharing? Can agents share tool registrations (same tools, different schemas) or does each need its own?
  4. What happens when two agents are addressed simultaneously? Queue per-agent or true parallel execution within one event loop?
  5. Should this replace the profile system or extend it? Extend seems safer — profiles become the workspace directories that agents reference.
  6. How does this interact with the existing permission tiers (Feature: Gateway Permission Tiers — Role-Based Access Control (Owner/Admin/User/Guest) for Messenger Platforms #527 / PR feat(gateway): user permission tiers — role-based access control for messaging platforms #4443)? Permission checks would need to be per-agent, not per-gateway.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/agentCore agent loop, run_agent.py, prompt buildercomp/gatewayGateway runner, session dispatch, deliverytool/memoryMemory tool and memory providerstype/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