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
34 changes: 27 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@

## Project Structure & Module Organization
- `src/`: core action runtime.
- `index.js`: orchestration entrypoint (PR file loading, planner/sub-agent loop, publish).
- `agents.js`: OpenAI Agents setup and structured-output execution.
- `diff-map.js`, `aggregate.js`, `globs.js`, `publish.js`, `config.js`: focused utility modules.
- `test/`: Node built-in test suite (`*.test.js`) for diff mapping, aggregation, globs, and publish helpers.
- `index.js`: orchestration entrypoint (PR file loading, planner/sub-agent parallel loop, publish).
- `agents.js`: planner and reviewer agent setup with structured-output schemas.
- `model-runtime.js`: AI SDK structured-output execution with repair retry.
- `provider.js`: multi-provider factory (OpenAI, Anthropic, Google, Mistral, OpenAI-compatible).
- `config.js`: action input parsing, validation, and defaults.
- `diff-map.js`: diff hunk parsing and inline comment line resolution.
- `aggregate.js`: finding normalization, deduplication, and sorting.
- `globs.js`: include/exclude glob filtering.
- `publish.js`: PR review and summary comment publishing with marker-based dedup.
- `inline-key.js`: stable inline comment key generation for cross-run dedup.
- `public-error.js`: error message sanitization for public-facing outputs.
- `repo-guidance.js`: project guidance loader (AGENTS.md / AGENT.md / CLAUDE.md).
- `test/`: Node built-in test suite (`*.test.js`) for all modules above.
- `.github/workflows/`: CI and self-test workflows.
- `examples/`: non-executed example workflow templates for consumers.
- `action.yml`: public action contract (inputs/outputs/defaults).
Expand All @@ -14,6 +23,7 @@
- `npm ci`: install locked dependencies exactly (same as CI).
- `npm run check`: syntax check for `src/index.js`.
- `npm test`: run all unit tests via `node --test`.
- `npm run test:schema-support`: run local compatibility check script.
- `npm start`: run action entrypoint locally (requires GitHub Actions env context to be meaningful).

Use Node `22` (see CI and `package.json` engines).
Expand All @@ -27,13 +37,22 @@ Use Node `22` (see CI and `package.json` engines).
- constants: `UPPER_SNAKE_CASE`.
- Keep modules small and single-purpose; add brief comments only when logic is non-obvious.

## Architecture Notes
- Multi-provider support via AI SDK: OpenAI, Anthropic, Google, Mistral, and OpenAI-compatible endpoints.
- Parallel execution within each round: batches run concurrently via `Promise.allSettled` with a shared semaphore (`max_concurrency`); within each batch, `general` dimension runs first, then remaining dimensions run in parallel.
- Round-level execution remains serial (each round depends on updated `coverageState`).
- Budget pre-allocation with 2x multiplier to account for structured-output repair retries.

## Testing Guidelines
- Framework: Node built-in `node:test` + `node:assert/strict`.
- Test files: `test/<module>.test.js`.
- Add/extend tests whenever changing:
- diff line resolution (`LEFT`/`RIGHT`),
- finding normalization/deduplication/sorting,
- publish/update marker behavior.
- publish/update marker behavior,
- config parsing or validation,
- provider creation or model instantiation,
- concurrency control (semaphore) behavior.
- Run locally before PR: `npm run check && npm test`.

## Commit & Pull Request Guidelines
Expand All @@ -48,6 +67,7 @@ Use Node `22` (see CI and `package.json` engines).
- any behavior changes for fork PR/security/token handling.

## Security & Configuration Tips
- Required secrets/permissions for real runs: `OPENAI_API_KEY`, `pull-requests: write`, `issues: write`.
- Required secrets/permissions for real runs: `api_key` (or provider-specific env), `pull-requests: write`, `issues: write`.
- `GITHUB_TOKEN` is runtime-injected by Actions; do not hardcode tokens.
- Keep `OPENAI_API_BASE` optional and compatibility-safe.
- Keep `api_base` optional and enforce HTTPS-only with hostname allowlist.
- Legacy `OPENAI_API_KEY` / `OPENAI_API_BASE` env vars are still supported as fallbacks.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

[![Build and Test](https://github.com/TiyAgents/code-review-agent-action/actions/workflows/self-test-current-branch.yml/badge.svg)](https://github.com/TiyAgents/code-review-agent-action/actions/workflows/self-test-current-branch.yml)

Reusable GitHub Action for automated Pull Request code review using an OpenAI-compatible structured runtime.
Reusable 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/).

This action:
- Runs on `pull_request` events.
- Reviews all changed files that match `include`/`exclude` filters.
- Uses planner + subagents (general/security/performance/testing) in multi-round batches for large diffs.
- Uses planner + subagents (general/security/performance/testing) in multi-round batches for large diffs, with **parallel batch and dimension execution** within each round.
- Publishes:
- one PR Review (`pulls.createReview`) with inline comments (`LEFT`/`RIGHT`), and
- one updatable summary issue comment (marker-based, no spam).
Expand All @@ -20,11 +20,14 @@ This action:
Simple flow explanation:
- `Planner` decides each round's batches under `max_rounds`, `max_model_calls`, and `max_files_per_batch`.
- `SubAgent(general)` always runs first for each batch, and can dynamically request extra dimensions (`security/performance/testing`).
- Within each round, batches execute in parallel (controlled by `max_concurrency`); within each batch, remaining dimensions run in parallel after `general` completes.
- All sub-agent outputs are aggregated, normalized, deduplicated, then mapped to inline-commentable diff lines.
- The publisher writes one review + one updatable summary, with historical dedupe and best-effort outdated comment minimization.

## Features

- **Multi-provider AI support**: OpenAI, Anthropic, Google, Mistral, and OpenAI-compatible endpoints via AI SDK.
- **Parallel execution**: batches and dimensions within each round run concurrently, controlled by `max_concurrency` (default 4). Set `max_concurrency=1` for serial execution.
- Full coverage target over filtered file set, including no-patch/binary files as file-level review entries.
- Structured schema output validation with one repair retry.
- Degradation mode: if structured output still fails after repair, posts summary-only with explicit reason.
Expand All @@ -34,8 +37,6 @@ Simple flow explanation:
- Stage 2: auto-minimize outdated historical inline comments (GraphQL best-effort).
- Confidence/evidence gating and semantic deduplication to reduce repeated/low-quality findings.
- Configurable review language via `review_language` (default `English`).
- Supports custom OpenAI base URL via `OPENAI_API_BASE` or `openai_api_base` input.
- Automatically falls back across `responses_json_schema`, `chat_json_schema`, `chat_json_object`, and prompt-only JSON modes for broader third-party compatibility.
- Enforces `openai_api_base` safety: HTTPS only, no URL credentials, and hostname allowlist (default `api.openai.com`).
- Automatically loads project guidance from `AGENTS.md`, `AGENT.md`, or `CLAUDE.md` (priority order) and passes it to review agents.
- General-first routing: batch review starts with `general`, and only `general` can dynamically request extra dimensions for that batch.
Expand Down Expand Up @@ -87,6 +88,7 @@ jobs:
coverage_first_round_primary_only: true
auto_minimize_outdated_comments: true
max_rounds: 8
max_concurrency: 4
max_model_calls: 128 # example override (default: 40)
max_files_per_batch: 8
max_context_chars: 256000 # example override (default: 128000)
Expand All @@ -110,7 +112,6 @@ jobs:
| `exclude` | no | empty | Exclude globs (comma/newline separated) |
| `planner_model` | no | `gpt-5.3-codex` | Planner model |
| `reviewer_model` | no | `gpt-5.3-codex` | Subagent model |
| `llm_compatibility_mode` | no | `auto` | **Deprecated**: AI SDK handles compatibility automatically |
| `review_dimensions` | no | `general,security,performance,testing` | Subagent dimensions |
| `review_language` | no | `English` | Preferred language for review comments and summary |
| `min_finding_confidence` | no | `0.72` | Keep only findings at or above this confidence (0-1) |
Expand All @@ -119,6 +120,7 @@ jobs:
| `coverage_first_round_primary_only` | no | `true` | Round 1 runs only primary dimension for faster file coverage |
| `auto_minimize_outdated_comments` | no | `true` | Best-effort GraphQL minimize for outdated historical inline comments from this action |
| `max_rounds` | no | `8` | Max planning/review rounds |
| `max_concurrency` | no | `4` | Max concurrent API calls within a round (batch + dimension parallelism) |
| `max_model_calls` | no | `40` | Hard cap for model calls |
| `max_files_per_batch` | no | `8` | Batch size cap |
| `max_context_chars` | no | `128000` | Per-batch context cap |
Expand All @@ -127,7 +129,7 @@ jobs:

## Budget Sizing (Rough Estimate)

This action spends model calls by **rounds × batches × dimensions**.
This action spends model calls by **rounds × batches × dimensions**. With parallel execution (`max_concurrency > 1`), wall-clock time decreases but total call count stays the same.

Approximation:

Expand Down Expand Up @@ -200,7 +202,6 @@ The script performs planner/reviewer checks across the supported compatibility m
It also includes a seeded-bug probe (`bug_probe`) to gauge defect detection capability:
- By default, bug probe is non-blocking (reported as PASS/FAIL).
- Set `BUG_PROBE_REQUIRED=true` to make bug probe failure exit non-zero.
- For third-party providers, use the reported recommended mode as the safest explicit `llm_compatibility_mode` override.

## Implementation Notes

Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ inputs:
description: Auto-minimize outdated historical inline comments posted by this action.
required: false
default: "true"
max_concurrency:
description: Maximum concurrent API calls within a single round (controls batch and dimension parallelism).
required: false
default: "4"
max_rounds:
description: Maximum planning/review rounds.
required: false
Expand Down
1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ function loadConfig() {
coverageFirstRoundPrimaryOnly: parseBooleanInput('coverage_first_round_primary_only', true),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自动审查已完成;聚合后没有可稳定定位的具体 inline 问题。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自动审查已完成;聚合后没有可稳定定位的具体 inline 问题。

autoMinimizeOutdatedComments: parseBooleanInput('auto_minimize_outdated_comments', true),
maxRounds: parsePositiveIntInput('max_rounds', 8),
maxConcurrency: parsePositiveIntInput('max_concurrency', 4),

This comment was marked as outdated.

maxModelCalls: parsePositiveIntInput('max_model_calls', 40),
maxFilesPerBatch: parsePositiveIntInput('max_files_per_batch', 8),
maxContextChars: parsePositiveIntInput('max_context_chars', 128000),
Expand Down
Loading
Loading