Skip to content

Commit 7e6249e

Browse files
committed
wip
1 parent 2db7f81 commit 7e6249e

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

src/a2a/server/apps/jsonrpc/jsonrpc_app.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from sse_starlette.sse import EventSourceResponse
5959
from starlette.applications import Starlette
6060
from starlette.authentication import BaseUser
61+
from starlette.datastructures import URL
6162
from starlette.exceptions import HTTPException
6263
from starlette.requests import Request
6364
from starlette.responses import JSONResponse, Response
@@ -485,6 +486,63 @@ async def event_generator(
485486
handler_result.root.model_dump(mode='json', exclude_none=True),
486487
headers=headers,
487488
)
489+
490+
def _modify_rpc_url(self, agent_card: AgentCard, request: Request):
491+
rpc_url = URL(agent_card.url)
492+
rpc_path = rpc_url.path
493+
port = None
494+
if "X-Forwarded-Host" in request.headers:
495+
host = request.headers["X-Forwarded-Host"]
496+
else:
497+
host = request.url.hostname
498+
port = request.url.port
499+
500+
if "X-Forwarded-Proto" in request.headers:
501+
scheme = request.headers["X-Forwarded-Proto"]
502+
else:
503+
scheme = request.url.scheme
504+
if not scheme:
505+
scheme = "http"
506+
if ":" in host: # type: ignore
507+
comps = host.rsplit(":", 1) # type: ignore
508+
host = comps[0]
509+
port = comps[1]
510+
511+
# Handle URL maps,
512+
# e.g. "agents/my-agent/.well-known/agent-card.json"
513+
if "X-Forwarded-Path" in request.headers:
514+
forwarded_path = request.headers["X-Forwarded-Path"].strip()
515+
if (
516+
forwarded_path and
517+
request.url.path != forwarded_path
518+
and forwarded_path.endswith(request.url.path)
519+
):
520+
# "agents/my-agent" for "agents/my-agent/.well-known/agent-card.json"
521+
extra_path = forwarded_path[:-len(request.url.path)]
522+
new_path = extra_path + rpc_path
523+
# If original path was just "/",
524+
# we remove trailing "/" in the the extended one
525+
if len(new_path) > 1 and rpc_path == "/":
526+
new_path = new_path.rstrip("/")
527+
rpc_path = new_path
528+
529+
if port:
530+
agent_card.url = str(
531+
rpc_url.replace(
532+
hostname=host,
533+
port=port,
534+
scheme=scheme,
535+
path=rpc_path
536+
)
537+
)
538+
else:
539+
agent_card.url = str(
540+
rpc_url.replace(
541+
hostname=host,
542+
scheme=scheme,
543+
path=rpc_path
544+
)
545+
)
488546

489547
async def _handle_get_agent_card(self, request: Request) -> JSONResponse:
490548
"""Handles GET requests for the agent card endpoint.
@@ -502,8 +560,12 @@ async def _handle_get_agent_card(self, request: Request) -> JSONResponse:
502560
)
503561

504562
card_to_serve = self.agent_card
563+
rpc_url = card_to_serve.url
505564
if self.card_modifier:
506565
card_to_serve = self.card_modifier(card_to_serve)
566+
# If agent's RPC URL was not modified, we build it dynamically.
567+
if rpc_url == card_to_serve.url:
568+
self._modify_rpc_url(card_to_serve, request)
507569

508570
return JSONResponse(
509571
card_to_serve.model_dump(
@@ -528,13 +590,17 @@ async def _handle_get_authenticated_extended_agent_card(
528590

529591
card_to_serve = self.extended_agent_card
530592

593+
rpc_url = card_to_serve.url if card_to_serve else None
531594
if self.extended_card_modifier:
532595
context = self._context_builder.build(request)
533596
# If no base extended card is provided, pass the public card to the modifier
534597
base_card = card_to_serve if card_to_serve else self.agent_card
535598
card_to_serve = self.extended_card_modifier(base_card, context)
536599

537600
if card_to_serve:
601+
# If agent's RPC URL was not modified, we build it dynamically.
602+
if rpc_url == card_to_serve.url:
603+
self._modify_rpc_url(card_to_serve, request)
538604
return JSONResponse(
539605
card_to_serve.model_dump(
540606
exclude_none=True,

0 commit comments

Comments
 (0)