review classifier: a setting makes the PR review list only the failed rules
failures_only (off by default, also for a stored document without it) makes the review the classifier posts on a PR list just the rows that failed their rule, or say that no check failed on an approval. A review with no clean verdict and a try-out keep every row. The classifier settings form gets a checkbox for it.
This commit is contained in:
parent
818d41eef3
commit
cf5746188a
3 changed files with 138 additions and 9 deletions
|
|
@ -15,6 +15,7 @@ import { Button } from "../../ui/button/Button.js";
|
|||
import { FieldGrid, FieldGridFull } from "../../ui/field-grid/FieldGrid.js";
|
||||
import { Hint } from "../../ui/hint/Hint.js";
|
||||
import { Disclosure } from "../../ui/disclosure/Disclosure.js";
|
||||
import { CheckboxField } from "../../ui/checkbox-field/CheckboxField.js";
|
||||
import { SelectField } from "../../ui/select-field/SelectField.js";
|
||||
import { TextField } from "../../ui/text-field/TextField.js";
|
||||
import {
|
||||
|
|
@ -187,6 +188,12 @@ export function ClassifierSettings() {
|
|||
pattern="[0-9]+"
|
||||
onInput={(maxRules) => edit({ ...draft, maxRules })}
|
||||
/>
|
||||
<CheckboxField
|
||||
id="classifier-failures-only"
|
||||
label="PR reviews list only failed rules"
|
||||
checked={draft.failuresOnly}
|
||||
onChange={(failuresOnly) => edit({ ...draft, failuresOnly })}
|
||||
/>
|
||||
</FieldGrid>
|
||||
{draft.runtime === "acp" ? (
|
||||
<fieldset class="ui-classifier-settings-group">
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ export interface ClassifierSettingsBody {
|
|||
max_concurrent_reviews: number;
|
||||
/** The most classifications (rules) one run carries. */
|
||||
max_classifications: number;
|
||||
/** Whether a posted PR review lists only the rules that failed. */
|
||||
failures_only: boolean;
|
||||
runtime: Runtime;
|
||||
/** The provider record. It stays stored while the runtime is `api-key`. */
|
||||
acp: AcpSettings | null;
|
||||
|
|
@ -48,6 +50,8 @@ export interface SettingsDraft {
|
|||
max: string;
|
||||
/** The most classifications one run carries. */
|
||||
maxRules: string;
|
||||
/** Whether a posted PR review lists only the failed rules. */
|
||||
failuresOnly: boolean;
|
||||
runtime: Runtime;
|
||||
acpUrl: string;
|
||||
acpModel: string;
|
||||
|
|
@ -70,6 +74,7 @@ export function draftOf(s: ClassifierSettingsBody): SettingsDraft {
|
|||
effort: s.effort ?? "",
|
||||
max: String(s.max_concurrent_reviews),
|
||||
maxRules: String(s.max_classifications),
|
||||
failuresOnly: s.failures_only,
|
||||
runtime: s.runtime,
|
||||
acpUrl: acp?.base_url ?? "",
|
||||
acpModel: acp?.model ?? "",
|
||||
|
|
@ -173,6 +178,7 @@ export function toSettings(
|
|||
effort: d.effort === "" ? null : (d.effort as Effort),
|
||||
max_concurrent_reviews: maxValue(d.max) ?? MIN_REVIEWS,
|
||||
max_classifications: rulesValue(d.maxRules) ?? MIN_RULES,
|
||||
failures_only: d.failuresOnly,
|
||||
runtime: d.runtime,
|
||||
};
|
||||
return d.runtime === "acp" ? { ...body, acp: toAcp(d) } : body;
|
||||
|
|
@ -190,6 +196,7 @@ export function changed(
|
|||
d.effort !== now.effort ||
|
||||
d.max.trim() !== now.max ||
|
||||
d.maxRules.trim() !== now.maxRules ||
|
||||
d.failuresOnly !== now.failuresOnly ||
|
||||
d.runtime !== now.runtime;
|
||||
if (base) return true;
|
||||
// The provider fields only save on the ACP runtime.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const apiKey = {
|
|||
effort: null,
|
||||
max_concurrent_reviews: 2,
|
||||
max_classifications: 10,
|
||||
failures_only: false,
|
||||
runtime: "api-key",
|
||||
acp: null,
|
||||
};
|
||||
|
|
@ -60,6 +61,7 @@ test("the API key request leaves the provider out, so the stored one stays", ()
|
|||
effort: null,
|
||||
max_concurrent_reviews: 2,
|
||||
max_classifications: 10,
|
||||
failures_only: false,
|
||||
runtime: "api-key",
|
||||
});
|
||||
assert.equal("acp" in body, false);
|
||||
|
|
@ -166,3 +168,11 @@ test("under ACP the summary names the provider's model, not the claude one", ()
|
|||
"acp · glm · 2 at once · up to 10 rules",
|
||||
);
|
||||
});
|
||||
|
||||
test("the failures-only switch round-trips and counts as a change", () => {
|
||||
const on = { ...draftOf(apiKey), failuresOnly: true };
|
||||
assert.equal(draftOf(apiKey).failuresOnly, false);
|
||||
assert.equal(toSettings(on).failures_only, true);
|
||||
assert.equal(changed(on, apiKey), true);
|
||||
assert.equal(changed(draftOf(apiKey), apiKey), false);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue