codex-agent-3 / README.md
m5ike's picture
up3
c1a62a8
|
Raw
History Blame Contribute Delete
15.9 kB
---
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`)
```bash
# 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**:
```bash
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:
```bash
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](https://www.pulsemcp.com/servers) (10k+),
[Smithery](https://smithery.ai) (hosting + HTTP endpointy),
[Glama](https://glama.ai/mcp/servers), [mcp.so](https://mcp.so),
[Awesome MCP Servers](https://github.com/punkpeye/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í
```bash
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
```bash
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