---
icon: lucide/user
---

# Agent Configuration

Agents are the core building blocks of MindRoom. Each agent is a specialized AI actor with specific capabilities.

## Basic Agent

```yaml
agents:
  assistant:
    display_name: Assistant
    role: A helpful AI assistant
    model: sonnet
    rooms: [lobby]
```

## Full Configuration

```yaml
agents:
  developer:
    # Display name shown in Matrix
    display_name: Developer

    # Role description - guides the agent's behavior
    role: Generate code, manage files, execute shell commands

    # Model to use (defined in models section)
    model: sonnet

    # Tools the agent can use
    tools:
      - file
      - shell
      - github

    # Skills the agent can use (defined in skills section or plugins)
    skills:
      - my_custom_skill

    # Custom instructions
    instructions:
      - Always read files before modifying them
      - Use clear variable names
      - Add comments for complex logic

    # Rooms to join (will be created if they don't exist)
    rooms:
      - lobby
      - dev

    # Enable markdown formatting
    markdown: true

    # Enable Agno Learning for this agent
    learning: true

    # Learning mode: always (automatic) or agentic (tool-driven)
    learning_mode: always

    # Memory backend override for this agent (optional: mem0 or file)
    memory_backend: file

    # Custom file-memory scope directory (optional, overrides default <root>/agent_<name>/)
    memory_file_path: ./openclaw_data

    # Assign agent to one or more configured knowledge bases (optional)
    knowledge_bases: [docs]

    # Optional: additional files loaded into role context at agent init/reload
    context_files:
      - ./openclaw_data/SOUL.md
      - ./openclaw_data/AGENTS.md
      - ./openclaw_data/USER.md
      - ./openclaw_data/IDENTITY.md
      - ./openclaw_data/MEMORY.md
      - ./openclaw_data/TOOLS.md
      - ./openclaw_data/HEARTBEAT.md

    # Whether to include defaults.tools for this agent (default: true)
    include_default_tools: true

    # Response mode: "thread" (replies in Matrix threads) or "room" (plain room messages)
    thread_mode: thread

    # Optional room-specific overrides for thread mode
    # Keys may be managed room aliases/names or Matrix room IDs
    room_thread_modes:
      lobby: thread
      bridge_telegram: room
      "!abc123:example.com": room

    # Tools to route through scoped workers via the sandbox proxy (optional, inherits from defaults)
    worker_tools: [shell, file]

    # How proxied tool state is shared (optional, inherits from defaults)
    worker_scope: user_agent

    # Allow this agent to read and modify its own config at runtime
    allow_self_config: false

    # Delegate tasks to other agents via tool calls
    delegate_to:
      - research
      - finance

    # History context controls (all optional, inherit from defaults)
    num_history_runs: null
    num_history_messages: null
    compress_tool_results: true
    enable_session_summaries: false
    max_tool_calls_from_history: null

```

## Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `display_name` | string | *required* | Human-readable name shown in Matrix as the bot's display name |
| `role` | string | `""` | System prompt describing the agent's purpose — guides its behavior and expertise |
| `model` | string | `"default"` | Model name (must match a key in the `models` section) |
| `tools` | list | `[]` | Agent-specific tool names (see [Tools](../tools/index.md)); effective tools are `tools + defaults.tools` with duplicates removed |
| `include_default_tools` | bool | `true` | When `true`, append `defaults.tools` to this agent's `tools`; set to `false` to opt this agent out |
| `skills` | list | `[]` | Skill names the agent can use (see [Skills](../skills.md)) |
| `instructions` | list | `[]` | Extra lines appended to the system prompt after the role |
| `rooms` | list | `[]` | Room aliases to auto-join; rooms are created if they don't exist |
| `markdown` | bool | `null` | When enabled, the agent is instructed to format responses as Markdown. Inherits from `defaults.markdown` (default: `true`) |
| `learning` | bool | `null` | Enable [Agno Learning](https://docs.agno.com/agents/learning) — the agent builds a persistent profile of user preferences and adapts over time. Inherits from `defaults.learning` (default: `true`) |
| `learning_mode` | string | `null` | `always`: agent automatically learns from every interaction. `agentic`: agent decides when to learn via a tool call. Inherits from `defaults.learning_mode` (default: `"always"`) |
| `memory_backend` | string | `null` | Memory backend override for this agent (`"mem0"` or `"file"`). Inherits from global `memory.backend` when omitted |
| `memory_file_path` | string | `null` | Custom directory to use as the file-memory scope for this agent instead of the default `<root>/agent_<name>/`. Useful for pointing an agent at an existing workspace (e.g. an OpenClaw workspace). Resolved relative to the config file directory |
| `knowledge_bases` | list | `[]` | Knowledge base IDs from top-level `knowledge_bases` — gives the agent RAG access to the indexed documents |
| `context_files` | list | `[]` | File paths loaded at agent init/reload and prepended to role context (under `Personality Context`) |
| `thread_mode` | string | `"thread"` | `thread`: responses are sent in Matrix threads (default). `room`: responses are sent as plain room messages with a single persistent session per room — ideal for bridges (Telegram, Signal, WhatsApp) and mobile |
| `room_thread_modes` | map | `{}` | Per-room thread mode overrides keyed by room alias/name or Matrix room ID. Values are `thread` or `room`. Overrides apply before `thread_mode` fallback |
| `num_history_runs` | int | `null` | Number of prior Agno runs to include as history context (`null` = all). Mutually exclusive with `num_history_messages` |
| `num_history_messages` | int | `null` | Max messages from history. Mutually exclusive with `num_history_runs` |
| `compress_tool_results` | bool | `null` | Compress tool results in history to save context. Inherits from `defaults.compress_tool_results` (default: `true`) |
| `enable_session_summaries` | bool | `null` | Generate AI summaries of older conversation segments for compaction (each summary costs an extra LLM call). Inherits from `defaults.enable_session_summaries` (default: `false`) |
| `max_tool_calls_from_history` | int | `null` | Limit tool call messages replayed from history (`null` = no limit) |
| `show_tool_calls` | bool | `null` | Show tool-call markers and trace metadata in Matrix messages. Inherits from `defaults.show_tool_calls` (default: `true`). When `false`, inline markers and `io.mindroom.tool_trace` are omitted from sent Matrix message content. Note: this flag is not currently enforced by the OpenAI-compatible `/v1/chat/completions` path. |
| `worker_tools` | list | `null` | Tool names to route through the [sandbox proxy](../deployment/sandbox-proxy.md). Inherits from `defaults.worker_tools` (default: `null` — defers to env vars). Set to `[]` to explicitly disable proxy routing for this agent |
| `worker_scope` | string | `null` | Worker-state sharing mode for proxied tools. Inherits from `defaults.worker_scope`. Valid values are `shared`, `user`, `user_agent`, and `room_thread` |
| `allow_self_config` | bool | `null` | Give this agent a scoped tool to read and modify its own configuration at runtime. Inherits from `defaults.allow_self_config` (default: `false`). Lighter-weight alternative to the `config_manager` tool |
| `delegate_to` | list | `[]` | Agent names this agent can delegate tasks to via tool calls (see [Agent Delegation](#agent-delegation)) |

Each entry in `knowledge_bases` must match a key under `knowledge_bases` in `config.yaml`.

Per-agent fields with a `null` default inherit from the `defaults` section at runtime.
Per-agent values override them.
`memory.backend` is the global memory default, and `agents.<name>.memory_backend` overrides it per agent.
`show_stop_button` and `enable_streaming` are global-only settings in `defaults` and cannot be overridden per-agent.
The dashboard Agents tab exposes this as the **Memory Backend** selector for each agent.

Learning data is persisted to `mindroom_data/learning/<agent>.db`, so it survives container restarts when the storage directory is mounted.

## Worker Routing

`worker_tools` decides which toolkits are executed through the sandbox proxy instead of directly in the main MindRoom process.
`worker_scope` decides which proxied calls share the same worker-owned state directory.
Some credential-backed custom tools stay local even if they are listed in `worker_tools`.
Currently that local-only set is `gmail`, `google_calendar`, `google_sheets`, and `homeassistant`.

The supported `worker_scope` values are:

- `shared`: one shared worker state per agent.
- `user`: one worker state per requester.
- `user_agent`: one worker state per requester and agent.
- `room_thread`: one worker state per room thread, or per room when no thread ID exists.

Leave `worker_scope` unset to keep proxied calls unscoped.
They still run in the sandbox runner, but they do not get a worker-specific storage root.
`worker_scope` primarily affects proxied tool execution, and it also affects dashboard credential support and OpenAI-compatible agent eligibility.

The dashboard credential UI can only manage credentials for unscoped agents and agents with `worker_scope=shared`.
Agents using `user`, `user_agent`, or `room_thread` treat credentials as runtime-owned worker state instead of dashboard-managed state.

## Thread Mode Resolution

Thread mode is resolved per message using the current room ID.
For an agent, MindRoom checks `room_thread_modes` in this order.
First, it checks an exact room ID key.
Second, it checks the managed room key/alias associated with that room ID.
Third, it resolves each configured `room_thread_modes` key to a room ID and matches that against the current room.
If none match, it falls back to `thread_mode`.

For a team, MindRoom resolves mode per member agent for that room.
If all member agents resolve to the same mode, the team uses that mode.
If member modes differ, the team defaults to `thread`.

For the router, MindRoom resolves mode using agents relevant to the active room.
This includes agents directly configured for the room and agents included via `teams.<name>.rooms`.
If all relevant agents resolve to the same mode, the router uses that mode.
If modes are mixed, the router defaults to `thread`.

## File-Based Context Loading

You can inject file content directly into an agent's role context without using a knowledge base.

`context_files` behavior:

- Paths are resolved relative to the config file directory
- Existing files are loaded in list order and added under `Personality Context`
- Missing files are skipped with a warning in logs

This loading happens when the agent is created (and on config reload), not continuously on every message.

## Agent Delegation

Agents can delegate tasks to other agents using the `delegate_to` field. When configured, a delegation tool is automatically added to the agent — no need to include `"delegate"` in the `tools` list.

The delegated agent runs as a fresh, one-shot instance with no shared session or history. It executes the task and returns its response as the tool result.

```yaml
agents:
  leader:
    display_name: Leader
    role: Orchestrate tasks by delegating to specialist agents
    model: sonnet
    delegate_to: [code, research]
    rooms: [lobby]

  code:
    display_name: CodeAgent
    role: Generate code, manage files
    model: sonnet
    tools: [file, shell]
    delegate_to: [research]  # can further delegate
    rooms: [lobby]

  research:
    display_name: ResearchAgent
    role: Research topics and provide summaries
    model: sonnet
    tools: [duckduckgo]
    rooms: [lobby]
```

**Constraints:**

- Targets must reference existing agent names in the config
- An agent cannot delegate to itself
- Recursive delegation is supported (agent A delegates to B, B delegates to C) up to a maximum depth of 3

## Rich Prompt Agents

Certain agent names (the YAML key, not `display_name`) have built-in rich prompts:

`code`, `research`, `calculator`, `general`, `shell`, `summary`, `finance`, `news`, `data_analyst`

When using these names, the built-in prompt replaces the `role` field and any custom `instructions` are ignored.

## Defaults

The `defaults` section sets fallback values for all agents. Any agent that omits a setting inherits the value from here.

```yaml
defaults:
  tools: [scheduler]                   # Tools added to every agent by default (set [] to disable)
  markdown: true                        # Format responses as Markdown
  learning: true                        # Enable Agno Learning
  learning_mode: always                 # "always" or "agentic"
  max_preload_chars: 50000              # Hard cap for preloaded context from context_files
  show_stop_button: true                # Show a stop button while agent is responding (global-only, cannot be overridden per-agent)
  num_history_runs: null                # Number of prior runs to include (null = all)
  num_history_messages: null            # Max messages from history (null = use num_history_runs)
  enable_streaming: true                # Stream agent responses via progressive message edits
  compress_tool_results: true           # Compress tool results in history to save context
  enable_session_summaries: false       # AI summaries of older conversation segments (costs extra LLM call)
  max_tool_calls_from_history: null     # Limit tool call messages replayed from history (null = no limit)
  show_tool_calls: true                 # Show tool-call markers and trace metadata in message content
  worker_tools: null                     # Tool names to route through workers (null = use env var config, [] = disable)
  worker_scope: null                     # Worker state scope for proxied tools (shared, user, user_agent, room_thread)
  allow_self_config: false               # Allow agents to read/modify their own config at runtime
```

To opt out a specific agent:

```yaml
agents:
  researcher:
    display_name: Researcher
    role: Focus on deep research
    include_default_tools: false
    tools: [web_search]
```
