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
1 change: 1 addition & 0 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3758,6 +3758,7 @@ jobs:
OPENCODE_DYNAMIC_RUN_TIMEOUT_CAP_SECONDS: "5400"
OPENCODE_DYNAMIC_TOTAL_BUDGET_CAP_SECONDS: "11700"
OPENCODE_DYNAMIC_MAX_CYCLES_CAP: "0"
OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "600"
# 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
Expand Down
5 changes: 4 additions & 1 deletion scripts/ci/run_opencode_review_model_pool.sh
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ cap_model_run_timeout() {
local cap_seconds

case "$model_candidate" in
opencode-free/*)
cap_seconds="$(env_integer_or_default OPENCODE_FREE_RUN_TIMEOUT_SECONDS 600)"
;;
github-models/openai/gpt-5 | github-models/openai/gpt-5-chat)
cap_seconds="$(env_integer_or_default OPENCODE_GITHUB_GPT5_RUN_TIMEOUT_SECONDS 45)"
;;
Expand Down Expand Up @@ -610,7 +613,7 @@ main() {
uncapped_run_timeout="$OPENCODE_RUN_TIMEOUT_SECONDS"
OPENCODE_RUN_TIMEOUT_SECONDS="$(cap_model_run_timeout "$model_candidate" "$OPENCODE_RUN_TIMEOUT_SECONDS")"
if [ "$OPENCODE_RUN_TIMEOUT_SECONDS" -lt "$uncapped_run_timeout" ]; then
printf 'OpenCode %s runtime cap selected %ss instead of %ss because this installation has returned a constrained request-body limit for that endpoint.\n' \
printf 'OpenCode %s runtime cap selected %ss instead of %ss because this provider has a bounded failover window.\n' \
"$model_candidate" "$OPENCODE_RUN_TIMEOUT_SECONDS" "$uncapped_run_timeout"
fi
export OPENCODE_RUN_TIMEOUT_SECONDS
Expand Down
3 changes: 2 additions & 1 deletion tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,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: "0"' in workflow
assert 'OPENCODE_FREE_RUN_TIMEOUT_SECONDS: "600"' in workflow
assert 'OPENCODE_GITHUB_GPT5_RUN_TIMEOUT_SECONDS: "45"' in workflow
assert 'OPENCODE_DYNAMIC_MAX_CYCLES: "0"' in workflow
assert 'OPENCODE_BACKOFF_MAX_SECONDS: "30"' in workflow
Expand Down Expand Up @@ -1351,7 +1352,7 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent():
assert "while :" in model_pool_runner
assert "should_skip_model_candidate" in model_pool_runner
assert "cap_model_run_timeout" in model_pool_runner
assert "constrained request-body limit" in model_pool_runner
assert "bounded failover window" in model_pool_runner
assert "run_central_adversarial_harness" not in model_pool_runner
assert "finish_pool_without_model" in model_pool_runner
assert "central-current-head-adversarial-harness" not in model_pool_runner
Expand Down
20 changes: 19 additions & 1 deletion tests/test_opencode_model_pool_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ def test_github_gpt5_runtime_cap_preserves_queue_budget(tmp_path: Path) -> None:
assert result.returncode == 1
assert (
"OpenCode github-models/openai/gpt-5 runtime cap selected 3s instead of 9s "
"because this installation has returned a constrained request-body limit for that endpoint."
"because this provider has a bounded failover window."
) in result.stdout
attempt_budget = re.search(
r"OpenCode github-models/openai/gpt-5 attempt 1/1 using (\d+)s run timeout "
Expand All @@ -772,6 +772,24 @@ def test_github_gpt5_runtime_cap_preserves_queue_budget(tmp_path: Path) -> None:
assert run_timeout <= remaining_budget <= 30


def test_free_provider_runtime_cap_preserves_queue_budget(tmp_path: Path) -> None:
"""A stalled free provider cannot consume a full paid-provider cadence slot."""
result = run_failed_model(
tmp_path,
extra_env={
"OPENCODE_FREE_RUN_TIMEOUT_SECONDS": "3",
"OPENCODE_RUN_TIMEOUT_SECONDS": "9",
},
model_candidates="opencode-free/nemotron-3-ultra-free",
)

assert result.returncode == 1
assert (
"OpenCode opencode-free/nemotron-3-ultra-free runtime cap selected 3s "
"instead of 9s because this provider has a bounded failover window."
) in result.stdout


def test_github_models_openai_prompt_references_evidence_without_inlining(
tmp_path: Path,
) -> None:
Expand Down
Loading