diff --git a/swe_af/app.py b/swe_af/app.py index af855a3..3b38624 100644 --- a/swe_af/app.py +++ b/swe_af/app.py @@ -2118,7 +2118,13 @@ async def resume_build( def main(): """Entry point for ``python -m swe_af`` and the ``swe-af`` console script.""" - app.run(port=8003, host="0.0.0.0") + # Don't hardcode the port: the AgentField control plane assigns a free port + # per launch and passes it via the PORT env var, then polls readiness on + # that port. The SDK's Agent.run() reads PORT when no port is given (and + # auto-selects a free port when run standalone), so leaving it unset is what + # lets `af run` work. Passing port=8003 bound the wrong port and made the + # control plane's readiness check time out ("did not become ready"). + app.run(host="0.0.0.0") if __name__ == "__main__": diff --git a/tests/test_main_entrypoint.py b/tests/test_main_entrypoint.py new file mode 100644 index 0000000..418651b --- /dev/null +++ b/tests/test_main_entrypoint.py @@ -0,0 +1,32 @@ +"""Contract test for the ``python -m swe_af`` entry point. + +The AgentField control plane assigns a free port per launch, passes it via the +``PORT`` env var, and polls readiness on that port. ``main()`` must therefore +NOT hardcode a port — it must let the SDK's ``Agent.run()`` read ``PORT`` (or +auto-select a free port when run standalone). Passing an explicit port bound the +wrong one and made the control plane's readiness check time out +("agent node did not become ready within 10s"). +""" +from __future__ import annotations + +import os + +os.environ.setdefault("AGENTFIELD_SERVER", "http://localhost:9999") + +import swe_af.app as app_module + + +def test_main_does_not_hardcode_a_port(monkeypatch): + captured: dict = {} + + def fake_run(*args, **kwargs): + captured["args"] = args + captured["kwargs"] = kwargs + + monkeypatch.setattr(app_module.app, "run", fake_run) + app_module.main() + + assert not captured["args"], "main() must not pass a positional port to app.run()" + assert "port" not in captured["kwargs"], ( + "main() must not hardcode a port; the SDK reads PORT from the control plane" + )