# 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.