Spaces:
Paused
title: CodeAgent
emoji: 🛠️
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 7860
pinned: false
CodeAgent v5 — AI kódovací agent s lokální vLLM inference a nastavením za běhu
Agentní chat běžící na HF Space 4× NVIDIA A100 80GB (320 GB VRAM, 568 GB RAM, 48 vCPU). Inference probíhá lokálně ve Space přes vLLM — žádné externí LLM API není potřeba (volitelně hybrid fallback přes HF router).
Co je nové ve v5
| Oblast | v4 | v5 |
|---|---|---|
| Inference | in-process vllm.LLM |
vllm serve subprocess (OpenAI server) řízený aplikací |
| Tool calling | ruční parsování <tool_call> |
nativní (--enable-auto-tool-choice + parser dle modelu) |
| Změna nastavení | HF Variables ⇒ restart Space | tab ⚙️ Nastavení / /admin/settings — za běhu, bez restartu |
| Výměna modelu | rebuild/restart | hot-swap: engine se přenačte na pozadí, UI/API běží dál |
| Modely | download při buildu (limit disku) | read-only volume mounty /repos/<repo_id> (bez stahování) |
| Pád enginu | pád celé aplikace | watchdog — automatický restart enginu (max 3×) |
| Stack | vLLM 0.23, Gradio 5 | vLLM 0.25, Gradio 6, huggingface_hub 1.x, hf_transfer |
| Režimy | single / dual / hybrid | single / hybrid (dual odstraněn — na 4×A100 je lepší 1 velký model) |
Architektura
┌────────────────────────── HF Space (Docker) ──────────────────────────┐
│ uvicorn app:app (port 7860) │
│ ├─ Gradio 6 UI: 💬 Chat · ⚙️ Nastavení (runtime) · 📜 Logy │
│ ├─ FastAPI: /health · /v1/* (OpenAI-kompatibilní) · /admin/* │
│ ├─ SettingsManager ⇒ /data/settings.json (bucket) | .agent/ │
│ └─ VLLMEngine (subprocess manager + watchdog) │
│ └─ vllm serve <model> --port 8001 … (4× A100, TP=4) │
│ ▲ modely: /repos/<repo_id> (RO volume) | HF download │
└───────────────────────────────────────────────────────────────────────┘
▲ nástroje (run_command, read_file, …) přes tunel
Open Terminal / runner na uživatelově Macu (LOCAL_RUNNER_URL)
- Aplikace startuje okamžitě — UI a
/healthjsou dostupné hned, model se načítá na pozadí (stav vidíš v UI i v/health.engine). - Změna enginových polí (model, kvantizace, TP, kontext…) spustí reload subprocessu na pozadí. Space se nerestartuje.
- Ostatní pole (limity agenta, runner URL, cache, log level…) platí okamžitě.
Nastavení za běhu
UI
Tab ⚙️ Nastavení: presety pro 4×A100, formulář všech polí, stav enginu (auto-refresh 5 s), tlačítka Uložit/Reload/Stop. Tab 📜 Logy: tail logu vLLM i aplikace.
API (Bearer AGENT_API_TOKEN)
# přečíst aktuální nastavení
curl -H "Authorization: Bearer $TOKEN" https://<space>.hf.space/admin/settings
# změnit model za běhu (spustí reload enginu na pozadí)
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen3-235B-A22B-Instruct-2507-FP8", "max_model_len": 65536}' \
https://<space>.hf.space/admin/settings
# jen instant pole — bez reloadu
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"max_steps": 40, "temperature": 0.1}' \
https://<space>.hf.space/admin/settings
# stav / reload / stop enginu, logy, presety
curl -H "Authorization: Bearer $TOKEN" https://<space>.hf.space/admin/engine/status
curl -X POST -H "Authorization: Bearer $TOKEN" https://<space>.hf.space/admin/engine/reload
curl -H "Authorization: Bearer $TOKEN" "https://<space>.hf.space/admin/logs?source=engine&lines=100"
curl -H "Authorization: Bearer $TOKEN" https://<space>.hf.space/admin/presets
Persistence: /data/settings.json, pokud je připojen storage bucket
(doporučeno — přežije restart), jinak .agent/settings.json (ephemeral).
Env Variables slouží jen jako výchozí hodnoty při úplně prvním startu.
Modely na 4×A100 (320 GB VRAM)
A100 = Ampere: FP8 checkpointy běží přes FP8-Marlin (weight-only). Ephemeral disk je jen ~50 GB ⇒ velké modely mountuj jako volume:
python3 scripts/space_ctl.py mount Qwen/Qwen3-Coder-30B-A3B-Instruct
python3 scripts/space_ctl.py mount Qwen/Qwen3-235B-A22B-Instruct-2507-FP8
python3 scripts/space_ctl.py volumes # výpis
(Mount změní konfiguraci Space ⇒ jednorázový restart. Poté už přepínáš modely za běhu v Nastavení.)
Persistentní stahování vah: Storage Bucket (read-write)
Alternativa k RO mountům — HF Storage Bucket připojený read-write. Stažené váhy pak přežijí restart Space a neomezuje je ~50GB ephemeral disk:
python3 scripts/space_ctl.py create-bucket codeagent-data
python3 scripts/space_ctl.py mount-bucket <owner>/codeagent-data /data
- Bucket na
/datase detekuje automaticky: váhy se stahují do/data/models(vLLM--download-dir, Xet high-performance transfer),settings.jsondo/data, a navíc se tam persistujíVLLM_CACHE_ROOT(torch.compile artefakty — další starty Space přeskočí kompilaci) aHF_HOME(tokenizery, configy, remote-code moduly). - Adresář lze změnit za běhu polem
download_dir(tab Nastavení neboPOST /admin/settings {"download_dir": "/muj-bucket/models"}); prázdná hodnota = auto-detekce. Env default:MODEL_DOWNLOAD_DIR. - Kdy co: RO model mount = okamžitá dostupnost bez stahování (oficiální repo váhy); RW bucket = univerzální cache pro libovolné modely vč. vlastních fine-tunů, platí se za uložená data (viz hf.co/storage).
| Preset | Váhy | Poznámka |
|---|---|---|
| Qwen3-Coder-Next-FP8 (80B-A3B) | ~80 GB | výchozí — SWE-bench Verified ~70 %, 256K ctx, jen 3B aktivních |
| Qwen3-Coder-Next (BF16) | ~159 GB | plná přesnost téhož |
| MiniMax-M2.7 (FP8, 229B-A10B) | ~230 GB | nejsilnější agentic coder, co se vejde; ctx ~96K, nutný mount |
| Qwen3.5-122B-A10B-FP8 | ~127 GB | nejnovější generace (04/2026), hybridní thinking |
| Qwen3.5-397B-A17B-GPTQ-Int4 | ~236 GB | oficiální Int4 vlajkové lodi; nutný mount |
| Devstral-2-123B (dense) | ~256 GB | Mistral SWE specialista; ctx ~48K, nutný mount |
| GLM-4.7-Flash (31B) | ~62 GB | rychlý malý agentní model (01/2026) |
| Qwen3-Coder-30B-A3B (BF16) | ~61 GB | prověřená stabilní jistota |
| Qwen3-Coder-30B-A3B-FP8 | ~31 GB | minimum VRAM, plný 256K kontext |
| Qwen3-235B-A22B-Instruct-2507-FP8 | ~236 GB | starší vlajková loď; ctx ~64K, nutný mount |
| GLM-4.5-Air-FP8 | ~110 GB | silný agentní model s thinking |
| Qwen3-32B | ~66 GB | dense reasoning s <think> |
| gpt-oss-120b | ~63 GB | Harmony formát; optimalizován pro Hopper |
Nevejdou se (07/2026): GLM-5.x (756 GB), GLM-4.7 (362 GB), MiniMax-M3 (444–854 GB), Kimi-K2.x (595+ GB), DeepSeek-V3.x — pro ně slouží hybrid režim.
Kimi-K2.7-Code lokálně neběží: 1.06T parametrů, nativní INT4 checkpoint má 595 GB (> 320 GB VRAM i po jakékoli další kvantizaci). Je dostupný jako výchozí
kimi_modelv hybrid režimu — volá se přes HF router API (tag[kimi], auto-routing těžkých dotazů, fallback při pádu enginu).
Proměnné prostředí (jen výchozí hodnoty + secrets)
| Proměnná | Popis | Výchozí |
|---|---|---|
HF_TOKEN (secret) |
token pro gated modely + HF router | — |
AGENT_API_TOKEN (secret) |
Bearer pro /v1/* a /admin/* |
— |
GRADIO_AUTH (secret) |
user:heslo pro UI |
— |
LOCAL_RUNNER_TOKEN (secret) |
Bearer pro runner | — |
MODEL_PRIMARY |
výchozí model | Qwen/Qwen3-Coder-Next-FP8 |
AGENT_MODE |
single / hybrid |
single |
ROUTER_MODE |
hybrid routing: ai / keywords |
ai |
TENSOR_PARALLEL_SIZE |
počet GPU | 4 |
GPU_MEMORY_UTILIZATION |
podíl VRAM | 0.92 |
MAX_MODEL_LEN |
kontext | 131072 |
QUANTIZATION |
auto/none/fp8/awq… |
auto |
MODEL_DOWNLOAD_DIR |
adresář pro stahované váhy (prázdné = auto /data/models → /app/cache/models) |
— |
MODEL_REVISION |
pin na commit/tag HF repa (doporučeno u trust_remote_code) |
— |
TOOL_CALL_PARSER / REASONING_PARSER |
auto = dle modelu |
auto |
KIMI_MODEL |
hybrid fallback (HF router) | moonshotai/Kimi-K2.7-Code |
LOCAL_RUNNER_URL |
URL Open Terminal tunelu | — |
PRELOAD_MODEL |
načíst model hned po startu | 1 |
ENGINE_STARTUP_TIMEOUT |
limit načítání modelu (s) | 2700 |
CHAT_VERBOSITY |
full / compact / final |
full |
CONTEXT_COMPACTION |
trim / off |
trim |
SUBAGENT_<ROLE>_ENABLED / _PROMPT |
konfigurace sub-agentů | zapnuto / výchozí |
MAX_STEPS a další limity |
viz settings.py |
Kompletní seznam runtime polí: GET /admin/settings nebo settings.py.
Hybrid režim: AI routing složitých úloh
V agent_mode=hybrid rozhoduje o každé zprávě router, zda ji řeší rychlý
lokální model, nebo velký API model (kimi_model přes HF router,
výchozí Kimi-K2.7-Code — 1T model, který se na 320 GB VRAM nevejde lokálně):
- Explicitní tagy mají absolutní přednost:
[kimi]/[api]⇒ API,[local]/[qwen]⇒ lokální. - Délka kontextu nad
local_context_limit⇒ API. - AI klasifikace (
router_mode=ai, výchozí): sám lokální model dostane krátký klasifikační prompt (~8 output tokenů, temperature 0) a rozhodne LOCAL vs API — API jen pro architekturu/design, deep debugging, security audity, velké refaktory a nejednoznačná zadání vyžadující těžké plánování. Při chybě/nejednoznačné odpovědi fallback na keywords. - Keywords (
router_mode=keywords): statická pravidla bez AI.
API model slouží zároveň jako failover — když lokální engine spadne nebo se právě reloaduje, smyčka automaticky přepne na API a pokračuje.
Sub-agenti: plná runtime konfigurace
delegate_task deleguje na role explorer / coder / reviewer. V tabu
🤝 Sub-agenti (nebo přes /admin/settings) lze za běhu u každé role:
- zapnout/vypnout (
subagent_<role>_enabled) — vypnutá role zmizí z nabídky nástrojedelegate_task(enum se generuje dynamicky; bez zapnutých rolí se nástroj vynechá úplně), - nastavit max kroků (
max_<role>_steps), - přepsat systémový prompt (
subagent_<role>_prompt, prázdné = výchozí).
Tokeny sub-agentů se počítají do statistik nadřazeného běhu.
Výřečnost chatu (chat_verbosity)
| Hodnota | Chování |
|---|---|
full (výchozí) |
nástroje + argumenty + JSON výsledky + 📊 token patička |
compact |
jen jednořádkové záznamy nástrojů + patička |
final |
pouze finální odpověď (během práce nenápadný ⏳ heartbeat) |
Platí okamžitě, ovlivňuje i obsah odpovědí /v1/chat/completions
(agentní režim).
Tokeny a inteligentní správa kontextu
Počítání tokenů — přesná čísla z usage každé odpovědi (vLLM i HF
router), žádné odhady: per-turn patička v chatu (volání, vstup/výstup,
aktuální velikost kontextu) a globální součty od startu v /health.tokens
a v UI statusu, rozpad podle zdroje (local / api / router /
passthrough). Cache hity se nepočítají. /v1 odpovědi vracejí skutečné
usage za celý agentní běh.
Kompakce kontextu (context_compaction=trim, výchozí) — drží kontext
pod budgetem (context_budget_tokens, 0 = auto z max_model_len − max_output_tokens − 2048) a šetří KV cache:
- Stárnutí: staré výsledky nástrojů (mimo posledních
context_keep_last_stepsbloků) se zkrátí natool_result_aged_charsznaků — plné výpisy ztrácejí hodnotu, jakmile na ně agent zareagoval. - Vypouštění: pokud se stále nevejde, nejstarší celé kroky konverzace se nahradí souhrnnou poznámkou (model ví, že historie byla zkrácena).
Nikdy se nekompaktuje: systémový prompt, zadání úlohy a posledních N bloků.
Kompakce nikdy nerozbije tool-calling strukturu (vypouští jen celé bloky)
a v chatu se hlásí řádkem 🧹 Kontext zhutněn (~X tokenů ušetřeno).
Externí tool servery (MCP)
Tab 🧰 Externí nástroje připojuje za běhu libovolný MCP server
(Model Context Protocol, Streamable HTTP) — jeho nástroje dostane hlavní
agent okamžitě jako ext_<server>_<tool> funkce, bez restartu:
- Přidání/editace/odebrání serverů (jméno, URL, Bearer token, timeout),
per-server zapnout/vypnout a filtr
allowed_tools(čárkami). - Hledání v oficiálním registru (registry.modelcontextprotocol.io — metaregistr Anthropic/GitHub/Microsoft/PulseMCP) přímo z UI/API; vrací servery s hotovým HTTP endpointem.
- Katalog ověřených veřejných serverů: Context7 (dokumentace knihoven), DeepWiki (Q&A nad GitHub repy), Hugging Face Hub, Microsoft Learn, Cloudflare docs — připojitelné na jeden klik, bez klíčů.
- Transport dle spec 2025-06-18: JSON i SSE odpovědi,
Mcp-Session-Idsession handling s automatickou re-inicializací. - API:
GET/POST /admin/toolservers,POST /admin/toolservers/delete|refresh,GET /admin/toolservers/registry?q=…,GET /admin/toolservers/catalog. - Persistence
/data/toolservers.json(bucket) nebo.agent/. - Bezpečnost: výstupy externích nástrojů jsou nedůvěryhodná data;
externí nástroje má jen hlavní agent (sub-agenti ne), výsledky ořezává
tool_result_max_chars. Připojuj jen servery, kterým věříš.
Další zdroje serverů: PulseMCP (10k+), Smithery (hosting + HTTP endpointy), Glama, mcp.so, Awesome MCP Servers.
OpenAI-kompatibilní API
POST /v1/chat/completionssmodel="code-agent"⇒ plná agentní smyčka (nástroje, sub-agenti, paměť).model="code-agent-llm"(nebo"raw") ⇒ passthrough přímo na lokální model bez agentní smyčky — pro OpenWebUI jako čistý chat model.GET /v1/models,GET /health(bez auth).
Nasazení
cd agent
# 1) nastav Variables/Secrets (jen první inicializace)
python3 scripts/init_space.py
# 2) namountuj modely, které chceš mít k dispozici
python3 scripts/space_ctl.py mount Qwen/Qwen3-Coder-30B-A3B-Instruct
# 3) push kódu do Space (build ~10 min; modely se nestahují)
git push
# 4) tunel na runner (Mac)
./scripts/tunnel.sh
Ovládání: space_ctl.py start|stop|status|stats|logs|price|volumes|mount|unmount.
Testy
pip install -r requirements.txt pytest
pytest tests/ -v
Testy běží bez GPU — vLLM subprocess je nahrazen mock OpenAI serverem
(tests/mock_vllm.py), takže se ověřuje i celý flow „změna nastavení ⇒
hot-swap enginu bez restartu aplikace".
Sub-agenti a nástroje (beze změny)
delegate_task(role="explorer"|"coder"|"reviewer")s vlastními limity kroků.- Nástroje přes Open Terminal API na
LOCAL_RUNNER_URL:run_command,git_command,read_file,write_file,replace_in_file,search_code,list_files+ trvalá paměťremember/recall(.agent/memory.md).
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference