meta(tasks): register [llm-router-failover-proxy] for pi (deepseek-flash/pro aliases, free-first failover)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# Admin Task Board
|
||||
_Updated: 2026-08-16 (15) — ⚪ **[llm-router-failover-proxy] заведена** (по запросу vitya через snolla). LLM-роутер/failover-прокси для pi: алиасы deepseek-flash/deepseek-pro поверх 3 free-роутеров (teamorouter/orcarouter/anymodel) + официальный DeepSeek платным fallback'ом. Приоритет free → провайдерский → платный. Деплой — решение админа (рекомендация заказчика: локально winsw). Спека: `.tasks/llm-router-failover-proxy.md` + письмо в инбокс._
|
||||
_Updated: 2026-08-16 (14) — 🟢 **[sched-fnf-04-embedded-alerts] ACCEPTED — F&F цикл закрыт.** Приёмка №4 (14:40Z): замечаний нет. Итоги sched: 6 багов/пробелов → 6 фич (exports-map 0.1.2, @sched/ui serve 0.1.1 + токен-бокс, validateConfig 0.12.2, ntfy basic 0.12.2, pollTimeoutMs 0.1.4). Версии: core 0.12.2 / daemon 0.1.4 / ui 0.1.1 / mcp 0.1.1, сьют 363 ✓. У них дальше: storage-сплит (по фидбеку) + полировка доков; раунд 2 согласован: docs-review после storage-сплита + полировки (пинг от sched, формат делал/ожидал/получил/раздел, фокусы: quick-start все пути, 07.storage, 10.cli, 13.ui)
|
||||
_Updated: 2026-08-16 (13) — 🟢 **[sched-fnf-03-async-poll] ACCEPTED + 🟡 [sched-fnf-04-embedded-alerts] DONE (репорт отправлен).** Приёмка №3 (14:31Z): pollTimeoutMs проброшен в daemon (0.1.4, +pollIntervalMs, CLI --poll-timeout), доки 10.cli.md/05.protocol.md. №4 embedded (финальная): createEngine+internal runner+sqlite+syncTasks в одном скрипте — реальная проверка свежести бэкапов kreknin по SSH (vds-kzntsv 12.4h / books-vds 11.4h → succeeded; порог 1h → failed «STALE backups»); retry 3x (a1 fail → a2 fail → a3 succeed, triggerTask не ретраится — доки честны); createAlerts ntfy **basic auth работает** («[sched] backup-freshness failed» в топике). Цикл F&F закрыт, замечаний нет. Репорт: `victor/sched/.agents/inbox/2026-08-16T14-36-01Z-admin-fnf-04-report.md`._
|
||||
_Updated: 2026-08-16 (12) — 🟢 **[sched-fnf-02-docker-runner] ACCEPTED + 🟡 [sched-fnf-03-async-poll] DONE (репорт отправлен).** Приёмка №2 (14:24Z): оба замечания стали фичами — validateConfig-хук (allowlist на load, abort при старте, core 0.12.2) + ntfy basic auth (user+password в createAlerts, daemon 0.1.3), сьют 362 ✓. №3 async/poll: свой воркер (:8293) envelope accepted+poll — happy path queued→running(50)→succeeded (progress 100, 3.5s), timeout-кейс hung → failed «poll timeout after 15000ms» (через createEngine, т.к. daemon не пробрасывает pollTimeoutMs — замечание в репорт). Фиксы №2 подтверждены (abort на load + ntfy basic в коде). Репорт: `victor/sched/.agents/inbox/2026-08-16T14-27-54Z-admin-fnf-03-report.md`._
|
||||
@@ -145,6 +146,17 @@ _Updated: 2026-05-25 (`iis-migration-to-ruvds` 🟢 closed Phase 1 per user deci
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [llm-router-failover-proxy] — LLM-роутер/failover-прокси для pi (deepseek-flash/pro алиасы)
|
||||
**Status:** ⚪ ready — заведена 2026-08-16 по запросу vitya (письмо `.agents/inbox/2026-08-16T14-57-25Z-snolla.md`).
|
||||
**Where I stopped:** (not started) — контекст и требования: `.tasks/llm-router-failover-proxy.md` (upstreams-таблица, ключи в `~/.pi/agent/auth.json`, priority free→paid, passthrough SSE/tools/thinking).
|
||||
**Next action:** прочитать спеку `.tasks/llm-router-failover-proxy.md` + письмо из инбокса → invoke `tdd-criteria` → выбрать стек и деплой (рекомендация: Node + winsw локально) → реализовать → принять решение по деплою → live-smoke через pi → отчитаться в `victor/snolla` inbox.
|
||||
**Branch:** n/a (новый проект)
|
||||
**Weight:** needs-claude
|
||||
**Notify:** victor/snolla
|
||||
<!-- created-by: vitya@victor/snolla / 2026-08-16 / trigger: запрос vitya — сгруппировать deepseek-flash/pro, free-first, failover -->
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [kreknin-self-backup] — второй таргет для приёмника бэкапов (на потом)
|
||||
**Status:** ⚪ backlog — заведена 2026-06-12 по итогам backup-gap аудита, user: «на потом».
|
||||
**Where I stopped:** kreknin (`195.19.90.188`, `/volume1` 7 ТБ) — единственный приёмник всех 4 пайплайнов, сам не бэкапится → SPOF всей estate. Направление: второй облачный таргет (Backblaze B2 / Synology Hyper Backup, client-side encryption) для critical-subset (`*/latest` ~30 ГБ + `.hbk` vault).
|
||||
|
||||
61
.tasks/llm-router-failover-proxy.md
Normal file
61
.tasks/llm-router-failover-proxy.md
Normal 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
|
||||
Reference in New Issue
Block a user