Skip to content
Open
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
6 changes: 5 additions & 1 deletion .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,11 @@ jobs:
VERTEX_LOCATION: ${{ secrets.VERTEX_LOCATION || 'us-central1' }}
STRIX_TARGET_PATH: ${{ (github.event_name == 'pull_request_target' || github.event.client_payload.pr_number != '') && '__PR_SCOPE__' || './' }}
STRIX_SOURCE_DIRS: ". backend frontend"
STRIX_REASONING_EFFORT: high
# OpenAI GPT-5.4's chat-completions endpoint rejects reasoning_effort
# when Strix supplies function tools. Keep high effort for providers
# that support it, but send the API-compatible neutral value to direct
# OpenAI scans so the security gate can complete.
STRIX_REASONING_EFFORT: ${{ steps.gate.outputs.provider_mode == 'openai_direct' && 'none' || 'high' }}
Comment thread
seonghobae marked this conversation as resolved.
Comment thread
seonghobae marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
STRIX_LLM_MAX_RETRIES: 1
STRIX_TRANSIENT_RETRY_PER_MODEL: 2
STRIX_TRANSIENT_RETRY_BACKOFF_SECONDS: 60
Expand Down
14 changes: 13 additions & 1 deletion scripts/ci/strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2551,6 +2551,7 @@ run_strix_once() {
local rc
local llm_api_base_value
local child_model
local child_reasoning_effort="${STRIX_REASONING_EFFORT:-high}"
local resolved_target_path
local timeout_seconds="$STRIX_PROCESS_TIMEOUT_SECONDS"
local total_budget_limited_timeout=0
Expand All @@ -2574,6 +2575,12 @@ run_strix_once() {
return 2
fi
child_model="$(child_model_for_api_base "$model" "$llm_api_base_value")"
if is_explicit_openai_model "$model"; then
# GPT-5.4 chat-completions rejects reasoning_effort when Strix
# supplies function tools; apply the override to every direct-OpenAI
# fallback, regardless of the selected primary provider.
child_reasoning_effort="none"
fi
if ! resolved_target_path="$(resolve_current_target_path "$TARGET_PATH")"; then
return 1
fi
Expand All @@ -2597,6 +2604,7 @@ run_strix_once() {
set -o pipefail
set +e
STRIX_CHILD_MODEL="$child_model" \
STRIX_CHILD_REASONING_EFFORT="$child_reasoning_effort" \
STRIX_CHILD_LLM_API_KEY="$child_llm_api_key" \
STRIX_CHILD_LLM_API_BASE="$llm_api_base_value" \
STRIX_CHILD_REPORTS_DIR="$ACTIVE_REPORTS_DIR" \
Expand Down Expand Up @@ -2671,7 +2679,6 @@ for key in (
"GEMINI_LOCATION",
"LLM_TIMEOUT",
"STRIX_MEMORY_COMPRESSOR_TIMEOUT",
"STRIX_REASONING_EFFORT",
"STRIX_LLM_MAX_RETRIES",
"GOOGLE_CLOUD_PROJECT",
"GCP_PROJECT",
Expand All @@ -2682,6 +2689,11 @@ for key in (
value = os.environ.get(key)
if value:
child_env[key] = value
child_reasoning_effort = os.environ.get("STRIX_CHILD_REASONING_EFFORT") or os.environ.get(
"STRIX_REASONING_EFFORT"
)
if child_reasoning_effort:
child_env["STRIX_REASONING_EFFORT"] = child_reasoning_effort
llm_api_base = os.environ.get("STRIX_CHILD_LLM_API_BASE", "")
if llm_api_base:
child_env["LLM_API_BASE"] = llm_api_base
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ assert_strix_workflow_pr_trigger_hardened() {
assert_file_contains "$workflow_file" "NVIDIA_NIM_API_KEY is required for Strix NVIDIA NIM scans" "strix workflow fails closed when NVIDIA credentials are absent"
assert_file_contains "$workflow_file" 'PROVIDER_MODE: ${{ steps.gate.outputs.provider_mode }}' "strix workflow passes provider mode through env"
assert_file_not_contains "$workflow_file" '[ "${{ steps.gate.outputs.provider_mode }}" = "openai_direct" ]' "strix workflow does not interpolate provider mode inside shell condition"
assert_file_contains "$workflow_file" "STRIX_REASONING_EFFORT: high" "strix workflow uses high reasoning effort when the selected provider/model supports it"
assert_file_contains "$workflow_file" "STRIX_REASONING_EFFORT: \${{ steps.gate.outputs.provider_mode == 'openai_direct' && 'none' || 'high' }}" "strix workflow disables unsupported OpenAI chat-completions reasoning effort while retaining high effort for other providers"
assert_file_contains "$workflow_file" 'trimmed_openai_key="$(printf '"'"'%s'"'"' "$sanitized_openai_key" | sed '"'"'s/^[[:space:]]*//;s/[[:space:]]*$//'"'"')"' "strix workflow trims whitespace-only OpenAI keys before gate validation"
assert_file_contains "$workflow_file" 'printf '"'"'%s'"'"' "$trimmed" > "$llm_api_key_file"' "strix workflow writes trimmed provider API keys into the trusted input file"
assert_file_contains "$workflow_file" 'STRIX_LLM_DEFAULT_PROVIDER: ${{ steps.gate.outputs.provider_mode == '"'"'vertex_ai'"'"' && '"'"'vertex_ai'"'"' || steps.gate.outputs.provider_mode == '"'"'nvidia_nim'"'"' && '"'"'nvidia_nim'"'"' || '"'"'openai'"'"' }}' "strix workflow selects the correct default provider"
Expand Down
17 changes: 16 additions & 1 deletion tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,10 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent():
assert "falling back to current-head REST check-runs" in workflow

strix_workflow = Path(".github/workflows/strix.yml").read_text(encoding="utf-8")
assert "STRIX_REASONING_EFFORT: high" in strix_workflow
assert (
"STRIX_REASONING_EFFORT: ${{ steps.gate.outputs.provider_mode == 'openai_direct' && 'none' || 'high' }}"
in strix_workflow
)

prompt_template = Path("scripts/ci/opencode_review_prompt_template.md").read_text(
encoding="utf-8"
Expand Down Expand Up @@ -2993,3 +2996,15 @@ def test_r_package_load_deferral_requires_current_head_r_cmd_check():
assert (
"if (!is.na(pkg) && !requireNamespace(pkg, quietly = TRUE))" not in workflow
)


def test_strix_direct_openai_fallback_overrides_child_reasoning_effort():
"""Direct OpenAI fallbacks must not inherit an incompatible effort value."""
quick_gate = Path("scripts/ci/strix_quick_gate.sh").read_text(encoding="utf-8")

assert 'local child_reasoning_effort="${STRIX_REASONING_EFFORT:-high}"' in quick_gate
assert 'if is_explicit_openai_model "$model"; then' in quick_gate
assert 'child_reasoning_effort="none"' in quick_gate
assert 'STRIX_CHILD_REASONING_EFFORT="$child_reasoning_effort"' in quick_gate
assert 'child_reasoning_effort = os.environ.get("STRIX_CHILD_REASONING_EFFORT") or os.environ.get(' in quick_gate
assert 'child_env["STRIX_REASONING_EFFORT"] = child_reasoning_effort' in quick_gate
Loading