feat(config): general to glm-5.2, add vision agent, drop plan model #99

Closed
opened 2026-08-17 16:56:14 +03:00 by slaid098 · 0 comments
Owner

Контекст

После PR #98 (per-agent models + task delegation) сложилась картина: основные кодинг-модели text-only, зрение есть только у minimax-m3. Пользователь хочет:

  1. Переключить general (кодинг) с deepseek-v4-pro на glm-5.2 — предпочтение по качеству кода.
  2. Оставить reviewer на deepseek-v4-pro (без изменений).
  3. Добавить новый сабагент vision на minimax-m3 (image+video+text) для любых задач со зрением — скриншоты, анализ UI, проверка браузера на сайтах-детекторах бот-защиты.
  4. Убрать model у plan (primary-агент) — модель plan'а выбирается в UI под задачу, не фиксируется в конфиге.
  5. explore/scout/memory-syncer остаются на deepseek-v4-flash (без изменений).

Архитектурное решение: vision — отдельный сабагент (оправдано, т.к. зрение нужно редко; vision-модель не будет расходовать токены основных моделей). Vision сам делает скриншот через antidetect-browser MCP или читает файл через Read (сабагент НЕ наследует вложения родителя — проверено в бинарнике 1.18.18, картинку можно получить только сам прочитав файл или вызвав MCP).

Задача

  1. .opencode/opencode.json (секция agent):

    • Удалить запись plan целиком (было {"model": "ollama-cloud/deepseek-v4-flash"}).
    • general.model → ollama-cloud/glm-5.2 (было deepseek-v4-pro). Остальные поля general (steps: 150, permission.task, tools) — без изменений.
    • reviewer — без изменений.
    • explore/scout/memory-syncer — без изменений.
    • Добавить новый агент vision:
      "vision": {
        "model": "ollama-cloud/minimax-m3",
        "hidden": true,
        "permission": {
          "task": { "*": "deny", "explore": "allow", "scout": "allow" }
        },
        "tools": {
          "commit": false,
          "create_pr": false,
          "create_issue": false,
          "merge_pr": false,
          "post_review": false
        }
      }
      
  2. .opencode/agents/vision.md (новый файл, по паттерну reviewer.md):

    • frontmatter:
      • description: «Vision-агент для задач со зрением (скриншоты, изображения, визуальный анализ UI). Сам делает скриншот через antidetect-browser MCP или читает файл через Read. Вызывай, когда твоя модель не поддерживает изображения.»
      • mode: subagent, temperature: 0.1, steps: 150, hidden: true
      • permission: edit: deny, doom_loop: deny, bash: {"*": deny, + read-only allow-список по паттерну reviewer.md: ls/cat/head/tail/date/grep/git read-only/rg/find/wc/diff/uv run/ruff/pytest/which — скопировать базовый read-only набор из reviewer.md, БЕЗ curl к Forgejo API (vision не работает с PR/issue)}
    • body (краткий протокол работы на русском): сделать скриншот через antidetect-browser MCP (screenshot) или прочитать файл-картинку через Read; проанализировать изображение; вернуть текстовое описание/вердикт; не коммитить, не редактировать код; для делегирования подзадач использовать explore/scout (разрешены в permission.task).
  3. AGENTS.md — добавить короткую секцию (универсальное правило, БЕЗ привязки к моделям, чтобы не устарело):

    Зрение: если твоя модель не поддерживает изображения (text-only) — для любой задачи со зрением (скриншоты, изображения, визуальный анализ UI) делегируй в vision сабагента через task. Если поддерживает — работай сам.

    Разместить в разделе после "Code Style" / перед "Config Edits" (или в другом подходящем месте — на усмотрение исполнителя, сохранить существующую структуру).

  4. tests/test_permissions.py:

    • test_agents_have_models: убрать plan из списка (теперь без model); добавить vision.
    • test_agent_models_exact: убрать plan; изменить general → ollama-cloud/glm-5.2; добавить vision → ollama-cloud/minimax-m3. Итог ожиданий: explore/scout/memory-syncer → deepseek-v4-flash, general → glm-5.2, reviewer → deepseek-v4-pro, vision → minimax-m3.
    • test_general_reviewer_task_permissions: добавить vision в список агентов с паттерном {"*": "deny", "explore": "allow", "scout": "allow"}.
    • Новый тест test_vision_readonly_and_hidden: vision имеет tools с commit/create_pr/create_issue/merge_pr/post_review = false, hidden: true, permission.edit == "deny" (если проверяется через .md — то в frontmatter; если через JSON — то в opencode.json; исполнитель: проверить, где reviewer хранит edit: deny — в .md frontmatter, значит vision тоже в .md).
    • При необходимости обновить test_agent_frontmatter.py (если он хардкодит список .md файлов — добавить vision.md).
  5. Тесты: uv run pytest tests/ -x -q — все зелёные (ожидаем 30+ passed). Если check-permissions.py валидатор ругается — привести в соответствие.

Контракты

  • Модель ID формат: provider/model-id (например ollama-cloud/glm-5.2). Все три модели (glm-5.2, minimax-m3, deepseek-v4-pro) — встроенные в opencode 1.18.18, регистрация в секции provider НЕ нужна (проверено в реестре бинарника).
  • minimax-m3: modalities input [text, image, video], attachment: true, reasoning (effort low/medium/high/max), tool_call, ctx 512000, out 131072.
  • glm-5.2: text-only (attachment: false), reasoning (effort high/max), structured_output, ctx 976000, out 131072.
  • permission.task — glob, семантика findLast (последний матч побеждает): "*": "deny" первым, конкретные allow после.
  • tools (legacy) — булевы флаги встроенных тулов; true = {"*": "allow"}, false = {"*": "deny"}. MCP-тулы (antidetect-browser, serena, context7) НЕ перечисляются в tools — они управляются через permission (по умолчанию все MCP включены у всех агентов; запрещать НЕ нужно, vision использует antidetect-browser).
  • hidden: true — скрывает сабагента из @-меню, но остаётся вызываемым через task tool (подтверждено в доке opencode.ai/docs/agents).
  • ADR-020/PR#49: НЕ добавлять model в frontmatter .md (unknown top-level поля форвардятся провайдеру). Модель — только в opencode.json секции agent.

Инварианты

  • reviewer.model остаётся ollama-cloud/deepseek-v4-pro (НЕ менять).
  • explore/scout/memory-syncer модели остаются ollama-cloud/deepseek-v4-flash (НЕ менять).
  • permission.bash deny-лист и глобальные правила — без изменений.
  • MCP-серверы (browser, context7, antidetect-browser, integrations, serena) — без изменений.
  • Структура reviewer.md / memory-syncer.md — не трогать (только создать новый vision.md по аналогии).
  • AGENTS.md — только добавить секцию про зрение, не переписывать существующие правила.

