Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion agents/autowebcompat-repro/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ services:
- RUN_ID
- BUG_DATA
- BUG_ID
- BUGZILLA_MCP_URL=http://autowebcompat-repro-broker:8765/mcp
- BROKER_URL=http://autowebcompat-repro-broker:8765
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?error}
# No uploader locally: summary/logs/attachments are written under
# /artifacts/<run_id>, bind-mounted to the host's ~/hackbot/artifacts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class AgentInputs(BaseSettings):
bugzilla_mcp_url: str
broker_url: str
bug_data: str | None = None
bug_id: int | None = None
model: str | None = None
Expand All @@ -38,6 +38,10 @@ class AgentInputs(BaseSettings):

model_config = SettingsConfigDict(extra="ignore")

@property
def bugzilla_mcp_url(self) -> str:
return f"{self.broker_url.rstrip('/')}/mcp"


class AutowebcompatResult(HackbotAgentResult):
result: AutowebcompatReproResult
Expand Down
3 changes: 1 addition & 2 deletions agents/bug-fix/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ services:
environment:
- RUN_ID
- BUG_ID=${BUG_ID:?error}
- BUGZILLA_MCP_URL=http://bug-fix-broker:8765/bugzilla/mcp
- PHABRICATOR_BROKER_URL=http://bug-fix-broker:8765
- BROKER_URL=http://bug-fix-broker:8765
- REVISION_ID
- COMMENT
- SOURCE_REPO=/workspace/firefox
Expand Down
14 changes: 10 additions & 4 deletions agents/bug-fix/hackbot_agents/bug_fix/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@

class AgentInputs(BaseSettings):
bug_id: int
bugzilla_mcp_url: str
broker_url: str
revision_id: int | None = None
comment: str | None = None
phabricator_broker_url: str
model: str | None = None
max_turns: int | None = None
effort: str | None = None

model_config = SettingsConfigDict(extra="ignore")

def broker_endpoint(self, path: str) -> str:
return f"{self.broker_url.rstrip('/')}/{path.lstrip('/')}"

@property
def bugzilla_mcp_url(self) -> str:
return self.broker_endpoint("/bugzilla/mcp")

@property
def phabricator_mcp_url(self) -> str:
"""The broker's Phabricator MCP endpoint.
Expand All @@ -25,7 +31,7 @@ def phabricator_mcp_url(self) -> str:
endpoints are served by the same sidecar, so there is nothing for a
caller to configure independently.
"""
return f"{self.phabricator_broker_url.rstrip('/')}/phabricator/mcp"
return self.broker_endpoint("/phabricator/mcp")

@model_validator(mode="after")
def _follow_up_with_comment(self) -> "AgentInputs":
Expand All @@ -43,7 +49,7 @@ async def main(ctx: HackbotContext) -> BugFixResult:
inputs = AgentInputs()

if inputs.revision_id:
await checkout_revision(ctx, inputs.revision_id, inputs.phabricator_broker_url)
await checkout_revision(ctx, inputs.revision_id, inputs.broker_url)
else:
await ctx.prepare_repo()

Expand Down
23 changes: 10 additions & 13 deletions agents/bug-fix/tests/test_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,43 @@

def test_broker_url_required(monkeypatch):
# Every run mounts the broker's Phabricator tools, follow-up or not.
monkeypatch.delenv("PHABRICATOR_BROKER_URL", raising=False)
with pytest.raises(ValidationError, match="phabricator_broker_url"):
AgentInputs(bug_id=1, bugzilla_mcp_url="http://x")
monkeypatch.delenv("BROKER_URL", raising=False)
with pytest.raises(ValidationError, match="broker_url"):
AgentInputs(bug_id=1)


def test_revision_requires_comment():
with pytest.raises(ValidationError, match="comment"):
AgentInputs(
bug_id=1,
bugzilla_mcp_url="http://x",
broker_url="http://broker",
revision_id=42,
phabricator_broker_url="http://broker",
)


def test_revision_with_broker_url_ok():
inputs = AgentInputs(
bug_id=1,
bugzilla_mcp_url="http://x",
broker_url="http://broker",
revision_id=42,
comment="@hackbot please fix",
phabricator_broker_url="http://broker",
)
assert inputs.phabricator_broker_url == "http://broker"
assert inputs.broker_url == "http://broker"


def test_no_revision_ok_without_comment():
inputs = AgentInputs(
bug_id=1,
bugzilla_mcp_url="http://x",
phabricator_broker_url="http://broker",
broker_url="http://broker",
)
assert inputs.revision_id is None
assert inputs.comment is None


