{ // OpenCode configuration for this repo's CI agents. // - ai-review-* agents: used by scripts/ai-review/run-review.mjs (dispatched via `opencode serve`) // for PR code review. ONE shared set, run once per provider by the matrix in // .github/workflows/ai-code-review.yml (DeepSeek-V4-Pro). The model is // supplied per-call by the runner, so the agents themselves are provider-agnostic. // Docs: https://opencode.ai/docs/ — verify provider shape against current docs at build time. "$schema": "https://opencode.ai/config.json", "provider": { // DeepSeek provider for PR review (DEEPSEEK_API_KEY). "deepseek-review": { "npm": "@ai-sdk/openai-compatible", "name": "DeepSeek (review)", "options": { "baseURL": "https://api.deepseek.com", "apiKey": "{env:DEEPSEEK_API_KEY}" }, "models": { "deepseek-v4-pro": { "name": "DeepSeek-V4-Pro", "limit": { "context": 1048576, "output": 262144 } } } } }, // Default model for runs that don't pass --model explicitly. run-review.mjs sends an explicit // model per call, so this is only a fallback for local/manual runs. "model": "deepseek-review/deepseek-v4-pro", "agent": { // 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. // // ONE shared agent set drives every provider. run-review.mjs sends an explicit // `model: {providerID, modelID}` (and `variant` when REVIEW_MODEL_VARIANT is set) on each // session.prompt call, which overrides whatever is declared here — so the `model` below is // only a default for local/manual `opencode` runs. Do NOT fork these into per-provider // copies: identical agents are exactly what makes a model-vs-model comparison meaningful, // and duplicated blocks drift. // // 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": "deepseek-review/deepseek-v4-pro", "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": "deepseek-review/deepseek-v4-pro", "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": "deepseek-review/deepseek-v4-pro", "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": "deepseek-review/deepseek-v4-pro", "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": "deepseek-review/deepseek-v4-pro", "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 } }, // Reads .claude/skills/ui-architect/references/*.md on demand, so `read`/`glob`/`grep` // are load-bearing here rather than incidental — same deny list as the rest. "ai-review-frontend": { "mode": "primary", "model": "deepseek-review/deepseek-v4-pro", "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-qa": { "mode": "primary", "model": "deepseek-review/deepseek-v4-pro", "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": "deepseek-review/deepseek-v4-pro", "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 } } } }