feat(config): per-agent models and task delegation for subagents #97
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Контекст
Зачем: subagent'ы наследуют модель вызывающей сессии — нельзя оптимизировать стоимость/качество (быстрая flash для простых задач, мощная pro для кода и ревью). Плюс найден конфликт правил: AGENTS.md предписывает main-chat оркестратору создавать плановые issues сам («Исключение: плановые issues создаёт main-chat оркестратор сам, последовательными вызовами create-issue»), а скиллы feature-spec и issue запрещают оркестратору это и делегируют subagent'у.
Контекст: секция
agentв.opencode/opencode.json(строки ~410–440) содержит толькоstepsиtools— полейmodelиpermission.taskнет. Встроенный провайдерollama-cloud(провереноopencode models, версия 1.18.18) уже содержитdeepseek-v4-flashиdeepseek-v4-pro— регистрация вproviderне нужна. Субагентам task tool фактически запрещён (дефолт opencode:task: deny, подтверждено логами).Задача
.opencode/opencode.json, секцияagent(строки ~410–440):modelшести агентам:plan,explore,scout,memory-syncer→"model": "ollama-cloud/deepseek-v4-flash";general,reviewer→"model": "ollama-cloud/deepseek-v4-pro".generalиreviewer:"permission": { "task": { "*": "deny", "explore": "allow", "scout": "allow" } }(glob-паттерны, последний матч побеждает).memory-syncer—permission.taskНЕ добавлять (deny по умолчанию остаётся).steps: 150иtools-блоки НЕ менять.tests/test_permissions.py(там уже есть_load_config()["agent"]["general"]["tools"], строка ~333, иsteps == 150, строка ~338) — добавить 4 теста:test_agents_have_models— у всех 6 агентов естьmodel, формат^[a-zA-Z0-9._-]+\/[a-zA-Z0-9:._-]+$test_agent_models_exact— точные значения: flash у plan/explore/scout/memory-syncer, pro у general/reviewertest_general_reviewer_task_permissions— у general и reviewerpermission.task == {"*": "deny", "explore": "allow", "scout": "allow"}test_memory_syncer_no_task— у memory-syncer нетpermission.task.opencode/skills/configure-opencode/SKILL.md, секция 6 (Permissions) — задокументироватьpermission.task: glob-семантика, последний матч побеждает,"*": "deny"первым (сейчас описаны только read/bash)..opencode/skills/feature-spec/SKILL.md— в секции «## 4. Handoff» и в разделе «Правила» заменить «Не создавай issues сам — только планируй. Issues черезissueскилл» на: после согласования плана (юзер сказал «создай issue») оркестратор создаёт issue сам, последовательными вызовамиcreate-issue(выход спеки = body, 8 секций 1:1) — согласовано с исключением в AGENTS.md..opencode/skills/issue/SKILL.md— разделы «Использование subagent для создания issue» и «Батчевое создание»: плановые issues (после согласованного плана, декомпозиция) создаёт main-chat оркестратор сам, последовательными вызовамиcreate-issue; subagent-делегирование оставить только для задач, найденных в ходе исполнения (bug-discovery: «Найденное в ходе исполнения — создаёт сабагент сам»). Убрать категоричное «Main agent НЕ запускаетcreate-issue».Контракты
ollama-cloud/deepseek-v4-flash(plan/explore/scout/memory-syncer),ollama-cloud/deepseek-v4-pro(general/reviewer). Обе — встроенные в opencode, вproviderНЕ регистрировать.deepseek-v4-flash:0731(с суффиксом) НЕ использовать.permission.task— объект glob→action, правила оцениваются по порядку, последний матч побеждает ("*": "deny"первым, конкретные агенты после).opencode.jsonсекцииagent, НЕ в frontmatter.md-агентов (ADR-020: unknown top-level поля frontmatter форвардятся провайдеру и ломают строгие провайдеры).Инварианты
memory-syncerостаётся безpermission.task.tools/stepsагентов не меняются.provider-секцию.Граничные случаи
deepseek-v4-flash(без:0731) резолвится встроенным реестром opencode; кастомные options из конфига (reasoningEffort: max, лимиты 200k/65k) к ней не применяются — ожидаемо для простых задач (explore/дистилляция/планирование).~/.local/share/opencode/log/opencode.logпроверитьmodelID=deepseek-v4-flashу explore иdeepseek-v4-proу general.Влияние на связанные компоненты
tests/test_permissions.py— paired update (пункт 2 Задачи)..opencode/skills/configure-opencode/SKILL.md— paired update (пункт 3 Задачи).pipeline-status.py,spec-status.py,project-status.py,check-permissions.py— читает толькоpermission.bash) — не затронуты, секциюagentне читают..opencode/tools/*.ts) — не затронуты (конфиг не читают).tests/test_agent_frontmatter.py— не затронут (поля добавляются в opencode.json, не в.mdfrontmatter)..github/workflows/ci.yml,permissions-check.yml) — триггерятся автоматически, пройдут..md(reviewer.md,memory-syncer.md), AGENTS.md, skills (run-pipeline, audit, bug-discovery) — не затронуты. Явного запрета subagent→subagent в правилах нет.Вне scope
OPENAI_EMBEDDING_MODEL) — отдельный контур.deepseek-v4-flash/deepseek-v4-proвprovider.ollama-cloud.Критерии приемки
opencode.jsonсодержитmodelу 6 агентов: flash у plan/explore/scout/memory-syncer, pro у general/reviewer.generalиreviewerимеютpermission.task == {"*": "deny", "explore": "allow", "scout": "allow"}; уmemory-syncerpermission.taskнет.steps: 150иtools-блоки не изменены.uv run pytest tests/test_permissions.py— зелёный, 4 новых теста проходят.feature-spec/SKILL.mdиissue/SKILL.mdговорят: плановые issues создаёт оркестратор сам; bug-issues — сабагент (bug-discovery).configure-opencode/SKILL.mdсекция 6 документируетpermission.task(glob, последний матч побеждает).git pullна хосте →docker compose restart opencode): smoke-тест — explore работает, в логахmodelID=deepseek-v4-flashу explore иdeepseek-v4-proу general..github/workflows/ci.yml,permissions-check.yml) зелёный.