def test_phabricator_mcp_url_derived_from_broker_url():
def test_mcp_urls_derived_from_broker_url():
inputs = AgentInputs(
bug_id=1,
bugzilla_mcp_url="http://x",
phabricator_broker_url="http://broker:8765/",
broker_url="http://broker:8765/",
)
assert inputs.bugzilla_mcp_url == "http://broker:8765/bugzilla/mcp"
assert inputs.phabricator_mcp_url == "http://broker:8765/phabricator/mcp"
4 changes: 2 additions & 2 deletions agents/build-repair/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ services:
- GIT_COMMIT=${GIT_COMMIT:-}
- FAILURE_TASKS=${FAILURE_TASKS:-}
- RUN_TRY_PUSH=${RUN_TRY_PUSH:-false}
- BUGZILLA_MCP_URL=http://build-repair-broker:8765/mcp
- BROKER_URL=http://build-repair-broker:8765
- SOURCE_REPO=/workspace/firefox
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?error}
# Weave tracing locally: an API key enables it (deploys use W&B WIF instead).
Expand Down Expand Up @@ -56,7 +56,7 @@ services:
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?error}
- WANDB_API_KEY=${WANDB_API_KEY:-}
- BUGZILLA_MCP_URL=http://build-repair-broker:8765/mcp
- BROKER_URL=http://build-repair-broker:8765
- FIREFOX_GIT_REPO=/firefox
volumes:
- ${FIREFOX_GIT_REPO:-/firefox}:/firefox
Expand Down
12 changes: 10 additions & 2 deletions agents/build-repair/evals/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ def _collect_diff(worktree_path: Path, base_commit: str) -> str:
def _bugzilla_server():
"""Bugzilla MCP server for the agent.

Prefer the broker (``BUGZILLA_MCP_URL``) so the eval container holds no
Prefer the broker (``BROKER_URL``) so the eval container holds no
Bugzilla credentials -- same isolation as production. Falls back to an
in-process server for local runs without a broker.
"""
mcp_url = os.environ.get("BUGZILLA_MCP_URL")
mcp_url = _broker_mcp_url()
if mcp_url:
return {"type": "http", "url": mcp_url}
client = bugsy.Bugsy(
Expand All @@ -77,6 +77,14 @@ def _bugzilla_server():
return build_sdk_server("bugzilla", BugzillaContext(client=client), bugzilla.TOOLS)


def _broker_mcp_url() -> str | None:
broker_url = os.environ.get("BROKER_URL")
if not broker_url:
# fall back to in-process Bugzilla server for local runs without a broker
return None
return f"{broker_url.rstrip('/')}/mcp"


class BuildRepairModel(weave.Model):
"""Weave Model: one worktree per example, runs the ported build-repair agent."""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AgentInputs(BaseSettings):
failure_tasks: dict[str, str]
git_commit: str | None = None
bug_id: int | None = None
bugzilla_mcp_url: str
broker_url: str
run_try_push: bool = False
model: str | None = None
max_turns: int | None = None
Expand All @@ -18,6 +18,10 @@ class AgentInputs(BaseSettings):
# treat those as absent so optional fields fall back to their defaults.
model_config = SettingsConfigDict(extra="ignore", env_ignore_empty=True)

@property
def bugzilla_mcp_url(self) -> str:
return f"{self.broker_url.rstrip('/')}/mcp"


async def main(ctx: HackbotContext) -> BuildRepairResult:
inputs = AgentInputs()
Expand Down
2 changes: 1 addition & 1 deletion agents/frontend-triage/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ services:
environment:
- RUN_ID
- BUG_ID=${BUG_ID:?error}
- BUGZILLA_MCP_URL=http://frontend-triage-broker:8765/mcp
- BROKER_URL=http://frontend-triage-broker:8765
- SOURCE_REPO=/workspace/firefox
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?error}
# No uploader locally: summary/logs/attachments are written under
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@

class AgentInputs(BaseSettings):
bug_id: int
bugzilla_mcp_url: str
broker_url: str
model: str = DEFAULT_MODEL
max_turns: int | None = None
effort: str | None = None

model_config = SettingsConfigDict(extra="ignore")

@property
def bugzilla_mcp_url(self) -> str:
return f"{self.broker_url.rstrip('/')}/mcp"


async def main(ctx: HackbotContext) -> FrontendTriageResult:
inputs = AgentInputs()
Expand Down