feat(action): first-class review controls (effort, max_tokens_budget, llm_reasoning_effort) and live progress - #1154
Conversation
|
🔍 OpenCodeReview found 4 issue(s) in this PR.
|
2ad0609 to
5a7923f
Compare
|
@lizhengfeng101 , PTAL. If duplicated in the implementation or not in the milestone, it should be good to close. Thanks. |
wu21-web
left a comment
There was a problem hiding this comment.
I appreciate your work. This can solve some important issues.
|
@thxCode Can you update the documentation, currently deployed at https://open-codereview.ai/docs/cicd |
|
@wu21-web Done — added an "Action inputs" section to the CI/CD docs page ( |
|
Four things to fix before this lands. 1. 2. 3. The node merge assumes the parsed body is an object. if (body === null || typeof body !== "object" || Array.isArray(body)) {
console.error("::error::llm_extra_body must be a JSON object");
process.exit(1);
}4. Non-blocking, but worth a look: the fingerprint reads |
|
Thanks — all four addressed in ca54207:
Each is locked in by a contract test. On the fingerprint notes: agreed they belong with #1157 — keeping this PR to the input plumbing. |
lizhengfeng101
left a comment
There was a problem hiding this comment.
Two things on this — the rest looks solid, and I checked the version floors (--effort first lands in v1.10.0, the stderr-progress commit in v1.9.8, --max-tokens-budget predates v1.9.6), those are all correct.
stream_progress: 'true' can silently eat the error banner
post-review-comments.js:227 dumps the whole stderr file into the summary comment when ocr-result.json fails to parse, and fencedBlock (:1802) doesn't truncate. That path was safe before, because --audience agent kept stderr down to actual error text. With the human audience it's the full progress stream, so on a decent-sized PR the body blows past GitHub's 65536-char comment limit, the post 422s, and you lose the error report — at exactly the moment you needed it.
Keeping the tail is enough (the thing that killed the run is the last thing written):
const MAX_COMMENT_STDERR_CHARS = 20000;
function tailForComment(text, limit = MAX_COMMENT_STDERR_CHARS) {
const s = String(text || "");
if (s.length <= limit) return s;
return `[... ${s.length - limit} earlier characters truncated; see the ocr-stderr.log artifact ...]\n${s.slice(-limit)}`;
}- const stderr = safeRead(fs, stderrPath).trim();
+ const stderr = tailForComment(safeRead(fs, stderrPath).trim());Strictly this is a pre-existing bug in a file you didn't touch, so a follow-up issue is fair — but it's ~10 lines and this PR is what makes it reachable, so I'd rather see it here. A test asserting the tail survives (not the head) would be worth adding.
Fingerprint uses the raw inputs instead of the normalized ones
OCR_FP_EFFORT / OCR_FP_MAX_TOKENS_BUDGET / OCR_FP_LLM_REASONING_EFFORT read inputs.*, but Validate inputs already normalized all three into $GITHUB_ENV. So effort: HIGH vs high, or max_tokens_budget: '0' vs '' vs '00', hash differently despite meaning the same thing — the checkpoint gets thrown away and the whole PR is re-reviewed. Slightly ironic for the token-budget feature.
- OCR_FP_EFFORT: ${{ inputs.effort }}
- OCR_FP_MAX_TOKENS_BUDGET: ${{ inputs.max_tokens_budget }}
+ OCR_FP_EFFORT: ${{ env.EFFORT }}
+ OCR_FP_MAX_TOKENS_BUDGET: ${{ env.MAX_TOKENS_BUDGET }}Same for OCR_FP_LLM_REASONING_EFFORT. OCR_HEAD_SHA: ${{ env.HEAD_SHA }} a few lines up already does exactly this, and Validate inputs has no if: and runs before this step, so the ordering is fine. Happy for this one to be a follow-up if you'd rather keep the PR tight.
(One leftover either way: an inline reasoning_effort in llm_extra_body plus an empty llm_reasoning_effort produces the same effective body as the reverse, but two fingerprints. Could collapse both axes onto the merged EFFECTIVE_EXTRA_BODY since Configure runs first — probably not worth it now.)
Also worth a line in the release notes that the three new fingerprint axes invalidate every existing checkpoint once on upgrade.
ca54207 to
08a6c27
Compare
|
Both addressed in 08a6c27 (branch rebased onto main @ 7f8fa44):
Left the merged-extra_body axis collapse out as you suggested — not worth it now. On the release note: the PR body's release-note block mentions the one-time checkpoint invalidation from the new fingerprint axes. |
- 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>
- 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>
- 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>
08a6c27 to
142d088
Compare
Description
This PR makes the review action tunable from workflow inputs, in three commits:
effort/max_tokens_budgetinputs (closes feat(action): expose --effort and --max-tokens-budget as action inputs #1147) — validated and normalized in the Validate inputs step, appended as--effort/--max-tokens-budgetto the review command; both join the checkpoint config fingerprint.stream_progress(closes feat(action): stream review progress to the workflow log instead of a long silent step #1148) — default behavior is unchanged (--audience agent, stderr captured to the log file, nothing streams). Settingstream_progress: 'true'drops--audience agentso[ocr]progress routes to stderr while the result JSON stays on stdout; a FIFO feeds a background tee that streams progress live into the workflow log and is awaited before the log file is read, so artifacts and the posting step always see a fully flushed capture.OCR_EXIT_CODEhandling is unaffected in either mode.llm_reasoning_effortinput (closes feat(action): first-class llm_reasoning_effort input for always-on-thinking models (e.g. GLM-5.3) #1149) — injected into the effectivellm.extra_bodyvia node in the Configure step (node, not jq: the Actions runtime guarantees node on PATH even inside container jobs), riding the existing extra_body merge so any published CLI supports it; an explicitreasoning_effortkey inllm_extra_bodywins. Thellm_extra_bodydefault is unchanged ({"thinking": {"type": "disabled"}}) — thinking stays disabled unless explicitly opted in. Malformedllm_extra_bodyJSON now fails the step with an actionable::error::naming the input.Testing
make checkmake testnpm run test:github-actions— 36/36 action contract tests passmax-tokens-budgetandllm-reasoning-effortwired from caller workflows