o-switcher
v0.1.1
Published
Routing and execution resilience layer for OpenCode
Maintainers
Readme
O-Switcher
English
What is it?
An OpenCode plugin that automatically switches between LLM providers when one goes down. If Anthropic returns errors — your request silently goes to OpenAI. No manual intervention needed.
Why?
- Provider APIs go down, hit rate limits, or return errors
- Without O-Switcher: you wait, manually switch providers, lose context
- With O-Switcher: automatic retry, failover to backup provider, work continues
Install
Add to your opencode.json:
{
"plugin": [
"@apolenkov/o-switcher@latest"
]
}Or for local development:
{
"plugin": [
"/path/to/o-switcher"
]
}Configure
That's it. O-Switcher auto-discovers all configured providers from your OpenCode config. No target configuration needed.
Want to customize retry and timeout?
{
"plugin": ["@apolenkov/o-switcher@latest"],
"switcher": {
"retry": 3,
"timeout": 30000
}
}Both fields are optional with sensible defaults.
Examples
Zero config — just add the plugin:
{
"plugin": ["@apolenkov/o-switcher@latest"]
}O-Switcher reads your configured providers (anthropic, openai, etc.) and creates targets automatically. You get: automatic retry on errors, circuit breaker protection, health monitoring.
Multiple API keys for one provider (rate limit distribution):
{
"provider": {
"openai-work": { "api": "openai", "apiKey": "sk-work-key-111" },
"openai-personal": { "api": "openai", "apiKey": "sk-personal-222" },
"openai-backup": { "api": "openai", "apiKey": "sk-backup-333" }
},
"plugin": ["@apolenkov/o-switcher@latest"]
}O-Switcher sees 3 separate targets (all OpenAI). When work key hits rate limit — switches to personal, then backup. Same model, different keys.
Custom retry and timeout:
{
"switcher": {
"retry": 5,
"timeout": 60000
}
}Advanced: Manual Targets
For full control, you can specify targets explicitly. When targets is present, auto-discovery is disabled.
Two providers — primary + backup:
{
"switcher": {
"targets": [
{
"target_id": "claude",
"provider_id": "anthropic",
"capabilities": ["chat"],
"enabled": true,
"operator_priority": 2,
"policy_tags": []
},
{
"target_id": "gpt",
"provider_id": "openai",
"capabilities": ["chat"],
"enabled": true,
"operator_priority": 1,
"policy_tags": []
}
]
}
}Claude is primary (priority 2). If Claude fails 3 times — switches to GPT.
Custom retry and failover limits:
{
"switcher": {
"targets": [/* ... */],
"retry_budget": 5,
"failover_budget": 3,
"backoff": {
"base_ms": 500,
"max_ms": 15000
}
}
}How it works
- You send a request in OpenCode
- O-Switcher picks the healthiest target
- If the request fails:
- Rate limited → waits and retries (up to 3 times)
- Server error → retries with backoff
- Model unavailable → immediately tries next target
- Auth error → stops, marks target for re-authentication
- If all retries fail → switches to backup target (up to 2 failovers)
- All decisions are logged for debugging
Docs
- Getting Started — installation, configuration, troubleshooting
- API Reference — all config options, operator tools, error classes, log format
- Examples — multi-key, multi-provider, log analysis, circuit breaker tuning
- Architecture — C4 diagrams, sequence flows, internals
Development
git clone https://github.com/apolenkov/o-switcher.git
cd o-switcher
npm install
npm test # 396 tests
npm run typecheck # TypeScript strict
npm run build # ESM + CJSLicense
Русский
Что это?
Плагин для OpenCode, который автоматически переключается между LLM-провайдерами, когда один падает. Если Anthropic возвращает ошибки — запрос тихо уходит в OpenAI. Никакого ручного вмешательства.
Зачем?
- API провайдеров падают, упираются в rate limit, возвращают ошибки
- Без O-Switcher: ждёшь, вручную переключаешь провайдера, теряешь контекст
- С O-Switcher: автоматический retry, failover на резервного провайдера, работа продолжается
Установка
Добавь в opencode.json:
{
"plugin": [
"@apolenkov/o-switcher@latest"
]
}Или для локальной разработки:
{
"plugin": [
"/путь/до/o-switcher"
]
}Настройка
Все. O-Switcher автоматически находит все настроенные провайдеры из конфига OpenCode. Настраивать таргеты не нужно.
Хочешь задать свои retry и timeout?
{
"plugin": ["@apolenkov/o-switcher@latest"],
"switcher": {
"retry": 3,
"timeout": 30000
}
}Оба поля опциональны и имеют разумные дефолты.
Примеры
Нулевой конфиг — просто добавь плагин:
{
"plugin": ["@apolenkov/o-switcher@latest"]
}O-Switcher читает настроенных провайдеров (anthropic, openai и т.д.) и создает таргеты автоматически. Получаешь: автоматический retry, circuit breaker, мониторинг здоровья.
Несколько API ключей для одного провайдера (распределение rate limit):
{
"provider": {
"openai-work": { "api": "openai", "apiKey": "sk-work-key-111" },
"openai-personal": { "api": "openai", "apiKey": "sk-personal-222" },
"openai-backup": { "api": "openai", "apiKey": "sk-backup-333" }
},
"plugin": ["@apolenkov/o-switcher@latest"]
}O-Switcher видит 3 отдельных таргета (все OpenAI). Когда ключ work упирается в rate limit — переключается на personal, потом backup. Та же модель, разные ключи.
Посмотреть настроенные провайдеры и ключи:
opencode providers list # все провайдеры и авторизации
opencode providers login # добавить новый ключ
opencode providers logout # удалить ключСвои retry и timeout:
{
"switcher": {
"retry": 5,
"timeout": 60000
}
}Продвинутое: Ручная настройка таргетов
Для полного контроля можно указать таргеты явно. Когда targets присутствует, автообнаружение отключается.
Два провайдера — основной + резервный:
{
"switcher": {
"targets": [
{
"target_id": "claude",
"provider_id": "anthropic",
"capabilities": ["chat"],
"enabled": true,
"operator_priority": 2,
"policy_tags": []
},
{
"target_id": "gpt",
"provider_id": "openai",
"capabilities": ["chat"],
"enabled": true,
"operator_priority": 1,
"policy_tags": []
}
]
}
}Claude основной (приоритет 2). Если Claude упал 3 раза — переключается на GPT.
Свои лимиты retry и failover:
{
"switcher": {
"targets": [/* ... */],
"retry_budget": 5,
"failover_budget": 3,
"backoff": {
"base_ms": 500,
"max_ms": 15000
}
}
}Как это работает
- Отправляешь запрос в OpenCode
- O-Switcher выбирает самый здоровый таргет
- Если запрос упал:
- Rate limit → ждёт и повторяет (до 3 раз)
- Ошибка сервера → повтор с backoff
- Модель недоступна → сразу пробует следующий таргет
- Ошибка авторизации → останавливается, помечает таргет
- Если все retry исчерпаны → переключение на резервный таргет (до 2 failover)
- Все решения логируются для отладки
Документация
- Getting Started — установка, настройка, траблшутинг
- API Reference — все опции конфига, операторские команды, классы ошибок, формат логов
- Примеры — мульти-ключи, мульти-провайдеры, анализ логов, тюнинг circuit breaker
- Архитектура — C4 диаграммы, sequence-диаграммы, внутреннее устройство
Разработка
git clone https://github.com/apolenkov/o-switcher.git
cd o-switcher
npm install
npm test # 359 тестов
npm run typecheck # TypeScript strict
npm run build # ESM + CJS