From cd4b64cede657afc09cbc2b7d0ff92a2bebcc36c Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Thu, 18 Jun 2026 13:39:06 -0700 Subject: [PATCH] chore(ci): remove Agent Shin pull_request_target workflows Drop the two Agent Shin workflows that ran on the pull_request_target trigger: the PR triage workflow and the review gate. Both were dry-run and gated behind AGENT_SHIN_ENABLED, so no live automation changes. The shared scripts under .github/scripts stay in place; four other Agent Shin workflows still depend on them and run on schedule, dispatch, and issue events rather than pull_request_target --- .github/workflows/review_gate.yml | 131 ----------------------- .github/workflows/triage_pr_with_llm.yml | 110 ------------------- 2 files changed, 241 deletions(-) delete mode 100644 .github/workflows/review_gate.yml delete mode 100644 .github/workflows/triage_pr_with_llm.yml diff --git a/.github/workflows/review_gate.yml b/.github/workflows/review_gate.yml deleted file mode 100644 index ba4b488b79d1..000000000000 --- a/.github/workflows/review_gate.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Agent Shin — review gate - -# Keeps the `ready for review` label in sync with whether an external PR -# currently clears BOTH the LLM rubric AND Greptile's confidence score. -# -# pass -> add `ready for review` + a "passed / all clear" comment -# regress -> remove the label + a "what's missing" comment (PR stays open) -# fail, <24h old -> a one-time "what's missing" notice (grace window) -# fail, >24h old -> close + a comment (reopen via `@agent-shin reconsider`) -# -# DRY-RUN BY DEFAULT. Every side effect (label add/remove, comment, close) is -# gated behind `--close`, which is only added when the repo variable -# `AGENT_SHIN_ENABLED == "true"`. Until then runs only write the verdict to the -# workflow step summary. -# -# Manual single PR: gh workflow run "Agent Shin — review gate" -f pr_number=NNN -# Manual dry-run: gh workflow run "Agent Shin — review gate" -f close=false -# -# We use `pull_request_target` so the workflow can read repo secrets and run -# against fork PRs. Fork code is never checked out — only PR metadata is read -# via `gh api`. - -on: - pull_request_target: - types: [opened, reopened, synchronize, ready_for_review] - schedule: - # Daily at 09:30 UTC — re-reconciles labels as Greptile re-reviews land. - - cron: "30 9 * * *" - workflow_dispatch: - inputs: - pr_number: - description: "Single PR to reconcile (omit to sweep all open PRs)." - required: false - close: - description: "If AGENT_SHIN_ENABLED=true, actually act (false = dry run)." - required: false - default: "false" - type: choice - options: - - "true" - - "false" - grace_days: - description: "Hours/24 a failing, un-tagged PR may stay open before close." - required: false - default: "1" - min_greptile_score: - description: "Greptile score below which a PR counts as not passing (1-5)." - required: false - default: "4" - -permissions: - contents: read - issues: write - pull-requests: write - -jobs: - review-gate: - if: github.repository == 'BerriAI/litellm' - runs-on: ubuntu-latest - steps: - - name: Checkout triage script - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - with: - sparse-checkout: .github/scripts - persist-credentials: false - - - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: "3.12" - - - name: Install LLM client - run: pip install --no-cache-dir --require-hashes -r .github/scripts/triage-requirements.txt - - - name: Run review gate - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Mirror the triage workflow: only expose the LLM key when the bot is - # enabled or a collaborator triggers it manually, so an external user - # can't force paid LLM calls by churning a fork PR while the bot is - # still in dry-run. - OPENAI_API_KEY: ${{ (vars.AGENT_SHIN_ENABLED == 'true' || github.event_name == 'workflow_dispatch') && secrets.OPENAI_API_KEY || '' }} - OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }} - TRIAGE_MODEL: ${{ vars.TRIAGE_MODEL }} - AGENT_SHIN_ENABLED: ${{ vars.AGENT_SHIN_ENABLED }} - CLOSE_FLAG: ${{ github.event.inputs.close || 'false' }} - GRACE_DAYS: ${{ github.event.inputs.grace_days || '1' }} - MIN_GREPTILE_SCORE: ${{ github.event.inputs.min_greptile_score || '4' }} - EVENT_PR: ${{ github.event.pull_request.number }} - INPUT_PR: ${{ github.event.inputs.pr_number }} - run: | - set -euo pipefail - COMMON=(--review-gate --grace-days "${GRACE_DAYS}" --min-greptile-score "${MIN_GREPTILE_SCORE}") - - # Fail-safe gating, identical philosophy to the Greptile closer: - # - AGENT_SHIN_ENABLED must be the EXACT string "true" to act at all. - # - A manual dispatch can still preview with close=false. - # - Automatic triggers (PR events, schedule) act once enabled — that - # is the whole point of the gate (re-tag / un-tag automatically). - DO_CLOSE="false" - if [ "${AGENT_SHIN_ENABLED:-false}" != "true" ]; then - echo "::notice::AGENT_SHIN_ENABLED is not 'true' -> dry-run (no labels/comments/closes)." - elif [ "${GITHUB_EVENT_NAME:-}" = "workflow_dispatch" ] && [ "${CLOSE_FLAG:-false}" = "true" ]; then - DO_CLOSE="true" - echo "::notice::Manual run -> acting for real." - elif [ "${GITHUB_EVENT_NAME:-}" != "workflow_dispatch" ]; then - DO_CLOSE="true" - echo "::notice::Enabled automatic trigger (${GITHUB_EVENT_NAME:-}) -> acting for real." - else - echo "::notice::Manual dispatch with close=false -> dry-run." - fi - if [ "${DO_CLOSE}" = "true" ]; then - COMMON+=(--close) - fi - - # Single PR (PR event or explicit input) vs. sweep over all open PRs. - TARGET_PR="${EVENT_PR:-${INPUT_PR:-}}" - if [ -n "${TARGET_PR}" ]; then - python3 .github/scripts/triage_with_llm.py --repo "${{ github.repository }}" --pr "${TARGET_PR}" "${COMMON[@]}" - else - echo "::notice::Sweeping all open PRs." - # Match GH_LIST_ALL_LIMIT in agent_shin_shared.py: gh lists newest-first, - # so any cap below the real backlog silently drops the *oldest* PRs — - # exactly the stale ones this daily sweep is meant to reconcile. - mapfile -t NUMBERS < <(gh pr list --repo "${{ github.repository }}" --state open --limit 100000 --json number --jq '.[].number') - for n in "${NUMBERS[@]}"; do - echo "::group::PR #${n}" - python3 .github/scripts/triage_with_llm.py --repo "${{ github.repository }}" --pr "${n}" "${COMMON[@]}" || echo "::warning::review gate errored on #${n}" - echo "::endgroup::" - done - fi diff --git a/.github/workflows/triage_pr_with_llm.yml b/.github/workflows/triage_pr_with_llm.yml deleted file mode 100644 index 936547598fbc..000000000000 --- a/.github/workflows/triage_pr_with_llm.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Agent Shin — PR triage - -# LLM-as-judge triage for external pull requests. -# -# DRY-RUN BY DEFAULT. Closures and public comments are gated on the repo -# variable `AGENT_SHIN_ENABLED` being set to the string `"true"`. Until then, -# every run only writes its verdict to the workflow step summary so the team -# can QA the judge's decisions before flipping it on. -# -# To enable for real: -# 1. Add a repo secret `OPENAI_API_KEY` (or compatible). -# 2. Set repo variable `AGENT_SHIN_ENABLED` to `true` -# (Settings > Secrets and variables > Actions > Variables). -# -# We use `pull_request_target` so the workflow has access to repo secrets -# and runs against PRs from forks. We never check out fork code — only read -# PR metadata via `gh api`, so this is safe. - -on: - pull_request_target: - types: [opened, reopened] - workflow_dispatch: - inputs: - pr_number: - description: "PR number to triage manually." - required: true - close: - description: "If true and AGENT_SHIN_ENABLED=true, actually close on fail." - required: false - default: "false" - type: choice - options: - - "true" - - "false" - -permissions: - contents: read - issues: write - pull-requests: write - -jobs: - triage: - if: github.repository == 'BerriAI/litellm' - runs-on: ubuntu-latest - steps: - - name: Checkout triage script - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - with: - sparse-checkout: .github/scripts - persist-credentials: false - - - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: "3.12" - - - name: Install LLM client - run: pip install --no-cache-dir --require-hashes -r .github/scripts/triage-requirements.txt - - - name: Run Agent Shin - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Only expose the LLM key when the bot is enabled or a collaborator - # triggers it manually, so an external user can't force paid LLM - # calls by churning a fork PR while the bot is still in dry-run. - # The Python script calls the LLM whenever this var is set - # (regardless of `--close`); stripping `--close` doesn't suppress - # the API call, only the destructive side effects. - OPENAI_API_KEY: ${{ (vars.AGENT_SHIN_ENABLED == 'true' || github.event_name == 'workflow_dispatch') && secrets.OPENAI_API_KEY || '' }} - OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }} - TRIAGE_MODEL: ${{ vars.TRIAGE_MODEL }} - AGENT_SHIN_ENABLED: ${{ vars.AGENT_SHIN_ENABLED }} - DISPATCH_CLOSE: ${{ github.event.inputs.close }} - PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }} - run: | - set -euo pipefail - ARGS=(--repo "${{ github.repository }}" --pr "${PR_NUMBER}") - # Fail-safe gating: only the EXACT string "true" enables the - # destructive --close path. The workflow_dispatch input is a - # `choice` dropdown of "true"/"false" so the UI is constrained, - # but the API (`gh workflow run -f close=...`) accepts any - # string, and a `!= "false"` check would treat "True", "yes", - # "1", "TRUE", typos, and accidental whitespace as enabling - # closure. Mirror the Greptile closer's `= "true"` pattern. - if [ "${AGENT_SHIN_ENABLED:-false}" = "true" ] && [ "${DISPATCH_CLOSE:-false}" = "true" ]; then - ARGS+=(--close) - echo "::notice::Agent Shin is ENABLED and running in close-on-fail mode." - elif [ "${AGENT_SHIN_ENABLED:-false}" = "true" ]; then - echo "::notice::Agent Shin is ENABLED but this trigger is dry-run (workflow_dispatch close != 'true' or scheduled event)." - else - echo "::notice::Agent Shin is in DRY-RUN mode (AGENT_SHIN_ENABLED is not 'true'). No comments will be posted; no PRs will be closed." - fi - # On the scheduled/automatic pull_request_target trigger we default to - # dry-run regardless, so the team can review verdicts in the step - # summary before any contributor sees a comment. Only the manual - # workflow_dispatch path (with close=true) closes PRs. - if [ "${GITHUB_EVENT_NAME:-}" = "pull_request_target" ]; then - # strip any --close added above (filter out, don't substitute - # to empty string — that would leave a stray "" positional arg - # that argparse rejects) - FILTERED=() - for arg in "${ARGS[@]}"; do - if [ "${arg}" != "--close" ]; then - FILTERED+=("${arg}") - fi - done - ARGS=("${FILTERED[@]}") - echo "::notice::pull_request_target trigger -> forcing dry-run." - fi - python3 .github/scripts/triage_with_llm.py "${ARGS[@]}"