codex-agent-3 / README.md
m5ike's picture
up3
c1a62a8
|
Raw
History Blame Contribute Delete
15.9 kB
metadata
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 /health jsou 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 /data se detekuje automaticky: váhy se stahují do /data/models (vLLM --download-dir, Xet high-performance transfer), settings.json do /data, a navíc se tam persistují VLLM_CACHE_ROOT (torch.compile artefakty — další starty Space přeskočí kompilaci) a HF_HOME (tokenizery, configy, remote-code moduly).
  • Adresář lze změnit za běhu polem download_dir (tab Nastavení nebo POST /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_model v 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ě):

  1. Explicitní tagy mají absolutní přednost: [kimi]/[api] ⇒ API, [local]/[qwen] ⇒ lokální.
  2. Délka kontextu nad local_context_limit ⇒ API.
  3. 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.
  4. 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ástroje delegate_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:

  1. Stárnutí: staré výsledky nástrojů (mimo posledních context_keep_last_steps bloků) se zkrátí na tool_result_aged_chars znaků — plné výpisy ztrácejí hodnotu, jakmile na ně agent zareagoval.
  2. 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-Id session 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/completions s model="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