Repository navigation
Conversation
hackbot-api now puts a front matter block at the top of every Bugzilla comment it posts: the run, the action, the agent and a link to the run in the Hackbot UI. BMO's Hackbot extension hides the block and shows the agent and the link in the comment header instead (bug 2086124). The block is added at apply time, so a model can't write or change it, and the Hackbot UI and Slack never show it. ApplyContext carries the action ID; a field update merged with a comment carries the comment's ID. The block is left out when the action has no ID (older summaries) or a value isn't an identifier, since BMO would show it as text. Agent text posted without our block (those comments, a comment inside update_bug's changes, attachment comments and new-bug descriptions) starts on a new line when it begins with a rule, so BMO can't read a block the model wrote as metadata.
|
It seems that the test failure is related to GitHub’s downtime, in the same way as the pull request to BMO. Please rerun the test once the issue has been resolved. |
suhaibmujahid
left a comment
There was a problem hiding this comment.
Thank you! It looks great. I left some simple comments.
| for member in member_rows | ||
| ] | ||
| # The group carries at most one comment, which keeps its own ID. | ||
| comment_id = next( |
There was a problem hiding this comment.
| comment_id = next( | |
| comment_action_id = next( |
| params = resolve_placeholders(row.params, results_by_ref) | ||
| outcome = await _dispatch( | ||
| run, row.type, params, attachments, hackbot_client | ||
| run, row.type, params, attachments, hackbot_client, row.ref |
There was a problem hiding this comment.
We should pass the id instead of the ref:
| run, row.type, params, attachments, hackbot_client, row.ref | |
| run, row.type, params, attachments, hackbot_client, row.id |
| ] | ||
| # The group carries at most one comment, which keeps its own ID. | ||
| comment_id = next( | ||
| (m.ref for m in member_rows if m.type == "bugzilla.add_comment"), |
There was a problem hiding this comment.
| params: dict, | ||
| attachments: list[dict], | ||
| hackbot_client: HackbotClient, | ||
| action_id: str | None, |
There was a problem hiding this comment.
If we use id instead of ref that would be int instead of str and it will never be None.
| body["comment"] = _with_front_matter(params["comment"], ctx) | ||
| body["comment_tags"] = [ctx.agent] | ||
| elif isinstance(body.get("comment"), dict) and isinstance( | ||
| body["comment"].get("body"), str | ||
| ): | ||
| # A comment the agent put in `changes` itself, which is also posted | ||
| # from the Hackbot account. | ||
| body["comment"] = _with_front_matter(body["comment"], ctx) |
There was a problem hiding this comment.
We could simplify it be checking for body.get("comment") after if params.get("comment"):
if params.get("comment"):
body["comment"] = params["comment"]
body["comment_tags"] = [ctx.agent]
if body.get("comment"):
body["comment"] = _with_front_matter(body["comment"], ctx)| return "\n".join(["---", "hackbot:", *lines, f" url: {url}", "---", "", ""]) | ||
|
|
||
|
|
||
| def _unparsed(text: str) -> str: |
There was a problem hiding this comment.
| def _unparsed(text: str) -> str: | |
| def _escape_front_matter(text: str) -> str: |
| fields = {"run": ctx.run_id, "action": ctx.action_id, "agent": ctx.agent} | ||
| invalid = [key for key, value in fields.items() if not _IDENTIFIER.fullmatch(value)] | ||
| if invalid: | ||
| log.warning( |
There was a problem hiding this comment.
So we get a single about this in Sentry:
| log.warning( | |
| log.error( |
Alternatively, we could raise an exception to fail loudly.
| # BMO's Hackbot extension reads this block off the top of comments from the | ||
| # Hackbot account, hides it, and shows the agent and a link to the run in the | ||
| # comment header instead. It reads only this shape: `run`, `action` and `agent` | ||
| # must be identifiers and `url` an https URL. Anything else shows as plain text, | ||
| # so a block that would not parse is left out rather than posted. | ||
| _IDENTIFIER = re.compile(r"[A-Za-z0-9._-]+") |
There was a problem hiding this comment.
Do we really need this? Could we make it dynamic so it accepts whatever we pass in? Or does it solve a technical limitation?
For Bug 2086124.
Important
Deploy this only once mozilla/bmo#2819 is in production and BMO's
hackbot_userparam names the account hackbot-api posts as. Until then, Bugzilla shows the block as plain text at the top of every Hackbot comment.hackbot-api now puts a front matter block at the top of every Bugzilla comment it posts:
BMO's Hackbot extension hides the block from readers, bugmail, webhooks and Pulse, and shows the agent and a link to the run in the comment header instead. REST
raw_textkeeps it. This is what native feedback (bug 2086122) will attach to.bugzilla_handler.py, so a model can't write or change it, and the Hackbot UI and Slack never show it.ApplyContextcarries the action ID (RunAction.ref). When a field update and a comment are merged into one PUT, it carries the comment's ID.---, so BMO can't read a block the model wrote as metadata. That covers the case above, a comment insideupdate_bug'schanges, attachment comments and new-bug descriptions.Testing
🤖 Generated with Claude Code