misospace/Miso PR Review

Review pull requests with OpenAI- or Anthropic-compatible models and post an optional sticky comment.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jul 9, 2026
License
MIT

Pinned Snippet

workflow.ymlSHA-pinned
uses: misospace/pr-reviewer-action@a177c3478b52a6f8402ebbe9a0ba59c61cf028ed # v2.1.2

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
github_tokenGitHub token for PR and API accessyes
repoRepository in owner/name format. Defaults to the current workflow repository.no""
pr_numberPull request number. Defaults to the current pull_request event number.no""
ai_base_urlBase URL of the primary AI APIyes
ai_api_formatAPI request/response format for the primary AI endpoint (openai or anthropic)noopenai
ai_modelModel name for the primary analysis passyes
ai_api_keyOptional API key for the primary AI endpointno""
ai_max_tokensMaximum completion tokens for the primary and fallback final review calls. Default 8192. Reasoning models that emit a thinking channel need this headroom — too low a cap is consumed by reasoning, leaving empty content with finish_reason=length, so the verdict JSON fails to parse and the review needlessly escalates or fails. Raise further (e.g. 16000) for verbose reasoning models.no8192
ai_temperatureSampling temperature for the review model. Default "0.1". Set to an empty string to omit the field entirely (some newer cloud models reject any non-default temperature).no0.1
ai_response_formatStructured-output mode for OpenAI-compatible endpoints (including LiteLLM): off (default), json_object, or json_schema (enforces a verdict/review_markdown schema). Ignored for the anthropic format. Improves output reliability with smaller local models. Applies to both the primary and fallback review calls.nooff
ai_tokens_paramToken-limit field name for OpenAI-compatible requests: max_tokens (default) or max_completion_tokens (required by newer OpenAI reasoning models). Ignored for anthropic.nomax_tokens
anthropic_versionAnthropic API version header used when ai_api_format or ai_fallback_api_format is anthropicno2023-06-01
ai_fallback_base_urlOptional base URL of a fallback AI APIno""
ai_fallback_api_formatFallback API request/response format; defaults to ai_api_format when blankno""
ai_fallback_modelOptional model name for the fallback analysis passno""
ai_fallback_api_keyOptional API key for the fallback endpointno""
ai_primary_retriesNumber of retries for the primary modelno8
ai_primary_retry_delay_secDelay between primary retries in secondsno15
on_model_failureBehavior when both primary and fallback models fail to return a usable review. 'fail' (default) fails the action step. 'notice' instead posts a visible request_changes notice explaining the review could not run (never auto-approves), so reviewers see an explanation instead of only a red check.nofail
verdict_policyHow the final verdict is decided. 'model' (default) uses the model's own verdict. 'findings_severity_gated' preserves request_changes from the model and escalates approve to request_changes when any blocker-severity finding exists. Non-blocker findings never weaken a model rejection. Enforcement settings (evidence blockers, tool failure) still apply afterwards and can force request_changes.nomodel
inline_findingsIf true, structured findings that anchor to a line in the PR diff are attached as native line-anchored review comments when publishing with publish_mode=review_comment or review_verdict. Findings that cannot be anchored stay in the review body only. Default false — no inline comments. Ignored for publish_mode=comment.nofalse
inline_findings_maxMaximum inline review comments attached per review when inline_findings=true.no20
validate_required_checksWhether to validate the final review against the classifier's must_check items. 'auto' (default) validates whenever must_check is non-empty; 'true' and 'false' force it on or off. Validation is deterministic keyword matching — it catches reviews that never discussed a required check, not incorrect discussion.noauto
required_check_validation_modeWhat to do when required checks are unaddressed. 'warn' (default) appends an 'Unaddressed required checks' section to the published review. 'fail' also forces a request_changes verdict. 'metadata_only' records the result (required_checks output and metadata marker) without changing the published review.nowarn
review_routing_modeRoute PR reviews between the primary and smart models based on the deterministic classification. 'off' (default) preserves existing primary/fallback behavior. 'auto' sends PRs whose pr_kind or risk_flags match escalate_on_risk_flags to the smart model (when one is configured) and keeps everything else on the primary model.nooff
ai_primary_modelModel for the primary review route when review_routing_mode=auto. Defaults to ai_model.no""
ai_primary_base_urlBase URL for the primary route model. Defaults to ai_base_url.no""
ai_primary_api_formatAPI format for the primary route model (openai or anthropic). Defaults to ai_api_format.no""
ai_primary_api_keyAPI key for the primary route model. Defaults to ai_api_key.no""
ai_smart_modelOpt-in smarter model for high-risk reviews (review_routing_mode=auto). With no smart model set, auto-routing stays on the primary model and never escalates. The fallback model is NEVER an escalation target — it only catches a primary-availability failure.no""
ai_smart_base_urlBase URL for the smart model. Defaults to ai_base_url.no""
ai_smart_api_formatAPI format for the smart model (openai or anthropic). Defaults to ai_api_format.no""
ai_smart_api_keyAPI key for the smart model. Defaults to ai_api_key.no""
escalate_on_risk_flagsComma-separated pr_kind / risk_flag names that route directly to the smart model when review_routing_mode=auto. Matched against route_signals — linked-issue flags and file-based signals backed by an actual changed filename — so a benign PR whose diff merely mentions a pattern (e.g. os.path) does not route.nolinked_security_issue,linked_priority_p0,linked_priority_p1,auth_changes,public_route_changes,file_serving_changes,path_handling_changes,secret_handling_changes,db_or_migration_changes
escalate_on_incomplete_required_checksEscalate a primary-route review to the smart model when required checks are unaddressed (review_routing_mode=auto only).notrue
escalate_on_fast_request_changesEscalate a primary-route review to the smart model when its verdict is request_changes (review_routing_mode=auto only).notrue
escalate_on_fast_low_confidenceEscalate when the primary-route review is low-confidence — a stub review (below ~80 chars) or one carrying a populated Unknowns/Needs Verification section. A concise, confident review is NOT escalated regardless of diff size. review_routing_mode=auto only.notrue
escalate_on_tool_or_evidence_blockersEscalate when evidence providers report blocker severity or every executed tool request failed (review_routing_mode=auto only).notrue
escalate_on_tool_planning_failureEscalate when the tool harness planning call failed (review_routing_mode=auto only). Off by default: a planning failure means the review ran with less evidence — the same situation as tool_mode 'off' — not that the PR is risky. The failure is still recorded in tool-harness.json and the step summary.nofalse
escalate_on_dirty_baselineEscalate incremental reviews whose baseline review found issues (review_routing_mode=auto only). Judging whether a delta resolves a previously-found blocker is exactly the judgment worth running on the smart model.notrue
ai_streamIf true, use streaming responses to avoid timeouts behind proxies with short read timeouts (e.g. Cloudflare 100s edge timer)notrue
ai_fallback_streamIf set, overrides ai_stream for the fallback model; defaults to ai_stream value when blankno""
allowed_source_hostsComma-separated list of hosts allowed for linked source fetchingnogithub.com,api.github.com,gitlab.com,registry.terraform.io,artifacthub.io
system_promptOptional system prompt overrideno""
system_prompt_fileOptional file path in the reviewed repository to use as the full system promptno""
system_prompt_modeHow a supplied system_prompt / system_prompt_file combines with the bundled default. 'replace' (default) uses the supplied prompt verbatim. 'append' keeps the conditionally-assembled bundled default and appends the supplied prompt as a repo-specific addendum — so consumers add conventions without copying (and re-syncing) the whole default.noreplace
standards_fileRepository standards file path for conventions and policy contextno""
standards_file_candidatesCandidate files to auto-discover when standards_file is not set. First found is used.noAGENTS.md,agents.md,CLAUDE.md,claude.md,.github/ai-review-rules.md,.github/ai-review-rules.txt
publish_review_commentIf true, publish or update a PR comment with the generated reviewnofalse
publish_modePublish mode for the review verdict. 'comment' publishes a sticky PR comment (default). 'review_comment' uses GitHub's native PR review API to submit a non-blocking review comment. 'review_verdict' uses GitHub's native PR review API to submit approve/request_changes. Requires permissions: pull-requests: write for review_comment and review_verdict modes.nocomment
allow_approveIf true and publish_mode=review_verdict, the model's approve verdict can be submitted as a native approval. Defaults to false — approval is blocked unless explicitly enabled. WARNING: native approvals can affect branch protection rules and automerge pipelines.nofalse
approve_forksIf true and publish_mode=review_verdict with allow_approve=true, native approvals are also allowed for cross-repository (fork) PRs. Defaults to false — fork PRs are blocked from approval even when allow_approve is set.nofalse
cleanup_previous_native_reviewsMark previous managed native PR reviews as outdated/superseded before publishing a new native review. Accepted values: `auto` (default, enables cleanup for review_comment and review_verdict modes), `true`, or `false`. Cleanup only targets reviews created by this action and carrying the managed marker. Dismissal of old approval/request-changes reviews is attempted when permissions allow but is secondary to visual cleanup.noauto
context_limit_modeContext budget mode - normal (140k/70k/220k), low (80k/40k/120k), minimal (40k/20k/60k)nonormal
model_context_tokensThe model's real context window in tokens (e.g. 8192, 32768). When set, corpus/diff/file byte budgets are derived from it (reserving ai_max_tokens for output) instead of context_limit_mode — recommended for local models whose windows are smaller than the named modes assume. Empty uses context_limit_mode.no""
enrichment_budget_secMaximum seconds to spend on enrichment (linked source fetching, release metadata, ghcr.io lookups). Exceeding the budget stops further enrichment. Default 60.no60
image_digest_budget_secMaximum seconds to spend on image digest provenance lookups (registry tokens, manifests, revision compares). 0 disables the budget. Default 60.no60
evidence_providers_fileOptional JSON file in the reviewed repository that defines evidence providers to run before reviewno""
evidence_provider_timeout_secDefault timeout in seconds for each evidence provider commandno30
evidence_provider_max_output_bytesMaximum stdout or stderr bytes captured per evidence provider commandno20000
evidence_provider_parallelismMaximum evidence provider commands run concurrently. Set 1 to force serial execution when providers contend on shared files. Default 4.no4
evidence_blocker_enforcementIf true, force request_changes when any evidence provider reports blocker severitynofalse
evidence_enable_for_forksIf true, allow evidence providers to run on cross-repository pull requestsnofalse
tool_modeOptional tool harness mode: "off" (no evidence tools) or "native_loop". With native_loop the model uses its native tool-calling API — it holds the tool schemas and decides each next read-only call from the previous result, enabling multi-hop evidence chains. A model that never emits a tool call degrades to a corpus-only review (the verdict is still produced). Loop turns stream by default (controlled by ai_stream) so long turns don't time out behind a short-idle proxy; a stream that can't be reassembled is retried non-streamed for that turn. Budgets: tool_max_requests, tool_max_rounds, and tool_loop_wall_clock_sec. (The legacy plan_execute_once / plan_execute_loop planner modes were removed in 2.0; a stale value is treated as "off".)nooff
tool_loop_wall_clock_secWall-clock ceiling in seconds for the whole tool_mode=native_loop exchange (all model round-trips plus tool execution). Ignored for other modes.no120
tool_loop_summarizeWhen "true", tool_mode=native_loop folds the oldest tool results into a model-generated evidence digest once the conversation outgrows its context budget, instead of blunt-truncating them — preserving salient facts (versions, paths, URLs, findings) in fewer tokens at the cost of one extra model call per compaction. Off by default (truncation). Ignored for other modes.nofalse
tool_loop_summarize_max_tokensMaximum completion tokens for each result-summarization call when tool_loop_summarize is enabled. Keep it small — the digest should be terse.no512
tool_evidence_memoryCarry the evidence a tool_mode=native_loop review gathers across incremental reviews of the same PR. The review stores a compact digest of what it read/fetched in its metadata marker; the next incremental review reuses it (re-verifying only what the delta touched) instead of re-gathering from scratch. On by default; set "false" to disable. No effect on full reviews or non-native modes.notrue
tool_max_requestsMaximum number of tool requests the harness executes when tool_mode is enabledno4
tool_max_roundsRound budget for tool_mode=native_loop, where a round is a single model turn: the loop allows up to twice this value (capped at 8) to leave room for one-call-per-turn chains and repair turns. Ignored when tool_mode=off.no3
tool_planning_timeout_secTimeout in seconds for the model planning call used by tool harness. Set generously for local models with slow prompt eval; native_loop streams turns by default (ai_stream) to avoid short-idle-proxy timeouts.no60
tool_planning_max_context_bytesMaximum corpus bytes passed to the planning modelno50000
tool_planning_max_tokensMaximum completion tokens for tool harness planning model callno400
tool_max_response_bytesMaximum bytes captured from each tool execution resultno12000
tool_allowed_gh_api_reposComma-separated owner/repo list allowed for gh_api tool requests; use * to allow any repo still permitted by the path allowlist (empty means current repo only)no""
tool_request_timeout_secTimeout in seconds for each tool request executionno20
search_urlSearch-engine endpoint (e.g. a SearXNG instance's /search URL) that enables the read-only web_search tool in the native tool loop. When set, the model can search for a page (release notes, a support/compatibility matrix) and then web_fetch the best result — useful when it doesn't know the exact URL. Empty (default) leaves web_search un-advertised. The model supplies only the query; the host is fixed by this setting. Subject to the same fork gating as the rest of the tool harness.no""
tool_max_search_resultsMaximum results returned per web_search callno5
tool_failure_enforcementIf true, force request_changes when tool harness planning failsnofalse
tool_min_successful_requestsMinimum number of successful tool requests required when tool failure enforcement is enabledno0
tool_enable_for_forksIf true, allow the tool harness to run on cross-repository pull requestsnofalse
tool_mcp_serversOptional allowlist of read-only MCP servers for tool_mode=native_loop, as a newline/comma list of name=url (e.g. konflate=https://konflate.example/mcp). Their read-verb tools (list/get/read/…) are advertised as mcp__<name>__<tool> (double underscores); write-verb tools are refused. Empty = off (default). Fork-gated like the rest of the harness (tool_enable_for_forks). Only host-bearing http(s) URLs are accepted (HTTPS recommended); other schemes are dropped.no""
tool_mcp_tokenOptional bearer token sent to every configured MCP server (tool_mcp_servers)no""
tool_mcp_name_prefixesComma-separated list of tool name prefixes to strip before the read-only verb check (e.g. toolhive workload prefixes from `prefixFormat: "{workload}_"`). Empty preserves the default-deny boundary.no""
ai_request_timeout_secTimeout in seconds for the primary model API request (curl --max-time)no300
ai_connect_timeout_secTimeout in seconds for the primary model API connection (curl --connect-timeout)no30
ai_fallback_request_timeout_secTimeout in seconds for the fallback model API request (curl --max-time). Defaults to ai_request_timeout_sec when blank.no""
ai_fallback_connect_timeout_secTimeout in seconds for the fallback model API connection (curl --connect-timeout). Defaults to ai_connect_timeout_sec when blank.no""
platformTarget hosting platform for API capability gating and backend selection. 'auto' (default) detects from GITHUB_SERVER_URL and FORGEJO_API_URL: non-github.com hosts or FORGEJO_API_URL set resolves to 'forgejo'; otherwise 'github'. Set 'forgejo' or 'github' explicitly to override auto-detection. On Forgejo, features requiring GitHub GraphQL (thread resolution, review minimization) degrade gracefully with a log line; the REST backend handles core PR operations. Linked-source enrichment always targets github.com regardless of this setting.noauto
forgejo_api_urlBase URL for the Forgejo instance API backend (for example, https://forgejo.example.com). Optional on Forgejo Actions runners when GITHUB_SERVER_URL is set; set it when running from GitHub Actions or any runner that does not export the Forgejo server URL.no""
forgejo_tokenOptional Forgejo API token. Defaults to github_token when blank. Use this when the token used for GitHub-compatible operations is not also valid for the Forgejo REST API.no""
skip_if_diff_unchangedIf true, skip the LLM review when the effective PR diff matches the last managed review comment fingerprintnotrue
force_reviewIf true, bypass the diff-unchanged guard and run a full PR review, even when the fingerprint matches the last managed review. Set automatically when the rereview_label is added; callers can also pass it from a workflow_dispatch or repository_dispatch. Default false.nofalse
rereview_labelLabel that, when added to a PR, forces a fresh review even if nothing changed — the easy re-review trigger (only users with write/triage can label, so it is self-authorizing). On a `labeled` event the action reviews iff the added label matches this, then removes the label so re-adding re-triggers; any other label add is ignored. To enable, add `labeled` to the workflow's pull_request types. Default "ai-review".noai-review
comment_markerHTML marker for the managed PR commentno<!-- ai-pr-reviewer -->
ci_status_checkIf true, wait for all CI checks to reach a terminal state before starting the AI review, then fold the per-check outcomes into the review corpus as evidence (so the model cites real test/lint results instead of "not verifiable"). Polls the Checks API for the PR head SHA. Default false — immediate review (original behavior).nofalse
ci_timeout_secMaximum seconds to wait for CI checks to complete when ci_status_check=true. Default 300.no300
ci_interval_secSeconds between CI status polls when ci_status_check=true. Default 15.no15
ci_skip_on_timeoutIf true, proceed with review after timeout instead of failing. If false, abort the action on timeout. Default true.notrue
review_scopeControls whether the action reviews the full PR or only changes since the last managed review. auto performs a full review first, then incremental reviews on later PR synchronize events when safe. Accepted values: auto, full, incremental.noauto
namedescription
verdictAI verdict, approve or request_changes
verdict_sourceWhere the final verdict came from ('model' or 'findings' per verdict_policy, or 'carry_forward' when a carried-forward blocker survived an incremental review)
required_checksRequired-check validation status ('complete', 'incomplete', or 'none' when validation did not run)
review_routeModel route used for this review ('legacy', 'primary', 'smart', or 'escalated')
escalation_reasonComma-separated escalation trigger names when review_route is 'escalated' (empty otherwise)
findingsNormalized structured findings as a JSON array (empty array when the model produced none)
review_markdownHuman-readable markdown review body
analysis_engineModel and endpoint that produced the final result
should_reviewWhether the action determined a new LLM review is needed
skip_reasonReason the LLM review was skipped
diff_fingerprintStable fingerprint of the current pull request patch
ci_status_skippedWhether CI status check was skipped (true) or completed (false)
ci_status_finalFinal CI state (success/failure) when ci_status_check completed
effective_review_scopeEffective review scope used (full or incremental)
previous_head_shaPrevious head SHA when effective scope is incremental
baseline_cleanWhether the full-review baseline was clean (for verdict safety)
cache_hit_ratioPrompt-cache hit ratio for this review (0.0-1.0, from the tool harness in native_loop mode; empty when unavailable)