update auto-agents-system scripts

This commit is contained in:
AutoPatchBot
2026-05-11 01:48:54 +00:00
parent 78be08870c
commit a85d44902c
@@ -81,8 +81,12 @@ export interface AugmentedPR extends RawPR {
approvals_count: number;
stale_state: StaleState;
ci_status: CIStatus;
priority_rank: number; // 0 = CI Blocker (highest), higher = lower; PRIORITY_NONE if unlabelled
priority_rank: number; // 0=Overdue Milestone/CI Blocker (highest), higher = lower
label_priority_rank: number; // rank from Priority/* label (0-5) or PRIORITY_NONE
priority_label: string | null; // matched Priority/* label name, or null if none
milestone_title: string | null;// milestone title, or null if no milestone set
milestone_due: string | null; // ISO 8601 deadline string, or null if no milestone
milestone_rank: number; // urgency rank from milestone (0-3), MILESTONE_LOW for none
}
interface Review {
@@ -122,8 +126,24 @@ const PRIORITY_ORDER = new Map<string, number>([
]);
const PRIORITY_NONE = 6; // rank for PRs with no recognised Priority/* label
// Milestone-urgency thresholds — lower rank number = more urgent milestone.
// Derived from the due_on date (ISO 8601) relative to the current time.
// Any PR without a milestone gets MILESTONE_LOW so it is sorted below
// every labelled or deadline-driven PR.
const MILESTONE_OVERDUE = 0; // already past due_on
const MILESTONE_TODAY = 1; // due today (same calendar day)
const MILESTONE_WEEK = 2; // due within the next 7 days
const MILESTONE_MONTH = 3; // due beyond 7 days or no milestone at all
// ─────────────────────────────────────────────────────────────────────────────
// pLimit — run an array of async tasks with bounded concurrency
// prMilestoneRank — compute urgency rank from a PR's milestone due_on date
//
// Inspects pr.milestone (a Forgejo Milestone object with title and due_on) and
// returns the urgency-based rank:
// 0 = overdue (past due_on), 1 = due today, 2 = due within 7 days,
// 3 = due beyond 7 days or no milestone at all
// ──
//
// Spawns `limit` worker coroutines that each pull the next available task from
// the shared queue. Results are returned in input order.
@@ -240,6 +260,78 @@ function prPriority(pr: RawPR): { rank: number; label: string | null } {
return { rank: bestRank, label: bestLabel };
}
// ─────────────────────────────────────────────────────────────────────────────
// prMilestoneRank — compute urgency-based PR rank from milestone due_on date
//
// Inspects pr.milestone (a Forgejo Milestone object with title and due_on) and
// returns the urgency-based rank:
// 0 = overdue (already past due_on), 1 = due today, 2 = due within 7 days,
// 3 = due beyond 7 days or no milestone at all
//
// Also extracts the milestone title and due_on string for output. The caller
// uses these to merge with label-based priority below.
// ─────────────────────────────────────────────────────────────────────────────
function prMilestoneRank(
pr: RawPR,
): { rank: number; title: string | null; due: string | null } {
const milestone = pr.milestone as Record<string, unknown> | null | undefined;
if (!milestone || typeof milestone !== 'object') return { rank: MILESTONE_MONTH, title: null, due: null };
const dueOn = (milestone.due_on as string | undefined) ?? null;
const title = (milestone.title as string | undefined) ?? null;
if (!dueOn) return { rank: MILESTONE_MONTH, title, due: null };
const now = Date.now();
const deadline = new Date(dueOn).getTime();
const diffMs = deadline - now;
const oneDay = 86_400_000;
// Deadline is today → high urgency (rank 1)
if (diffMs <= oneDay) return { rank: MILESTONE_TODAY, title, due: dueOn };
// Deadline is within the next week → medium urgency (rank 2)
const sevenDays = 7 * oneDay;
if (diffMs <= sevenDays) return { rank: MILESTONE_WEEK, title, due: dueOn };
// Beyond a week or no deadline → low urgency (rank 3)
return { rank: MILESTONE_MONTH, title, due: dueOn };
}
// ─────────────────────────────────────────────────────────────────────────────
// mergePriority — combine label-based and milestone-based priority into one rank
//
// Priority is based on whichever source has the stronger (lower) rank.
// This gives urgent milestones a chance to climb above PRs that only have
// low Priority/* labels and vice-versa. Label-based priority acts as a tie-
// breaker when both ranks are equal, so that a labelled PR beats an unlabelled
// one at the same milestone urgency level.
// ─────────────────────────────────────────────────────────────────────────────
function mergePriority(
labelRank: number,
labelLabel: string | null,
milestoneRank: number,
): { final_rank: number; label_priority_rank: number; priority_label: string | null } {
if (labelRank < milestoneRank) {
// Label is stronger → use label rank
return { final_rank: labelRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
if (milestoneRank < labelRank) {
// Milestone is stronger → use milestone rank with a bump based on label strength
// to break ties within the same milestone urgency level.
// The base milestone rank starts at 0-3; we add label_priority_rank as an
// offset starting from PRIORITY_NONE so that labelled PRs sort ahead of
// unlabelled ones at equal milestone urgency.
const finalRank = milestoneRank + Math.max(PRIORITY_NONE - 4, 0);
return { final_rank: finalRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
// Equal ranks → labelled PR wins (lower offset from MILESTONE_MONTH baseline)
const combinedRank = milestoneRank + Math.max(PRIORITY_NONE - 4, 0);
return { final_rank: combinedRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
// ─────────────────────────────────────────────────────────────────────────────
// countApprovals — distinct non-dismissed APPROVED review count for a PR
//
@@ -494,14 +586,26 @@ export async function listPRs(
if (filters.hasUnaddressedRequestChanges !== undefined &&
hasUnaddressedRequestChangesCheck(allReviews[i], pr.head.sha) !== filters.hasUnaddressedRequestChanges) continue;
const { rank: priorityRank, label: priorityLabel } = prPriority(pr);
// ── Compute label priority ────────────────────────────────────────────────
const { rank: labelPriorityRank, label: priorityLabel } = prPriority(pr);
// ── Compute milestone urgency ─────────────────────────────────────────────
const { rank: milestoneRank, title:milestoneTitle, due:milestoneDue } = prMilestoneRank(pr);
// ── Merge into combined priority_rank ─────────────────────────────────────
const { final_rank } = mergePriority(labelPriorityRank, priorityLabel, milestoneRank);
results.push({
...pr,
approvals_count: approvalsCount,
stale_state: staleState,
ci_status: ciStatus,
priority_rank: priorityRank,
priority_label: priorityLabel,
approvals_count: approvalsCount,
stale_state: staleState,
ci_status: ciStatus,
priority_rank: final_rank,
label_priority_rank: labelPriorityRank,
priority_label: priorityLabel,
milestone_title: milestoneTitle,
milestone_due: milestoneDue,
milestone_rank: milestoneRank,
});
}
@@ -648,9 +752,17 @@ the full Forgejo PR plus:
.approvals_count integer distinct non-dismissed APPROVED review count
.stale_state string one of the stale states listed above
.ci_status string passing|failing|pending|unknown (see --ci-status above)
.priority_rank integer 0=CI Blocker, 1=Critical, 2=High, 3=Medium,
4=Low, 5=Backlog, 6=none (unlabelled)
.priority_label string|null matched Priority/* label name, or null
.priority_rank integer priority rank — the lower the number, the higher
the urgency; ranges from 0 (overdue milestone /
CI Blocker label) to ~7+ (low-unlabelled PR).
See merged priority computation in file header.
.label_priority_rank integer rank derived solely from a Priority/* label
(0-5), or PRIORITY_NONE if no such label exists
.priority_label string|null matched Priority/* label name, or null
.milestone_title string|null milestone title assigned to the PR, or null
.milestone_due string|null ISO 8601 deadline of the milestone, or null
.milestone_rank integer urgency derived from deadline:
0=overdue, 1=today, 2=within 7 days, 3=beyond / none
`);
}