mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-09-02 04:01:25 +02:00
Add Daily Dedupe Digest workflow driven by AI Issue Triage output (#49907)
## Summary Rewrites the Daily Dedupe Digest as a lightweight aggregator over the existing **AI Issue Triage** workflow, superseding #48244. Instead of running its own `gpt-4o-mini` duplicate-detection pass, this workflow treats the triage workflow as the single source of truth. AI Issue Triage already: - posts a canonical comment per issue (marker `<!-- powertoys-ai-triage:canonical:v1 -->`) containing a `### 🔁 Possible duplicates` section, and - files a *pending* native duplicate-close suggestion pointing at the strongest canonical candidate. The digest simply collects those and drops them into one daily review issue. ## Behavior Runs daily (`0 8 * * *`) and via `workflow_dispatch`. Each run: 1. Ensures the `dedupe-digest` label exists. 2. Builds a candidate set from **carry-over** issues remembered in the previous digest (hidden `<!-- dup:ISSUE=.. CANON=.. -->` markers) plus **fresh** open issues updated in the lookback window (default 26h). 3. Re-validates each candidate against its *live* triage comment — issues that are closed or labeled `duplicate` / `Resolution-Duplicate` drop out automatically. 4. Opens a **new** issue each day, assigned to `@niels9001`, listing every flagged issue (the duplicate → to close) with its suggested canonical issue (→ keep) and the triage reason. Links to each triage summary comment are included. 5. Closes the previous digest, superseded by the new one. 6. If nothing is flagged, it closes the previous digest and creates none. ## Notes - No model calls / no `models: read` permission — only `issues: write`. - Untrusted issue/comment text is sanitized (HTML comments, control chars, angle brackets stripped) before being written into the digest, to avoid marker injection. - Tunable via `env`: assignee, label, title prefix, lookback hours, scan/flag caps, resolved-duplicate labels. Supersedes #48244. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 26025067-259e-43e3-9dc7-a9fc4b5ba58b
This commit is contained in:
11
.github/scripts/issue-triage/issue-context.py
vendored
11
.github/scripts/issue-triage/issue-context.py
vendored
@@ -533,6 +533,17 @@ def existing_input_hash(comments):
|
||||
|
||||
def should_process(event, report_comment):
|
||||
action = event.get("action")
|
||||
issue = event.get("issue") or {}
|
||||
issue_labels = {
|
||||
(label.get("name", "") if isinstance(label, dict) else str(label)).lower()
|
||||
for label in (issue.get("labels") or [])
|
||||
}
|
||||
# Never triage the automated dedupe-digest issue. It is bot-authored and
|
||||
# aggregates untrusted text from many issues, so re-triaging it wastes AI
|
||||
# credits and creates a prompt-injection surface. See
|
||||
# .github/workflows/dedupe-digest.yml (DIGEST_LABEL).
|
||||
if "dedupe-digest" in issue_labels:
|
||||
return False, False
|
||||
if "comment" not in event:
|
||||
if (
|
||||
action == "reopened"
|
||||
|
||||
@@ -338,6 +338,17 @@ class IssueContextTests(unittest.TestCase):
|
||||
}
|
||||
self.assertEqual(CONTEXT.should_process(event, None), (False, False))
|
||||
|
||||
def test_dedupe_digest_issue_is_never_triaged(self):
|
||||
event = {
|
||||
"action": "opened",
|
||||
"sender": {"login": "github-actions[bot]"},
|
||||
"issue": {
|
||||
"number": 11,
|
||||
"labels": [{"name": "dedupe-digest"}],
|
||||
},
|
||||
}
|
||||
self.assertEqual(CONTEXT.should_process(event, None), (False, False))
|
||||
|
||||
def test_unrelated_comment_writes_noop(self):
|
||||
event = {
|
||||
"action": "created",
|
||||
|
||||
Reference in New Issue
Block a user