Files
EventHubAiRouter/README.md
T
aleksey a2d238d92e
CI / build-gateway (push) Failing after 16s
CI / sync-config (push) Failing after 0s
feat(agent): hierarchical executor with path resolve, runtime probe, quiet UI
Make Zed Agent closer to Cursor: deterministic DevOps path index, live Traefik
port probe before blind edits, stop-after-edit, and quieter Russian progress.
2026-08-13 11:41:27 +03:00

159 lines
6.8 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.
# EventHub AI Router — Zed gateway + LiteLLM on IFT
OpenAI-compatible endpoint for [Zed](https://zed.dev) with tier/lane routing, optional **hierarchical** orchestration (**Qwen3.8-Max** plan → cheap **Qwen3-Coder-30B** workers/executor → conditional **DeepSeek V3.2** verify), GigaChat classifier, VLESS VPN, Grafana, LiteLLM Admin UI.
Цель: качество правок близко к Cursor при экономии бюджета — дорогие модели только на plan/hard/verify, рутина на дешёвом coder.
## URLs (IFT, Calentiq TLS)
| Service | URL |
|---------|-----|
| **Zed API** | `https://ai-router.ift.calentiq.com/v1` |
| **LiteLLM Admin UI** | `https://litellm.ift.calentiq.com/ui` (login: `admin` / `LITELLM_MASTER_KEY`) |
| **Grafana** | `https://grafana.ift.calentiq.com` |
| Legacy (self-signed) | `https://ai-router.ift.eventhub.local/v1` |
## Клиент (канон): Zed Agent → AiRouter
**Primary:** встроенный Zed Agent (OpenAI-compatible), не Claude Code / Codex ACP — те обходят Novita-бюджет.
Пример `settings.json` (Zed 2026 openai-compatible provider):
```json
{
"language_models": {
"openai_compatible": {
"AiRouter": {
"api_url": "https://ai-router.ift.calentiq.com/v1",
"available_models": [
{
"name": "smart-router",
"display_name": "EventHub smart-router",
"max_tokens": 16384,
"max_output_tokens": 4096,
"capabilities": {
"tools": true,
"images": false,
"parallel_tool_calls": false
}
}
]
}
}
},
"agent": {
"default_model": {
"provider": "AiRouter",
"model": "smart-router"
}
}
}
```
API key: `ROUTER_API_KEY` в Agent Settings / provider UI.
Checklist:
- модель `smart-router`, `capabilities.tools: true`
- профиль **Write** (tools on) для правок файлов
- Ask без tools → text hierarchical / lane routing
Optional headers / metadata:
- `X-AI-Quality: auto|economy|balanced|max``max` поднимает hard на Qwen3.8-Max
- `X-AI-Orchestrate: off|auto|force` — hierarchical (`force` always; `auto` на COMPLEX/REASONING; `economy` quality пропускает hierarchical)
### Запасной клиент (тот же AiRouter)
Если native Zed Agent loop хрупкий: **OpenCode** или **Cline** с `base_url=https://ai-router.ift.calentiq.com/v1` и тем же ключом — иерархия бюджета сохраняется. Claude Code / Codex ACP в Zed — **не** primary (свой биллинг).
### Zed Agent Write + hierarchical
Если в запросе есть `tools` (профиль **Write**), gateway **не** подменяет agent-цикл текстовым синтезом:
1. **Max**-планировщик строит план (`paths` / `edit_goal` / `constraints`) → при `plan_confirm: true` ждёт **утвердить / правка / отмена**
2. После `ok`**Qwen3-Coder-30B** executor получает `tools` и отвечает **`tool_calls`** (Zed сам правит файлы)
3. Пока в истории есть `role: tool` / `tool_calls` — только executor; при повторных fail edit → escalate на DeepSeek (без synthetic tool_calls)
Чат без tools (Ask / Minimal) по-прежнему может идти через полный text hierarchical.
### Progress в Zed (hierarchical)
При `stream: true` (дефолт Zed) gateway сразу стримит блок **«Ход выполнения»**: план → волны workers → verify → синтез, затем `---` и финальный ответ. Конфиг: `hierarchical.stream_progress` / `progress_in_content` в `config/orchestration.yaml`.
## Provider profiles (`PRIMARY_PROVIDER`)
| Profile | Keys | VPN | Role |
|---------|------|-----|------|
| **`hybrid`** (default) | `NOVITA_API_KEY` | workers direct | Novita workers + **Novita** plan/verify |
| **`openrouter`** | `OPENROUTER_API_KEY` | **VPN** | Reserve (`:free` / non-Anthropic); Claude/OpenAI/Google may be region-blocked |
GigaChat (`GIGACHAT_CREDENTIALS`) — classifier. Optional: Groq / Gemini / Grok / Anthropic (если биллинг заработает).
```bash
bash scripts/switch-provider.sh hybrid
bash scripts/deploy.sh
# VPN нужен только для OpenRouter / Grok / Anthropic — не для Novita hierarchical
```
## Hierarchical flow (COMPLEX / force)
1. **`novita-planner`** (**Qwen3.8-Max**) — JSON subtasks (`simple` | `medium_code` | `hard`) + `paths` / `edit_goal`
2. **Workers / agent executor**: `simple` → Llama (text only); `medium_code`**Qwen3-Coder-30B**; `hard`**DeepSeek V3.2**; `quality=max` hard → **Qwen3.8-Max**
3. Checks; **`novita-verifier`** (DeepSeek V3.2) только на fail / hard / `quality=max`
4. **Synthesize** (text path) на `a-medium-code`
> Anthropic / OpenRouter-Claude недоступны при RU billing — plan/verify идут через Novita.
Response `x_router_meta.mode=hierarchical` / `hierarchical_agent` with `worker_calls`, `executor_model`, `role_cost`, `verify_skipped`, etc.
## Architecture
- **Gateway** (`router/`) — classify, lanes A/B/C, hierarchical runner, Redis session
- **LiteLLM** — named models + Auto Router (`smart-router-internal`)
- **PostgreSQL** — spend logs / Admin UI
- **Redis** — cache + session
- **VPN** — `vless-proxy` (Anthropic, OpenRouter, Grok)
Config: `config/providers.yaml`, `orchestration.yaml`, `routing_rules.yaml`, `model_matrix.yaml`.
## Deploy on IFT
```bash
git clone git.sabilin.com/eventhub/EventHubAiRouter /opt/ai-router-stack
cd /opt/ai-router-stack
cp .env.example .env # NOVITA_API_KEY; PRIMARY_PROVIDER=hybrid
bash scripts/deploy.sh
bash scripts/smoke-test.sh
SMOKE_HIERARCHICAL=1 bash scripts/smoke-test.sh
```
Swarm secrets: `novita_api_key`, optional `anthropic_api_key` / `openrouter_api_key`, `gigachat_credentials`, …
**`LITELLM_SALT_KEY`** — generate once, never change after first deploy.
## VPN
```bash
bash scripts/vpn-enable.sh
bash scripts/vpn-disable.sh
```
| Provider | Host | Route |
|----------|------|-------|
| Novita | `api.novita.ai` | **direct** (NO_PROXY) |
| Groq / Gemini / GigaChat | … | **direct** |
| **Anthropic** | `api.anthropic.com` | **VPN** (App unavailable without) |
| **OpenRouter** | `openrouter.ai` | **VPN** |
| **xAI Grok** | `api.x.ai` | **VPN** |
Canon: `scripts/no-proxy-default.sh`.
## LLM classifier (GigaChat)
`CLASSIFIER_MODE=hybrid|heuristic|llm` — see `config/orchestration.yaml`. Freemium GigaChat for personal test.
## Scripts
See `scripts/``deploy.sh`, `smoke-test.sh`, `gen-litellm-config.py`, `switch-provider.sh`, VPN helpers.