From ddcab2b26d9e70425268752e09d9e6271b29fe8b Mon Sep 17 00:00:00 2001 From: Cory Thomas Date: Wed, 5 Aug 2026 15:10:41 -0400 Subject: [PATCH] Ask for feedback via Bugzilla reactions and comment tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no way to tell whether Hackbot's Bugzilla comments are any good. Bugzilla already has per-comment reactions and comment tags, so collecting feedback needs no UI of ours — only for readers to be told the affordances are there, since the reaction control is an unlabelled icon. Every agent's comments now ask for a 👍/👎 reaction in place of the needinfo footer, which was meant to have been dropped earlier and never was. frontend-triage appends a second line offering ai-triage-* tags to categorise the feedback. Those tag names have no business on another agent's comments, so they are registered as a hook on that agent rather than added to the shared footer. Literal 👍/👎 rather than :+1:/:-1: — BMO builds its markdown parser with only autolink, tagfilter, table and strikethrough, so a shortcode would render as visible text. The tag list sits on its own line because that same parser sets hardbreaks, making a single newline a line break. --- .../hackbot_agents/frontend_triage/agent.py | 17 +++++++++++++++++ .../hackbot_runtime/actions/bugzilla.py | 4 ++-- .../tests/test_bugzilla_actions.py | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/agent.py b/agents/frontend-triage/hackbot_agents/frontend_triage/agent.py index 5e5a6e7311..52fadb1e47 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/agent.py +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/agent.py @@ -56,6 +56,22 @@ # machine-consumable for downstream handoff (summary.json -> execution agent). _JSON_BLOCK = re.compile(r"```json\s*(\{.*?\})\s*```", re.DOTALL) +_FEEDBACK_TAGS = ( + "If you want to categorize your feedback you can add one of the following " + "tags: ai-triage-wrong-file, ai-triage-wrong-cause, ai-triage-hallucination, " + "ai-triage-out-of-scope." +) + + +def feedback_tags_hook(action: dict) -> None: + """Offer the triage-specific feedback tags below the runtime's footer.""" + params = action.get("params") + if not isinstance(params, dict): + return + text = params.get("text") + if isinstance(text, str): + params["text"] = f"{text.rstrip()}\n{_FEEDBACK_TAGS}" + class FrontendTriageResult(HackbotAgentResult): bug_id: int @@ -233,6 +249,7 @@ async def run_frontend_triage( "bugzilla.add_comment", permalink_hook(permalink_prefix(searchfox_rev), source_repo.resolve()), ) + actions_recorder.add_hook("bugzilla.add_comment", feedback_tags_hook) system_prompt = load_system_prompt(rules_dir, instructions) diff --git a/libs/hackbot-runtime/hackbot_runtime/actions/bugzilla.py b/libs/hackbot-runtime/hackbot_runtime/actions/bugzilla.py index c8087b298b..2043293ce2 100644 --- a/libs/hackbot-runtime/hackbot_runtime/actions/bugzilla.py +++ b/libs/hackbot-runtime/hackbot_runtime/actions/bugzilla.py @@ -21,8 +21,8 @@ from hackbot_runtime.actions.recorder import ActionsRecorder _COMMENT_FOOTER = ( - "*This is an automated analysis result. If this result is incorrect " - "please add a needinfo and feel free to correct the error.* " + "If you'd like to provide feedback on this comment, please use the 👍 or 👎 " + "reaction." ) _ATTACHMENT_COMMENT_FOOTER = ( "*This is the analysis tool's suggested fix. Feel welcome to adopt " diff --git a/libs/hackbot-runtime/tests/test_bugzilla_actions.py b/libs/hackbot-runtime/tests/test_bugzilla_actions.py index ab27e3447c..6d3cecae59 100644 --- a/libs/hackbot-runtime/tests/test_bugzilla_actions.py +++ b/libs/hackbot-runtime/tests/test_bugzilla_actions.py @@ -10,7 +10,7 @@ async def test_add_comment_appends_footer(): await bugzilla.add_comment(rec, bug_id=1, text="Looks invalid.", reasoning="r") text = rec.actions[0]["params"]["text"] assert text.startswith("Looks invalid.") - assert "automated analysis result" in text + assert text.endswith(bugzilla._COMMENT_FOOTER) assert rec.actions[0]["params"]["is_private"] is False