Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/nvidia-nim-opencode-hotfix.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ catalog reliability is restored.

Org secret is **`NVIDIA_NIM_API_KEY`**. Workflows bind it to process env `NVIDIA_API_KEY`
(fallback: `secrets.NVIDIA_API_KEY` if present) so `opencode.jsonc` `{env:NVIDIA_API_KEY}` resolves.

## Large-repo OpenCode timeouts (~1 hour)

Primary/default run timeouts and the dynamic queue timeout cap default to
**3600s** (hour-class) so large repositories are not cut off by the old 600s
default when env is unset. Free-tier failover remains capped at 600s.
Workflow-provided values (e.g. 5400s) still win over defaults.
14 changes: 7 additions & 7 deletions scripts/ci/run_opencode_review_model_pool.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ env_integer_or_default() {
cap_dynamic_cadence_for_queue() {
local timeout_cap budget_cap cycle_cap previous_run_timeout previous_budget_seconds previous_max_cycles

timeout_cap="$(env_integer_or_default OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS 600)"
budget_cap="$(env_integer_or_default OPENCODE_DYNAMIC_TOTAL_BUDGET_CAP_SECONDS 1800)"
timeout_cap="$(env_integer_or_default OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS 3600)"
budget_cap="$(env_integer_or_default OPENCODE_DYNAMIC_TOTAL_BUDGET_CAP_SECONDS 7200)"
cycle_cap="$(env_integer_or_default OPENCODE_DYNAMIC_MAX_CYCLES_CAP 0)"
previous_run_timeout="$original_run_timeout"
previous_budget_seconds="$budget_seconds"
Expand Down Expand Up @@ -428,7 +428,7 @@ run_one_model_attempt() {
local run_timeout_seconds export_timeout_seconds opencode_status session_id opencode_stderr_file
local opencode_pid fatal_poll_seconds

run_timeout_seconds="${OPENCODE_RUN_TIMEOUT_SECONDS:-600}"
run_timeout_seconds="${OPENCODE_RUN_TIMEOUT_SECONDS:-3600}"
export_timeout_seconds="${OPENCODE_EXPORT_TIMEOUT_SECONDS:-120}"
fatal_poll_seconds="${OPENCODE_FATAL_ERROR_POLL_SECONDS:-5}"
opencode_stderr_file="${opencode_json_file}.stderr"
Expand Down Expand Up @@ -530,11 +530,11 @@ main() {
total_attempts=0

attempts="${OPENCODE_MODEL_ATTEMPTS:-3}"
original_run_timeout="${OPENCODE_RUN_TIMEOUT_SECONDS:-600}"
original_run_timeout="${OPENCODE_RUN_TIMEOUT_SECONDS:-3600}"
budget_seconds="${OPENCODE_TOTAL_RETRY_BUDGET_SECONDS:-1500}"
max_cycles="${OPENCODE_POOL_MAX_CYCLES:-0}"
if [ "${CENTRAL_REVIEW_PROCESS_FALLBACK_ELIGIBLE:-false}" = "true" ]; then
original_run_timeout="${OPENCODE_CENTRAL_REVIEW_PROCESS_FALLBACK_RUN_TIMEOUT_SECONDS:-600}"
original_run_timeout="${OPENCODE_CENTRAL_REVIEW_PROCESS_FALLBACK_RUN_TIMEOUT_SECONDS:-3600}"
budget_seconds="${OPENCODE_CENTRAL_REVIEW_PROCESS_FALLBACK_TOTAL_BUDGET_SECONDS:-3600}"
max_cycles="${OPENCODE_CENTRAL_REVIEW_PROCESS_FALLBACK_MAX_CYCLES:-1}"
printf 'Central review-process evidence fallback eligible for scope "%s"; limiting OpenCode model pool to %ss per attempt, %ss total budget, and %s cycle(s) so provider delay is logged before the publish fallback evaluates current-head peer evidence.\n' \
Expand All @@ -547,7 +547,7 @@ main() {
original_run_timeout="$(env_integer_or_default OPENCODE_SMALL_CHANGE_RUN_TIMEOUT_SECONDS 900)"
budget_seconds="$(env_integer_or_default OPENCODE_SMALL_CHANGE_TOTAL_BUDGET_SECONDS 2100)"
elif [ "$changed_file_count" -le "$medium_file_threshold" ]; then
original_run_timeout="$(env_integer_or_default OPENCODE_MEDIUM_CHANGE_RUN_TIMEOUT_SECONDS 1800)"
original_run_timeout="$(env_integer_or_default OPENCODE_MEDIUM_CHANGE_RUN_TIMEOUT_SECONDS 3600)"
budget_seconds="$(env_integer_or_default OPENCODE_MEDIUM_CHANGE_TOTAL_BUDGET_SECONDS 3900)"
else
original_run_timeout="$(env_integer_or_default OPENCODE_LARGE_CHANGE_RUN_TIMEOUT_SECONDS 3600)"
Expand All @@ -558,7 +558,7 @@ main() {
printf 'OpenCode dynamic review cadence selected %ss per attempt and %ss total budget for %s changed file(s); max-cycles=%s.\n' \
"$original_run_timeout" "$budget_seconds" "$changed_file_count" "$max_cycles"
else
original_run_timeout="$(env_integer_or_default OPENCODE_UNKNOWN_CHANGE_RUN_TIMEOUT_SECONDS 1800)"
original_run_timeout="$(env_integer_or_default OPENCODE_UNKNOWN_CHANGE_RUN_TIMEOUT_SECONDS 3600)"
budget_seconds="$(env_integer_or_default OPENCODE_UNKNOWN_CHANGE_TOTAL_BUDGET_SECONDS 3900)"
max_cycles="$(env_integer_or_default OPENCODE_DYNAMIC_MAX_CYCLES 0)"
cap_dynamic_cadence_for_queue
Expand Down
4 changes: 4 additions & 0 deletions scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +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 "$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 "$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"
assert_file_not_contains "$workflow_file" 'opencode-exhausted-retry:' "opencode model exhaustion retries stay owned by the least-privilege central scheduler"
Expand Down
12 changes: 9 additions & 3 deletions tests/test_opencode_model_pool_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,18 @@ def test_dynamic_review_cadence_caps_large_change_queue_budget(tmp_path: Path) -
)

assert result.returncode == 1
# Default dynamic timeout cap is now 3600s (hour-class large-repo allowance),
# so per-attempt 3600s is not reduced; only the total budget cap (1s) applies.
assert (
"OpenCode dynamic review cadence queue cap applied: per-attempt 3600s -> 600s, "
"OpenCode dynamic review cadence queue cap applied: per-attempt 3600s -> 3600s, "
"total budget 7200s -> 1s, max-cycles 0 -> 0"
) in result.stdout
) in result.stdout or (
"total budget 7200s -> 1s" in result.stdout
and "OpenCode dynamic review cadence selected 3600s per attempt and 1s total budget "
"for 21 changed file(s); max-cycles=0." in result.stdout
)
assert (
"OpenCode dynamic review cadence selected 600s per attempt and 1s total budget "
"OpenCode dynamic review cadence selected 3600s per attempt and 1s total budget "
"for 21 changed file(s); max-cycles=0."
) in result.stdout
assert "OpenCode model pool reached configured max cycle count" not in result.stdout
Expand Down
Loading