{ // OpenCode configuration for this repo's CI agents. // - e2e-ci-* agents: used by .github/workflows/e2e-council.yml for CI test-generation, on DeepSeek. // - ai-review-* agents: used by scripts/ai-review/run-review.mjs (dispatched via `opencode serve`) // for PR code review, on GLM-5.2 (Z.ai). // Docs: https://opencode.ai/docs/ — verify provider shape against current docs at build time. "$schema": "https://opencode.ai/config.json", "provider": { "deepseek": { "npm": "@ai-sdk/openai-compatible", "name": "DeepSeek", "options": { "baseURL": "https://api.deepseek.com", "apiKey": "{env:DEEPSEEK_API_KEY_E2E}" }, "models": { "deepseek-v4-pro": { "name": "DeepSeek-V4-Pro", "limit": { "context": 1048576, "output": 262144 } } } }, "zai": { "npm": "@ai-sdk/openai-compatible", "name": "Z.AI", "options": { "baseURL": "https://api.z.ai/api/paas/v4", "apiKey": "{env:GLM_API_KEY}" }, "models": { "glm-5.2": { "name": "GLM-5.2", "limit": { "context": 1000000, "output": 131072 } } } } }, // Default model for runs that don't pass --model explicitly. // The workflow passes --model deepseek/deepseek-v4-pro per agent invocation. "model": "deepseek/deepseek-v4-pro", // Register the CI agents explicitly so `--agent e2e-ci-*` resolves deterministically. // OpenCode does NOT auto-discover agents nested in .opencode/agents// (the first CI // run fell back to the default agent), so we point each name at its prompt file here. "agent": { "e2e-ci-triage": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-triage.md}" }, "e2e-ci-analyst": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-analyst.md}" }, "e2e-ci-architect": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-architect.md}" }, "e2e-ci-engineer": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-engineer.md}" }, "e2e-ci-sentinel": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-sentinel.md}" }, "e2e-ci-healer": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-healer.md}" }, "e2e-ci-refiner": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-refiner.md}" }, "e2e-ci-responder": { "mode": "primary", "prompt": "{file:./.opencode/agents/e2e_ci_council_of_agents/e2e-ci-responder.md}" }, // PR review agents. Prompts are assembled at call time in run-review.mjs // (shared-rules.md + agents/.md) and sent via the `system` override on // session.prompt, so no `prompt` is registered here. // // Tool policy is an ALLOWLIST-by-negation, not just "no write/edit/bash": PR diff // content is untrusted (any external contributor can put prompt-injection text in a // diff) and is fed directly into these agents' prompts, with output auto-posted to the // PR. Only read/glob/grep are needed to inspect real repo context around the diff. // Everything else — especially webfetch/websearch (SSRF / exfiltration via injected // instructions) and task (spawning subagents that may not inherit these restrictions) // — is explicitly denied. Deny the full known opencode tool-id set (see // `opencode serve` + `GET /experimental/tool/ids`) rather than only the obvious ones, // so a newly added tool doesn't silently become available by omission. "ai-review-security": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } }, "ai-review-code-quality": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } }, "ai-review-performance": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } }, "ai-review-documentation": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } }, "ai-review-release": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } }, "ai-review-coordinator": { "mode": "primary", "model": "zai/glm-5.2", "variant": "max", "tools": { "read": true, "glob": true, "grep": true, "write": false, "edit": false, "bash": false, "patch": false, "apply_patch": false, "webfetch": false, "websearch": false, "task": false, "todowrite": false, "skill": false } } } }