How Agent Reach Handles Platform API Changes Like the BiliBili yt-dlp Block

Agent Reach uses a multi-backend channel architecture that automatically probes and falls back to alternative implementations when platforms like BiliBili block specific tools such as yt-dlp.

The open-source Agent Reach repository (Panniantong/Agent-Reach) provides AI agents with stable internet access through a plugin-style channel system where each platform is encapsulated in a Python class that can switch between multiple backend implementations without code changes. This design ensures that when upstream APIs change or anti-bot measures block specific tools, the system silently redirects to working alternatives.

Multi-Backend Channel Architecture

Agent Reach represents every internet platform as a standalone channel that inherits from BaseChannel. Rather than hard-coding a single method to fetch data, each channel declares an ordered list of candidate backends that can satisfy the same capability—such as reading video metadata or performing searches.

Ordered Backend Lists

In agent_reach/channels/bilibili.py, the BilibiliChannel class defines its resilience strategy through the backends attribute:


# agent_reach/channels/bilibili.py

class BilibiliChannel(Channel):
    ...
    backends = ["bili-cli", "OpenCLI", "B站搜索 API"]

The system prioritizes these backends in sequence:

  • bili-cli: A public CLI tool handling search, hot lists, and video details without requiring login credentials.
  • OpenCLI: Reuses browser sessions to fetch subtitles when the CLI-only approach fails.
  • B站搜索 API: A zero-dependency HTTP endpoint serving as a last-ditch fallback.

These backends are hard-coded in order of preference, meaning a platform change that disables one tool (such as the yt-dlp block) requires no modifications to the core logic—only a potential reordering of this list.

The BaseChannel Contract

The abstract base class in agent_reach/channels/base.py defines the interface that enables this flexibility. Each channel implements can_handle(), read(), search(), and critically, the check() method, which validates backend availability at runtime.

Automatic Probe-Based Fallback

The resilience mechanism operates through proactive probing. When a channel initializes, it iterates through its candidate backends and selects the first functional option.

How the check() Method Works

The check() method in agent_reach/channels/bilibili.py implements the selection logic:


# agent_reach/channels/bilibili.py

def check(self, config=None):
    self.active_backend = None
    findings = []
    for backend in self.ordered_backends(config):
        if backend == "bili-cli":
            result = self._check_bili_cli()
        elif backend == "OpenCLI":
            result = self._check_opencli()
        else:
            result = self._check_search_api()
        ...

The ordered_backends() method respects user configuration while maintaining the default priority order. Each private _check_* helper runs a probe command that evaluates the specific backend's health.

Probe States and Error Handling

The probing system in agent_reach/probe.py normalizes command execution into four distinct states:

  • missing: The backend binary is not installed—candidate is ignored.
  • broken: The binary exists but cannot execute—candidate marked as "error."
  • ok: The backend runs successfully and is fully operational.
  • warn: The backend functions but may have limitations or deprecation notices.

If bili-cli returns missing or broken, the channel automatically advances to OpenCLI; if that also fails, the HTTP search API attempts to satisfy the request. This cascade happens silently without user intervention.

Case Study: The BiliBili yt-dlp Block

The BiliBili channel's module header explicitly documents the architectural decision to remove yt-dlp following platform changes:


# agent_reach/channels/bilibili.py

"""Bilibili — multi-backend: bili-cli / OpenCLI / search API.

yt-dlp was REMOVED from this channel (live-verified 2026-06):
bilibili's risk control 412-blocks yt-dlp's requests...
"""

Why yt-dlp Was Removed

BiliBili's risk control systems began returning 412 error codes specifically blocking yt-dlp requests. Because Agent Reach maintains a data-driven backend list, maintainers removed yt-dlp from the backends array entirely. The probe logic never attempts to initialize it, preventing the channel from entering a broken state.

Current Backend Stack

The channel now relies exclusively on bili-cli for video retrieval and OpenCLI for subtitle extraction when the CLI approach falls short. When upstream risk controls changed, the diagnostics automatically switched the active backend and surfaced informative messages:


bili-cli 可用(搜索/热门/排行/视频详情/音频,无需登录;
字幕需 OpenCLI。上游 2026-03 起停更)

The adaptation required only updating the backend list in the source file—no changes to the probing logic or fallback mechanisms.

Diagnostic and Maintenance Tools

Agent Reach provides visibility into backend status through the doctor command, ensuring users can verify which implementation is currently active.

The doctor Command

The agent_reach/doctor.py module implements a CLI command that runs check() on every registered channel:

$ agent-reach doctor

# … output …

Bilibili: ok (active backend: bili-cli)

If the primary backend is unavailable, the output reflects the automatic fallback:

$ agent-reach doctor

# … output …

Bilibili: warn (bili-cli not installed, falling back to OpenCLI)

Real-Time Status Reporting

Programmatic verification is available through the Python API:

from agent_reach.channels.bilibili import BilibiliChannel

channel = BilibiliChannel()
status, message = channel.check()
print(f"Status: {status}\nMessage: {message}")

# → Status: ok

# → Message: bili-cli 可用(搜索/热门/排行/视频详情/音频,无需登录;字幕需 OpenCLI。上游 2026-03 起停更)

When upstream changes occur, maintainers simply reorder or append candidates to the channel file, and the doctor command immediately surfaces the new configuration to users.

Summary

  • Agent Reach uses a plugin-style channel architecture where each platform inherits from BaseChannel and declares multiple backends.
  • The check() method automatically probes candidates in agent_reach/channels/bilibili.py and selects the first functional option.
  • Probe states (missing, broken, ok, warn) determined by agent_reach/probe.py enable seamless fallback without user intervention.
  • The BiliBili yt-dlp block was handled by removing yt-dlp from the backend list, allowing the channel to fall back to bili-cli and OpenCLI.
  • The agent-reach doctor command provides real-time visibility into active backends and diagnostic information.

Frequently Asked Questions

How does Agent Reach detect when a backend stops working?

The check() method in each channel runs probe commands via agent_reach/probe.py that execute lightweight validation tests. If a backend returns a broken status or fails to execute, the channel marks it as unavailable and moves to the next candidate in the ordered_backends() list.

Can I manually configure which backend Agent Reach uses?

Yes. While ordered_backends() respects hard-coded defaults in files like agent_reach/channels/bilibili.py, the method accepts an optional config parameter that can override the priority order or disable specific candidates without modifying source code.

What happens if all backends for a platform fail?

If every candidate returns missing or broken, the channel reports an error status through agent-reach doctor. The system will not crash, but the specific capability (such as video search) will be unavailable until maintainers add a new backend or the upstream API restores service.

How do I add a new backend to handle future API changes?

To add a new backend, modify the backends list in the specific channel file (e.g., agent_reach/channels/bilibili.py) and implement a corresponding _check_<backend>() method. The existing probe logic in agent_reach/probe.py will automatically include the new candidate in the health check cycle.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →