1414
1515# adapted from Google ADK models adk-python/blob/main/src/google/adk/models/lite_llm.py at f1f44675e4a86b75e72cfd838efd8a0399f23e24 · google/adk-python
1616
17+ import json
1718import uuid
1819from typing import Any , Dict , Optional , cast , List , Generator , Tuple , Union
1920
2021import litellm
21- from google .adk .models import LlmResponse
22+ from google .adk .models import LlmResponse , LlmRequest
23+ from google .adk .models .cache_metadata import CacheMetadata
2224from google .adk .models .lite_llm import (
2325 TextChunk ,
2426 FunctionChunk ,
@@ -139,6 +141,74 @@ def ark_field_reorganization(request_data: dict) -> dict:
139141 return request_data
140142
141143
144+ def build_cache_metadata (agent_response_id : dict ) -> CacheMetadata :
145+ """Create a new CacheMetadata instance for agent response tracking.
146+
147+ Args:
148+ agent_name: Name of the agent
149+ response_id: Response ID to track
150+
151+ Returns:
152+ A new CacheMetadata instance with the agent-response mapping
153+ """
154+ cache_name = json .dumps (agent_response_id )
155+ if "contents_count" in CacheMetadata .model_fields : # adk >= 1.17
156+ cache_metadata = CacheMetadata (
157+ cache_name = cache_name ,
158+ expire_time = 0 ,
159+ fingerprint = "" ,
160+ invocations_used = 0 ,
161+ contents_count = 0 ,
162+ )
163+ else : # 1.15 <= adk < 1.17
164+ cache_metadata = CacheMetadata (
165+ cache_name = cache_name ,
166+ expire_time = 0 ,
167+ fingerprint = "" ,
168+ invocations_used = 0 ,
169+ cached_contents_count = 0 ,
170+ )
171+ return cache_metadata
172+
173+
174+ def update_cache_metadata (
175+ cache_metadata : CacheMetadata ,
176+ agent_name : str ,
177+ response_id : str ,
178+ ) -> CacheMetadata :
179+ """Update cache metadata by creating a new instance with updated cache_name.
180+
181+ Since CacheMetadata is frozen, we cannot modify it directly. Instead,
182+ we create a new instance with the updated cache_name field.
183+ """
184+ try :
185+ agent_response_id = json .loads (cache_metadata .cache_name )
186+ agent_response_id [agent_name ] = response_id
187+ updated_cache_name = agent_response_id
188+
189+ # Create a new CacheMetadata instance with updated cache_name
190+ return build_cache_metadata (updated_cache_name )
191+ except json .JSONDecodeError as e :
192+ logger .warning (
193+ f"Failed to update cache metadata. The cache_name is not a valid JSON string., { str (e )} "
194+ )
195+ return cache_metadata
196+
197+
198+ def get_previous_response_id (
199+ cache_metadata : CacheMetadata ,
200+ agent_name : str ,
201+ ):
202+ try :
203+ agent_response_id = json .loads (cache_metadata .cache_name )
204+ return agent_response_id .get (agent_name , None )
205+ except json .JSONDecodeError as e :
206+ logger .warning (
207+ f"Failed to get previous response id. The cache_name is not a valid JSON string., { str (e )} "
208+ )
209+ return None
210+
211+
142212class CompletionToResponsesAPIHandler :
143213 def __init__ (self ):
144214 self .litellm_handler = LiteLLMResponsesTransformationHandler ()
@@ -231,7 +301,7 @@ def transform_response(
231301 return result_list
232302
233303 def openai_response_to_generate_content_response (
234- self , raw_response : OpenAITypeResponse
304+ self , llm_request : LlmRequest , raw_response : OpenAITypeResponse
235305 ) -> list [LlmResponse ]:
236306 """
237307 OpenAITypeResponse -> litellm.ModelResponse -> LlmResponse
@@ -246,6 +316,7 @@ def openai_response_to_generate_content_response(
246316 llm_response = _model_response_to_generate_content_response (model_response )
247317
248318 llm_response = self .adapt_responses_api (
319+ llm_request ,
249320 model_response ,
250321 llm_response ,
251322 )
@@ -254,6 +325,7 @@ def openai_response_to_generate_content_response(
254325
255326 def adapt_responses_api (
256327 self ,
328+ llm_request : LlmRequest ,
257329 model_response : ModelResponse ,
258330 llm_response : LlmResponse ,
259331 stream : bool = False ,
@@ -262,9 +334,21 @@ def adapt_responses_api(
262334 Adapt responses api.
263335 """
264336 if not model_response .id .startswith ("chatcmpl" ):
265- if llm_response .custom_metadata is None :
266- llm_response .custom_metadata = {}
267- llm_response .custom_metadata ["response_id" ] = model_response ["id" ]
337+ # if llm_response.custom_metadata is None:
338+ # llm_response.custom_metadata = {}
339+ # llm_response.custom_metadata["response_id"] = model_response["id"]
340+ previous_response_id = model_response ["id" ]
341+ if not llm_request .cache_metadata :
342+ llm_response .cache_metadata = build_cache_metadata (
343+ {llm_request .config .labels ["adk_agent_name" ]: previous_response_id }
344+ )
345+ else :
346+ llm_response .cache_metadata = update_cache_metadata (
347+ llm_request .cache_metadata ,
348+ llm_request .config .labels ["adk_agent_name" ],
349+ previous_response_id ,
350+ )
351+
268352 # add responses cache data
269353 if not stream :
270354 if model_response .get ("usage" , {}).get ("prompt_tokens_details" ):
0 commit comments