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.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Static LiteLLM settings — model_list generated by scripts/gen-litellm-config.py
|
||||
|
||||
general_settings:
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
store_model_in_db: false
|
||||
max_budget: 50
|
||||
budget_duration: 30d
|
||||
|
||||
litellm_settings:
|
||||
drop_params: true
|
||||
set_verbose: false
|
||||
request_timeout: 300
|
||||
num_retries: 2
|
||||
cache: true
|
||||
cache_params:
|
||||
type: redis
|
||||
host: redis
|
||||
port: 6379
|
||||
ttl: 3600
|
||||
callbacks: ["prometheus"]
|
||||
require_auth_for_metrics_endpoint: false
|
||||
|
||||
environment_variables:
|
||||
NOVITA_API_KEY: os.environ/NOVITA_API_KEY
|
||||
GROQ_API_KEY: os.environ/GROQ_API_KEY
|
||||
XAI_API_KEY: os.environ/XAI_API_KEY
|
||||
GEMINI_API_KEY: os.environ/GEMINI_API_KEY
|
||||
GIGACHAT_CREDENTIALS: os.environ/GIGACHAT_CREDENTIALS
|
||||
TOGETHER_API_KEY: os.environ/TOGETHER_API_KEY
|
||||
OPENROUTER_API_KEY: os.environ/OPENROUTER_API_KEY
|
||||
|
||||
router_settings:
|
||||
routing_strategy: simple-shuffle
|
||||
num_retries: 2
|
||||
timeout: 300
|
||||
allowed_fails: 5
|
||||
cooldown_time: 15
|
||||
+22
-50
@@ -1,104 +1,76 @@
|
||||
# tier × lane (A/B/C) → Novita model id + LiteLLM fallbacks
|
||||
# Tier × lane orchestration metadata (model IDs → config/providers.yaml)
|
||||
|
||||
lanes:
|
||||
A: economy
|
||||
B: balanced
|
||||
C: max
|
||||
|
||||
# LiteLLM per-lane RPM (proxy-side). Zed agent bursts tool calls — keep high for personal IFT.
|
||||
# OpenRouter :free upstream may still 429; router fallbacks + cooldown_time apply separately.
|
||||
models:
|
||||
a-simple:
|
||||
novita: novita/qwen/qwen3-4b-fp8
|
||||
fallbacks: [b-simple, groq-llama-8b]
|
||||
rpm: 60
|
||||
rpm: 300
|
||||
b-simple:
|
||||
novita: novita/meta-llama/llama-3.1-8b-instruct
|
||||
fallbacks: [a-simple, groq-llama-8b]
|
||||
rpm: 60
|
||||
rpm: 300
|
||||
c-simple:
|
||||
novita: novita/qwen/qwen3-8b-fp8
|
||||
fallbacks: [b-simple]
|
||||
rpm: 60
|
||||
rpm: 300
|
||||
|
||||
a-medium-ops:
|
||||
novita: novita/qwen/qwen3-8b-fp8
|
||||
fallbacks: [a-medium-code, b-medium-ops]
|
||||
rpm: 40
|
||||
rpm: 240
|
||||
b-medium-ops:
|
||||
novita: novita/deepseek/deepseek-v3.2
|
||||
fallbacks: [a-medium-code, c-medium-ops]
|
||||
rpm: 40
|
||||
rpm: 240
|
||||
c-medium-ops:
|
||||
novita: novita/deepseek/deepseek-v3.2
|
||||
fallbacks: [b-medium-ops]
|
||||
rpm: 40
|
||||
rpm: 240
|
||||
|
||||
a-medium-code:
|
||||
novita: novita/qwen/qwen3-coder-30b-a3b-instruct
|
||||
fallbacks: [a-medium-ops, groq-qwen-coder]
|
||||
rpm: 40
|
||||
rpm: 240
|
||||
b-medium-code:
|
||||
novita: novita/qwen/qwen3-coder-30b-a3b-instruct
|
||||
fallbacks: [b-medium-ops, c-medium-code]
|
||||
rpm: 40
|
||||
rpm: 240
|
||||
c-medium-code:
|
||||
novita: novita/qwen/qwen3-coder-30b-a3b-instruct
|
||||
fallbacks: [b-medium-code, c-medium-ops]
|
||||
rpm: 30
|
||||
rpm: 180
|
||||
|
||||
a-complex:
|
||||
novita: novita/deepseek/deepseek-v3.2
|
||||
fallbacks: [b-complex, a-reasoning]
|
||||
rpm: 30
|
||||
rpm: 180
|
||||
b-complex:
|
||||
novita: novita/deepseek/deepseek-r1-0528
|
||||
fallbacks: [a-complex, c-complex]
|
||||
rpm: 20
|
||||
rpm: 120
|
||||
c-complex:
|
||||
novita: novita/deepseek/deepseek-r1-turbo
|
||||
fallbacks: [b-complex]
|
||||
rpm: 15
|
||||
rpm: 120
|
||||
|
||||
a-reasoning:
|
||||
novita: novita/deepseek/deepseek-r1-0528-qwen3-8b
|
||||
fallbacks: [b-reasoning, gemini-flash]
|
||||
rpm: 30
|
||||
rpm: 120
|
||||
b-reasoning:
|
||||
novita: novita/deepseek/deepseek-r1-0528
|
||||
fallbacks: [a-reasoning, c-reasoning]
|
||||
rpm: 20
|
||||
rpm: 120
|
||||
c-reasoning:
|
||||
novita: novita/deepseek/deepseek-r1-turbo
|
||||
fallbacks: [b-reasoning, gemini-flash]
|
||||
rpm: 15
|
||||
rpm: 120
|
||||
|
||||
a-vision-ocr:
|
||||
novita: novita/paddlepaddle/paddleocr-vl
|
||||
fallbacks: [a-vision]
|
||||
rpm: 30
|
||||
rpm: 120
|
||||
no_escalation: true
|
||||
a-vision:
|
||||
novita: novita/qwen/qwen3-vl-30b-a3b-instruct
|
||||
fallbacks: [a-vision-ocr]
|
||||
rpm: 20
|
||||
rpm: 120
|
||||
b-vision:
|
||||
novita: novita/qwen/qwen2.5-vl-72b-instruct
|
||||
fallbacks: [a-vision, c-vision]
|
||||
rpm: 15
|
||||
rpm: 90
|
||||
c-vision:
|
||||
novita: novita/qwen/qwen3-vl-235b-a22b-instruct
|
||||
fallbacks: [b-vision]
|
||||
rpm: 10
|
||||
|
||||
optional_providers:
|
||||
groq-llama-8b:
|
||||
model: groq/llama-3.1-8b-instant
|
||||
api_key: os.environ/GROQ_API_KEY
|
||||
groq-qwen-coder:
|
||||
model: groq/qwen-qwen-2.5-coder-32b
|
||||
api_key: os.environ/GROQ_API_KEY
|
||||
gemini-flash:
|
||||
model: gemini/gemini-2.0-flash
|
||||
api_key: os.environ/GEMINI_API_KEY
|
||||
rpm: 90
|
||||
|
||||
audit:
|
||||
price_drift_threshold_pct: 10
|
||||
|
||||
@@ -32,9 +32,89 @@ redis:
|
||||
ttl_sec: 1800
|
||||
|
||||
classifier:
|
||||
# heuristic | hybrid (default) | llm
|
||||
mode: hybrid
|
||||
llm_model: gigachat-classifier
|
||||
low_confidence_threshold: 0.6
|
||||
timeout_sec: 15
|
||||
max_tokens: 64
|
||||
|
||||
# Strong Max plan → cheap coder workers/executor → conditional DeepSeek verify
|
||||
hierarchical:
|
||||
enabled: true
|
||||
trigger_tiers: [COMPLEX, REASONING]
|
||||
header: X-AI-Orchestrate # off | auto | force
|
||||
planner_model: novita-planner
|
||||
verifier_model: novita-verifier
|
||||
planner_fallback: b-complex
|
||||
verifier_fallback: b-complex
|
||||
verify_policy: on_fail_or_hard
|
||||
verify_input: digests
|
||||
synthesize_model: a-medium-code
|
||||
plan_confirm: true
|
||||
agent_executor_model: a-medium-code
|
||||
agent_escalate_model: b-complex
|
||||
agent_escalate_after_edit_failures: 2
|
||||
skip_synthesize_if_single: true
|
||||
max_subtasks: 3
|
||||
max_verify_retries: 1
|
||||
plan_max_tokens: 1024
|
||||
verify_max_tokens: 384
|
||||
synthesize_max_tokens: 1024
|
||||
worker_max_tokens: 768
|
||||
wall_clock_sec: 600
|
||||
digest_chars: 300
|
||||
call_timeout_sec: 300
|
||||
# First turn (kickstart read) can stay longer; after read_file body Coder hangs —
|
||||
# tool_loop uses short timeout + escalate_after_read → DeepSeek.
|
||||
executor_timeout_sec: 90
|
||||
executor_num_retries: 0
|
||||
executor_input_chars: 16000
|
||||
executor_tool_loop_chars: 12000
|
||||
executor_tool_loop_timeout_sec: 45
|
||||
executor_newest_tool_chars: 3500
|
||||
executor_minimal_context: true
|
||||
executor_max_tools: 6
|
||||
executor_tool_desc_chars: 120
|
||||
executor_tools_full_chars: 8000
|
||||
executor_max_tokens: 1024
|
||||
executor_use_stream: false
|
||||
executor_synthetic_on_timeout: true
|
||||
# First turn only: synthetic read_file on plan path if model returns prose.
|
||||
# Mid-loop still stops (no fake edits).
|
||||
executor_synthetic_mode: kickstart_only
|
||||
executor_max_synthetic_continues: 1
|
||||
executor_max_edit_failures: 4
|
||||
executor_midloop_model_retry: true
|
||||
executor_midloop_escalate: true
|
||||
# After successful read_file skip DeepSeek (was 408→400 loop) → edit_file
|
||||
executor_force_edit_after_read: true
|
||||
# After a successful read_file, skip cheap coder — it stalls on fat tool results
|
||||
executor_escalate_after_read: true
|
||||
# Rewrite read_file on already-read paths → edit (breaks re-read loops)
|
||||
executor_rewrite_reread: true
|
||||
# When model returns 200 without tool_calls: one escalate retry before kickstart
|
||||
executor_no_tools_escalate: true
|
||||
# After plan approve: 1) deterministic path index 2) if gaps → cheap find_* model
|
||||
path_resolve_enabled: true
|
||||
path_resolve_model: a-simple
|
||||
path_resolve_timeout_sec: 45
|
||||
path_resolve_max_tools: 3
|
||||
# DevOps (*.calentiq.com / Bad Gateway): probe live ports before edit
|
||||
runtime_probe_enabled: true
|
||||
runtime_probe_timeout_sec: 8
|
||||
# Optional: ssh host for docker inspect (empty = TCP probe from gateway only)
|
||||
runtime_probe_ssh_host: ""
|
||||
# Quiet Zed: milestones only (no ctx bars / LiteLLM waits / subtask dumps)
|
||||
progress_verbose: false
|
||||
show_context_fill: false
|
||||
progress_in_content: true
|
||||
stream_progress: true
|
||||
context_window_tokens: 32768
|
||||
plan_input_chars: 48000
|
||||
llm_cache_ttl_sec: 3600
|
||||
worker_map:
|
||||
simple: a-simple
|
||||
medium_code: a-medium-code
|
||||
hard: b-complex
|
||||
worker_map_max:
|
||||
hard: c-complex
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# Provider profiles — active: PRIMARY_PROVIDER env (default: hybrid)
|
||||
# Regenerate: bash scripts/gen-litellm-config.py
|
||||
|
||||
profiles:
|
||||
hybrid:
|
||||
label: "Hybrid: Novita workers + Novita plan/verify (no Claude geo-billing)"
|
||||
welcome_credit: false
|
||||
requires: [NOVITA_API_KEY]
|
||||
smart_router:
|
||||
model: novita/meta-llama/llama-3.1-8b-instruct
|
||||
api_key: NOVITA_API_KEY
|
||||
fallbacks:
|
||||
# No groq/gemini here — VPN off on IFT; those hang until client timeout.
|
||||
a-simple: [b-simple, a-medium-ops]
|
||||
a-medium-code: [b-medium-code, a-complex]
|
||||
a-complex: [b-complex, a-reasoning]
|
||||
b-complex: [a-complex, c-complex]
|
||||
a-reasoning: [b-reasoning, a-complex]
|
||||
a-vision: [a-vision-ocr]
|
||||
smart-router-internal: [a-medium-ops, a-medium-code, a-complex]
|
||||
# Planner is Max — fallback to DeepSeek then coder (never Llama)
|
||||
novita-planner: [b-complex, a-medium-code]
|
||||
novita-verifier: [b-complex, a-medium-code]
|
||||
default_fallbacks: [a-medium-code, a-complex, a-medium-ops]
|
||||
lanes:
|
||||
# Prefer Llama for fast lanes — Qwen3 puts answers in reasoning_content
|
||||
a-simple: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
b-simple: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
c-simple: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
a-medium-ops: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
b-medium-ops: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
c-medium-ops: { model: novita/meta-llama/llama-3.1-8b-instruct, api_key: NOVITA_API_KEY }
|
||||
# medium_code → coder / Plus-class (disable thinking — else stream hangs)
|
||||
a-medium-code: { model: novita/qwen/qwen3-coder-30b-a3b-instruct, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
b-medium-code: { model: novita/qwen/qwen3-coder-30b-a3b-instruct, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
c-medium-code: { model: novita/qwen/qwen3-coder-30b-a3b-instruct, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
# complex/reasoning A/B → coder/deepseek; C (hard) → Qwen3.8-Max only
|
||||
a-complex: { model: novita/qwen/qwen3-coder-30b-a3b-instruct, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
b-complex: { model: novita/deepseek/deepseek-v3.2, api_key: NOVITA_API_KEY }
|
||||
c-complex: { model: novita/qwen/qwen3.8-max, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
a-reasoning: { model: novita/qwen/qwen3-coder-30b-a3b-instruct, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
b-reasoning: { model: novita/deepseek/deepseek-v3.2, api_key: NOVITA_API_KEY }
|
||||
c-reasoning: { model: novita/qwen/qwen3.8-max, api_key: NOVITA_API_KEY, disable_thinking: true }
|
||||
a-vision-ocr: { model: novita/paddlepaddle/paddleocr-vl, api_key: NOVITA_API_KEY }
|
||||
a-vision: { model: novita/qwen/qwen3-vl-30b-a3b-instruct, api_key: NOVITA_API_KEY }
|
||||
b-vision: { model: novita/qwen/qwen2.5-vl-72b-instruct, api_key: NOVITA_API_KEY }
|
||||
c-vision: { model: novita/qwen/qwen3-vl-235b-a22b-instruct, api_key: NOVITA_API_KEY }
|
||||
|
||||
openrouter:
|
||||
label: OpenRouter reserve (VPN; free :free + pay-as-you-go)
|
||||
welcome_credit: true
|
||||
requires: [OPENROUTER_API_KEY]
|
||||
requires_vpn: true
|
||||
smart_router:
|
||||
model: openrouter/openrouter/free
|
||||
api_key: OPENROUTER_API_KEY
|
||||
fallbacks:
|
||||
a-simple: [b-simple, c-simple]
|
||||
a-medium-code: [b-medium-code, c-medium-code]
|
||||
a-complex: [b-complex, c-complex]
|
||||
smart-router-internal: [a-medium-ops, a-medium-code]
|
||||
default_fallbacks: [a-medium-code, a-medium-ops]
|
||||
lanes:
|
||||
a-simple: { model: openrouter/openai/gpt-oss-20b:free, api_key: OPENROUTER_API_KEY }
|
||||
b-simple: { model: openrouter/openai/gpt-oss-20b:free, api_key: OPENROUTER_API_KEY }
|
||||
c-simple: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
a-medium-ops: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
b-medium-ops: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
c-medium-ops: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
a-medium-code: { model: openrouter/cohere/north-mini-code:free, api_key: OPENROUTER_API_KEY }
|
||||
b-medium-code: { model: openrouter/cohere/north-mini-code:free, api_key: OPENROUTER_API_KEY }
|
||||
c-medium-code: { model: openrouter/cohere/north-mini-code:free, api_key: OPENROUTER_API_KEY }
|
||||
a-complex: { model: openrouter/google/gemma-4-26b-a4b-it:free, api_key: OPENROUTER_API_KEY }
|
||||
b-complex: { model: openrouter/nvidia/nemotron-3-nano-30b-a3b:free, api_key: OPENROUTER_API_KEY }
|
||||
c-complex: { model: openrouter/nvidia/nemotron-3-nano-30b-a3b:free, api_key: OPENROUTER_API_KEY }
|
||||
a-reasoning: { model: openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free, api_key: OPENROUTER_API_KEY }
|
||||
b-reasoning: { model: openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free, api_key: OPENROUTER_API_KEY }
|
||||
c-reasoning: { model: openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free, api_key: OPENROUTER_API_KEY }
|
||||
a-vision-ocr: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
a-vision: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
b-vision: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
c-vision: { model: openrouter/openrouter/free, api_key: OPENROUTER_API_KEY }
|
||||
|
||||
# Always registered when keys present (all profiles)
|
||||
fixed_models:
|
||||
# Hierarchical: strong Max plan (rare); DeepSeek verify (conditional)
|
||||
novita-planner:
|
||||
model: novita/qwen/qwen3.8-max
|
||||
api_key: NOVITA_API_KEY
|
||||
max_tokens: 1024
|
||||
temperature: 0
|
||||
disable_thinking: true
|
||||
novita-verifier:
|
||||
model: novita/deepseek/deepseek-v3.2
|
||||
api_key: NOVITA_API_KEY
|
||||
max_tokens: 1024
|
||||
temperature: 0
|
||||
# Optional Claude — only if ANTHROPIC_API_KEY works later (VPN + billing)
|
||||
claude-haiku-planner:
|
||||
model: anthropic/claude-haiku-4-5-20251001
|
||||
api_key: ANTHROPIC_API_KEY
|
||||
requires_vpn: true
|
||||
max_tokens: 1024
|
||||
temperature: 0
|
||||
claude-sonnet-verifier:
|
||||
model: anthropic/claude-sonnet-5
|
||||
api_key: ANTHROPIC_API_KEY
|
||||
requires_vpn: true
|
||||
max_tokens: 2048
|
||||
temperature: 0
|
||||
grok-3:
|
||||
model: xai/grok-3
|
||||
api_key: XAI_API_KEY
|
||||
requires_vpn: true
|
||||
groq-llama-8b:
|
||||
model: groq/llama-3.1-8b-instant
|
||||
api_key: GROQ_API_KEY
|
||||
groq-qwen-coder:
|
||||
model: groq/qwen-qwen-2.5-coder-32b
|
||||
api_key: GROQ_API_KEY
|
||||
gemini-flash:
|
||||
model: gemini/gemini-2.0-flash
|
||||
api_key: GEMINI_API_KEY
|
||||
gigachat-classifier:
|
||||
model: gigachat/GigaChat-2-Lite
|
||||
api_key: GIGACHAT_CREDENTIALS
|
||||
ssl_verify: false
|
||||
max_tokens: 64
|
||||
temperature: 0
|
||||
gigachat-pro:
|
||||
model: gigachat/GigaChat-2-Pro
|
||||
api_key: GIGACHAT_CREDENTIALS
|
||||
ssl_verify: false
|
||||
@@ -38,6 +38,18 @@ gateway:
|
||||
- novita
|
||||
- traefik
|
||||
- mnesia
|
||||
medium_code_keywords:
|
||||
- поправь
|
||||
- исправь
|
||||
- fix
|
||||
- edit
|
||||
- patch
|
||||
- bugfix
|
||||
- typo
|
||||
- rename
|
||||
- add test
|
||||
- unit test
|
||||
- lint
|
||||
ocr_keywords:
|
||||
- ocr
|
||||
- прочитай текст
|
||||
@@ -64,6 +76,8 @@ litellm:
|
||||
tier: SIMPLE
|
||||
- keywords: ["bash", "docker", "swarm", "ci/cd", "gitea", "rebar", "erlang", "devops", "kubectl", "terraform", "playwright", "npm", "wsl"]
|
||||
tier: MEDIUM
|
||||
- keywords: ["поправь", "исправь", "fix", "edit", "patch", "bugfix", "typo", "rename", "add test", "lint"]
|
||||
tier: MEDIUM
|
||||
- keywords: ["рефакторинг", "refactor", "архитектура", "architecture", "спроектируй", "design system", "microservice", "distributed", "migration plan"]
|
||||
tier: COMPLEX
|
||||
- keywords: ["step by step", "reasoning", "prove", "analyze deeply", "think through"]
|
||||
|
||||
Reference in New Issue
Block a user