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
16 changes: 9 additions & 7 deletions src/bedrock_agentcore/runtime/a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,10 @@ def build_a2a_app(
executor: An ``AgentExecutor`` that implements the agent logic.
agent_card: Optional ``a2a.types.AgentCard`` describing the agent.
If ``None``, one is built automatically by introspecting the executor.
runtime_url: URL advertised by an automatically generated agent card.
Defaults to ``http://localhost:9000/``. ``AGENTCORE_RUNTIME_URL``
takes precedence when set.
runtime_url: URL advertised by the agent card. When an explicit card is
supplied, its JSON-RPC URL is updated when this argument is set.
Defaults to ``http://localhost:9000/`` for automatically generated
cards. ``AGENTCORE_RUNTIME_URL`` takes precedence when set.
task_store: Optional ``TaskStore``; defaults to ``InMemoryTaskStore``.
context_builder: Optional ``ServerCallContextBuilder``; defaults to
``BedrockCallContextBuilder``.
Expand All @@ -273,13 +274,14 @@ def build_a2a_app(
from starlette.responses import JSONResponse
from starlette.routing import Route

runtime_url = os.environ.get(AGENTCORE_RUNTIME_URL_ENV, runtime_url or "http://localhost:9000/")
runtime_url_override = os.environ.get(AGENTCORE_RUNTIME_URL_ENV) or runtime_url
advertised_url = runtime_url_override or "http://localhost:9000/"
is_a2a_v1 = _is_a2a_v1()

if agent_card is None:
agent_card = _build_agent_card(executor, runtime_url)
elif os.environ.get(AGENTCORE_RUNTIME_URL_ENV):
_set_jsonrpc_url(agent_card, runtime_url)
agent_card = _build_agent_card(executor, advertised_url)
elif runtime_url_override:
_set_jsonrpc_url(agent_card, advertised_url)

if task_store is None:
task_store = InMemoryTaskStore()
Expand Down
39 changes: 38 additions & 1 deletion tests/bedrock_agentcore/runtime/test_a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,15 @@ def test_agent_card_url_auto_populated_from_env(self):
build_a2a_app(_EchoExecutor(), card)
assert _card_url(card) == "https://deployed.example.com/"

def test_agent_card_url_uses_explicit_runtime_url(self):
"""A supplied runtime_url overrides the URL on an explicit card."""
card = _make_agent_card()
with patch.dict("os.environ", {}, clear=True):
build_a2a_app(_EchoExecutor(), card, runtime_url="http://localhost:9002/")
assert _card_url(card) == "http://localhost:9002/"

def test_agent_card_url_unchanged_without_env(self):
"""When AGENTCORE_RUNTIME_URL is not set, the agent card URL stays as-is."""
"""Without a runtime URL override, an explicit card URL stays as-is."""
card = _make_agent_card()
original_url = _card_url(card)
with patch.dict("os.environ", {}, clear=False):
Expand Down Expand Up @@ -466,11 +473,41 @@ def test_port_from_environment(self, mock_uvicorn_run):
assert mock_uvicorn_run.call_args.kwargs["port"] == 9001
assert _card_response_url(response.json()) == "http://localhost:9001/"

@patch("uvicorn.run")
def test_port_from_environment_updates_explicit_card(self, mock_uvicorn_run):
with patch.dict("os.environ", {"PORT": "9002"}, clear=True):
serve_a2a(_EchoExecutor(), _make_agent_card())

app = mock_uvicorn_run.call_args.args[0]
response = TestClient(app).get("/.well-known/agent-card.json")
assert mock_uvicorn_run.call_args.kwargs["port"] == 9002
assert _card_response_url(response.json()) == "http://localhost:9002/"

@patch("uvicorn.run")
def test_explicit_port_overrides_environment(self, mock_uvicorn_run):
with patch.dict("os.environ", {"PORT": "9001"}):
serve_a2a(_EchoExecutor(), _make_agent_card(), port=8888)
app = mock_uvicorn_run.call_args.args[0]
response = TestClient(app).get("/.well-known/agent-card.json")
assert mock_uvicorn_run.call_args.kwargs["port"] == 8888
assert _card_response_url(response.json()) == "http://localhost:8888/"

@patch("uvicorn.run")
def test_runtime_url_environment_overrides_port_for_card(self, mock_uvicorn_run):
with patch.dict(
"os.environ",
{
"PORT": "9002",
"AGENTCORE_RUNTIME_URL": "https://deployed.example.com/",
},
clear=True,
):
serve_a2a(_EchoExecutor(), _make_agent_card())

app = mock_uvicorn_run.call_args.args[0]
response = TestClient(app).get("/.well-known/agent-card.json")
assert mock_uvicorn_run.call_args.kwargs["port"] == 9002
assert _card_response_url(response.json()) == "https://deployed.example.com/"

@patch("uvicorn.run")
def test_docker_detection_dockerenv(self, mock_uvicorn_run):
Expand Down
Loading