# Agent Reach Probe Module Command Executability Check: Validating External CLI Tools

> Validate Agent Reach probe module command executability by running external CLIs. Get detailed diagnostics ok, missing, broken, timeout, or error for robust tool verification.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-07-10

---

**The Agent Reach probe module validates external command-line tools by actually executing them and classifying results into five distinct states—ok, missing, broken, timeout, or error—providing granular diagnostics beyond simple PATH checks.**

The **Agent Reach probe module command executability check** solves a critical gap in dependency validation for the Panniantong/Agent-Reach repository. While `shutil.which()` can confirm a binary exists on PATH, it cannot detect stale virtual environment shims, missing interpreters, or commands that fail immediately upon execution. The [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) module addresses this by invoking commands with harmless flags like `--version` and categorizing the runtime behavior into actionable health states.

## Why Executability Checks Matter in Agent Reach

Agent Reach depends on numerous external CLI tools such as `twitter-cli`, `rdt-cli`, and `bili-cli`. A binary might present on PATH yet remain unusable due to broken shebangs or outdated virtual environment references. The **probe module** eliminates false positives by testing actual execution, ensuring that the **doctor** health-check system ([`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py)) provides accurate guidance—whether that means reinstalling a package, adding a missing interpreter, or troubleshooting network timeouts.

## The Five ProbeResult States

The `ProbeResult` dataclass in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) captures five specific execution outcomes:

- **ok** — Command executes and returns exit code 0.
- **missing** — Binary not found on PATH via `shutil.which()`.
- **broken** — Binary found but cannot execute (e.g., broken shebang, permission issues).
- **timeout** — Command runs but stalls beyond the configured timeout (default 10 seconds).
- **error** — Command runs but returns a non-zero exit code indicating functional failure.

These granular distinctions allow the doctor system to generate specific remediation hints rather than generic "command not found" errors.

## Core Implementation in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)

### The ProbeResult Dataclass

The result structure is defined as a lightweight dataclass at lines 27-34:

```python

# agent_reach/probe.py

@dataclass
class ProbeResult:
    status: str            # "ok" | "missing" | "broken" | "timeout" | "error"

    output: str = ""
    hint: str = ""

```

This container holds the execution status, captured stdout/stderr, and human-readable guidance for remediation.

### The probe_command Function

The public API entry point `probe_command()` (lines 47-76) accepts configuration for flexible testing:

```python
def probe_command(
    cmd: str,
    args: Sequence[str] = ("--version",),
    timeout: int = 10,
    retries: int = 0,
    package: Optional[str] = None,
) -> ProbeResult:

```

The function first validates PATH presence using `shutil.which()`. If missing, it immediately returns `ProbeResult("missing")`. For found binaries, it delegates to the `_run_once` helper (lines 79-103) which executes the command using `subprocess.run()` within a UTF-8-safe environment provided by `utf8_subprocess_env()` from [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py).

### Error Handling and Classification

The probe distinguishes between infrastructure failures and command errors:

- **Broken detection**: Any `FileNotFoundError` or `OSError` raised after the binary is located indicates a broken installation (stale shim or missing interpreter). Exit codes 126 and 127 also trigger the **broken** status.
- **Timeout handling**: `subprocess.TimeoutExpired` exceptions map to **timeout** with a hint indicating the command exceeded the allotted seconds.
- **Error capture**: All other non-zero exit codes return **error** status with the captured output attached for debugging.

When a broken state is detected, the `reinstall_hint()` function generates tool-specific reinstallation commands, such as `uv tool install --force twitter-cli` or `pipx reinstall twitter-cli`.

## Integration with the Doctor Health-Check System

### Channel-Level Checks

Each platform channel inherits from `BaseChannel` ([`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)) and implements a `check(config)` method that utilizes the probe module. For example, the Reddit channel in [`agent_reach/channels/reddit.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/reddit.py) validates its dependency:

```python
from agent_reach.probe import probe_command

def check(self, config):
    result = probe_command("rdt")
    if result.ok:
        return "ok", "rdt-cli reachable"
    return result.status, result.hint or "rdt-cli not usable"

```

### Aggregation and Reporting

The doctor aggregates these checks in `check_all()` ([`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py)), wrapping each channel validation in exception handling to ensure a single broken backend does not crash the entire health report:

```python

# doctor.py – collection loop

for ch in get_all_channels():
    try:
        status, message = ch.check(config)
        active = getattr(ch, "active_backend", None)
    except Exception as e:
        status, message, active = "error", f"体检异常：{e}", None

```

The `format_report()` function then renders a clear status matrix, displaying icons and specific hints for each probed command, including the Chinese-language remediation guidance for broken Python environment shims.

## Practical Usage Examples

### Direct Command Probing

Import and invoke the probe directly to validate specific tools:

```python
from agent_reach.probe import probe_command

# Check the `twitter` CLI (installed via pipx/uv)

res = probe_command("twitter")
print(f"Status: {res.status}")
if res.hint:
    print(f"Hint: {res.hint}")

```

When the binary is broken, this outputs:

```

Status: broken
Hint: 命令存在但无法执行——通常是系统 Python 升级后 venv 解释器丢失。重装即可修复：
  uv tool install --force twitter-cli
  或：pipx reinstall twitter-cli

```

### Channel Integration

Implement the check contract in custom channels by probing dependencies:

```python

# Inside a custom channel's `check()` method

from agent_reach.probe import probe_command

def check(self, config):
    # Verify that `yt-dlp` is functional

    result = probe_command("yt-dlp", args=["--version"])
    return result.status, result.hint or "yt-dlp ready"

```

### CLI Health Checks

Run the complete diagnostic suite from the command line:

```bash
$ agent-reach doctor

```

This invokes `check_all()` in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py), which iterates through all registered channels, executes their `probe_command()` calls, and displays the formatted report with actionable next steps for any missing or broken dependencies.

## Summary

- The **Agent Reach probe module** ([`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)) provides executable validation beyond PATH checks by actually running commands with `subprocess.run()`.
- **Five distinct states** (ok, missing, broken, timeout, error) allow precise diagnosis of dependency issues.
- The `probe_command()` function uses `utf8_subprocess_env()` from [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py) to ensure consistent execution environments.
- Exit codes 126 and 127 specifically indicate **broken** installations requiring reinstallation.
- Integration with [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) and `BaseChannel` ([`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)) provides automated health reports across all platform backends.
- Public APIs in [`agent_reach/core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/core.py) and CLI entry points in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) expose these diagnostics to end users.

## Frequently Asked Questions

### How does the probe module differ from using `shutil.which()`?

While `shutil.which()` only verifies that a binary exists on PATH, the **Agent Reach probe module** actually executes the command (typically with `--version`) to confirm it runs without errors. This catches stale virtual environment shims, permission issues, and missing interpreters that `shutil.which()` cannot detect.

### What exit codes indicate a broken installation versus a functional error?

Exit codes **126** and **127** specifically trigger the **broken** status in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py), indicating the command cannot execute due to environment issues. All other non-zero exit codes result in **error** status, suggesting the binary runs but encountered application-level failures.

### Can I customize the timeout or arguments for probing a command?

Yes, the `probe_command()` function accepts optional parameters including `timeout` (default 10 seconds), `args` (default `("--version",)`), and `retries`. These allow you to adjust the probe behavior for commands that require different validation flags or longer startup times.

### How does the doctor system handle probe failures without crashing?

The `check_all()` function in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) wraps each channel's `check()` method in a try-except block. If `probe_command()` raises an unexpected exception or the channel check fails, the doctor catches the error, logs it as "error" status, and continues aggregation, ensuring the health report remains complete even when individual probes fail.