From c5cf17ab3982fef16bdb64e06c6c148b91ad7756 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 28 May 2026 03:51:02 +0000 Subject: [PATCH] fix(agents): merge agent card even when agent_card_params is an empty dict Treat an explicitly provided empty agent_card_params ({}) as 'card provided but empty' instead of 'no card', so the LiteLLM-fronting merge still injects securitySchemes, supportedInterfaces, and protocolVersion. Without this, the well-known endpoint could serve a bare card with only a rewritten url, advertising no authentication to A2A clients. Co-authored-by: Yassin Kortam --- litellm/proxy/agent_endpoints/endpoints.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/litellm/proxy/agent_endpoints/endpoints.py b/litellm/proxy/agent_endpoints/endpoints.py index b5c5f9116b0..7de4297cdb2 100644 --- a/litellm/proxy/agent_endpoints/endpoints.py +++ b/litellm/proxy/agent_endpoints/endpoints.py @@ -381,7 +381,7 @@ async def create_agent( upstream_card = request.get("agent_card_params") agent_to_create: AgentConfig = request new_agent_id: Optional[str] = None - if upstream_card: + if upstream_card is not None: # Pre-generate the agent_id so the merged card can reference it # in ``supportedInterfaces`` before the DB row exists. new_agent_id = str(uuid.uuid4()) @@ -593,7 +593,7 @@ async def update_agent( # card for them. upstream_card = request.get("agent_card_params") agent_to_update: AgentConfig = request - if upstream_card: + if upstream_card is not None: merged_card = _build_merged_agent_card( upstream_card, agent_id=agent_id, @@ -697,14 +697,15 @@ async def patch_agent( # Get the user ID from the API key auth updated_by = user_api_key_dict.user_id or "unknown" - # Re-merge only when the patch actually touches agent_card_params with - # a non-empty card; a patch updating just litellm_params/rate limits - # shouldn't rewrite the stored card, and a patch clearing - # ``agent_card_params`` shouldn't synthesise a default A2A card for - # what is effectively a non-A2A agent. + # Re-merge only when the patch actually touches agent_card_params; a + # patch updating just litellm_params/rate limits (``agent_card_params`` + # omitted) shouldn't rewrite the stored card. An explicitly provided + # ``agent_card_params`` — even an empty dict — still goes through the + # merge so LiteLLM applies its security schemes and supported + # interfaces instead of storing a bare card. patch_payload: PatchAgentRequest = request upstream_card = request.get("agent_card_params") - if upstream_card: + if upstream_card is not None: merged_card = _build_merged_agent_card( upstream_card, agent_id=agent_id,