Let reviews be stopped, and fail stuck reviewers automatically

This commit is contained in:
Ian Gulliver
2026-10-17 07:24:08 -07:00
parent 00cd1ed958
commit 9b3f775dac
11 changed files with 397 additions and 220 deletions
+43
View File
@@ -664,6 +664,25 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/reviews/{reviewId}/stop": {
parameters: {
query?: never;
header?: never;
path: {
reviewId: string;
};
cookie?: never;
};
get?: never;
put?: never;
/** @description Ends a running review's reviewer and records the review as failed. Refused unless the review is running. */
post: operations["stopReview"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/tasks/{taskId}/snapshots/{n}/fork": {
parameters: {
query?: never;
@@ -2549,6 +2568,30 @@ export interface operations {
404: components["responses"]["Error"];
};
};
stopReview: {
parameters: {
query?: never;
header?: never;
path: {
reviewId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The review. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Review"];
};
};
404: components["responses"]["Error"];
409: components["responses"]["Error"];
};
};
forkSnapshot: {
parameters: {
query?: never;
+15
View File
@@ -62,12 +62,27 @@ export function reviewCard(r: Review, taskId: string | undefined): HTMLElement {
h("span", { class: "review-snapshot" }, `snapshot #${r.snapshot_n}`),
h("span", { class: `review-state ${r.state}` }, stateText(r)),
h("time", { dateTime: r.created_at, title: r.created_at }, ago(r.created_at)),
r.state === "running" ? stopButton(r) : null,
),
r.state === "failed" ? h("p", { class: "error-text" }, r.error) : null,
r.state === "done" ? reviewResult(r, taskId) : null,
);
}
function stopButton(r: Review): HTMLElement {
const b = h("button", { type: "button", class: "danger review-stop", title: "End the reviewer and record this review as failed" }, "Stop");
b.onclick = async () => {
b.disabled = true;
try {
await post("/api/reviews/{reviewId}/stop", { path: { reviewId: r.id } });
} catch (err) {
b.disabled = false;
void showAlert(errorText(err));
}
};
return b;
}
function reviewResult(r: Review, taskId: string | undefined): HTMLElement {
const res = (r.result ?? {}) as Record<string, unknown>;
const findings = findingsOf(r);