How ModLens Chains Vision Providers for Failover: Provider Selection Logic Explained
ModLens builds a prioritized provider chain in src/providers/availability.ts that filters available providers by binary presence or API credentials, orders them by input type (local vs remote), and inserts user preferences at the front to create a robust failover sequence.
The open-source ModLens project (liustack/modlens) implements a sophisticated provider selection system that ensures reliable vision analysis across diverse environments. By dynamically constructing a provider chain based on real-time availability checks and user configuration, ModLens guarantees that image analysis proceeds even when primary providers fail.
Understanding the Provider Availability System
At the core of ModLens’s failover capability lies a strict availability validation system. Before any provider enters the execution chain, the system verifies that all prerequisites are satisfied.
Provider Descriptors and Type Classification
Each vision provider in ModLens is defined by a provider descriptor that specifies its operational type—either subprocess for local CLI tools or api for remote endpoints. These descriptors declare required binaries (such as antigravity-cli or claude-cli) or mandatory API settings including apiKey, baseUrl, and model. This metadata allows ModLens to determine, before execution, whether a provider can possibly succeed given the current environment configuration.
The Availability Check Mechanism
The function providerAvailable() (lines 9-26 in src/providers/availability.ts) performs the gatekeeping logic for the failover chain. For subprocess providers, it checks that the binary exists on PATH. For API providers, it validates that all required configuration fields are present and non-empty. Only providers passing this availability check are eligible for inclusion in the final execution chain.
Building the Failover Chain
ModLens constructs the provider chain through a multi-stage filtering and reordering process that balances performance, reliability, and user preference.
Static Failover Orders for Input Types
The system maintains two distinct static orderings defined in src/providers/availability.ts:
LOCAL_FAILOVER_ORDER(lines 36-42): Prioritizes fast inline API providers (gemini-api,openai,anthropic) before falling back toantigravity-cliand finallyclaude-clifor local file inputs.REMOTE_FAILOVER_ORDER(line 49): Uses a similar priority structure optimized for remote URL inputs, ensuring network-efficient providers are attempted first.
These predefined sequences ensure that cloud-based APIs—typically faster and more capable—are exhausted before attempting local subprocess executions.
User Preference Injection
When a user specifies a default provider via config.provider, the logic in lines 71-86 resolves the canonical provider name and reorders the chain. The preferred provider is moved to the front of the array, ensuring it receives first priority. This user-override mechanism allows consistent use of specific backends without disabling the safety net of failover alternatives.
Pin-Only Providers and Chain Construction
Certain providers like kimi-cli operate as pin-only entries—they are excluded from the default chain unless explicitly requested. The providerChain() function (lines 58-63 and 98-102 in src/providers/availability.ts) orchestrates the final assembly:
- Selects the base order (
LOCAL_FAILOVER_ORDERorREMOTE_FAILOVER_ORDER) based on input type. - Applies the
reuse.claudeconfiguration flag to optionally omitclaude-clifrom the sequence. - Injects the user-preferred provider at the chain’s head or as a pinned entry.
- Filters by availability using
providerAvailable(). - Resolves each name to its concrete
VisionProviderimplementation viaresolveProvider()fromsrc/providers/index.ts.
The resulting array is consumed by src/analyzer.ts, which iterates sequentially until successful completion.
CLI Failover Configuration Examples
The following commands demonstrate practical failover scenarios using ModLens’s provider selection system:
# Use the default provider (antigravity-cli). If it fails,
# ModLens will automatically fall back to the next available API.
modlens -i screenshot.png
# Prefer the OpenAI compatible endpoint. It is placed first
# in the chain, but if the API key is missing or the call fails,
# ModLens will try Gemini, then Anthropic, then antigravity-cli.
modlens -i screenshot.png -p openai
# Set a global default provider (persisted in the config).
# The chosen provider is moved to the front of the chain for all runs.
modlens config set provider gemini-api
modlens -i screenshot.png # gemini-api is tried first
# Disable Claude CLI reuse (useful when the user does not want
# to spend a Claude subscription). The chain then omits claude-cli.
modlens config set reuse.claude false
modlens -i localfile.png # chain: gemini-api → openai → anthropic → antigravity-cli
# Pin-only provider: request Kimi CLI explicitly. It is added
# only when requested and runs before any other local providers.
modlens -i screenshot.png -p kimi-cli
Key Source Files and Functions
src/providers/availability.ts– ContainsproviderAvailable()for prerequisite validation andproviderChain()for building the ordered failover sequence.src/providers/index.ts– ExportsresolveProvider()to map provider names to concrete implementation objects.src/config.ts– Stores user preferences includingproviderandreuse.claudeflags that influence chain ordering.src/analyzer.ts– Orchestrates the iteration over the constructed provider chain to execute vision analysis.
Summary
- ModLens implements provider availability checking in
src/providers/availability.tsbefore adding any provider to the execution chain. - The system uses distinct failover orders for local files (
LOCAL_FAILOVER_ORDER) versus remote URLs (REMOTE_FAILOVER_ORDER) to optimize for latency and capability. - User preferences specified via
config.providerare dynamically injected at the front of the chain while preserving fallback options. - Pin-only providers like
kimi-cliare excluded from automatic selection unless explicitly requested via CLI flags. - The analyzer in
src/analyzer.tsexecutes providers sequentially until successful completion, ensuring robust fault tolerance.
Frequently Asked Questions
How does ModLens determine if a provider is available for the failover chain?
ModLens calls providerAvailable() in src/providers/availability.ts (lines 9-26), which checks that subprocess binaries exist on PATH or that API providers have required configuration fields (apiKey, baseUrl, model) populated. Only providers passing this validation are included in the final chain.
What happens if my preferred provider fails during execution?
If the provider specified via -p or config.provider fails, ModLens automatically proceeds to the next available provider in the chain. The system maintains the complete ordered list from LOCAL_FAILOVER_ORDER or REMOTE_FAILOVER_ORDER (minus unavailable providers), ensuring seamless failover to alternatives like gemini-api, anthropic, or antigravity-cli.
Can I exclude specific providers from the failover sequence?
Yes. You can disable claude-cli specifically by setting reuse.claude to false in the configuration, which removes it from the chain. Additionally, providers marked as pin-only (such as kimi-cli) never appear in the default chain unless explicitly requested with the -p flag.
Where does ModLens store the logic for resolving provider names to implementations?
The resolution occurs in src/providers/index.ts, which exports resolveProvider(). This function maps canonical provider names (like openai or gemini-api) to their concrete VisionProvider class instances that perform the actual image analysis.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →