{"id":50294919,"url":"https://github.com/tiylabs/code-review-agent-action","last_synced_at":"2026-05-28T08:08:57.628Z","repository":{"id":341794166,"uuid":"1171407857","full_name":"tiylabs/code-review-agent-action","owner":"tiylabs","description":"Reusable GitHub Action for automated Pull Request code review with multi-provider AI support (OpenAI, Anthropic, Google, Mistral, OpenAI-compatible) via AI SDK","archived":false,"fork":false,"pushed_at":"2026-05-27T10:56:17.000Z","size":1808,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-27T11:08:00.636Z","etag":null,"topics":["codereviewer","pr-review","review-action"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tiylabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-03T07:39:44.000Z","updated_at":"2026-05-27T10:51:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tiylabs/code-review-agent-action","commit_stats":null,"previous_names":["tiyagents/code-review-agent-action","tiylabs/code-review-agent-action"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/tiylabs/code-review-agent-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiylabs%2Fcode-review-agent-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiylabs%2Fcode-review-agent-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiylabs%2Fcode-review-agent-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiylabs%2Fcode-review-agent-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tiylabs","download_url":"https://codeload.github.com/tiylabs/code-review-agent-action/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiylabs%2Fcode-review-agent-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33599839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codereviewer","pr-review","review-action"],"created_at":"2026-05-28T08:08:56.365Z","updated_at":"2026-05-28T08:08:57.622Z","avatar_url":"https://github.com/tiylabs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI Code Review Agent Action\n\n[![Build and Test](https://github.com/tiylabs/code-review-agent-action/actions/workflows/self-test-current-branch.yml/badge.svg)](https://github.com/tiylabs/code-review-agent-action/actions/workflows/self-test-current-branch.yml)\n\nReusable GitHub Action for automated Pull Request code review with multi-provider AI support (OpenAI, Anthropic, Google, Mistral, OpenAI-compatible) via [AI SDK](https://sdk.vercel.ai/).\n\nThis action:\n- Runs on `pull_request` events.\n- Reviews all changed files that match `include`/`exclude` filters.\n- Uses planner + subagents (general/security/performance/testing) in multi-round batches for large diffs, with **parallel batch and dimension execution** within each round.\n- Publishes:\n  - one PR Review (`pulls.createReview`) with inline comments (`LEFT`/`RIGHT`), and\n  - one updatable summary issue comment (marker-based, no spam).\n- Tracks coverage and budget limits; outputs uncovered files + reasons when budget is exhausted.\n\n## Agent Architecture\n\n![Agent Architecture](docs/images/agent-architecture-cute-variant-b-16x9.png)\n\nSimple flow explanation:\n- `Planner` decides each round's batches under `max_rounds`, `max_model_calls`, and `max_files_per_batch`.\n- `SubAgent(general)` always runs first for each batch, and can dynamically request extra dimensions (`security/performance/testing`).\n- Within each round, batches execute in parallel (controlled by `max_concurrency`); within each batch, remaining dimensions run in parallel after `general` completes.\n- All sub-agent outputs are aggregated, normalized, deduplicated, then mapped to inline-commentable diff lines.\n- The publisher writes one review + one updatable summary, with historical dedupe and best-effort outdated comment minimization.\n\n## Features\n\n- **Multi-provider AI support**: OpenAI, Anthropic, Google, Mistral, and OpenAI-compatible endpoints via AI SDK.\n- **Parallel execution**: batches and dimensions within each round run concurrently, controlled by `max_concurrency` (default 4). Set `max_concurrency=1` for serial execution.\n- Full coverage target over filtered file set, including no-patch/binary files as file-level review entries.\n- Structured schema output validation with one repair retry.\n- Degradation mode: if structured output still fails after repair, posts summary-only with explicit reason.\n- Duplicate suppression for same `head_sha` + same digest.\n- Two-stage historical inline lifecycle control:\n  - Stage 1: dedupe by `path + side + line + issue-key` across runs.\n  - Stage 2: auto-minimize outdated historical inline comments (GraphQL best-effort).\n- Confidence/evidence gating and semantic deduplication to reduce repeated/low-quality findings.\n- Configurable review language via `review_language` (default `English`).\n- Enforces `openai_api_base` safety: HTTPS only, no URL credentials, and hostname allowlist (default `api.openai.com`).\n- Automatically loads project guidance from `AGENTS.md`, `AGENT.md`, or `CLAUDE.md` (priority order) and passes it to review agents.\n- General-first routing: batch review starts with `general`, and only `general` can dynamically request extra dimensions for that batch.\n- Security note: when using `openai_api_base`, only point to trusted HTTPS gateways you control (prefer an allowlist); this endpoint receives review context payloads.\n\n## Usage\n\n```yaml\nname: PR AI Review\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened, ready_for_review]\n\npermissions:\n  contents: read\n  pull-requests: write\n  issues: write\n\njobs:\n  ai-review:\n    runs-on: ubuntu-latest\n    steps:\n      - name: AI Code Review\n        uses: tiylabs/code-review-agent-action@v3\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          ai_provider: openai\n          api_key: ${{ secrets.OPENAI_API_KEY }}\n          api_base: ${{ vars.OPENAI_API_BASE }}\n          api_base_allowlist: |\n            api.openai.com\n            your-gateway.example.com\n          include: |\n            **/*.js\n            **/*.ts\n            **/*.py\n          exclude: |\n            **/*.lock\n            **/dist/**\n            **/*.min.js\n          planner_model: gpt-5.3-codex\n          reviewer_model: gpt-5.3-codex\n          review_dimensions: general,security,performance,testing\n          review_language: English\n          min_finding_confidence: 0.72\n          missing_confidence_policy: na\n          fallback_confidence_value: 0.5\n          coverage_first_round_primary_only: true\n          auto_minimize_outdated_comments: true\n          max_rounds: 8\n          max_concurrency: 4\n          max_model_calls: 128 # example override (default: 40)\n          max_files_per_batch: 8\n          max_context_chars: 256000 # example override (default: 128000)\n          max_findings: 60\n          max_inline_comments: 30\n```\n\n## Inputs\n\n| Name | Required | Default | Description |\n| --- | --- | --- | --- |\n| `github_token` | yes | - | GitHub token with review/comment write permissions |\n| `ai_provider` | no | `openai` | AI provider type: `openai`, `anthropic`, `google`, `mistral`, or `openai-compatible` |\n| `api_key` | no | env `OPENAI_API_KEY` | API key for the selected AI provider |\n| `api_base` | no | env `OPENAI_API_BASE` | Optional base URL for the AI provider API endpoint |\n| `api_base_allowlist` | no | `api.openai.com` | Allowed hostnames for `api_base` (HTTPS only) |\n| `openai_api_key` | no | - | **Deprecated**: use `api_key` |\n| `openai_api_base` | no | - | **Deprecated**: use `api_base` |\n| `openai_api_base_allowlist` | no | - | **Deprecated**: use `api_base_allowlist` |\n| `include` | no | `**` | Include globs (comma/newline separated) |\n| `exclude` | no | empty | Exclude globs (comma/newline separated) |\n| `planner_model` | no | `gpt-5.3-codex` | Planner model |\n| `reviewer_model` | no | `gpt-5.3-codex` | Subagent model |\n| `review_dimensions` | no | `general,security,performance,testing` | Subagent dimensions |\n| `review_language` | no | `English` | Preferred language for review comments and summary |\n| `min_finding_confidence` | no | `0.72` | Keep only findings at or above this confidence (0-1) |\n| `missing_confidence_policy` | no | `na` | Handling for missing/invalid confidence: `drop`, `na`, or `fallback` |\n| `fallback_confidence_value` | no | `0.5` | Fallback confidence used only when `missing_confidence_policy=fallback` |\n| `coverage_first_round_primary_only` | no | `true` | Round 1 runs only primary dimension for faster file coverage |\n| `auto_minimize_outdated_comments` | no | `true` | Best-effort GraphQL minimize for outdated historical inline comments from this action |\n| `max_rounds` | no | `8` | Max planning/review rounds |\n| `max_concurrency` | no | `4` | Max concurrent API calls within a round (batch + dimension parallelism) |\n| `max_model_calls` | no | `40` | Hard cap for model calls |\n| `max_files_per_batch` | no | `8` | Batch size cap |\n| `max_context_chars` | no | `128000` | Per-batch context cap |\n| `max_findings` | no | `60` | Max findings retained after dedupe/sort |\n| `max_inline_comments` | no | `30` | Max inline comments posted |\n\n## Budget Sizing (Rough Estimate)\n\nThis action spends model calls by **rounds × batches × dimensions**. With parallel execution (`max_concurrency \u003e 1`), wall-clock time decreases but total call count stays the same.\n\nApproximation:\n\n```text\ncalls ~= rounds * (1 + batches * dimensions)\nbatches ~= ceil(patch_files / max_files_per_batch)\n```\n\n- `1` is the planner call in each round.\n- `dimensions` is from `review_dimensions` (default: 4).\n- Cost scales more with **changed file count** than changed line count.\n- With `coverage_first_round_primary_only=true` (default), round 1 often costs less than full dimensions.\n\nExamples:\n- If `patch_files=15`, `max_files_per_batch=8`, `dimensions=4`, one round is about `1 + 2*4 = 9` calls.\n- If `patch_files=100`, `max_files_per_batch=8`, `dimensions=4`, one round is about `1 + 13*4 = 53` calls.\n\nPractical guidance:\n- For medium PRs (10-20 files), start with `max_model_calls: 30-50`.\n- For large PRs (~100 files), start with `max_model_calls: 80-120`.\n- If coverage is low, increase `max_model_calls` first, then `max_rounds`.\n- To control cost, reduce `review_dimensions` (for example `general,security`).\n\n## Outputs\n\n| Name | Description |\n| --- | --- |\n| `covered_files` | Number of covered files in filtered target set |\n| `target_files` | Number of files in filtered target set |\n| `uncovered_files` | Number of uncovered files |\n| `degraded` | `true` if summary-only degradation was triggered |\n\n## Confidence Semantics\n\n- Finding `confidence` can be `null` when the model cannot confidently estimate a value.\n- Inline comments show unknown values as `N/A`.\n- `min_finding_confidence` is applied only when confidence is numeric.\n- Use `missing_confidence_policy=fallback` if your downstream expects numeric confidence only.\n- When `missing_confidence_policy` is `drop` or `na`, `fallback_confidence_value` is ignored.\n\n## Fork PR Notes\n\n- For public fork PRs, repository secrets are typically unavailable on `pull_request`.\n- If `OPENAI_API_KEY` is unavailable, this action cannot call the model.\n- If you choose to run on `pull_request_target`, evaluate security risk carefully before using untrusted code context.\n\n## Publishing\n\n1. Push this repository to GitHub.\n2. Tag a release, for example `v1.0.0`.\n3. Consumers reference: `uses: tiylabs/code-review-agent-action@v1`.\n\n## Local Compatibility Check\n\nUse this when validating which structured-output mode a configured model/base URL can successfully follow.\n\n1. Create `.env` from `.env.example` and set:\n   - `OPENAI_API_KEY`\n   - `OPENAI_API_BASE` (optional)\n   - `MODEL` (supports `|` to test multiple models, e.g. `model-a|model-b`)\n   - `COMPATIBILITY_MODES` (optional, `|` or `,` separated; defaults to all explicit modes)\n   - `BUG_PROBE_REQUIRED` (optional, default `false`)\n2. Run:\n\n```bash\nnpm run test:schema-support\n```\n\nThe script performs planner/reviewer checks across the supported compatibility modes and reports which mode succeeded.\nIt also includes a seeded-bug probe (`bug_probe`) to gauge defect detection capability:\n- By default, bug probe is non-blocking (reported as PASS/FAIL).\n- Set `BUG_PROBE_REQUIRED=true` to make bug probe failure exit non-zero.\n\n## Implementation Notes\n\n- Trigger support: this action expects `pull_request` event payload.\n- Inline comments use `path` + `side` + `line`, with fallback to summary-only file-level entries when mapping is invalid.\n- Inline comments include a stable hidden issue key marker for cross-run dedupe and stale-thread minimization.\n- Summary comment update uses marker metadata and deduplicates by `head_sha` + digest.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiylabs%2Fcode-review-agent-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftiylabs%2Fcode-review-agent-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiylabs%2Fcode-review-agent-action/lists"}