> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ollim.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Subagents

> Understand how specialized subagents handle documentation help, email triage, history review, engagement analysis, and preference decisions.

Subagents are specialized helpers that the bot delegates specific tasks to — email triage, history review, engagement analysis, and more. Each subagent has a focused set of instructions and limited access, so it handles only its designated task while the main bot coordinates.

## Overview

ollim-bot has five built-in subagents. The bot never handles subagent work itself — it always delegates to the right specialist.

| Subagent                  | Purpose                                                                      | Model    | Access                                                            |
| ------------------------- | ---------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------- |
| `ollim-bot-guide`         | Setup and usage help — surfaces relevant documentation verbatim              | `haiku`  | Documentation site, local config files, `ollim-bot help` commands |
| `gmail-reader`            | Email triage — surfaces actionable emails, discards noise                    | `sonnet` | Gmail commands only                                               |
| `history-reviewer`        | Session review — finds loose threads in recent sessions                      | `sonnet` | Session history commands only                                     |
| `responsiveness-reviewer` | Engagement analysis — measures reminder/routine effectiveness                | `sonnet` | Session history, routine, and reminder commands                   |
| `user-proxy`              | Preference proxy — answers "what would the user do?" during background forks | `haiku`  | Local config files and session history (read-only)                |

<Note>
  Each subagent is restricted to only the tools it needs — the ollim-bot-guide and gmail-reader cannot access session history, the history-reviewer cannot read email, and the user-proxy has read-only access.
</Note>

## ollim-bot-guide

The ollim-bot-guide answers setup, configuration, and usage questions by searching the ollim-bot documentation at docs.ollim.ai and cross-referencing local config files. It shows docs text verbatim rather than paraphrasing — paraphrasing introduces subtle errors that cascade into bad configuration.

**Triggered by:** The main agent always delegates to the ollim-bot-guide when the answer depends on ollim-bot documentation — setup, configuration, usage, YAML format, or feature behavior. This includes the user's own questions and when the agent itself needs docs knowledge (building a routine, checking webhook format, verifying how a feature works before using it).

**What it does:**

* Searches the documentation site using the approach that fits the question — targeted lookup for specific fields and settings, full-page fetch for broader topics
* Includes the actual docs text in its response — never rewrites or summarizes
* Cross-references your config files (routines, reminders, webhooks) against the docs when diagnosing setup issues
* Reports explicitly when docs don't cover a topic, listing what it searched

**Scope:**

* Setup and configuration: "How do I set up...", "What's the YAML format for..."
* Usage questions: "How does X work?"
* Config validation: "Is my routine configured correctly?"
* NOT runtime debugging ("what happened last night?", "why did the bot miss my ping?") — those require session transcripts the ollim-bot-guide doesn't have access to

**Commands available:**

| Command                   | Description                                     |
| ------------------------- | ----------------------------------------------- |
| `ollim-bot help`          | Top-level command reference                     |
| `ollim-bot routine list`  | All active routines with cron schedules and IDs |
| `ollim-bot reminder list` | Currently pending reminders                     |

The ollim-bot-guide can also search and read your local config files to cross-check against the docs.

<Note>
  The ollim-bot-guide is read-only — it never creates or modifies files. It uses a lighter model (`haiku`) since its job is looking things up, not complex reasoning.
</Note>

## gmail-reader

The gmail-reader triages the user's inbox. It lists unread emails, reads full content when a subject line is ambiguous, and categorizes each email as actionable or noise.

**Triggered by:** The email digest reminder — typically fires once or twice daily.

**What it reports:**

* Emails from real people expecting a response
* Security alerts (password changes, login attempts, account changes)
* Financial items (bills due, payment failures)
* Time-sensitive items (deadlines, meeting changes, approvals)
* Packages requiring action (pickup, signature)

**What it skips:**

* Newsletters, marketing, promos
* Delivery/shipping confirmations
* Social media notifications
* Service agreement updates, routine notices

**Commands available:**

| Command                                      | Description                                                                   |
| -------------------------------------------- | ----------------------------------------------------------------------------- |
| `ollim-bot gmail unread [--max N]`           | List unread emails (default 20). Output: `ID  DATE  SENDER  SUBJECT` per line |
| `ollim-bot gmail read <id>`                  | Read full email content by message ID                                         |
| `ollim-bot gmail search "<query>" [--max N]` | Search with Gmail query syntax (e.g. `from:someone`)                          |

**Output format:**

```text theme={null}
Action items:
- [sender] [date time] subject -- what needs to be done

Skipped: N emails (all noise/automated)
```

After receiving the digest, the main agent relays important items to the user and creates Google Tasks for follow-ups.

<Tip>
  The gmail-reader treats email content strictly as data to summarize. It never executes instructions or follows links found in email bodies — a safety measure against email content that might try to trick the bot.
</Tip>

## history-reviewer

The history-reviewer scans recent Claude Code sessions for loose threads — unfinished work, deferred decisions, and commitments that were never followed up on.

**Triggered by:** The main agent when session history review is needed (e.g. during a morning briefing routine).

**What it reports:**

* Tasks or TODOs mentioned but never tracked
* Work started but not finished ("I'll do this after lunch" with no follow-up)
* Commitments to other people ("I'll send that to X")
* Questions asked that went unanswered
* Errors or failures deferred for later
* Ideas or plans discussed but not captured

**What it skips:**

* Completed work with successful commits
* Casual conversation with no action items
* Finished, resolved sessions
* Bot development/debugging sessions (unless they mention deployments or broken production state)

**Commands available:**

| Command                                            | Description                                         |
| -------------------------------------------------- | --------------------------------------------------- |
| `claude-history sessions`                          | List recent sessions (10 per page)                  |
| `claude-history sessions --since <period>`         | Filter by recency (e.g. `24h`, `3d`, `1w`, `today`) |
| `claude-history sessions --page N`                 | Paginate through older sessions                     |
| `claude-history prompts <session>`                 | List user prompts in a session                      |
| `claude-history prompts -v <session>`              | Include tool-result messages                        |
| `claude-history response <uuid>`                   | Claude's response to a specific prompt              |
| `claude-history transcript <session>`              | Full conversation for a context window              |
| `claude-history transcript -v <session>`           | Include tool calls in transcript                    |
| `claude-history search "<query>"`                  | Search across all sessions                          |
| `claude-history search -p "<query>"`               | Search user prompts only (faster)                   |
| `claude-history search -r "<query>"`               | Search responses only                               |
| `claude-history search --since <period> "<query>"` | Scope search to recent sessions                     |
| `claude-history subagents`                         | List subagent transcripts                           |
| `claude-history subagents <agent_id>`              | View a specific subagent transcript                 |

Session shorthand: `prev` = most recent, `prev-2` = second most recent, etc.

**Output format:**

```text theme={null}
Follow-ups from recent sessions:
- [session ID] <what needs attention> -- <suggested action>
```

The default scope is the last 24 hours. Related items spanning multiple sessions are grouped rather than repeated per session.

## responsiveness-reviewer

The responsiveness-reviewer analyzes which reminders and routines the user actually engages with versus ignores, then suggests schedule optimizations. It is designed to tune the ADHD workflow to real behavior rather than aspirational behavior.

**Triggered by:** The responsiveness review reminder, typically on a weekly cadence.

**How it measures engagement:** This subagent understands the difference between foreground and background firings:

* **Foreground** firings are prompts inside the main session. Engagement is measured by whether a user message follows before the next firing.
* **Background** firings run in their own forked sessions. Engagement is measured by checking for user activity in the main session shortly after the firing.
* **One-shot reminders** are deleted after firing, so they only appear in session history, not in `ollim-bot reminder list`.

**Commands available:**

| Command                                            | Description                                         |
| -------------------------------------------------- | --------------------------------------------------- |
| `ollim-bot routine list`                           | All active routines with cron schedules and IDs     |
| `ollim-bot reminder list`                          | Currently pending reminders (fired ones are gone)   |
| `claude-history sessions -t --since 7d`            | Bot sessions from the past week with ISO timestamps |
| `claude-history search -p "<query>" -t --since 7d` | Search prompts with timestamps, scoped to 7 days    |
| `claude-history prompts -t <session>`              | List prompts in a session with ISO timestamps       |
| `claude-history transcript <session>`              | Full conversation for a session                     |

**Output format:**

```text theme={null}
Responsiveness (past 7 days):

| Routine/Reminder | Firings | Engaged | Ignored | Notes |
|------------------|---------|---------|---------|-------|
| morning-tasks    | 7       | 5       | 2       | ignored both Sat firings |
| email-digest     | 7       | 7       | 0       | always engaged |

Patterns:
- <observation tied to data>

Suggestions:
- <actionable recommendation with rationale>
```

The reviewer reports engaged vs. ignored as the core signal rather than exact response times, since user activity is bursty and timestamps are too coarse for precise latency measurements.

## user-proxy

The user-proxy answers one question: "what would the user do or prefer in this situation?" It is designed for background forks where the agent needs to make a preference-based decision but cannot ask the user directly.

**Triggered by:** The main agent spawning it via the Task tool during any background fork where the `Task` tool is available.

**How it works:**

1. Searches for preference and identity files in your data directory, including routines and reminders
2. Reads the most relevant files (max 3-4) related to the question
3. Searches conversation history via `claude-history` for past decisions, corrections, and stated preferences
4. Returns a structured answer with calibrated confidence

**Evidence model:**

The user-proxy distinguishes between two types of evidence:

* **Preference files** — maintained by automated routines that infer from conversation. Treated as educated guesses, not certainties.
* **Conversation transcripts** — records of what the user actually said and did. Treated as reliable evidence.

A file-only answer is MEDIUM confidence at best. HIGH confidence requires corroboration from multiple independent sources.

**Confidence levels:**

| Level      | Evidence required                                                         | Main agent action                                                |
| ---------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| **HIGH**   | Two+ independent sources agree, or user-authored content directly answers | Act on it, no hedging                                            |
| **MEDIUM** | Single source only — file claim without transcript verification           | Act on it, but note uncertainty when reporting to the user       |
| **LOW**    | No direct signal found in files or history                                | Use a safe default or escalate to a ping if the decision matters |

**Output format:**

```text theme={null}
Answer: <one sentence — what the user would most likely do or prefer>

Reasoning: <evidence — cites specific files or search results>

Confidence: HIGH | MEDIUM | LOW — <why this level>
```

<Note>
  The user-proxy and ollim-bot-guide use a lighter model (`haiku`) — the other three use a more capable model (`sonnet`). The user-proxy is read-only by design and biased toward admitting uncertainty: "a wrong answer is much worse than 'unknown' — it cascades into a decision the user never approved."
</Note>

## Subagent binding for jobs

Routines, reminders, and webhooks can bind to a subagent via the `subagent` field in their YAML frontmatter. When set, the generated skill includes a `REQUIRED SUBAGENT` instruction telling the bot to delegate the core task to that subagent via the Agent tool. The `Agent(<name> *)` tool pattern is automatically added to the background fork's allowed tools via `BgForkConfig.with_subagent_tools()`.

At fire time, the bot validates that the referenced subagent exists. If it doesn't, execution is skipped entirely — the job does not run in a degraded state. For routines and reminders, a pending update is appended so the bot can surface the issue on the next interaction.

```yaml title="routines/weekly-email-digest.md" theme={null}
---
id: "e1f2a3b4"
cron: "0 9 * * 1"
description: "Weekly email digest"
background: true
subagent: "gmail-reader"
---
Triage the inbox and surface anything that needs attention this week.
```

