From bf845e2dcb1cefe4cf929983f7baa5ebe04af21e Mon Sep 17 00:00:00 2001 From: dttb Date: Wed, 6 May 2026 13:42:11 +0300 Subject: [PATCH] =?UTF-8?q?kb:=20OmniRoute=20Opus=20audit=20=E2=80=94=20cc?= =?UTF-8?q?/claude-opus-4-7=20main,=20=D1=80=D0=B0=D0=B7=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D0=BC=20?= =?UTF-8?q?CLIProxy=208317?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- claude-memory/cliproxy_code_server.md | 23 ++++ ...5-06-openclaw-opus-4-7-via-max-cliproxy.md | 1 + snippets/omniroute-models-audit.md | 126 ++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 snippets/omniroute-models-audit.md diff --git a/claude-memory/cliproxy_code_server.md b/claude-memory/cliproxy_code_server.md index 3a439f9..6fc5aac 100644 --- a/claude-memory/cliproxy_code_server.md +++ b/claude-memory/cliproxy_code_server.md @@ -32,3 +32,26 @@ Claude Code на code-server (LXC 132, IP 10.0.0.179) работает чере ## TODO - Выяснить, почему auto-refresh не срабатывает (проверить после следующего протухания) - Рассмотреть cron для принудительного рефреша до истечения токена + +## Update 2026-05-06 — два разных CLIProxy-механизма + +После audit'а (см. [[../decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy]]) выяснилось: + +1. **Standalone `cliproxy.service` на порту 8317** — описан выше, OAuth `batlaew@gmail.com` (Pro), auto-refresh ломается. Сейчас используется только legacy ботами (NIIKN 133, Знам 134), которым ещё не выдан прямой API ключ. Когда мигрируют — service выключить. + +2. **Встроенный CLIProxy-модуль OmniRoute** (через `cc/*` модели) — **другой mechanism**. Использует Max-подписку Олега, OAuth flow через `claude-cli/1.0.83` user-agent. У OmniRoute есть **HealthCheck loop** (`/root/.npm/_npx/cb5891f90ae65d14/node_modules/omniroute/app`) который **проактивно** refresh'ит токены до их истечения — видно в `journalctl -u omniroute`: + + ``` + [HealthCheck] Refreshing gemini-cli/... (token expiring soon) + [HealthCheck] [TOKEN_REFRESH] Successfully refreshed Google token + [HealthCheck] Refreshing antigravity/... (token expiring soon) + [HealthCheck] [TOKEN_REFRESH] Successfully refreshed Google token + [HealthCheck] Refreshing kiro/... (token expiring soon) + [HealthCheck] [TOKEN_REFRESH] Successfully refreshed Kiro AWS token + ``` + + То есть проблема старого CLIProxy (8h cycle + ломаный refresh) **в OmniRoute не повторяется** — refresh работает по событию `expiring soon`. + +**Где живёт state OAuth:** `/root/.omniroute/storage.sqlite` → таблица `provider_connections` (поля `access_token`, `refresh_token`, `expires_at`). 11 провайдеров активно (claude:1, antigravity:5, codex:7, kiro:5, и т.д.). + +**Мониторинг здоровья cc/* для openclaw** — см. [[../snippets/omniroute-models-audit]] (smoke test шаблоны и интерпретация ошибок). diff --git a/decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy.md b/decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy.md index 0bf95e6..afefc11 100644 --- a/decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy.md +++ b/decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy.md @@ -116,3 +116,4 @@ sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 "pct exec 137 -- bash -c ' - [[../claude-memory/omniroute]] — OmniRoute setup, провайдеры, версии - [[../projects/dttb/openclaw]] — справочник по openclaw - [[../snippets/clawdbot-cliproxy-config]] — старый шаблон CLIProxy +- [[../snippets/omniroute-models-audit]] — шаблон smoke-тестов и парсинга ошибок (использовался при этом аудите) diff --git a/snippets/omniroute-models-audit.md b/snippets/omniroute-models-audit.md new file mode 100644 index 0000000..8201eb6 --- /dev/null +++ b/snippets/omniroute-models-audit.md @@ -0,0 +1,126 @@ +--- +date: 2026-05-06 +type: snippet +tags: [omniroute, claude, opus, smoke-test, audit, lxc-132] +--- + +# OmniRoute — аудит живости моделей (smoke-test) + +Каталог OmniRoute (`/v1/models`) перечисляет все модели, **подключенные** к провайдерам, но это не значит что они живые. Реальная проверка — пинг через `/v1/chat/completions` с `max_tokens: 10`. Пригождается каждые 1-2 недели или после `npm install omniroute@latest` чтобы убедиться что важные источники Opus/Sonnet не отвалились. + +См. также: [[../decisions/2026-05-06-openclaw-opus-4-7-via-max-cliproxy]] — последний полный аудит и результаты. + +## Где живёт OmniRoute + +| Артефакт | Путь / адрес | +|----------|--------------| +| LXC | 132, hostname `code-server`, IP `10.0.0.179` | +| Service | `systemctl status omniroute` | +| Cmd | `/usr/bin/node /root/.npm/_npx/cb5891f90ae65d14/node_modules/omniroute/app/server.js` | +| EnvFile | `/root/OmniRoute/.env` | +| Repo | `/root/OmniRoute/` (Git) | +| Storage | `/root/.omniroute/storage.sqlite` | +| Local API | `http://localhost:20128` (порт из `.env` PORT=20128) | +| Public | `https://ai.dttb.ru` (через NPM, требует Bearer) | + +## Получить API key + +```bash +sshpass -p '1qaz!QAZ' ssh root@10.0.0.179 \ + "sqlite3 /root/.omniroute/storage.sqlite \"SELECT id, key, name FROM api_keys;\"" +``` + +Использовать `name=test-key` для тестов чтобы не задеть production `claw`. + +## Список моделей + +```bash +KEY='' +sshpass -p '1qaz!QAZ' ssh root@10.0.0.179 \ + "curl -s -H 'Authorization: Bearer $KEY' http://localhost:20128/v1/models" +``` + +Парсинг с фильтром по подстроке (например все `opus`): + +```bash +... | python3 -c ' +import sys, json +d = json.load(sys.stdin) +models = d.get("data", d) if isinstance(d, dict) else d +for m in models: + if "opus" in m["id"].lower(): + print(m["id"]) +' +``` + +## Smoke test одной модели + +```bash +KEY='' +MODEL='cc/claude-opus-4-7' + +curl -s --max-time 30 -X POST http://localhost:20128/v1/chat/completions \ + -H "Authorization: Bearer $KEY" \ + -H 'Content-Type: application/json' \ + -d '{ + "model": "'$MODEL'", + "messages": [{"role":"user","content":"Reply only: ok"}], + "max_tokens": 10, + "stream": false + }' | python3 -m json.tool +``` + +Ожидание `choices[0].message.content` = `"ok"` (или похожее короткое). Если streaming возвращается даже при `stream:false` — это чистый прокси-bypass от Claude Code OAuth, тоже норм. + +## Batch smoke test нескольких моделей + +```bash +sshpass -p '1qaz!QAZ' ssh root@10.0.0.179 " +KEY='' +URL='http://localhost:20128/v1/chat/completions' + +for model in 'cc/claude-opus-4-7' 'cc/claude-opus-4-6' 'claude/claude-opus-4-7' 'kr/claude-opus-4.6' 'gh/claude-opus-4.6' 'antigravity/claude-opus-4-6-thinking'; do + echo '--- '\$model' ---' + curl -s --max-time 25 -X POST \"\$URL\" \\ + -H \"Authorization: Bearer \$KEY\" \\ + -H 'Content-Type: application/json' \\ + -d '{\"model\":\"'\$model'\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply ok\"}],\"max_tokens\":10}' \\ + | head -c 350 + echo '' +done +" +``` + +## Как читать ошибки + +| Сообщение | Что значит | Как чинить | +|-----------|------------|-----------| +| `Unauthorized` / `Missing API key` | Нет Bearer header или ключ отозван | Достать новый из `api_keys` | +| `[400]: The requested model is not available for integrator "vscode-chat"` | MS GitHub Copilot integrator не отдаёт эту модель | Использовать другой источник; проверить какие модели MS сейчас выдаёт (в самом сообщении список Available) | +| `[400]: The requested model is not supported` | OmniRoute шлёт ID который провайдер не понимает (часто `4.6` vs `4-6`) | Баг mapping в OmniRoute → `npm install omniroute@latest` или вручную писать поддерживаемый ID | +| `[400]: Invalid model. Please select a different model` | Провайдер (Kiro/Kilo) не выдаёт эту модель в их каталоге | Использовать другую модель этого провайдера (у Kiro есть только Sonnet) | +| `Missing Google projectId for Antigravity account. Please reconnect OAuth in Providers → Antigravity` | OAuth-сессия Google Antigravity без активного Cloud Code project | Зайти на [antigravity.google](https://antigravity.google), создать project, OmniRoute Dashboard → Providers → Antigravity → Reconnect | +| Empty response | Провайдер не отвечает / dead | Проверить аккаунт/ключ провайдера в OmniRoute Dashboard | +| `401` от Anthropic | CLIProxy OAuth протух (Claude Code session) | OmniRoute Dashboard → Providers → Claude → Reconnect | + +## Логи OmniRoute + +```bash +sshpass -p '1qaz!QAZ' ssh root@10.0.0.179 "journalctl -u omniroute --since '1 hour ago' --no-pager | tail -50" +``` + +Ключевые маркеры в логах: +- `[USAGE] ` — фактические вызовы (KIRO, CC, CLAUDE, ANTIGRAVITY...) +- `model fallback decision` — failover включился +- `Account quota exceeded` — pool аккаунта провайдера исчерпан +- `circuit breaker open` — провайдер временно отключён OmniRoute из-за серии ошибок +- `MEMORY_EXTRACTION` — Memory Tool через OmniRoute + +## Известные «вечные» гнилые модели (на 2026-05-06) + +Не тратить на них тесты, пока OmniRoute не обновится: +- `gh/claude-opus-4.6` — MS убрала из integrator scope +- `gh/claude-opus-4.7` — баг ID mapping +- `kr/claude-opus-*` / `kiro/claude-opus-*` — Kiro Opus не выдаёт в принципе +- `kc/anthropic/*` / `kilocode/anthropic/*` — провайдеры мёртвы / не настроены +- `antigravity/claude-opus-4-6-thinking` — пока OAuth projectId не подключен