Make Zed Agent closer to Cursor: deterministic DevOps path index, live Traefik port probe before blind edits, stop-after-edit, and quieter Russian progress.
6.8 KiB
EventHub AI Router — Zed gateway + LiteLLM on IFT
OpenAI-compatible endpoint for Zed 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):
{
"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-MaxX-AI-Orchestrate: off|auto|force— hierarchical (forcealways;autoна COMPLEX/REASONING;economyquality пропускает 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-цикл текстовым синтезом:
- Max-планировщик строит план (
paths/edit_goal/constraints) → приplan_confirm: trueждёт утвердить / правка / отмена - После
ok— Qwen3-Coder-30B executor получаетtoolsи отвечаетtool_calls(Zed сам правит файлы) - Пока в истории есть
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 scripts/switch-provider.sh hybrid
bash scripts/deploy.sh
# VPN нужен только для OpenRouter / Grok / Anthropic — не для Novita hierarchical
Hierarchical flow (COMPLEX / force)
novita-planner(Qwen3.8-Max) — JSON subtasks (simple|medium_code|hard) +paths/edit_goal- Workers / agent executor:
simple→ Llama (text only);medium_code→ Qwen3-Coder-30B;hard→ DeepSeek V3.2;quality=maxhard → Qwen3.8-Max - Checks;
novita-verifier(DeepSeek V3.2) только на fail / hard /quality=max - 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
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 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.