Skip to content
Closed
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
59 changes: 38 additions & 21 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,18 @@ jobs:
;;
esac

if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
# An npm lockfile is authoritative: npm owns this project even when a
# vestigial pnpm-lock.yaml or yarn.lock is also committed. This mirrors
# the base materializer (materialize_base_javascript_packages.py), which
# already treats a pnpm-lock.yaml with a sibling package-lock.json and no
# exact packageManager as a vestigial second lockfile. Without this the
# runtime runner selected pnpm/yarn and refused on the missing exact
# packageManager, failing coverage-evidence for npm projects that also
# carry a stray pnpm-lock.yaml.
command -v npm >/dev/null 2>&1 && printf '%s\n' "npm"
return
fi
if [ -f pnpm-lock.yaml ]; then
ensure_corepack_runner pnpm "$declared_spec" && printf '%s\n' "pnpm"
return
Expand Down Expand Up @@ -3857,7 +3869,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 ' || '' }}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 ' || '' }}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 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"
# 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.
Expand Down Expand Up @@ -6692,6 +6704,29 @@ jobs:
return 1
}

hold_for_missing_r_cmd_check() {
local body
body="$(printf '%s\n' \
"## Pull request overview" \
"" \
"OpenCode reviewed the current-head source evidence but R package tests were deferred after bounded package-load-only failures." \
"" \
"## Approval hold" \
"" \
"### Successful current-head R CMD check evidence is required" \
"- Problem: coverage-evidence deferred package-load-only testthat failures, but no successful current-head R CMD check was found." \
"- Root cause: deterministic coverage deferral is safe only when the repository's peer R CMD check installs dependencies and passes on this exact head." \
"- Fix: add or repair the R CMD check workflow and rerun it successfully on the current head." \
"- Regression test: Keep deferred R coverage fail-closed unless a successful R CMD check is present." \
"" \
"- Result: WAITING_FOR_R_CMD_CHECK" \
"- Head SHA: \`${HEAD_SHA}\`" \
"- Workflow run: ${RUN_ID}" \
"- Workflow attempt: ${RUN_ATTEMPT}"
)"
hold_approval_without_review "WAITING_FOR_R_CMD_CHECK" "$body"
}

stop_without_review_after_model_unavailable() {
local body
body="$(printf '%s\n' \
Expand Down Expand Up @@ -6809,7 +6844,7 @@ jobs:
fi

if ! require_r_cmd_check_for_deferred_coverage; then
return 1
hold_for_missing_r_cmd_check
fi

failed_check_evidence_file="$(mktemp)"
Expand Down Expand Up @@ -7197,25 +7232,7 @@ jobs:
fi
fi
if ! require_r_cmd_check_for_deferred_coverage; then
body="$(printf '%s\n' \
"## Pull request overview" \
"" \
"OpenCode reviewed the current-head source evidence but R package tests were deferred after bounded package-load-only failures." \
"" \
"## Approval hold" \
"" \
"### Successful current-head R CMD check evidence is required" \
"- Problem: coverage-evidence deferred package-load-only testthat failures, but no successful current-head R CMD check was found." \
"- Root cause: deterministic coverage deferral is safe only when the repository's peer R CMD check installs dependencies and passes on this exact head." \
"- Fix: add or repair the R CMD check workflow and rerun it successfully on the current head." \
"- Regression test: Keep deferred R coverage fail-closed unless a successful R CMD check is present." \
"" \
"- Result: WAITING_FOR_R_CMD_CHECK" \
"- Head SHA: \`${HEAD_SHA}\`" \
"- Workflow run: ${RUN_ID}" \
"- Workflow attempt: ${RUN_ATTEMPT}"
)"
hold_approval_without_review "WAITING_FOR_R_CMD_CHECK" "$body"
hold_for_missing_r_cmd_check
fi
unresolved_reviewer_threads_file="$(mktemp)"
reviewer_thread_review_body_file="$(mktemp)"
Expand Down
26 changes: 20 additions & 6 deletions tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates():
["github-models", "openai/o3"],
["github-models", "deepseek/deepseek-r1-0528"],
["github-models", "deepseek/deepseek-r1"],
["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"],
]
assert direct_openai_models == ["gpt-5.6-luna"]
assert openrouter_models == [
Expand Down Expand Up @@ -181,6 +184,12 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates():
assert "response_format" not in deepseek_model.get("options", {})
assert north_model["tool_call"] is True
assert "response_format" not in north_model["options"]
for model_name, model_config in free_models.items():
if model_config.get("reasoning") is True:
assert model_config["options"]["reasoningEffort"] == "high", model_name
assert model_config["variants"]["high"]["reasoningEffort"] == "high", (
model_name
)
assert free_models["laguna-s-2.1-free"]["limit"] == {
"context": 256000,
"output": 32000,
Expand All @@ -197,12 +206,6 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates():
"context": 200000,
"output": 32000,
}
for model_name, model_config in free_models.items():
if model_config.get("reasoning") is True:
assert model_config["options"]["reasoningEffort"] == "high", model_name
assert model_config["variants"]["high"]["reasoningEffort"] == "high", (
model_name
)
assert github_candidate_models == [
"deepseek/deepseek-v3-0324",
"openai/gpt-4.1",
Expand All @@ -211,6 +214,9 @@ def test_opencode_model_pool_sets_high_effort_for_capable_candidates():
"openai/o3",
"deepseek/deepseek-r1-0528",
"deepseek/deepseek-r1",
"mistral-ai/mistral-medium-2505",
"meta/llama-4-maverick-17b-128e-instruct-fp8",
"meta/llama-4-scout-17b-16e-instruct",
]
banned_review_candidates = {
"gpt-5-nano",
Expand Down Expand Up @@ -735,6 +741,13 @@ def test_opencode_coverage_prefers_preinstalled_declared_pnpm_before_npm():
assert select_function.index("[ -f pnpm-lock.yaml ]") < select_function.rindex(
"elif command -v npm"
)
# A committed npm lockfile is authoritative: an npm project that also carries a
# vestigial pnpm-lock.yaml / yarn.lock must resolve to npm rather than refuse on
# a missing exact packageManager (mirrors materialize_base_javascript_packages.py).
# The npm-lockfile check therefore precedes the pnpm/yarn lockfile fallback.
assert select_function.index(
"[ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]"
) < select_function.index("[ -f pnpm-lock.yaml ]")

declared_pnpm_start = select_function.index(" pnpm)")
declared_pnpm_end = select_function.index(
Expand Down Expand Up @@ -2388,6 +2401,7 @@ def test_r_package_load_deferral_requires_current_head_r_cmd_check():
assert marker in workflow
assert "require_r_cmd_check_for_deferred_coverage" in workflow
assert workflow.count("require_r_cmd_check_for_deferred_coverage") == 3
assert workflow.count("hold_for_missing_r_cmd_check") == 3
assert "WAITING_FOR_R_CMD_CHECK" in workflow
assert "testthat unavailable in coverage runner" not in workflow
assert (
Expand Down
Loading