Files
admin/.tasks/llm-router-failover-proxy.md

62 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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