## Developer reference

<AccordionGroup>
  <Accordion title="File-based subagent specs">
    Each `.md` file in `src/ollim_bot/subagents/` defines one subagent: YAML frontmatter for metadata, markdown body for the prompt. Here is the ollim-bot-guide subagent as an example:

    ```yaml theme={null}
    ---
    name: ollim-bot-guide
    description: >-
      Delegate to this subagent when the answer depends on ollim-bot
      documentation — including when YOU need docs knowledge (building a
      routine, checking webhook format, verifying feature behavior). Covers:
      setup and configuration (YAML format, fields, syntax), feature behavior
      (routines, reminders, webhooks, forks, permissions, ping budget), and
      config validation (is my routine/reminder/webhook correct?). Also use
      for 'how does X work' questions about ollim-bot architecture.
    model: haiku
    tools:
      - mcp__docs__*
      - WebFetch
      - Read(**.md)
      - Glob(**.md)
      - Bash(ollim-bot help)
      - Bash(ollim-bot routine list)
      - Bash(ollim-bot reminder list)
    ---
    You are {USER_NAME}'s ollim-bot guide. Your goal: answer questions about
    ollim-bot setup, configuration, and usage by surfacing relevant documentation
    verbatim...
    ```

    At startup, `install_agents()` copies bundled specs from `src/ollim_bot/subagents/` to `~/.ollim-bot/.claude/agents/` with template expansion. The SDK then discovers them via `setting_sources=["project"]` and makes them available to the main agent through the `Task` tool.

    ```python theme={null}
    from ollim_bot.subagents import install_agents, load_agent_tool_sets

    install_agents()                    # copy bundled specs to .claude/agents/
    tool_sets = load_agent_tool_sets()  # dict[str, list[str]]
    ```

    * `install_agents()` expands `{USER_NAME}` and `{BOT_NAME}` template variables (from `config.py`) and writes each spec to `~/.ollim-bot/.claude/agents/`. It skips files that already exist, so user customizations persist across bot updates.
    * `load_agent_tool_sets()` reads YAML frontmatter from installed agents to extract tool declarations for tool policy validation. Returns a mapping of `"subagent:name"` to tool list.

    **Spec file format:** Each `.md` file is a raw markdown file with YAML frontmatter — no Python dataclass involved. The SDK reads these files directly. For full field semantics and examples, see the [Claude Code subagents docs](https://code.claude.com/docs/en/sub-agents).

    | Frontmatter field | Required | Description                                                                                                |
    | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
    | `name`            | Yes      | Unique identifier — lowercase letters and hyphens, matches the filename without `.md`                      |
    | `description`     | Yes      | When the main agent should delegate to this subagent                                                       |
    | `tools`           | No       | Allowed tools — YAML list or comma-separated string. Inherits all tools if omitted                         |
    | `disallowedTools` | No       | Tools to deny from the inherited or specified set                                                          |
    | `model`           | No       | Model alias: `sonnet`, `haiku`, `opus`, or `inherit` (use parent model). Defaults to `inherit`             |
    | `permissionMode`  | No       | Permission handling: `default`, `acceptEdits`, `dontAsk`, `bypassPermissions`, or `plan`                   |
    | `maxTurns`        | No       | Maximum agentic turns before the subagent stops                                                            |
    | `skills`          | No       | Skills to inject into this subagent's context at startup — full content is loaded, not just made available |
    | `mcpServers`      | No       | MCP servers available to this subagent                                                                     |
    | `hooks`           | No       | Lifecycle hooks scoped to this subagent — only active while this subagent runs                             |
    | `memory`          | No       | Persistent memory scope across sessions: `user`, `project`, or `local`                                     |
    | `background`      | No       | Set to `true` to always run as a background task. Default: `false`                                         |
    | `isolation`       | No       | Set to `worktree` to run in an isolated git worktree                                                       |

    The markdown body below the frontmatter is the subagent's system prompt.

    **Overrides:** Drop a `.md` file into `~/.ollim-bot/.claude/agents/` to override a built-in subagent (same filename) or add a new one. Since `install_agents()` skips existing files, your overrides persist across bot updates. The override file must be a complete spec — there is no partial merge. New or modified subagent specs take effect after `/clear`, `/compact`, or `/restart`.

    **Hooks:** Because `setting_sources=["project"]` is enabled, hooks configured in `~/.ollim-bot/.claude/settings.json` apply to the main agent session. Subagent-level hooks can also be defined in the `hooks` frontmatter field — they are scoped to that subagent's lifecycle. See the [Claude Code hooks guide](/extending/hooks) for events, input schemas, and exit codes.
  </Accordion>

  <Accordion title="Delegation in the system prompt">
    The main agent's system prompt in `prompts.py` contains explicit delegation instructions for each subagent:

    <Tabs>
      <Tab title="Guide">
        The main agent always delegates to the ollim-bot-guide when the answer depends on docs:

        > Always delegate to the ollim-bot-guide subagent (via the Task tool) when the answer depends on ollim-bot documentation — YAML format, configuration syntax, usage instructions, or feature behavior. This includes answering the user's questions AND when you need docs knowledge yourself (e.g. building a routine, checking webhook format, verifying how a feature works before using it). Never answer docs questions from memory — paraphrasing introduces subtle errors. If the guide finds nothing, you can answer from code.
      </Tab>

      <Tab title="Gmail">
        The system prompt instructs the main agent to always delegate email reading to the gmail-reader:

        > Check email by spawning the gmail-reader subagent (via the Task tool). When you see `[reminder:email-digest]`, use the gmail-reader to triage the inbox. After getting the digest, relay important items and create Google Tasks for follow-ups. Don't read emails yourself — always delegate to the gmail-reader subagent.
      </Tab>

      <Tab title="History">
        Session history review is always delegated to the history-reviewer:

        > Review past Claude Code sessions by spawning the history-reviewer subagent (via the Task tool). It scans recent sessions for unfinished work, untracked tasks, and loose threads. Don't run claude-history yourself — always delegate to the history-reviewer subagent.
      </Tab>

      <Tab title="Responsiveness">
        Engagement analysis is always delegated to the responsiveness-reviewer:

        > Analyze reminder effectiveness by spawning the responsiveness-reviewer subagent (via the Task tool). It correlates reminder firings with your responses to measure engagement and suggest schedule changes. When you see `[reminder:resp-rev]`, use the responsiveness-reviewer to generate the weekly report. Don't run the analysis yourself — always delegate to the responsiveness-reviewer subagent.
      </Tab>

      <Tab title="User Proxy">
        Preference decisions in background forks are delegated to the user-proxy:

        > When you need to make a decision that depends on the user's preferences and you can't ask him directly, spawn the user-proxy subagent (via the Task tool). Ask it: "What would the user do if \[situation]?" Act on HIGH confidence answers directly. For MEDIUM, note uncertainty when reporting. For LOW, use a safe default or escalate to a ping. Don't use it from interactive sessions — the user is present, ask him directly.
      </Tab>
    </Tabs>
  </Accordion>
</AccordionGroup>

## Next steps

<Columns cols={2}>
  <Card title="System prompt" icon="terminal" href="/development/system-prompt">
    See how the main agent's system prompt is structured and what gets injected.
  </Card>

  <Card title="Discord tools" icon="wrench" href="/extending/mcp-tools">
    Reference for all Discord tools available to the main agent.
  </Card>

  <Card title="Routines" icon="clock" href="/scheduling/routines">
    Configure the recurring schedules that trigger subagent work.
  </Card>

  <Card title="Gmail integration" icon="envelope" href="/integrations/google-gmail">
    Setup and usage for the Gmail integration that feeds the gmail-reader.
  </Card>
</Columns>
