Files
knowledge-base/decisions/2026-06-30-cptr-computer-agent.md

6.0 KiB
Raw Blame History

date, type, tags
date type tags
2026-06-30 decision
dttb
proxmox
ai
agent
open-webui
computer-use

cptr (Open WebUI Computer) — агент-песочница, 5-й коннект chat.dttb.ru

Контекст

Олег попросил завести open-webui/computer («cptr») и подцепить к Open WebUI. cptr = «компьютер в браузере»: файлы, терминал, git, редактор + AI-агент. Отдаёт OpenAI-совместимый /v1/chat/completions, где каждый workspace виден как модель cptr/<basename> с полным агентским доступом (терминал/ФС/web/git) к хосту, где крутится.

Решение

Отдельный LXC 146 cptr (песочница) на Proxmox 10.0.0.250 — radius взрыва ограничен контейнером. Мозг агента = OmniRoute Opus 4.8. cptr держим LAN-only (авторы: «только доверенная сеть, не в публичный интернет»); публичный chat.dttb.ru ходит к нему server-side по локалке (как Hermes 8642 / openclaw 18789).

Что развёрнуто

  • LXC 146 Debian 12, unprivileged + nesting=1,keyctl=1, Docker 20.10, 2 vCPU / 2 GB / 12 GB на work, onboot.
  • IP 10.0.0.166 (nameserver 1.1.1.1, без NetBird). См. грабли с IP ниже.
  • Контейнер ghcr.io/open-webui/computer:latest: docker run -d --name cptr --restart unless-stopped -p 8000:8000 -v cptr-data:/data …. Образ сам стартует cptr run --host 0.0.0.0 --port 8000 --headless (из Dockerfile CMD).
  • Admin oleg/1qaz!QAZ (web http://10.0.0.166:8000).
  • Workspace cptr/main/data/workspaces/main (persistent в томе).
  • 5-й OpenAI-коннект Open WebUI (idx4): http://10.0.0.166:8000/v1 + Bearer sk-cptr-…. В дропдауне chat.dttb.ru появилась модель cptr/main.

Headless-настройка cptr (всё через API, FastAPI — точные пути из /openapi.json)

  1. Startup-токен: cptr run генерит свой 64-hex и печатает в логах (docker logs cptr…/?token=…), env CPTR_STARTUP_TOKEN игнорится. Брать из логов.
  2. Создать админа: POST /api/auth/setup {username,password,token,display_name}{ok:true} (даёт cookie cptr_session).
  3. Логин: POST /api/auth/login {username,password} → cookie.
  4. Ключ для /v1: POST /v1/keys {name} (cookie-auth) → отдаёт {key:"sk-cptr-…",id,name} raw один раз.
  5. Мозг (brain): POST /api/admin/connections {name,provider:"openai",base_url,api_key,models,enabled}; проверка POST /api/admin/connections/{id}/verify.
  6. Workspace: PUT /api/state/workspace?path=/data/workspaces/main с JSON-телом {"name":"main","path":"…"} (без тела — 500: роутер читает request.json()). После — cptr/main появляется в GET /v1/models (Bearer-ключ).
  7. В Open WebUI: POST /openai/config/update (полное тело) — добавить URL+key в OPENAI_API_BASE_URLS/OPENAI_API_KEYS индексом 4 + OPENAI_API_CONFIGS["4"]={enable,name:"cptr (computer agent)",connection_type:"external",model_ids:["cptr/main"]}. НЕ затирать idx0-3.

Грабли (за что наступали)

  • ⚠️ Конфликт IP: сначала дали .146 — там реальное устройство Яндекс-Станция Миди (MAC AC:BA:C0:39:82:64). Тесты прошли (ARP случайно указывал на контейнер), но это мина → Станция перехватит ARP → chat.dttb.ru 502. Та же грабля, что у LXC 145 (2026-06-27-homepage-dashboard-lxc145). Перенесли на .166 (pct set 146 -net0 …ip=10.0.0.166/24 + pct reboot), проверено arping + ping-sweep. Урок: сверять IP с ../projects/dttb/network-topology ДО раздачи; .145/.146 заняты TP-Link/Яндексом.
  • Пустой api_key мозга → битый заголовок: cptr при пустом ключе шлёт Authorization: Bearer (пустой) → httpx «Illegal header value» → verify=false. Лечится любым непустым значением (lan-trust) — OmniRoute на LAN всё равно отдаёт cc/claude-opus-4-8 по произвольному Bearer (проверено: Bearer dummy → completion 200). Это отличие от Open WebUI, где ключ OmniRoute = пустая строка.
  • /v1/models пустой, пока нет ни одного workspace (модели гейтвея = workspaces, не мозг). Завести через PUT /api/state/workspace.
  • Workspace-dir держать в томе /data (переживает пересоздание контейнера), не в /home/cptr.

Безопасность

Гейт = Bearer-ключ sk-cptr-… (только у Open WebUI) + LAN + admin-only Open WebUI. Агент исполняет тулы (терминал/ФС) внутри LXC 146 — проверено: на hostname/uname агент видит хостнейм контейнера (d01b45f09cc6), не Proxmox-хост. Аудит-лог включён (CPTR_AUDIT_LOG_LEVEL=INFO). cptr не за NPM и без публичного домена.

Проверено (e2e)

chat.dttb.ru → cptr/main → OmniRoute Opus → агент → run_command: uname -a; pwd вернул Linux d01b45f09cc6 … x86_64 + cwd /data/workspaces/main. echo cptr-live; whoamicptr-live/cptr.

См. ../projects/dttb/proxmox-inventory#LXC 146 — cptr (Open WebUI Computer / агент-исполнитель), 2026-06-22-open-webui-deploy.