docs(tasks): add llm-web-proxy spec (web-LLM provider for pi+Claude Code) + omniroute tuning wiki
This commit is contained in:
84
.wiki/concepts/omniroute-combo-deepseek-web-tuning.md
Normal file
84
.wiki/concepts/omniroute-combo-deepseek-web-tuning.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: OmniRoute: настройка web-комбо под агентскую работу (deepseek-web + тулы)
|
||||
type: concept
|
||||
tags: [omniroute, deepseek-web, tool-calling, combo, pi, web-cookie]
|
||||
sources: [../sources/omniroute-session-2026-08-22.md]
|
||||
updated: 2026-08-22
|
||||
---
|
||||
|
||||
# OmniRoute: настройка web-комбо под агентскую работу
|
||||
|
||||
Диагностика и настройка комбо `deepseek-v4-flash-web` / `deepseek-v4-pro-web` (провайдер deepseek-web = веб-чат chat.deepseek.com через userToken, 3 аккаунта megan/yulia/vitya). Сессия 2026-08-22.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
pi (клиент) → omniroute (localhost:20128, Next.js + sqlite + MCP) → combo → deepseek-web executor → chat.deepseek.com/api/v0/chat/completion
|
||||
```
|
||||
|
||||
- Веб-чат DeepSeek **не имеет нативного function calling** — omniroute **эмулирует**: сериализует `tools[]` в текстовый контракт `<tool>{"name":"...","arguments":{...}}</tool>` в промпт, модель пишет блоки текстом, парсер (`open-sse/translator/deepseekWebTools.ts`, 486 строк) разбирает зоопарк форматов обратно в OpenAI `tool_calls`.
|
||||
- `toolCalling: "emulated"` в `src/shared/constants/providers/web-cookie.ts` — маркер эмуляции (claude-web = `"none"`, grok-web = нативный `true`).
|
||||
- Executor: `open-sse/executors/deepseek-web.ts` (1147 строк): userToken→accessToken, PoW-челлендж, создание/удаление сессий, SSE-парсинг фрагментов (THINK/ANSWER), эмуляция тулов.
|
||||
- Управление: REST `http://127.0.0.1:20128/api/combos` (GET список, PUT /api/combos/[id]). MCP-тулы omniroute в pi-сессии отваливаются с `Unknown Mcp-Session-Id` — работать через HTTP напрямую.
|
||||
|
||||
## Найденные причины вылетов агента (по убыванию важности)
|
||||
|
||||
### 1. `system_message` override убивает скилы pi ⭐
|
||||
`applyComboAgentMiddleware` (`open-sse/services/comboAgentMiddleware.ts`) **удаляет ВСЕ system-сообщения от pi** (скилы, AGENTS.md, инструкции) и ставит свой `system_message` комбо. Модель физически не видит скилы.
|
||||
**Фикс:** `PUT /api/combos/[id]` с `"system_message": ""` — пустая строка = override не применяется (`trim()`-проверка), промпт pi проходит.
|
||||
|
||||
### 2. `tool_filter_regex` режет инструменты ⭐
|
||||
Было `^(bash|computer)$` — из 339 тулов pi оставалось 2, модель слепая (не могла звать read/write/edit/MCP).
|
||||
**Фикс:** `^(bash|read|write|edit|grep|glob|list|describe_image|mcp__[a-z0-9_]+)$` — базовые + все MCP (filesystem, projects_meta, interns, books_ops...). Проверено: 339→25 тулов, все имена матчатся.
|
||||
|
||||
### 3. search-режим модели ломает tool-calling ⭐
|
||||
`deepseek-v4-flash-think-search` (суффикс `-search`) включает веб-поиск чата: при URL модель сама лезет «читать» (сообщение «Link reading is unavailable in Expert Mode» — это веб-чат, не pi), генерит токены `DEEP_SEARCH`/`SEARCHING` в стриме → валидатор качества режет → `Upstream response failed quality validation: streaming upstream error`.
|
||||
**Фикс:** модель в комбо → `deepseek-v4-flash-think` (без search; thinking остаётся).
|
||||
|
||||
### 4. `streaming upstream error` — валидатор качества
|
||||
`open-sse/services/combo/validateQuality.ts` `isStreamingUpstreamError()`: SSE-фрейм с `eventType === "error"` / `parsed.error != null` / `type:"error"` до контента → стрим режется, все 3 аккаунта round-robin фейлятся → «All models failed». Через API не настраивается — патч кода.
|
||||
|
||||
### 5. 503 `chat_admission_busy` — лимит веб-чата DeepSeek
|
||||
Перегрузка их серверов / слишком частые запросы (агентный цикл pi = серия быстрых запросов). Не настройка omniroute, а capacity провайдера.
|
||||
**Фикс:** `config.maxRetries: 4`, `config.retryDelayMs: 4000` (было 1–2 / 1500–2000). Также qwen-web падал по DNS (`EAI_AGAIN chat.qwen.ai`) — сетевой глюк, не ключ.
|
||||
|
||||
### 6. Пустые tool_calls (`arguments: {}`, `name: undefined`)
|
||||
Модель иногда генерит `<tool>{"name":"bash","arguments":{}}</tool>` без аргументов → pi-валидация падает (`command: must have required properties command`). Следствие длинного контекста + слабого контракта. Сокращение тулов (фикс №2) снижает частоту.
|
||||
|
||||
## Что работает после фиксов (проверено тестами)
|
||||
|
||||
- Эмуляция tool-calling **исправна**: тест с 1 тулом и с 25 тулами (stream=true и false) возвращает корректные `tool_calls` (`{"name":"read","arguments":{"path":...}}`).
|
||||
- То, что выглядит как «модель пишет read("...") текстом» — это **`reasoning_content`** (мысли модели), pi их показывает, реальный tool_call при этом корректный.
|
||||
- Скиллы видны после удаления system_message.
|
||||
|
||||
## Web-провайдеры с tool calling (для кастомного провайдера)
|
||||
|
||||
Из кода omniroute (`web-cookie.ts` + executors). Эмуляция (`"emulated"`) у: deepseek-web, qwen-web, gemini-web, chatgpt-web, kimi-web, t3-web, perplexity-web, blackbox-web, muse-spark-web, inner-ai, adapta-web. Нативный (`true`): grok-web. `"none"`: claude-web (не стоит скрейпить).
|
||||
|
||||
Бесплатные без подписки: **deepseek-web** (✅ есть), **qwen-web** (✅ ключ есть, DNS-глюк), **gemini-web** (Google-аккаунт), **kimi-web** (свободный лимит), **grok-web** (free-тир).
|
||||
|
||||
## План кастомного провайдера (идея, не реализовано)
|
||||
|
||||
OmniRoute для 2 комбо — overkill (Next.js + sqlite + дашборд + MCP). Идея: **вытащить** готовые `executor/deepseek-web.ts` + `translator/deepseekWebTools.ts` из omniroute (они работают), завернуть в минимальный OpenAI-совместимый сервер:
|
||||
|
||||
- `POST /v1/chat/completions` + `GET /v1/models` (pi подключается как провайдер)
|
||||
- round-robin по аккаунтам из конфига (отдельное комбо на провайдера — **не смешивать** в одном)
|
||||
- **без quality validation** (убирает все streaming upstream error)
|
||||
- `persistSession: true` (переиспользование сессии → меньше 503)
|
||||
- ~300 строк обвязки + 2 готовых файла
|
||||
- Плюс: поддержать qwen-web / gemini-web / kimi-web / grok-web как отдельные комбо (один парсер webTools.ts, разные executors)
|
||||
|
||||
## Ключевые файлы omniroute
|
||||
|
||||
- `src/shared/constants/providers/web-cookie.ts` — реестр web-провайдеров, toolCalling
|
||||
- `open-sse/executors/deepseek-web.ts` — executor веб-чата DeepSeek
|
||||
- `open-sse/translator/deepseekWebTools.ts` + `webTools.ts` — эмуляция/парсинг тулов
|
||||
- `open-sse/services/combo/validateQuality.ts` — валидатор качества (режет стримы)
|
||||
- `open-sse/services/comboAgentMiddleware.ts` — system_message override + tool_filter_regex
|
||||
- `src/shared/validation/schemas/combo.ts` — `updateComboSchema` (PUT-поля)
|
||||
- Данные: docker volume `omniroute-data` → `/app/data/storage.sqlite`, логи `/app/data/logs/application/app.log`, call_logs `/app/data/call_logs/`
|
||||
|
||||
## Связанное
|
||||
|
||||
- [[admin-infra-project]] — контекст стека
|
||||
- [[omniroute-session-2026-08-22]] — хронология сессии (sources)
|
||||
@@ -21,6 +21,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
||||
- [windows-recovery-host](entities/windows-recovery-host.md) — Windows Recovery Host (рабочий PC пользователя)
|
||||
|
||||
## Concepts
|
||||
- [omniroute-combo-deepseek-web-tuning](concepts/omniroute-combo-deepseek-web-tuning.md) — настройка web-комбо под агента: system_message убивает скилы pi, tool_filter_regex режет тулы, search-режим ломает tool-calling, 503 chat_admission_busy, эмуляция `<tool>` работает, план кастомного провайдера
|
||||
- [sched-admin-client-openapi](concepts/sched-admin-client-openapi.md) — F&F раунды 2026-08-18: Python-клиент одной командой из спеки (openapi-generator 7.24.0); r1 0.1.2 — 24/24+smoke 19/19, находки F-1..F-5 (8 операций на raw-обходе); r2 0.2.0/0.3.5 — все 5 закрыты, raw_ops удалён, 11/11 typed-only, вердикт «claim подтверждён полностью»
|
||||
- [openapi-generator-3-1-spec-gotchas](concepts/openapi-generator-3-1-spec-gotchas.md) — генерация клиентов из 3.1-спеки (openapi-generator 7.24.0, python): wrapped-ответы {} → ValidationError (raw-обход историчен: r2 спека фикснута), const:true → строковый enum, oneOf+discriminator → actual_instance=None (r2: плоская схема), java из PATH а не JAVA_HOME, InlineObjectN-имена, info.version не бьётся
|
||||
- [nvm-junction-ismain-gate-gotcha](concepts/nvm-junction-ismain-gate-gotcha.md) — ESM isMain-гейт молча не выполняется под junction'нутым npm-рутом (nvm/mise/volta); realpath-фикс; диагностика за 30 сек
|
||||
@@ -96,6 +97,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
||||
|
||||
## Sources
|
||||
|
||||
- [omniroute-session-2026-08-22](sources/omniroute-session-2026-08-22.md) — хронология сессии настройки omniroute web-комбо (deepseek-web): корни вылетов, фиксы, тесты эмуляции, план кастомного провайдера
|
||||
- [iis-host-migration-2026-05-19](sources/iis-host-migration-2026-05-19.md) — IIS Host Migration Session 2026-05-19 chronology
|
||||
- [iis-migration-to-ruvds-2026-05-23](sources/iis-migration-to-ruvds-2026-05-23.md) — IIS migration to RUVDS — session 2026-05-23/24 (SSH/scp pivot, 25 SNI bindings, partial DNS cutover)
|
||||
- [nas-recovery-session-2026-05-18](sources/nas-recovery-session-2026-05-18.md) — NAS Recovery Session 2026-05-18/19 chronology
|
||||
|
||||
@@ -139,3 +139,5 @@ Append-only log of wiki operations (ingests, promotions, lints, migrations).
|
||||
## [2026-08-18] ingest | NEW concepts/openapi-generator-3-1-spec-gotchas.md — из F&F openapi-client sched (2026-08-18): генерация Python-клиента из 3.1-спеки openapi-generator 7.24.0. Гочи: (1) ответы `{}` в спеке + wrapped-тело ({task/run/schedule:…}) → pydantic ValidationError, фикс — реальные схемы ответов, обход raw-транспорт + by_alias=True; (2) `const:true` → строковый enum ('true') ломает boolean; (3) oneOf+discriminator → actual_instance=None, контент только через raw JSON; Java 11+ обязателен (системная 8 падает), Windows excluded-порты 8090/8091 (EACCES), консоль cp1251 без →/«». Полные находки F-1..F-5: sched/.agents/inbox репорт 19:15Z; пример sched/examples/admin-client-python (24/24). index.md updated.
|
||||
## [2026-08-18] ingest | NEW concepts/sched-admin-client-openapi.md — F&F раунд openapi-claim sched (по предписанию таски): Python-клиент одной командой (openapi-generator 7.24.0 из спеки verdaccio 0.1.2), сьют 24/24 + smoke 19/19 против published daemon 0.3.4 (:8127), вердикт «claim подтверждён с оговорками» (8 операций требуют raw-обхода). Код sched/examples/admin-client-python (e89e868), репорт — sched инбокс 19:15Z, находки F-1..F-5 (спеку не чинил). Таска [sched-admin-client-openapi] 🟢. Гочи генерации — concepts/openapi-generator-3-1-spec-gotchas.md. index.md updated.
|
||||
## [2026-08-18] ingest | UPDATE concepts/openapi-generator-3-1-spec-gotchas.md + concepts/sched-admin-client-openapi.md — round 2 ретест (0.2.0/daemon 0.3.5): все 5 находок F-1..F-5 закрыты, raw_ops.py удалён, 11/11 ранее-сырых операций typed-only, сьют 24/24 + smoke 19/19 (коммит sched d658ff0, репорт sched инбокс 22:55Z). Новые грабли в окружение: CLI спавнит java из PATH а не JAVA_HOME; wrapped-ответы в components.responses → InlineObjectN; info.version не бьётся с версией пакета. index.md hooks обновлены.
|
||||
|
||||
## [2026-08-22] ingest | NEW concepts/omniroute-combo-deepseek-web-tuning.md + sources/omniroute-session-2026-08-22.md — сессия настройки web-комбо omniroute (deepseek-v4-flash/pro-web). Корни вылетов агента: (1) system_message override режет скилы pi, (2) tool_filter_regex ^(bash|computer)$ режет 337/339 тулов, (3) search-модель генерит DEEP_SEARCH-мусор + «Link reading unavailable», (4) quality validation режет стрим на type:error, (5) 503 chat_admission_busy = capacity веб-чата. Фиксы применены: system_message="", regex расширен (базовые+mcp__*), flash think-search→think, maxRetries 2→4, retryDelayMs→4000. Эмуляция tool-calling проверена тестами — исправна. План кастомного провайдера (вытащить executor+translator, без quality validation, persistSession). index.md updated (+2).
|
||||
|
||||
42
.wiki/sources/omniroute-session-2026-08-22.md
Normal file
42
.wiki/sources/omniroute-session-2026-08-22.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: OmniRoute web-комбо — хронология сессии 2026-08-22
|
||||
type: source
|
||||
tags: [omniroute, deepseek-web, session-trace]
|
||||
ingested: 2026-08-22
|
||||
raw_path: ../raw/omniroute-session-2026-08-22.md
|
||||
updated: 2026-08-22
|
||||
---
|
||||
|
||||
# OmniRoute web-комбо — хронология сессии 2026-08-22
|
||||
|
||||
Сессия настройки omniroute-комбо `deepseek-v4-flash-web` / `deepseek-v4-pro-web` (провайдер deepseek-web). Полный вывод в диалоге pi 2026-08-22; здесь — ключевые точки.
|
||||
|
||||
## Контекст
|
||||
|
||||
- pi использует omniroute (localhost:20128) как LLM-провайдера, модель `deepseek-v4-flash-web`.
|
||||
- Веб-чат DeepSeek (chat.deepseek.com) не имеет нативного function calling — omniroute эмулирует через `<tool>`-контракт.
|
||||
- Симптомы: модель «не видит скилы», агент «вылетает» на вызове тулов, `Upstream response failed quality validation: streaming upstream error`, `503 chat_admission_busy`.
|
||||
|
||||
## Ход
|
||||
|
||||
1. **MCP-тулы omniroute не работают** из pi-сессии (`Unknown Mcp-Session-Id`) — перешли на REST `http://127.0.0.1:20128/api/*`.
|
||||
2. **Собрали картину**: 2 комбо, round-robin, 3 аккаунта deepseek-web (megan/yulia/vitya), qwen-web (test=error, DNS), deepseek API + tokenrouter (test=active, но API-доступ «за скобками»).
|
||||
3. **Метрики** показали дисбаланс: pro-web 81% успешности, yulia 64%/40s, vitya 50%/42s (last=error), megan 90–100%.
|
||||
4. **Найден корень №1**: `system_message` комбо переопределяет системный промпт pi → скилы вырезаются. Убран (`""`).
|
||||
5. **Найден корень №2**: `tool_filter_regex: ^(bash|computer)$` режет 337 из 339 тулов. Расширен до базовых + `mcp__[a-z0-9_]+`.
|
||||
6. **Найден корень №3**: search-модель (`think-search`) генерит DEEP_SEARCH-мусор и «Link reading unavailable» при URL. Модель в flash-комбо заменена на `deepseek-v4-flash-think`.
|
||||
7. **Тесты эмуляции** (1 тул, 25 тулов, stream=true/false) — всё возвращает корректные tool_calls. Вывод: эмуляция исправна; «read("...") текстом» = reasoning_content.
|
||||
8. **503 chat_admission_busy** — capacity веб-чата DeepSeek. maxRetries 2→4, retryDelayMs 1500→4000.
|
||||
9. **Идея**: кастомный провайдер на базе вытащенного кода omniroute (executor + translator), без quality validation, persistSession, несколько web-провайдеров отдельными комбо. Обсуждено, не реализовано.
|
||||
|
||||
## Итоговое состояние комбо
|
||||
|
||||
Оба (`deepseek-v4-flash-web`, `deepseek-v4-pro-web`):
|
||||
- `system_message`: `""`
|
||||
- `tool_filter_regex`: `^(bash|read|write|edit|grep|glob|list|describe_image|mcp__[a-z0-9_]+)$`
|
||||
- `config.maxRetries`: 4, `config.retryDelayMs`: 4000
|
||||
- flash: модель `deepseek-v4-flash-think` (search убран); pro: `deepseek-v4-pro` (без search и так)
|
||||
|
||||
## Ссылки
|
||||
|
||||
- [[omniroute-combo-deepseek-web-tuning]] — сводный концепт
|
||||
Reference in New Issue
Block a user