meta(tasks): register [llm-router-failover-proxy] for pi (deepseek-flash/pro aliases, free-first failover)

This commit is contained in:
2026-08-16 17:58:09 +03:00
parent d6ad59c678
commit 98b1e28e1e
2 changed files with 73 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
# llm-router-failover-proxy
## Goal
LLM-роутер / failover-прокси для pi (кодинг-агент на Windows-воркстейшне vitya). Группирует все deepseek-v4-flash модели из разных роутеров в один алиас (`deepseek-flash`), отдельно deepseek-v4-pro (`deepseek-pro`). Приоритет: **free-модели первыми**, затем по приоритету провайдеров, официальный DeepSeek API (платный) — последним fallback'ом. При ошибке апстрима (429/5xx/таймаут/сеть) — автоматический переход к следующему.
Заказчик: vitya (через snolla-сессию). **Решение, куда деплоить — за админом** (см. «Деплой»).
## Контекст
Потребитель один — pi на машине vitya (`~/.pi/`). Сейчас модели прописаны вручную в `~/.pi/agent/models.json` (4 провайдера, ключи в `~/.pi/agent/auth.json`):
| Провайдер | baseUrl | deepseek-v4-flash | deepseek-v4-pro |
|---|---|---|---|
| teamorouter | https://api.teamorouter.com/v1 | `deepseek-v4-flash-free` (free) | `deepseek-v4-pro-free` (free) |
| orcarouter | https://api.orcarouter.ai/v1 | `deepseek/deepseek-v4-flash-free` (free) | `deepseek/deepseek-v4-pro-free` (free) |
| anymodel | https://anymodel.org/v1 | `am/deepseek-v4-flash` (free) | `am/deepseek-v4-pro` (free) |
| routerai | https://routerai.ru/api/v1 | — | — |
| deepseek (официальный) | https://api.deepseek.com | `deepseek-chat` (платный) | `deepseek-reasoner` (платный) |
- Ключи всех апстримов уже лежат в `~/.pi/agent/auth.json` (формат: `{ "<provider>": { "type": "api_key", "key": "..." } }`). Конфиг прокси может ссылаться на них или держать свои копии — на усмотрение админа (ключи не публиковать, gitignore).
- Все free-модели — это deepseek-v4-flash/pro у разных посредников. Официальный DeepSeek API платный — **последний** в цепочке (fallback, когда все free лежат).
- Ранее обсуждено (рекомендация, НЕ приказ): деплой локально на Windows как winsw-сервис (паттерн agents-task-runner уже обкатан), Node-прокси без docker/WSL2. **Решение за админом.**
## Требования
1. **OpenAI-совместимый эндпоинт** (`/v1/chat/completions`, openai-completions API). pi подключается одной записью в `~/.pi/agent/models.json` (провайдер + алиасы).
2. **Алиасы моделей**: `deepseek-flash` → пул flash-апстримов, `deepseek-pro` → пул pro-апстримов.
3. **Приоритет выбора**: free-апстримы (teamorouter → orcarouter → anymodel, порядок конфига) → платный официальный DeepSeek → (остальные провайдеры, если появятся).
4. **Failover**: на 429 / 5xx / таймаут / сетевую ошибку — retry к следующему апстриму в порядке приоритета. Желательно: cooldown для упавших апстримов (не долбить мёртвый), опционально circuit-breaker.
5. **Прозрачный passthrough**: SSE-стриминг, tool-calls (pi использует активно, много раундов), thinking-блоки deepseek (reasoning) — всё должно доезжать без искажений. Модель в ответе — какую реально использовал.
6. **Логика по умолчанию**: если все free живы — платный апстрим не вызывается (экономия).
7. **Конфиг** — файл (YAML/JSON): алиас → упорядоченный список апстримов (baseUrl, key-ref, model-id, free/paid флаг, таймауты).
8. **Учёт**: лог, какой апстрим обслужил запрос + usage. Cost-трекинг не обязателен (модели free), но знать, что сработал платный fallback — обязательно.
9. **Тесты**: TDD (см. ниже).
## Acceptance
- [ ] pi подключается к прокси одной записью в `~/.pi/agent/models.json`; `/model` (или `pi --list-models`) показывает `deepseek-flash` / `deepseek-pro`.
- [ ] Стриминг работает: ответ идёт потоком (не цельным blob).
- [ ] Tool-calls работают: несколько последовательных инструмент-раундов (типа как pi вызывает tools).
- [ ] Failover доказан тестом: верхний апстрим недоступен → запрос обслуживает следующий; при живых free — платный НЕ вызывается.
- [ ] Thinking/reasoning-контент deepseek не ломается (хотя бы smoke: ответ не пустой, без мусора).
- [ ] Инструкция для pi-интеграции (что писать в models.json) + как запускать/останавливать прокси (сервис/скрипт).
- [ ] Деплой выполнен (локально или VDS — решение админа) и живой smoke пройден.
## Деплой (решение за админом)
Рекомендация заказчика: **локально** на Windows (Node-процесс, winsw-сервис — паттерн agents-task-runner; ключи не уходят на сервер; потребитель один — pi на этой машине; docker/WSL2 на Windows — боль). Если админ видит причину иначе (VDS, доступ с других устройств, Portainer-стек) — обосновать и сделать. Ключи апстримов на VDS — только если деплой туда, тогда по правилам админа (pass / env, не в git).
## Обязательные скилы — вызвать до начала работы
- invoke `tdd-criteria` — до написания кода
- invoke `using-tasks` — управление статусом задачи
- invoke `project-discipline` — коммиты/пуши
- invoke `using-wiki` после закрытия — заингесть `.wiki/concepts/llm-router-failover-proxy.md` (архитектура, решения, runbook)
**TDD:** да — failover/приоритет/стриминг это чистые юнит-кейсы; тест-харнесс обязателен (мок-апстримы).
**Разрешения:** интерны: да | автопуш: да
**Weight:** needs-claude
**Notify:** victor/snolla