# How the Doctor Command Detects Which Channels Are Working in Agent-Reach

> Discover how the doctor command in Agent Reach detects active channels by checking each channel's backend and consolidating status into a health report.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-07-11

---

**The `doctor` command detects working channels by iterating over all channel classes in `agent_reach/channels/`, invoking each channel's `check()` method to probe available backends, and aggregating status results into a unified health report.**

The Agent-Reach repository provides a diagnostic utility that automatically identifies which communication channels are operational. Understanding how the doctor command detects which channels are working requires examining the health check architecture that spans the orchestration layer in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) and the channel-specific implementations under `agent_reach/channels/`.

## Channel Discovery and Health Check Orchestration

The detection process begins in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) within the `check_all()` function. This orchestrator discovers all available channels through `get_all_channels()`, imported from [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py), which inspects the module package to return instantiated channel objects.

For each discovered channel, the system invokes the `check()` method and captures the returned status tuple containing the state (`ok`, `warn`, `off`, or `error`) and a descriptive message. The function also extracts the `active_backend` attribute to identify which specific backend is currently serving the channel.

```python

# agent_reach/doctor.py

def check_all(config: Config) -> Dict[str, dict]:
    results = {}
    for ch in get_all_channels():
        try:
            status, message = ch.check(config)          # per-channel health probe

            active = getattr(ch, "active_backend", None) # backend actually serving the channel

        except Exception as e:                           # misbehaving channel never breaks the report

            status, message, active = "error", f"体检异常：{e}", None
        results[ch.name] = {
            "status": status,
            "name": ch.description,
            "message": message,
            "tier": ch.tier,
            "backends": ch.backends,
            "active_backend": active,
        }
    return results

```

## The Check Method: From Base Implementation to Concrete Channels

Each channel inherits from the abstract `Channel` class defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). The health detection mechanism relies on the `check()` method, which channels override to implement specific validation logic.

### Base Channel Implementation

The base class provides a default `check()` implementation that marks the channel as `"ok"` if it has any built-in backends, automatically selecting the first backend as the active one.

```python

# agent_reach/channels/base.py

def check(self, config=None) -> Tuple[str, str]:
    self.active_backend = self.backends[0] if self.backends else "内置"
    return "ok", f"{'、'.join(self.backends) if self.backends else '内置'}"

```

### Multi-Backend Probing (Twitter Example)

Concrete channels override the base `check()` method to implement real health verification. The `TwitterChannel` in [`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py) demonstrates multi-backend detection by probing three possible backends: `twitter-cli`, `OpenCLI`, and the legacy `bird CLI`.

Using `probe_command` from [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py), the channel executes lightweight commands like `twitter status` or `opencli_status()` to determine backend availability. The first backend returning `"ok"` becomes the `active_backend`; if none return `"ok"` but one returns `"warn"`, the channel reports `"warn"`; otherwise, it returns `"error"`.

```python

# agent_reach/channels/twitter.py

def check(self, config=None):
    self.active_backend = None
    findings = []
    for backend in self.ordered_backends(config):
        # ... probe logic ...

        if result is None:          # not installed → ignore

            continue
        findings.append((backend, *result))
    for wanted in ("ok", "warn"):
        for backend, status, message in findings:
            if status == wanted:
                self.active_backend = backend
                return status, message
    # ... error handling ...

```

## Error Handling and Resilience

The detection mechanism includes robust exception handling to prevent individual channel failures from corrupting the entire report. If a channel's `check()` method raises an exception, `check_all()` catches the error and records the status as `"error"` with the exception message, allowing the doctor command to continue evaluating remaining channels.

After `check_all()` returns the raw dictionary, `format_report()` (also in [`doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/doctor.py)) transforms the results into a human-readable Rich-styled text block for CLI display.

## Running the Doctor Command

### CLI Usage

Invoke the health check from the terminal:

```bash
python -m agent_reach.cli doctor

```

The CLI calls `check_all()`, then prints the formatted report showing which channels are available and which backends are active.

### Programmatic Usage

Access the detection logic directly in Python:

```python
from agent_reach.doctor import check_all, format_report
from agent_reach.config import Config

cfg = Config()                     # loads ~/.agent-reach/config.yaml

raw = check_all(cfg)               # → dict with per-channel status

print(format_report(raw))          # → Rich output matching CLI

```

### Adding Custom Channels

To include custom channels in the health check, create a class inheriting from `Channel` and implement the `check()` method:

```python

# mychannel.py

from .base import Channel
from agent_reach.probe import probe_command

class MyChannel(Channel):
    name = "my"
    description = "My custom platform"
    backends = ["mycli"]
    tier = 1

    def check(self, config=None):
        probe = probe_command("mycli", ["status"], timeout=10, retries=1)
        if probe.status == "missing":
            return "warn", "mycli not installed"
        if probe.ok:
            self.active_backend = "mycli"
            return "ok", "mycli ready"
        return "error", "mycli present but broken"

```

Place the file in `agent_reach/channels/` and ensure it is imported in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to automatically include it in the doctor's detection cycle.

## Summary

- **Channel discovery** occurs through `get_all_channels()` in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py), which locates all channel classes.
- **Health probing** happens via the `check()` method defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) and overridden by concrete implementations.
- **Multi-backend detection** allows channels like `TwitterChannel` to test multiple backends and select the first working one.
- **Exception safety** ensures that one broken channel cannot hide the status of others.
- **Report formatting** converts raw status dictionaries into readable output via `format_report()` in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py).

## Frequently Asked Questions

### What status codes does the doctor command return?

The doctor command returns four status codes: `"ok"` for fully operational channels, `"warn"` for channels with degraded functionality, `"off"` for unavailable channels, and `"error"` for channels that threw exceptions during the check. These statuses are determined by each channel's `check()` method implementation.

### How does the doctor command handle channels with multiple backends?

Channels with multiple backends, such as `TwitterChannel`, iterate through an ordered list of backends using `ordered_backends()` and probe each one using `probe_command()` from [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py). The first backend returning `"ok"` becomes the `active_backend`; if none are `"ok"` but one returns `"warn"`, that backend is selected with a warning status.

### Can I run health checks programmatically without the CLI?

Yes, import `check_all()` and `format_report()` from [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) along with `Config` from [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py). Pass a configuration instance to `check_all()` to receive a dictionary of results, then pass those results to `format_report()` to generate the same Rich-formatted output shown in the CLI.

### Where should I add custom channels to include them in the doctor check?

Place custom channel files in the `agent_reach/channels/` directory and ensure they are imported in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). The `get_all_channels()` function automatically discovers any class inheriting from `Channel`, making it immediately available to the doctor command's detection cycle without additional configuration.