diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index b0f38796..8be016e3 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -2006,7 +2006,7 @@ jobs: "$schema": "https://opencode.ai/config.json", "model": "github-models/deepseek/deepseek-r1-0528", "small_model": "github-models/deepseek/deepseek-v3-0324", - "enabled_providers": ["github-models"], + "enabled_providers": ["openai", "github-models"], "lsp": true, "mcp": { "codegraph": { @@ -2132,6 +2132,50 @@ jobs: } }, "provider": { + "openai": { + "npm": "@ai-sdk/openai", + "name": "OpenAI (direct)", + "options": { + "baseURL": "https://api.openai.com/v1", + "apiKey": "{env:OPENAI_API_KEY}" + }, + "models": { + "gpt-5": { + "name": "OpenAI GPT-5 (direct)", + "tool_call": true, + "reasoning": true, + "options": { + "reasoningEffort": "high" + }, + "variants": { + "high": { + "reasoningEffort": "high" + } + }, + "limit": { + "context": 400000, + "output": 128000 + } + }, + "gpt-5-mini": { + "name": "OpenAI GPT-5 Mini (direct)", + "tool_call": true, + "reasoning": true, + "options": { + "reasoningEffort": "high" + }, + "variants": { + "high": { + "reasoningEffort": "high" + } + }, + "limit": { + "context": 400000, + "output": 128000 + } + } + } + }, "github-models": { "npm": "@ai-sdk/openai-compatible", "name": "GitHub Models", @@ -2339,20 +2383,31 @@ jobs: env: STRIX_GITHUB_MODELS_TOKEN: ${{ secrets.STRIX_GITHUB_MODELS_TOKEN || github.token }} GITHUB_TOKEN: ${{ secrets.STRIX_GITHUB_MODELS_TOKEN || github.token }} + # Native OpenAI backend for the lead review model. GitHub Models + # rate-limits every request and caps bodies at ~4000 tokens, so the + # rate-starved shared pool never returned a verdict; hitting + # api.openai.com directly with the org OPENAI_API_KEY gives the lead + # model a working, un-throttled backend. Resolves {env:OPENAI_API_KEY} + # in the opencode.jsonc "openai" provider block. + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} USE_GITHUB_TOKEN: "true" SHARE: "false" NPM_CONFIG_IGNORE_SCRIPTS: "true" NO_COLOR: "1" - # Ordered contract-reliability first, then quota, with the rate-starved - # flagships last. The mini reasoning models (o4-mini, o3-mini, gpt-5- - # mini/nano/chat) reliably emit the strict review contract — every - # required label and only source-backed findings — so they lead. The - # high-quota non-reasoning models (deepseek-v3, mistral, llama-4) emit - # bare or hallucinated reviews the publish/approve gates reject, so - # they are fallbacks only. gpt-5/o3 ("Reasoning" tier, 8-12 req/day) - # stay last: first-placing them stalled every review until timeout - # because a rate-limited/hung flagship never fell back. - OPENCODE_MODEL_CANDIDATES: "github-models/openai/o4-mini github-models/openai/o3-mini github-models/openai/gpt-5-mini github-models/openai/gpt-5-nano github-models/openai/gpt-5-chat github-models/deepseek/deepseek-r1-0528 github-models/deepseek/deepseek-r1 github-models/deepseek/deepseek-v3-0324 github-models/mistral-ai/mistral-medium-2505 github-models/meta/llama-4-maverick-17b-128e-instruct-fp8 github-models/meta/llama-4-scout-17b-16e-instruct github-models/openai/o3 github-models/openai/gpt-5" + # Lead with the NATIVE OpenAI backend (openai/gpt-5, openai/gpt-5-mini + # via api.openai.com with the org OPENAI_API_KEY). GitHub Models + # rate-limited ("Too many requests") and 4000-token-capped + # (413 tokens_limit_reached) EVERY model in the shared pool, so the + # reviewer never produced a verdict and every run hung to the 350-min + # timeout — a 100% org-wide failure. The native provider is not subject + # to those limits, so it can actually complete and approve. The + # existing github-models entries stay as fallbacks (tried only if the + # native key is missing or the direct call fails). + # github-models ordering rationale (unchanged): contract-reliable mini + # reasoning models first, high-quota non-reasoning models next, and the + # rate-starved github-models flagships (gpt-5/o3, 8-12 req/day) last so + # a throttled/hung leader always falls back instead of eating the step. + OPENCODE_MODEL_CANDIDATES: "openai/gpt-5 openai/gpt-5-mini github-models/openai/o4-mini github-models/openai/o3-mini github-models/openai/gpt-5-mini github-models/openai/gpt-5-nano github-models/openai/gpt-5-chat github-models/deepseek/deepseek-r1-0528 github-models/deepseek/deepseek-r1 github-models/deepseek/deepseek-v3-0324 github-models/mistral-ai/mistral-medium-2505 github-models/meta/llama-4-maverick-17b-128e-instruct-fp8 github-models/meta/llama-4-scout-17b-16e-instruct github-models/openai/o3 github-models/openai/gpt-5" # One attempt per model, then fall through to the next model. Retrying # the SAME model 5x let a rate-limited/hung leader consume the whole # step, so the pool never reached a healthy fallback model. @@ -2732,6 +2787,9 @@ jobs: CHECK_LOOKUP_GH_TOKEN: ${{ github.token }} GH_REPOSITORY: ${{ github.event.pull_request.base.repo.full_name || github.event.inputs.target_repository || github.repository }} STRIX_GITHUB_MODELS_TOKEN: ${{ secrets.STRIX_GITHUB_MODELS_TOKEN || github.token }} + # Exposed so the "openai" provider in opencode.jsonc resolves during the + # failed-check diagnosis opencode run that shares this config. + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENCODE_APP_TOKEN: ${{ steps.opencode_app_token.outputs.token }} OPENCODE_EVIDENCE_FILE: ${{ runner.temp }}/opencode-review-evidence.md OPENCODE_FAILED_CHECK_EVIDENCE_FILE: ${{ runner.temp }}/opencode-failed-check-evidence.md