From 634924b963f7d0388b0f23e620de0395afce06e5 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 31 Jul 2026 19:36:35 +0900 Subject: [PATCH 1/2] Prefer NVIDIA NIM models in OpenCode review pool OpenCode skipped usable reviews on fast-mlsirm PR #290+. Add an OpenAI-compatible nvidia-nim provider, prioritize Nemotron/Llama NIM candidates in OPENCODE_MODEL_CANDIDATES, skip when NVIDIA_API_KEY is unset, and document the temporary hotfix bypass (no permanent security gate weaken). --- .../workflows/opencode-review-dispatch.yml | 4 +- docs/nvidia-nim-opencode-hotfix.md | 41 ++++++++ opencode.jsonc | 96 ++++++++++++++++++- scripts/ci/run_opencode_review_model_pool.sh | 11 +++ scripts/ci/test_strix_quick_gate.sh | 6 +- 5 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 docs/nvidia-nim-opencode-hotfix.md diff --git a/.github/workflows/opencode-review-dispatch.yml b/.github/workflows/opencode-review-dispatch.yml index 4e1ac1640..1bb9bad85 100644 --- a/.github/workflows/opencode-review-dispatch.yml +++ b/.github/workflows/opencode-review-dispatch.yml @@ -3937,6 +3937,7 @@ jobs: # in the opencode.jsonc "openai" provider block. OPENCODE_API_KEY: ${{ secrets.OPENCODE_ZEN_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} SHARE: "false" NPM_CONFIG_IGNORE_SCRIPTS: "true" @@ -3958,7 +3959,7 @@ jobs: # 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: "${{ needs.validate-pr-metadata.outputs.is_private == 'false' && 'opencode-free/nemotron-3-ultra-free opencode-free/deepseek-v4-flash-free opencode-free/north-mini-code-free opencode-free/laguna-s-2.1-free opencode-free/ling-3.0-flash-free opencode-free/big-pickle opencode-free/mimo-v2.5-free ' || '' }}opencode/gpt-5.6-terra 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" + OPENCODE_MODEL_CANDIDATES: "${{ needs.validate-pr-metadata.outputs.is_private == 'false' && 'opencode-free/nemotron-3-ultra-free opencode-free/deepseek-v4-flash-free opencode-free/north-mini-code-free opencode-free/laguna-s-2.1-free opencode-free/ling-3.0-flash-free opencode-free/big-pickle opencode-free/mimo-v2.5-free ' || '' }}nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5 nvidia-nim/nvidia/llama-3.1-nemotron-ultra-253b-v1 nvidia-nim/nvidia/nemotron-3-super-120b-a12b nvidia-nim/meta/llama-3.3-70b-instruct nvidia-nim/deepseek-ai/deepseek-v4-pro nvidia-nim/mistralai/codestral-22b-instruct-v0.1 opencode/gpt-5.6-terra 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. @@ -4592,6 +4593,7 @@ 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 }} + NVIDIA_API_KEY: ${{ secrets.NVIDIA_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 diff --git a/docs/nvidia-nim-opencode-hotfix.md b/docs/nvidia-nim-opencode-hotfix.md new file mode 100644 index 000000000..619128f9f --- /dev/null +++ b/docs/nvidia-nim-opencode-hotfix.md @@ -0,0 +1,41 @@ +# NVIDIA NIM OpenCode model priority (hotfix) + +## Why + +OpenCode Agent failed to produce a usable review on the PR thread starting at +ContextualWisdomLab/fast-mlsirm#290 (`opencode-review` check **skipped**, no +`opencode-agent[bot]` review comment). Central review therefore prioritizes +**NVIDIA NIM** models as additional catalog candidates so the model pool can +still emit APPROVE / REQUEST_CHANGES when GitHub Models / free tiers stall. + +## Changes + +1. `opencode.jsonc` + - `enabled_providers`: `nvidia-nim` first, then `github-models` + - default `model` / `small_model` prefer NIM Nemotron / Llama 3.3 + - new OpenAI-compatible provider `nvidia-nim` → `https://integrate.api.nvidia.com/v1` + with `apiKey: {env:NVIDIA_API_KEY}` +2. `.github/workflows/opencode-review-dispatch.yml` + - `OPENCODE_MODEL_CANDIDATES` prefixes six NIM models before existing pool + - binds `NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}` +3. `scripts/ci/run_opencode_review_model_pool.sh` + - skips `nvidia-nim/*` when `NVIDIA_API_KEY` is unset (same pattern as OpenRouter) + +## Temporary permission bypass (hotfix only) + +For this merge-aid hotfix only: + +- Branch-protection / ruleset admin override may be used to land the central + `.github` change if required checks conflict during the hotfix window. +- **Do not** permanently weaken Security Scan, trivy-fs, osv-scan, or + CodeQL gates. +- **Do not** flip OpenCode agent `permission.edit` / `bash` from `deny` to + `allow` permanently; review agents remain read-only. +- Org secret `NVIDIA_API_KEY` must be set on ContextualWisdomLab for NIM pool + entries to execute; without it the pool falls through to prior candidates. + +## Rollback + +Remove the `nvidia-nim/*` prefixes from `OPENCODE_MODEL_CANDIDATES`, drop the +`nvidia-nim` provider block, and delete this note once GitHub Models / OpenCode +catalog reliability is restored. diff --git a/opencode.jsonc b/opencode.jsonc index fa5933b2b..ddd22f5e0 100644 --- a/opencode.jsonc +++ b/opencode.jsonc @@ -1,8 +1,8 @@ { "$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"], + "model": "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5", + "small_model": "nvidia-nim/meta/llama-3.3-70b-instruct", + "enabled_providers": ["nvidia-nim", "github-models"], "lsp": false, "mcp": {}, "permission": { @@ -281,6 +281,96 @@ } } } + }, + "nvidia-nim": { + "npm": "@ai-sdk/openai-compatible", + "name": "NVIDIA NIM", + "options": { + "baseURL": "https://integrate.api.nvidia.com/v1", + "apiKey": "{env:NVIDIA_API_KEY}" + }, + "models": { + "nvidia/llama-3.3-nemotron-super-49b-v1.5": { + "name": "NVIDIA Llama 3.3 Nemotron Super 49B v1.5", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/llama-3.1-nemotron-ultra-253b-v1": { + "name": "NVIDIA Llama 3.1 Nemotron Ultra 253B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/nemotron-3-super-120b-a12b": { + "name": "NVIDIA Nemotron 3 Super 120B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/nemotron-3-ultra-550b-a55b": { + "name": "NVIDIA Nemotron 3 Ultra 550B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "meta/llama-3.3-70b-instruct": { + "name": "Meta Llama 3.3 70B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "meta/llama-3.1-70b-instruct": { + "name": "Meta Llama 3.1 70B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "deepseek-ai/deepseek-v4-pro": { + "name": "DeepSeek V4 Pro (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "mistralai/mistral-large-2-instruct": { + "name": "Mistral Large 2 Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "mistralai/codestral-22b-instruct-v0.1": { + "name": "Codestral 22B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 32768, + "output": 8192 + } + }, + "google/gemma-4-31b-it": { + "name": "Gemma 4 31B IT (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + } + } } } } diff --git a/scripts/ci/run_opencode_review_model_pool.sh b/scripts/ci/run_opencode_review_model_pool.sh index 3c4583069..f849c4db1 100644 --- a/scripts/ci/run_opencode_review_model_pool.sh +++ b/scripts/ci/run_opencode_review_model_pool.sh @@ -345,6 +345,13 @@ is_openrouter_candidate() { esac } +is_nvidia_nim_candidate() { + case "$1" in + nvidia-nim/*) return 0 ;; + *) return 1 ;; + esac +} + is_low_sensitivity_candidate() { case "$1" in openai/*-mini | openai/*-nano | \ @@ -372,6 +379,10 @@ should_skip_model_candidate() { printf 'Skipping OpenCode %s because OPENROUTER_API_KEY is not configured; falling back to the next provider-qualified candidate.\n' "$model_candidate" return 0 fi + if is_nvidia_nim_candidate "$model_candidate" && [ -z "${NVIDIA_API_KEY:-}" ]; then + printf 'Skipping OpenCode %s because NVIDIA_API_KEY is not configured; falling back to the next provider-qualified candidate.\n' "$model_candidate" + return 0 + fi return 1 } diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index 4c2d5609c..b9c48e4da 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -719,7 +719,7 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { 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" "opencode-free/north-mini-code-free" "opencode review starts public repository reviews with a free coding model" - assert_file_contains "$workflow_file" "opencode/gpt-5.6-terra 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 retains paid Zen and DeepSeek V3 before full-size GPT fallbacks" + assert_file_contains "$workflow_file" "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5 nvidia-nim/nvidia/llama-3.1-nemotron-ultra-253b-v1 nvidia-nim/nvidia/nemotron-3-super-120b-a12b nvidia-nim/meta/llama-3.3-70b-instruct nvidia-nim/deepseek-ai/deepseek-v4-pro nvidia-nim/mistralai/codestral-22b-instruct-v0.1 opencode/gpt-5.6-terra 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 retains paid Zen and 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" @@ -868,7 +868,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" "opencode/gpt-5.6-terra 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 paid Zen and DeepSeek V3 before OpenAI fallbacks" + assert_file_contains "$workflow_file" "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5 nvidia-nim/nvidia/llama-3.1-nemotron-ultra-253b-v1 nvidia-nim/nvidia/nemotron-3-super-120b-a12b nvidia-nim/meta/llama-3.3-70b-instruct nvidia-nim/deepseek-ai/deepseek-v4-pro nvidia-nim/mistralai/codestral-22b-instruct-v0.1 opencode/gpt-5.6-terra 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 paid Zen and 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" @@ -1197,7 +1197,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" "opencode/gpt-5.6-terra 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 paid Zen before DeepSeek V3 and full-size GPT fallbacks" + assert_file_contains "$workflow_file" "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5 nvidia-nim/nvidia/llama-3.1-nemotron-ultra-253b-v1 nvidia-nim/nvidia/nemotron-3-super-120b-a12b nvidia-nim/meta/llama-3.3-70b-instruct nvidia-nim/deepseek-ai/deepseek-v4-pro nvidia-nim/mistralai/codestral-22b-instruct-v0.1 opencode/gpt-5.6-terra 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 paid Zen before DeepSeek V3 and 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" From cc4ed880796c9ba4d44e3c42efb612419477e0e2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 31 Jul 2026 20:07:18 +0900 Subject: [PATCH 2/2] fix(opencode): wire nvidia-nim into isolated review workspace Include the NIM provider in the generated isolated opencode.jsonc used by the model pool (not only OPENCODE_MODEL_CANDIDATES), prefer NIM defaults, fail fast if the generated config lacks NIM, and update quick-gate asserts. --- .../workflows/opencode-review-dispatch.yml | 102 +++++++++++++++++- scripts/ci/test_strix_quick_gate.sh | 6 +- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/.github/workflows/opencode-review-dispatch.yml b/.github/workflows/opencode-review-dispatch.yml index 1bb9bad85..668557dd4 100644 --- a/.github/workflows/opencode-review-dispatch.yml +++ b/.github/workflows/opencode-review-dispatch.yml @@ -3411,9 +3411,9 @@ jobs: jq -n '{ "$schema": "https://opencode.ai/config.json", - "model": "github-models/deepseek/deepseek-r1-0528", - "small_model": "github-models/deepseek/deepseek-v3-0324", - "enabled_providers": ["opencode-free", "opencode", "openai", "openrouter", "github-models"], + "model": "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5", + "small_model": "nvidia-nim/meta/llama-3.3-70b-instruct", + "enabled_providers": ["nvidia-nim", "opencode-free", "opencode", "openai", "openrouter", "github-models"], "lsp": false, "mcp": {}, "permission": { @@ -3714,6 +3714,96 @@ jobs: } } }, + "nvidia-nim": { + "npm": "@ai-sdk/openai-compatible", + "name": "NVIDIA NIM", + "options": { + "baseURL": "https://integrate.api.nvidia.com/v1", + "apiKey": "{env:NVIDIA_API_KEY}" + }, + "models": { + "nvidia/llama-3.3-nemotron-super-49b-v1.5": { + "name": "NVIDIA Llama 3.3 Nemotron Super 49B v1.5", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/llama-3.1-nemotron-ultra-253b-v1": { + "name": "NVIDIA Llama 3.1 Nemotron Ultra 253B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/nemotron-3-super-120b-a12b": { + "name": "NVIDIA Nemotron 3 Super 120B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "nvidia/nemotron-3-ultra-550b-a55b": { + "name": "NVIDIA Nemotron 3 Ultra 550B", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "meta/llama-3.3-70b-instruct": { + "name": "Meta Llama 3.3 70B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "meta/llama-3.1-70b-instruct": { + "name": "Meta Llama 3.1 70B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "deepseek-ai/deepseek-v4-pro": { + "name": "DeepSeek V4 Pro (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "mistralai/mistral-large-2-instruct": { + "name": "Mistral Large 2 Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + }, + "mistralai/codestral-22b-instruct-v0.1": { + "name": "Codestral 22B Instruct (NIM)", + "tool_call": true, + "limit": { + "context": 32768, + "output": 8192 + } + }, + "google/gemma-4-31b-it": { + "name": "Gemma 4 31B IT (NIM)", + "tool_call": true, + "limit": { + "context": 131072, + "output": 8192 + } + } + } + }, "github-models": { "npm": "@ai-sdk/openai-compatible", "name": "GitHub Models", @@ -3920,6 +4010,12 @@ jobs: } }' >"${OPENCODE_REVIEW_WORKDIR}/opencode.jsonc" + + if ! grep -Fq 'nvidia-nim' "${OPENCODE_REVIEW_WORKDIR}/opencode.jsonc" \ + || ! grep -Fq 'integrate.api.nvidia.com' "${OPENCODE_REVIEW_WORKDIR}/opencode.jsonc"; then + echo '::error::Generated isolated opencode.jsonc is missing the nvidia-nim provider; refusing to run the model pool without NIM priority.' + exit 1 + fi printf 'Prepared isolated OpenCode review workspace: %s\n' "$OPENCODE_REVIEW_WORKDIR" - name: Run OpenCode PR Review model pool diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index b9c48e4da..daada89a7 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -1396,8 +1396,10 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() { assert_file_not_contains "$opencode_config" '"@upstash/context7-mcp' "opencode config does not install Context7 at runtime" assert_file_not_contains "$opencode_config" '"@guhcostan/web-search-mcp' "opencode config does not install web-search MCP at runtime" assert_file_not_contains "$opencode_config" '"serve"' "opencode config does not launch CodeGraph inside the credentialed model process" - assert_file_contains "$opencode_config" '"small_model": "github-models/deepseek/deepseek-v3-0324"' "opencode config uses a reachable DeepSeek V3 small model" - assert_file_contains "$opencode_config" '"model": "github-models/deepseek/deepseek-r1-0528"' "opencode config defaults review sessions to DeepSeek R1" + assert_file_contains "$opencode_config" '"small_model": "nvidia-nim/meta/llama-3.3-70b-instruct"' "opencode config uses NVIDIA NIM Llama 3.3 70B small model" + assert_file_contains "$opencode_config" '"model": "nvidia-nim/nvidia/llama-3.3-nemotron-super-49b-v1.5"' "opencode config defaults review sessions to NVIDIA NIM Nemotron Super" +assert_file_contains "$opencode_config" '"nvidia-nim"' "opencode config enables nvidia-nim provider" +assert_file_contains "$opencode_config" 'integrate.api.nvidia.com' "opencode config points nvidia-nim at NIM API" assert_file_contains "$opencode_config" '"openai/gpt-5"' "opencode config defines GitHub Models GPT-5 with full model id" assert_file_contains "$opencode_config" '"openai/gpt-5-chat"' "opencode config defines GPT-5 Chat catalog fallback" assert_file_contains "$opencode_config" '"openai/gpt-5-mini"' "opencode config defines GPT-5 Mini catalog fallback"