Граничные случаи

  • Если test_agent_frontmatter.py хардкодит список .md файлов — добавить vision.md в ожидаемый список, иначе тест упадёт. Исполнитель: проверить тест и обновить.
  • Если check-permissions.py валидатор проверяет frontmatter всех .md в .opencode/agents/ — vision.md должен проходить (edit: deny, doom_loop: deny, bash deny-по-умолчанию). Проверить локально: python3 .opencode/scripts/check-permissions.py.
  • plan без model: primary-агент без явной модели наследует глобальную из UI. Это документированное поведение opencode («If you don't specify a model, primary agents use the model globally configured»). Тесты не должны требовать model у plan.
  • vision с hidden: true: в @-меню не виден, но вызывается через task. permission.task у general/reviewer/explore/scout должны разрешать vision (добавить "vision": "allow" после "scout": "allow" в их permission.task).
  • Делегирование vision → explore/scout: разрешено (в permission.task vision). Делегирование vision → general/reviewer/memory-syncer — запрещено ("*": "deny").

Влияние на связанные компоненты

  • permission.task у general и reviewer — добавить "vision": "allow" (сейчас {"*": "deny", "explore": "allow", "scout": "allow"} → станет {"*": "deny", "explore": "allow", "scout": "allow", "vision": "allow"}).
  • explore/scout — у них сейчас нет permission.task (по умолчанию deny). Нужно ли им разрешать vision? Решение: НЕ добавлять (explore/scout — read-only исследователи, им зрение без надобности; если понадобится — отдельная задача). Оставить как есть.
  • Oracle-скрипты (pipeline-status.py, spec-status.py, project-status.py, check-permissions.py) — НЕ читают секцию agent (проверено в прошлых исследованиях). check-permissions.py читает только permission.bash. Поломок нет.
  • CI (permissions-check.yml) — проверяет изменения .opencode/opencode.json, .opencode/agents/**, .opencode/scripts/check-permissions.py. Добавление vision.md и правки opencode.json попадают под проверку — валидатор должен пройти.
  • Тесты — test_permissions.py, test_agent_frontmatter.py обновить. Другие тесты не затронуты.
  • Memory — после merge memory-syncer зафиксирует durable-записи (vision-агент, universal vision rule, glm-5.2 для general).

Вне scope

  • Модель main chat / build (primary) — выбирается в UI, не в конфиге.
  • OPENAI_EMBEDDING_MODEL (RAG) — не трогать.
  • Регистрация моделей в секции provider — не нужна (встроенные).
  • Добавление vision в permission.task у explore/scout — отдельная задача, если понадобится.
  • Обновление configure-opencode/SKILL.md секции 6 (документация permission.task) — опционально, не блокирующее (уже задокументирован паттерн).
  • Создание skill для vision-протокола — опционально, не в этом issue.

Критерии приемки

  • general.model == "ollama-cloud/glm-5.2" в opencode.json
  • reviewer.model == "ollama-cloud/deepseek-v4-pro" (без изменений)
  • explore/scout/memory-syncer модели == deepseek-v4-flash (без изменений)
  • Запись plan удалена из секции agent (primary-агент без явной модели)
  • Новый агент vision в opencode.json: model minimax-m3, hidden true, permission.task с explore/scout allow, tools read-only
  • Файл .opencode/agents/vision.md существует, frontmatter валиден (description, mode: subagent, temperature, steps, hidden, permission с edit: deny / doom_loop: deny / bash deny-по-умолчанию + read-only allow)
  • permission.task у general и reviewer содержит "vision": "allow" (после scout)
  • AGENTS.md содержит универсальную секцию про зрение (без привязки к моделям)
  • uv run pytest tests/ -x -q — все зелёные
  • python3 .opencode/scripts/check-permissions.py — exit 0, "OK: No dangerous permission rules found."
  • CI зелёный на PR
## Контекст После PR #98 (per-agent models + task delegation) сложилась картина: основные кодинг-модели text-only, зрение есть только у minimax-m3. Пользователь хочет: 1. Переключить `general` (кодинг) с `deepseek-v4-pro` на `glm-5.2` — предпочтение по качеству кода. 2. Оставить `reviewer` на `deepseek-v4-pro` (без изменений). 3. Добавить новый сабагент `vision` на `minimax-m3` (image+video+text) для любых задач со зрением — скриншоты, анализ UI, проверка браузера на сайтах-детекторах бот-защиты. 4. Убрать `model` у `plan` (primary-агент) — модель plan'а выбирается в UI под задачу, не фиксируется в конфиге. 5. `explore`/`scout`/`memory-syncer` остаются на `deepseek-v4-flash` (без изменений). Архитектурное решение: vision — отдельный сабагент (оправдано, т.к. зрение нужно редко; vision-модель не будет расходовать токены основных моделей). Vision сам делает скриншот через antidetect-browser MCP или читает файл через Read (сабагент НЕ наследует вложения родителя — проверено в бинарнике 1.18.18, картинку можно получить только сам прочитав файл или вызвав MCP). ## Задача 1. **`.opencode/opencode.json`** (секция `agent`): - Удалить запись `plan` целиком (было `{"model": "ollama-cloud/deepseek-v4-flash"}`). - `general.model` → `ollama-cloud/glm-5.2` (было `deepseek-v4-pro`). Остальные поля `general` (`steps: 150`, `permission.task`, `tools`) — без изменений. - `reviewer` — без изменений. - `explore`/`scout`/`memory-syncer` — без изменений. - Добавить новый агент `vision`: ```json "vision": { "model": "ollama-cloud/minimax-m3", "hidden": true, "permission": { "task": { "*": "deny", "explore": "allow", "scout": "allow" } }, "tools": { "commit": false, "create_pr": false, "create_issue": false, "merge_pr": false, "post_review": false } } ``` 2. **`.opencode/agents/vision.md`** (новый файл, по паттерну `reviewer.md`): - frontmatter: - `description`: «Vision-агент для задач со зрением (скриншоты, изображения, визуальный анализ UI). Сам делает скриншот через antidetect-browser MCP или читает файл через Read. Вызывай, когда твоя модель не поддерживает изображения.» - `mode: subagent`, `temperature: 0.1`, `steps: 150`, `hidden: true` - `permission`: `edit: deny`, `doom_loop: deny`, `bash: {"*": deny, + read-only allow-список по паттерну reviewer.md: ls/cat/head/tail/date/grep/git read-only/rg/find/wc/diff/uv run/ruff/pytest/which — скопировать базовый read-only набор из reviewer.md, БЕЗ curl к Forgejo API (vision не работает с PR/issue)}` - body (краткий протокол работы на русском): сделать скриншот через antidetect-browser MCP (screenshot) или прочитать файл-картинку через Read; проанализировать изображение; вернуть текстовое описание/вердикт; не коммитить, не редактировать код; для делегирования подзадач использовать explore/scout (разрешены в permission.task). 3. **`AGENTS.md`** — добавить короткую секцию (универсальное правило, БЕЗ привязки к моделям, чтобы не устарело): > **Зрение:** если твоя модель не поддерживает изображения (text-only) — для любой задачи со зрением (скриншоты, изображения, визуальный анализ UI) делегируй в `vision` сабагента через `task`. Если поддерживает — работай сам. Разместить в разделе после "Code Style" / перед "Config Edits" (или в другом подходящем месте — на усмотрение исполнителя, сохранить существующую структуру). 4. **`tests/test_permissions.py`**: - `test_agents_have_models`: убрать `plan` из списка (теперь без model); добавить `vision`. - `test_agent_models_exact`: убрать `plan`; изменить `general` → `ollama-cloud/glm-5.2`; добавить `vision` → `ollama-cloud/minimax-m3`. Итог ожиданий: `explore`/`scout`/`memory-syncer` → `deepseek-v4-flash`, `general` → `glm-5.2`, `reviewer` → `deepseek-v4-pro`, `vision` → `minimax-m3`. - `test_general_reviewer_task_permissions`: добавить `vision` в список агентов с паттерном `{"*": "deny", "explore": "allow", "scout": "allow"}`. - Новый тест `test_vision_readonly_and_hidden`: `vision` имеет `tools` с commit/create_pr/create_issue/merge_pr/post_review = false, `hidden: true`, `permission.edit == "deny"` (если проверяется через .md — то в frontmatter; если через JSON — то в opencode.json; исполнитель: проверить, где reviewer хранит edit: deny — в .md frontmatter, значит vision тоже в .md). - При необходимости обновить `test_agent_frontmatter.py` (если он хардкодит список .md файлов — добавить vision.md). 5. **Тесты**: `uv run pytest tests/ -x -q` — все зелёные (ожидаем 30+ passed). Если `check-permissions.py` валидатор ругается — привести в соответствие. ## Контракты - Модель ID формат: `provider/model-id` (например `ollama-cloud/glm-5.2`). Все три модели (`glm-5.2`, `minimax-m3`, `deepseek-v4-pro`) — встроенные в opencode 1.18.18, регистрация в секции `provider` НЕ нужна (проверено в реестре бинарника). - `minimax-m3`: modalities input `[text, image, video]`, attachment: true, reasoning (effort low/medium/high/max), tool_call, ctx 512000, out 131072. - `glm-5.2`: text-only (attachment: false), reasoning (effort high/max), structured_output, ctx 976000, out 131072. - `permission.task` — glob, семантика findLast (последний матч побеждает): `"*": "deny"` первым, конкретные allow после. - `tools` (legacy) — булевы флаги встроенных тулов; `true` = `{"*": "allow"}`, `false` = `{"*": "deny"}`. MCP-тулы (antidetect-browser, serena, context7) НЕ перечисляются в `tools` — они управляются через `permission` (по умолчанию все MCP включены у всех агентов; запрещать НЕ нужно, vision использует antidetect-browser). - `hidden: true` — скрывает сабагента из @-меню, но остаётся вызываемым через task tool (подтверждено в доке opencode.ai/docs/agents). - ADR-020/PR#49: НЕ добавлять `model` в frontmatter `.md` (unknown top-level поля форвардятся провайдеру). Модель — только в `opencode.json` секции `agent`. ## Инварианты - `reviewer.model` остаётся `ollama-cloud/deepseek-v4-pro` (НЕ менять). - `explore`/`scout`/`memory-syncer` модели остаются `ollama-cloud/deepseek-v4-flash` (НЕ менять). - `permission.bash` deny-лист и глобальные правила — без изменений. - MCP-серверы (browser, context7, antidetect-browser, integrations, serena) — без изменений. - Структура `reviewer.md` / `memory-syncer.md` — не трогать (только создать новый `vision.md` по аналогии). - `AGENTS.md` — только добавить секцию про зрение, не переписывать существующие правила. ## Граничные случаи - **Если `test_agent_frontmatter.py` хардкодит список .md файлов** — добавить `vision.md` в ожидаемый список, иначе тест упадёт. Исполнитель: проверить тест и обновить. - **Если `check-permissions.py` валидатор проверяет frontmatter всех .md в `.opencode/agents/`** — vision.md должен проходить (edit: deny, doom_loop: deny, bash deny-по-умолчанию). Проверить локально: `python3 .opencode/scripts/check-permissions.py`. - **`plan` без model**: primary-агент без явной модели наследует глобальную из UI. Это документированное поведение opencode («If you don't specify a model, primary agents use the model globally configured»). Тесты не должны требовать model у plan. - **`vision` с `hidden: true`**: в @-меню не виден, но вызывается через task. `permission.task` у general/reviewer/explore/scout должны разрешать `vision` (добавить `"vision": "allow"` после `"scout": "allow"` в их permission.task). - **Делегирование vision → explore/scout**: разрешено (в permission.task vision). Делегирование vision → general/reviewer/memory-syncer — запрещено (`"*": "deny"`). ## Влияние на связанные компоненты - **`permission.task` у general и reviewer** — добавить `"vision": "allow"` (сейчас `{"*": "deny", "explore": "allow", "scout": "allow"}` → станет `{"*": "deny", "explore": "allow", "scout": "allow", "vision": "allow"}`). - **explore/scout** — у них сейчас нет `permission.task` (по умолчанию deny). Нужно ли им разрешать vision? Решение: НЕ добавлять (explore/scout — read-only исследователи, им зрение без надобности; если понадобится — отдельная задача). Оставить как есть. - **Oracle-скрипты** (`pipeline-status.py`, `spec-status.py`, `project-status.py`, `check-permissions.py`) — НЕ читают секцию `agent` (проверено в прошлых исследованиях). `check-permissions.py` читает только `permission.bash`. Поломок нет. - **CI** (`permissions-check.yml`) — проверяет изменения `.opencode/opencode.json`, `.opencode/agents/**`, `.opencode/scripts/check-permissions.py`. Добавление `vision.md` и правки `opencode.json` попадают под проверку — валидатор должен пройти. - **Тесты** — `test_permissions.py`, `test_agent_frontmatter.py` обновить. Другие тесты не затронуты. - **Memory** — после merge memory-syncer зафиксирует durable-записи (vision-агент, universal vision rule, glm-5.2 для general). ## Вне scope - Модель main chat / build (primary) — выбирается в UI, не в конфиге. - `OPENAI_EMBEDDING_MODEL` (RAG) — не трогать. - Регистрация моделей в секции `provider` — не нужна (встроенные). - Добавление vision в permission.task у explore/scout — отдельная задача, если понадобится. - Обновление `configure-opencode/SKILL.md` секции 6 (документация permission.task) — опционально, не блокирующее (уже задокументирован паттерн). - Создание skill для vision-протокола — опционально, не в этом issue. ## Критерии приемки - [ ] `general.model == "ollama-cloud/glm-5.2"` в `opencode.json` - [ ] `reviewer.model == "ollama-cloud/deepseek-v4-pro"` (без изменений) - [ ] `explore`/`scout`/`memory-syncer` модели == `deepseek-v4-flash` (без изменений) - [ ] Запись `plan` удалена из секции `agent` (primary-агент без явной модели) - [ ] Новый агент `vision` в `opencode.json`: model `minimax-m3`, hidden true, permission.task с explore/scout allow, tools read-only - [ ] Файл `.opencode/agents/vision.md` существует, frontmatter валиден (description, mode: subagent, temperature, steps, hidden, permission с edit: deny / doom_loop: deny / bash deny-по-умолчанию + read-only allow) - [ ] `permission.task` у general и reviewer содержит `"vision": "allow"` (после scout) - [ ] `AGENTS.md` содержит универсальную секцию про зрение (без привязки к моделям) - [ ] `uv run pytest tests/ -x -q` — все зелёные - [ ] `python3 .opencode/scripts/check-permissions.py` — exit 0, "OK: No dangerous permission rules found." - [ ] CI зелёный на PR
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/opencode-config#99
No description provided.