# How Agent Reach's Probe Module Tests Connectivity to External Platforms

> Agent Reach's probe module tests external platform connectivity by running a harmless version command. Discover how it classifies results into five states: ok, missing, broken, timeout, or error.

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

---

**The `agent_reach.probe` module runs a harmless `--version` command to verify CLI tools are actually executable, classifying results into five states: `ok`, `missing`, `broken`, `timeout`, or `error`.**

Agent Reach depends on external command-line tools to interact with platforms like Twitter and Reddit. Before attempting any operation, the probe module validates that these tools are not merely present on `PATH` but genuinely functional. This prevents silent failures caused by broken shims, missing interpreters, or permission issues that would otherwise derail agent tasks.

---

## Core Architecture: The Five Status States

The probe module uses a deterministic classification system to describe exactly why a tool check failed. This granularity distinguishes Agent Reach from simpler "file exists" checks.

| Status | Cause | Typical Fix |
|--------|-------|-------------|
| `ok` | Command exits 0 with output | None needed |
| `missing` | `shutil.which` returns `None` | Install the package |
| `broken` | Found but not executable (exit 126/127, `FileNotFoundError`, `OSError`) | Reinstall via `uv` or `pipx` |
| `timeout` | Exceeds configured duration | Check system load or increase timeout |
| `error` | Non-zero exit code (not 126/127) | Review tool-specific error output |

The `ProbeResult` dataclass bundles these fields:

```python
from dataclasses import dataclass

@dataclass
class ProbeResult:
    status: str      # one of the five states above

    output: str      # stdout + stderr captured

    hint: str        # human-readable remediation advice

```

---

## The probe_command Implementation

Located in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py), the `probe_command` function orchestrates the validation workflow through four discrete phases.

### Phase 1: Binary Location

The function first attempts to locate the executable using `shutil.which`. If this returns `None`, the probe immediately returns `ProbeResult("missing")` without attempting execution.

```python

# Simplified excerpt from probe.py lines 67-70

binary_path = shutil.which(cmd)
if binary_path is None:
    return ProbeResult(status="missing", output="", hint=_reinstall_hint(package))

```

### Phase 2: Clean Environment Setup

Before execution, `_run_once` constructs a controlled subprocess environment via `utf8_subprocess_env()` from [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py). This ensures consistent UTF-8 encoding and allows users to inject or strip specific variables.

### Phase 3: Execution and Classification

The `_run_once` helper (lines 84-100) executes the probe command and classifies exceptions and exit codes:

| Condition | Result Status | Source Lines |
|-----------|---------------|--------------|
| `FileNotFoundError` or `OSError` | `broken` | 106-110 |
| `subprocess.TimeoutExpired` | `timeout` | 111-112 |
| Exit code 126 or 127 | `broken` | 114-115 |
| Other non-zero exit | `error` | 118-120 |

Exit codes 126 and 127 are POSIX standard codes meaning "command not executable" and "command not found" respectively—these indicate a broken installation even when the file exists.

### Phase 4: Retry Logic for Transient Failures

For `timeout` and `error` statuses, `probe_command` retries up to the configured limit before finalizing the result. This handles flaky network-dependent tools or momentary system load spikes.

```python

# Simplified retry loop from probe.py lines 72-80

for attempt in range(retries + 1):
    result = _run_once(cmd, args, env, remove_env, timeout)
    if result.status in ("ok", "missing", "broken"):
        return result
    # retry on timeout or error

```

---

## Practical Usage Examples

### Basic Tool Health Check

```python
from agent_reach.probe import probe_command

result = probe_command("yt-dlp")  # probes `yt-dlp --version`

if result.ok:
    print("Tool is healthy:", result.output)
else:
    print(f"Problem ({result.status}): {result.hint}")

```

### Custom Environment Control

```python
result = probe_command(
    "some-tool",
    env={"PROBE_ONLY": "yes"},
    remove_env=("UNWANTED_VAR",),
    retries=2,
)

```

### Detecting Broken Shims

A stale pipx or homebrew shim often presents as a file that exists but fails to execute:

```python
result = probe_command("stale-tool", package="stale-tool-pkg")
if result.status == "broken":
    print("Reinstall hint:", result.hint)
    # Output: "Try reinstalling with: uv tool install stale-tool-pkg or pipx install stale-tool-pkg"

```

### Handling Flaky Executions

```python

# First run fails with timeout, second succeeds → returns ok status

result = probe_command("flaky-tool", retries=1)

```

---

## Integration with Platform Channels

Each platform channel in Agent Reach implements a `check()` method that delegates to `probe_command`. For example, [`twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/twitter.py) and [`reddit.py`](https://github.com/Panniantong/Agent-Reach/blob/main/reddit.py) call the probe for their respective CLI dependencies. This unified approach ensures that the Doctor diagnostics system can provide specific, actionable guidance regardless of which platform fails validation.

The hint generation via `reinstall_hint` (lines 38-44) consistently mentions both `uv` and `pipx` as installation options, accommodating different user preferences.

---

## Source File Reference

| File | Purpose | Key Components |
|------|---------|----------------|
| [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) | Core probe implementation | `ProbeResult`, `probe_command`, `_run_once`, `reinstall_hint` |
| [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py) | Environment construction | `utf8_subprocess_env()` |
| [`tests/test_probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_probe.py) | Comprehensive test coverage | Unit tests for all five status states, retry logic, environment handling |

- [probe.py source](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)
- [test_probe.py source](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_probe.py)
- [process.py source](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py)

---

## Summary

- **Five precise status states** distinguish between missing, broken, timeout, error, and healthy tools—preventing false positives.
- **Clean subprocess environment** via `utf8_subprocess_env()` ensures reproducible probe behavior across platforms.
- **Retry mechanism** handles transient failures without manual intervention.
- **Actionable hints** guide users to reinstall broken tools using `uv` or `pipx`.
- **Channel integration** means every platform check benefits from the same robust validation logic.

---

## Frequently Asked Questions

### What does the "broken" status mean in Agent Reach's probe module?

A `broken` status indicates the executable was found on `PATH` but could not be executed. Common causes include stale shims with invalid shebang lines, missing interpreters, or permission issues. The probe detects this through `FileNotFoundError`, `OSError`, or exit codes 126/127, and suggests reinstalling the package via `uv` or `pipx`.

### How does probe_command handle environment variables?

The `probe_command` function accepts `env` and `remove_env` parameters. Values in `env` are injected into a clean UTF-8 environment built by `utf8_subprocess_env()`, while variables listed in `remove_env` are explicitly excluded. This prevents inherited environment state from interfering with probe results.

### Why does the probe run `--version` instead of just checking file existence?

File existence checks are insufficient because a binary can be present but non-functional due to broken dependencies, missing dynamic libraries, or interpreter mismatches. Running `--version` validates the entire execution chain including loader resolution and basic runtime initialization.

### How many retries does probe_command attempt by default?

The default retry count is 0, meaning a single execution attempt. Users can increase this via the `retries` parameter. Retries only occur for `timeout` and `error` statuses—`missing` and `broken` results return immediately since they indicate persistent configuration problems.