1414
1515from __future__ import annotations
1616
17+ from urllib .parse import quote
18+ from urllib .parse import unquote
19+
1720ADK_METADATA_KEY_PREFIX = "adk_"
1821ADK_CONTEXT_ID_PREFIX = "ADK"
1922ADK_CONTEXT_ID_SEPARATOR = "/"
@@ -54,18 +57,23 @@ def _to_a2a_context_id(app_name: str, user_id: str, session_id: str) -> str:
5457 raise ValueError (
5558 "All parameters (app_name, user_id, session_id) must be non-empty"
5659 )
57- return ADK_CONTEXT_ID_SEPARATOR .join (
58- [ADK_CONTEXT_ID_PREFIX , app_name , user_id , session_id ]
59- )
60+ return ADK_CONTEXT_ID_SEPARATOR .join ([
61+ ADK_CONTEXT_ID_PREFIX ,
62+ quote (app_name , safe = "" ),
63+ quote (user_id , safe = "" ),
64+ quote (session_id , safe = "" ),
65+ ])
6066
6167
6268def _from_a2a_context_id (
6369 context_id : str | None ,
6470) -> tuple [str , str , str ] | tuple [None , None , None ]:
6571 """Converts an A2A context id to app name, user id and session id.
66- if context_id is None, return None, None, None
67- if context_id is not None, but not in the format of
68- ADK$app_name$user_id$session_id, return None, None, None
72+
73+ Reverses ``_to_a2a_context_id``. The context id is expected to be
74+ ``ADK/<app_name>/<user_id>/<session_id>`` with each field percent-encoded, so
75+ that ids containing the separator still round-trip. Returns (None, None, None)
76+ if context_id is None or does not match this format.
6977
7078 Args:
7179 context_id: The A2A context id.
@@ -76,16 +84,18 @@ def _from_a2a_context_id(
7684 if not context_id :
7785 return None , None , None
7886
79- try :
80- parts = context_id .split (ADK_CONTEXT_ID_SEPARATOR )
81- if len (parts ) != 4 :
82- return None , None , None
83-
84- prefix , app_name , user_id , session_id = parts
85- if prefix == ADK_CONTEXT_ID_PREFIX and app_name and user_id and session_id :
86- return app_name , user_id , session_id
87- except ValueError :
88- # Handle any split errors gracefully
89- pass
87+ parts = context_id .split (ADK_CONTEXT_ID_SEPARATOR )
88+ if len (parts ) != 4 :
89+ return None , None , None
90+
91+ prefix , app_name , user_id , session_id = parts
92+ if prefix != ADK_CONTEXT_ID_PREFIX :
93+ return None , None , None
94+
95+ app_name = unquote (app_name )
96+ user_id = unquote (user_id )
97+ session_id = unquote (session_id )
98+ if app_name and user_id and session_id :
99+ return app_name , user_id , session_id
90100
91101 return None , None , None
0 commit comments