Промпт отправляется в /api/session/:id/message (v1.18) с новым форматом
тела parts:[{type:"text"}], вместо {prompt:{text}}. Причина перехода:
/prompt сам подставляет не ту модель, что в конфиге; /message использует
модель из конфига.
- client.go: Send → POST /message + тело parts; шапка-док v1.18
- тесты: fakeAPIServer + e2eFakeAPI отвечают на POST /message (GET уже был)
В единой точке Client.do добавлены отладочные логи (всегда включены):
- строка вызова: opencode api <op> -> <METHOD> <url><path>
- тело запроса (усечено до 5000 байт)
- тело ответа 2xx (усечено до 5000 байт)
- тело ответа при ошибке/не-2xx (усечено до 1000 байт)
Нужно для диагностики проблемы аналитика (serve отвечал на модель
opencode/nemotron, ratatoskr не видел вердикт).
procgroup_unix.go имеет unix build-tag; под windows setpgid/killGroup не
определялись → GOOS=windows сборка падала. Добавлен procgroup_windows.go:
setpgid — no-op (нет Setpgid), killGroup — Process.Kill (дочерние группы не
завершаются).
Runner теперь ходит к постоянным serve по HTTP API (v1.17+, /api):
- клиент Client (create/send/wait/abort/messages/verdict)
- Pool: по одному serve на каталог, ленивый подъём, root-сервер в worktree,
выделение портов, ReleaseTask при завершении задачи
- Run: CreateSession('ratatoskr-<агент>') -> Send -> поллинг Verdict из
text-частей assistant-сообщений; idle/hard таймауты дают RC=-1
- вердикт извлекается из последнего assistant text-парта (плоский text)
- тесты: unit на фейковом HTTP-сервере; e2e эмулирует serve через httptest,
агент определяется по title сессии
Супервайзер Server spawn'ит opencode serve (или ходит на внешний URL),
Runner ходит к нему через 'opencode run --attach <url>'. По умолчанию
serve.enabled=false — историческая spawn-модель сохранена; наличие
serve.url переключает на внешний сервер.
- config: ServeCfg (enabled/hostname/port/url/password) + дефолты; лоадер
научился int/bool (раньше только string/Duration/struct).
- opencode: Server (Start/Run/Close, /global/health, рестарт упавшего,
reaper-горутина владеет Wait; .Exited() непригоден для SIGKILL).
- Runner.AttachURL: run --attach <url> при заданном URL, иначе как раньше.
- app: composition root — при включённом serve запускает супервайзер.
- тесты: TestRun_AttachMode, TestServer_{ExternalURL,OwnProcess,Restart}.
- opencode ищет кастомных агентов в поддиректории agents/ (как .opencode),
а не в корне OPENCODE_CONFIG_DIR → распаковка теперь в <dir>/agents/*.md
- markdown-агентам добавлен mode: primary (иначе subagent по умолчанию)
- idle-детекция сбрасывает таймер при live-строках (text/tool/agent/reasoning),
а не только по росту БД → «LLM думает и стримит» не считается зависанием
- дефолт idle_timeout поднят с 2м до 5м
LiveRegistry собирает live-шаги из stdout процесса opencode по taskID
(через контекст, без изменения интерфейса Runner). /status N для running-задачи
прикладывает живое состояние: активный субагент, давность последнего шага,
последние text-шаги агента. Ничего не перезапускается и не убивается —
только наблюдение по запросу.