diff --git a/.github/workflows/opencode-review-dispatch.yml b/.github/workflows/opencode-review-dispatch.yml index c11d61ad4..e765a99dc 100644 --- a/.github/workflows/opencode-review-dispatch.yml +++ b/.github/workflows/opencode-review-dispatch.yml @@ -4033,6 +4033,8 @@ jobs: # in the opencode.jsonc "openai" provider block. OPENCODE_API_KEY: ${{ secrets.OPENCODE_ZEN_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + # Org secret NVIDIA_NIM_API_KEY preferred; fallback NVIDIA_API_KEY. + # opencode.jsonc expects env NVIDIA_API_KEY for nvidia-nim/* models. NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY || secrets.NVIDIA_API_KEY }} OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} SHARE: "false" @@ -4087,7 +4089,7 @@ jobs: OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS: "5400" OPENCODE_DYNAMIC_TOTAL_BUDGET_CAP_SECONDS: "11700" OPENCODE_DYNAMIC_MAX_CYCLES_CAP: "1" - OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "600" + OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "3600" # This installation currently reports a 4k request-body limit for # GitHub Models GPT-5 endpoints even though the public catalog is # larger. Keep the exact runtime failure visible without spending a @@ -4689,6 +4691,8 @@ jobs: # 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 }} + # Org secret NVIDIA_NIM_API_KEY preferred; fallback NVIDIA_API_KEY. + # opencode.jsonc expects env NVIDIA_API_KEY for nvidia-nim/* models. NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY || secrets.NVIDIA_API_KEY }} OPENCODE_APP_TOKEN: ${{ steps.opencode_app_token.outputs.token }} OPENCODE_EVIDENCE_FILE: ${{ runner.temp }}/opencode-review-evidence.md diff --git a/scripts/ci/run_opencode_review_model_pool.sh b/scripts/ci/run_opencode_review_model_pool.sh index 0775b1138..e83bb981d 100644 --- a/scripts/ci/run_opencode_review_model_pool.sh +++ b/scripts/ci/run_opencode_review_model_pool.sh @@ -352,8 +352,10 @@ is_nvidia_nim_candidate() { esac } -# Org secret is NVIDIA_NIM_API_KEY; opencode.jsonc expects NVIDIA_API_KEY. -# Normalize once so skip checks and the provider env share one name. +# Org secret name is NVIDIA_NIM_API_KEY (GitHub Actions / org secrets UI). +# opencode.jsonc nvidia-nim provider block resolves {env:NVIDIA_API_KEY}. +# Workflow maps secrets.NVIDIA_NIM_API_KEY || secrets.NVIDIA_API_KEY → env NVIDIA_API_KEY. +# Normalize here too so local/CLI runs with only NVIDIA_NIM_API_KEY set do not skip nim/*. if [ -z "${NVIDIA_API_KEY:-}" ] && [ -n "${NVIDIA_NIM_API_KEY:-}" ]; then export NVIDIA_API_KEY="$NVIDIA_NIM_API_KEY" fi @@ -399,7 +401,7 @@ cap_model_run_timeout() { case "$model_candidate" in opencode-free/*) - cap_seconds="$(env_integer_or_default OPENCODE_FREE_RUN_TIMEOUT_SECONDS 600)" + cap_seconds="$(env_integer_or_default OPENCODE_FREE_RUN_TIMEOUT_SECONDS 3600)" ;; github-models/openai/gpt-5 | github-models/openai/gpt-5-chat) cap_seconds="$(env_integer_or_default OPENCODE_GITHUB_GPT5_RUN_TIMEOUT_SECONDS 45)" diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index 63adfb301..61af0dd63 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -708,9 +708,10 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_contains "$workflow_file" 'timeout-minutes: 34' "opencode fast approval publication is bounded around the dynamic image and package/GPU check wait" assert_file_contains "$workflow_file" 'continue-on-error: true' "opencode approval gate still runs after model-pool failure to publish a reason" assert_file_contains "$workflow_file" 'OPENCODE_RUN_TIMEOUT_SECONDS: "5400"' "opencode primary review preserves legitimate full-hour provider sessions" +assert_file_contains "$workflow_file" 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "3600"' "opencode free-tier failover timeout is hour-class (~3600s)" assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" 'OPENCODE_RUN_TIMEOUT_SECONDS:-3600' "opencode pool defaults primary run timeout to hour-class (~3600s) for large repos" assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" 'OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS 3600' "opencode pool dynamic timeout cap defaults to hour-class (~3600s)" -assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS 600' "opencode free-tier failover timeout stays short" +assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS 3600' "opencode free-tier failover timeout is hour-class (~3600s)" assert_file_contains "$workflow_file" 'OPENCODE_TOTAL_RETRY_BUDGET_SECONDS: "11700"' "opencode model pool exits before the step timeout so the approval gate can publish a reason" assert_file_contains "$workflow_file" 'OPENCODE_POOL_MAX_CYCLES: "1"' "opencode model pool exhausts each candidate only once before bounded fallback" diff --git a/tests/test_opencode_agent_contract.py b/tests/test_opencode_agent_contract.py index 7a651aa31..d5d48b25b 100644 --- a/tests/test_opencode_agent_contract.py +++ b/tests/test_opencode_agent_contract.py @@ -1374,7 +1374,7 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent(): assert 'OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS: "5400"' in workflow assert 'OPENCODE_DYNAMIC_TOTAL_BUDGET_CAP_SECONDS: "11700"' in workflow assert 'OPENCODE_DYNAMIC_MAX_CYCLES_CAP: "1"' in workflow - assert 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "600"' in workflow + assert 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "3600"' in workflow assert 'OPENCODE_GITHUB_GPT5_RUN_TIMEOUT_SECONDS: "45"' in workflow assert 'OPENCODE_DYNAMIC_MAX_CYCLES: "1"' in workflow assert 'OPENCODE_BACKOFF_MAX_SECONDS: "30"' in workflow