From 3356d7b8efc79d637deef22269b282b3a18a0e1a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 25 Jul 2026 01:01:19 +0900 Subject: [PATCH] fix(opencode-review): replace free OpenRouter pins with paid coder models Free-tier candidates hit the shared free-models-per-day cap (free-models-per-day-high-balance) and hung for the full 5400s candidate timeout each, exhausting the pool. Live probe confirmed every :free model 429s once the daily cap is spent. Pin cheap paid coder models instead (deepseek/deepseek-v3.2, qwen/qwen3-coder) billed against org OpenRouter credits, so the OpenRouter slots always have live capacity. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/opencode-review.yml | 23 ++++++++++++----------- scripts/ci/test_strix_quick_gate.sh | 6 +++--- tests/test_opencode_agent_contract.py | 16 ++++++++-------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index 2385de32..390d8f5f 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -3299,20 +3299,20 @@ jobs: "apiKey": "{env:OPENROUTER_API_KEY}" }, "models": { - "nvidia/nemotron-3-ultra-550b-a55b:free": { - "name": "NVIDIA Nemotron 3 Ultra 550B (free)", + "deepseek/deepseek-v3.2": { + "name": "DeepSeek V3.2 (paid)", "tool_call": true, "limit": { - "context": 1000000, + "context": 163840, "output": 65536 } }, - "poolside/laguna-m.1:free": { - "name": "Poolside Laguna M.1 (free)", + "qwen/qwen3-coder": { + "name": "Qwen3 Coder 480B (paid)", "tool_call": true, "limit": { "context": 262144, - "output": 32768 + "output": 65536 } } } @@ -3545,16 +3545,17 @@ jobs: NO_COLOR: "1" # High-sensitivity review candidates only. DeepSeek V3 has been the # most reliable first-pass reviewer in the org queue, then the pool - # falls through to the direct GPT-5.6 Luna slot, pinned OpenRouter - # free models (the openrouter/free router routed to weak models that - # never produced a control block, so tool-capable free models are - # pinned explicitly), then the full-size GPT-4.1 long-context + # falls through to the direct GPT-5.6 Luna slot, pinned PAID + # OpenRouter coder models (free-tier candidates hit the shared + # free-models-per-day cap and hung for the full candidate timeout, + # so the OpenRouter slots use cheap paid models billed against the + # org's OpenRouter credits), then the full-size GPT-4.1 long-context # endpoint and provider-specific GPT/o3 fallbacks. # The direct-OpenAI slot runs GPT-5.6 Luna: the newest family's # cost-efficient tier, cheaper than the legacy gpt-5 it replaced # ($1/$6 vs $1.25/$10 per 1M tokens) so the org OpenAI budget # stretches further between top-ups. - OPENCODE_MODEL_CANDIDATES: "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/nvidia/nemotron-3-ultra-550b-a55b:free openrouter/poolside/laguna-m.1:free github-models/openai/gpt-4.1 github-models/openai/gpt-5 github-models/openai/gpt-5-chat github-models/openai/o3 github-models/deepseek/deepseek-r1-0528 github-models/deepseek/deepseek-r1" + OPENCODE_MODEL_CANDIDATES: "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/deepseek/deepseek-v3.2 openrouter/qwen/qwen3-coder github-models/openai/gpt-4.1 github-models/openai/gpt-5 github-models/openai/gpt-5-chat github-models/openai/o3 github-models/deepseek/deepseek-r1-0528 github-models/deepseek/deepseek-r1" # 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. diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index ab959302..3f2a610f 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -700,7 +700,7 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_contains "$workflow_file" 'OPENCODE_MODEL_ATTEMPTS: "1"' "opencode fallback tries the catalog promptly instead of spending the entire review on one model" assert_file_contains "$workflow_file" "Run OpenCode PR Review model pool" "opencode review includes a broad catalog fallback pool" assert_file_not_contains "$workflow_file" "steps.opencode_review_model_pool.outcome == 'success'" "opencode approval gate still runs after model pool failure to publish a reason" - assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/nvidia/nemotron-3-ultra-550b-a55b:free openrouter/poolside/laguna-m.1:free github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review starts with DeepSeek V3 before full-size GPT fallbacks" + assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/deepseek/deepseek-v3.2 openrouter/qwen/qwen3-coder github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review starts with DeepSeek V3 before full-size GPT fallbacks" assert_file_contains "$workflow_file" "The publish gate re-runs source-backed validation against PR-head data" "opencode review publish gate validates model output against the PR-head worktree" assert_file_contains "$workflow_file" '"openai/o3"' "opencode config declares OpenAI o3 fallback" assert_file_contains "$workflow_file" '"openai/o4-mini"' "opencode config declares OpenAI o4-mini fallback" @@ -848,7 +848,7 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_contains "$workflow_file" 'OPENCODE_RUN_TIMEOUT_SECONDS: "5400"' "opencode catalog fallback preserves legitimate full-hour provider sessions" assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" "OpenCode %s attempt %s/%s failed" "opencode catalog fallback records per-model retry failures" assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" "exponential backoff" "opencode model retry paths use exponential backoff instead of fixed sleeps" - assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/nvidia/nemotron-3-ultra-550b-a55b:free openrouter/poolside/laguna-m.1:free github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review tries DeepSeek V3 before OpenAI fallbacks" + assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/deepseek/deepseek-v3.2 openrouter/qwen/qwen3-coder github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review tries DeepSeek V3 before OpenAI fallbacks" assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-r1-0528 github-models/deepseek/deepseek-r1" "opencode review keeps DeepSeek reasoning fallback coverage after OpenAI candidates" assert_file_contains "$workflow_file" "coverage-source-tree:" "opencode workflow materializes coverage source before running PR-head tests" assert_file_contains "$workflow_file" "coverage-evidence:" "opencode workflow measures coverage before review" @@ -1165,7 +1165,7 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_contains "$workflow_file" 'GH_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN || steps.review_read_app_token.outputs.token || github.token }}' "opencode manual dispatch uses the cross-repo approval token for target PR evidence lookups with app-token fallback" assert_file_contains "$workflow_file" 'repos/${GH_REPOSITORY}' "opencode review workflow uses env-backed repository context in shell commands" assert_file_contains "$workflow_file" "Run OpenCode PR Review model pool" "opencode review starts the central model pool" - assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/nvidia/nemotron-3-ultra-550b-a55b:free openrouter/poolside/laguna-m.1:free github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review starts with DeepSeek V3 before full-size GPT fallbacks" + assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324 openai/gpt-5.6-luna openrouter/deepseek/deepseek-v3.2 openrouter/qwen/qwen3-coder github-models/openai/gpt-4.1 github-models/openai/gpt-5" "opencode review starts with DeepSeek V3 before full-size GPT fallbacks" assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-r1-0528" "opencode review keeps a reachable DeepSeek R1 reasoning fallback model" assert_file_contains "$workflow_file" "github-models/deepseek/deepseek-v3-0324" "opencode review has a reachable DeepSeek V3 fallback model" assert_file_contains "$workflow_file" "github-models/openai/gpt-5" "opencode review still has a bounded GPT-5 fallback model" diff --git a/tests/test_opencode_agent_contract.py b/tests/test_opencode_agent_contract.py index b9c872d7..597d23fb 100644 --- a/tests/test_opencode_agent_contract.py +++ b/tests/test_opencode_agent_contract.py @@ -108,8 +108,8 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates(): assert candidate_pairs == [ ["github-models", "deepseek/deepseek-v3-0324"], ["openai", "gpt-5.6-luna"], - ["openrouter", "nvidia/nemotron-3-ultra-550b-a55b:free"], - ["openrouter", "poolside/laguna-m.1:free"], + ["openrouter", "deepseek/deepseek-v3.2"], + ["openrouter", "qwen/qwen3-coder"], ["github-models", "openai/gpt-4.1"], ["github-models", "openai/gpt-5"], ["github-models", "openai/gpt-5-chat"], @@ -119,8 +119,8 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates(): ] assert direct_openai_models == ["gpt-5.6-luna"] assert openrouter_models == [ - "nvidia/nemotron-3-ultra-550b-a55b:free", - "poolside/laguna-m.1:free", + "deepseek/deepseek-v3.2", + "qwen/qwen3-coder", ] assert set(github_candidate_models).issubset(set(github_models)) assert github_candidate_models == [ @@ -1103,8 +1103,8 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent(): assert ( 'OPENCODE_MODEL_CANDIDATES: "github-models/deepseek/deepseek-v3-0324 ' "openai/gpt-5.6-luna " - "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free " - "openrouter/poolside/laguna-m.1:free " + "openrouter/deepseek/deepseek-v3.2 " + "openrouter/qwen/qwen3-coder " "github-models/openai/gpt-4.1 " "github-models/openai/gpt-5 " "github-models/openai/gpt-5-chat " @@ -1228,8 +1228,8 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent(): assert ( 'OPENCODE_MODEL_CANDIDATES: "github-models/deepseek/deepseek-v3-0324 ' "openai/gpt-5.6-luna " - "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free " - "openrouter/poolside/laguna-m.1:free " + "openrouter/deepseek/deepseek-v3.2 " + "openrouter/qwen/qwen3-coder " "github-models/openai/gpt-4.1 " "github-models/openai/gpt-5 " "github-models/openai/gpt-5-chat "