8 Commits
Author SHA1 Message Date
Captain e0805839eb fix(action): honor an explicit llm_protocol instead of forcing openai or anthropic (#1192)
The Configure OCR step derived llm.protocol from llm_use_anthropic alone,
so it always wrote openai or anthropic. Anyone on the Responses API was
sent to /v1/chat/completions no matter what OCR_LLM_PROTOCOL they set.

Add an optional llm_protocol input (anthropic, openai, openai-responses).
When it is set, or when OCR_LLM_PROTOCOL is inherited from the job
environment, that value is written and llm.use_anthropic is mirrored
from it, the same way `ocr config set llm.protocol` mirrors the boolean.
An unknown value fails the step with the accepted list. The explicit
protocol joins the checkpoint fingerprint, appended only when set so
existing checkpoints stay valid.

Fixes #1134
2026-09-21 17:42:02 +08:00
chethanuk cb6ea26292 feat(action): opt-in resolution of the bot's own outdated review threads (#567) (#944)
* feat(action): opt-in resolution of the bot's own outdated review threads (#567)

Adds a resolve_outdated input, default off, that resolves review threads
GitHub has already marked outdated. No model is involved in the decision:
the signal is GitHub's server-computed isOutdated, and five vetoes sit on
top of it, each of which can only refuse to resolve a thread.

Three modes: 'false' (no GraphQL calls at all), 'report' (log the verdict
for every thread, mutate nothing), 'true'.

* fix(action): address review on resolve_outdated

- Veto by path instead of disabling the whole run: a finding with a path but
  no line is ordinary output and now costs only its own path, while a finding
  with no path at all still disables the run.
- Normalize paths before the overlap veto, so ./src/a.js and src/a.js no
  longer compare unequal and resolve a thread over a live finding.
- Resolve the authenticated login once per run rather than once per caller.
- Validate resolve_outdated in the Validate inputs step, so a typo fails
  before the LLM runs rather than silently falling back to off.
- Correct the permission documentation from measurement, and show the
  contents: write scope in a job that never checks out the pull request.
- Split the overloaded unverified reason, fix the documented preview count,
  list the missing outputs, and replace the nested ternary with a Map.
2026-09-17 19:28:42 +08:00
Doksanbir 042c382c73 feat(action): add optional pr_number input and workflow_run fallback (#1156)
* feat(action): add optional pr_number input and workflow_run fallback

The pull request number was read from the event payload in two places: the
fetch step's `github.event.pull_request.number || github.event.issue.number`,
and `context.issue.number` in the range and posting steps. Neither resolves on
`workflow_run`, whose payload names the pull request only under
`workflow_run.pull_requests[0]`. The review therefore ran to completion and the
posting step then requested /repos/OWNER/REPO/issues//comments, got a 404, and
the findings were lost.

"Resolve PR refs" now resolves the number once — the new optional `pr_number`
input, then the event payload, then `workflow_run.pull_requests[0].number` —
publishes it as $PR_NUMBER, and fails there when nothing resolves or the value
is not a PR number, before OCR is installed or any LLM quota is spent. The head
fetch, the checkpoint resolver and the posting step all read that one value;
runPostReviewComments takes it as an option and still falls back to
context.issue.number when a caller omits it.

Behavior is unchanged for pull_request, pull_request_target and issue_comment:
an unset input falls through to the existing resolution.

Closes #1150

* style(action): use strict equality for the pr_number override

The review guidelines rule out loose equality, so spell out the null and undefined checks that `!= null` covered.
2026-09-16 16:37:28 +08:00
thxCode 0a74720560 feat(action): first-class review controls (effort, max_tokens_budget, llm_reasoning_effort) and live progress (#1154)
* feat(action): expose effort and max_tokens_budget as inputs

- Add validated, case-insensitive effort and base-10 max_tokens_budget
  workflow inputs, forwarded to ocr review as --effort and
  --max-tokens-budget; empty values omit the flags so CLI defaults apply
- Reject an explicit effort input on ocr older than v1.10.0, where the
  flag first shipped, instead of dying on an unknown flag
- Join both axes to the checkpoint config fingerprint

Closes #1147

Signed-off-by: thxCode <thxcode0824@gmail.com>

* feat(action): opt-in live review progress via stream_progress

- add stream_progress input (true|false, case-insensitive, default
  'false'), validated and normalized in the Validate inputs step
- the default keeps the original behavior: --audience agent in the
  review args, stderr captured to /tmp/ocr-stderr.log with no live tee
- stream_progress=true drops --audience agent so human-audience routing
  sends [ocr] progress lines to stderr while the result JSON stays on
  stdout; a FIFO feeds a background tee so progress streams live into
  the workflow log and is still captured to /tmp/ocr-stderr.log for
  artifacts and the posting step
- the tee runs as a real background job and is awaited before the log
  file is read, so the capture is fully flushed; OCR_EXIT_CODE is
  unaffected in either mode

Task 2 of action-review-controls.

Signed-off-by: thxCode <thxcode0824@gmail.com>

* feat(action): first-class llm_reasoning_effort input

- Merge llm_reasoning_effort into the effective llm.extra_body via node
  in the Configure step, riding the existing extra_body merge so any
  published CLI supports it; an explicit reasoning_effort key in
  llm_extra_body wins
- Reject llm_reasoning_effort on the anthropic protocol, and reject a
  malformed or non-object llm_extra_body with an actionable ::error::
- Fingerprint the normalized effort, max_tokens_budget, and
  llm_reasoning_effort values instead of the raw inputs, so equivalent
  spellings keep the checkpoint
- Keep the last 20000 characters of stderr in the unparseable-result
  summary so streamed progress cannot push the error report past
  GitHub's comment limit
- Document the new action inputs on the CI/CD docs page (en/zh/ja/ko/ru)

Closes #1149

Signed-off-by: thxCode <thxcode0824@gmail.com>

---------

Signed-off-by: thxCode <thxcode0824@gmail.com>
2026-09-07 14:10:56 +08:00
Kite 5f64f842fa fix(agent): scale subtask timeout linearly with effort review rounds (#1085)
* fix(agent): scale subtask timeout linearly with effort review rounds

Previously the timeout applied a flat 1.5x multiplier whenever
ReviewRounds > 1, giving both medium (2 rounds) and high (3 rounds)
the same deadline. Replace this with a linear formula:
timeout = base × ReviewRounds(), producing 10/20/30 min defaults
for low/medium/high effort respectively.

* chore: bump default --timeout from 10 to 15 minutes

The base unit of 10 min was too tight for real-world reviews.
Raising it to 15 min gives linear scaling of 15/30/45 min
for low/medium/high effort respectively.

Update CLI flags, action.yml, docs, and skill files.

* test: update action-contract assertions for 15-min default timeout
2026-08-27 20:55:29 +08:00
chethanuk c0f277589f feat(action): opt-in completeness-gated checkpoint ranges (#476) (#945)
On every push the reusable Action re-reviews the whole merge-base range, so
later pushes on a large PR cost the same as the first one. This adds an opt-in
`checkpoint_range` input that records the last completely reviewed head in the
sticky summary and narrows the next run to checkpoint..head.

Every gate fails closed to a full review: force-push, base change, config or
rule change, incomplete prior run, or any resolver error.

The config fingerprint hashes one environment variable per axis instead of a
single "|"-joined string. The joined form let a value containing the separator
shift the field boundaries, so `route_severity_below=low|a` with an empty
`route_categories` hashed identically to `low` with `route_categories=a|` —
a checkpoint surviving a config change that should have invalidated it. It also
made the digest depend on how the YAML happened to be wrapped.

`llm_extra_headers`, `llm_auth_header` and `llm_timeout` are axes too: extra
headers can point the same `llm_model` string at a different backend model or
provider, and a timeout change shifts which runs finish. Header values can be
credentials, so that axis goes in as a digest rather than raw.

The author check is pinned to `github-actions` when `github_token` is the
default one, which always belongs to that app. Unpinned, `dependabot[bot]`,
`renovate[bot]` and any linter App all read as ours. A caller-supplied token
keeps the wider bot check, since an installation token cannot ask GitHub which
app it is.

A version `ocr version` does not print yields an empty fingerprint rather than
a `spec:` fallback: `ocr_version` defaults to "latest", so the spec is a
constant that distinguishes nothing. Empty matches no stored fingerprint and
blocks the checkpoint write — don't narrow, don't advance.
2026-08-27 10:17:26 +08:00
Kite 76cd6d35fe ci(workflows): run the contract suite in a dedicated workflow (#1058)
The contract suite asserts examples/github_actions/README.md's documented
defaults, so a README change has to be able to trigger it. Expressing that
inside ci.yml meant inverting paths-ignore into a three-stage paths filter,
which also pulled the whole matrix — Go race tests, native Windows,
cross-compile — on a markdown-only change.

Move the job into its own workflow with a narrow positive paths filter and
restore ci.yml's original paths-ignore. The job keeps the self-hosted runner
and the node:24 container it was given in review, so the queueing behaviour
does not change.

The workflow assertions in action-contract.test.js now read the new file;
their regexes are unchanged. Since that file holds a single job, the
checkout SHA-pin and container-image assertions become structurally precise
instead of incidentally so: previously they searched all of ci.yml, so a
floating tag on this job could still pass as long as some pinned action
existed elsewhere in the file.
2026-08-25 19:28:23 +08:00
Jim TurnerandKite 5679f44a07 fix(action): forward review timeout and complete LLM config (#1051)
* fix(action): forward review timeout and LLM config

* fix(action): normalize validated review timeout

* fix(action): harden timeout configuration contract

* fix: Apply suggestions from code review

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>

* feat: Apply suggestions from code review

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>

---------

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>
2026-08-25 18:51:41 +08:00