3030from google .genai .errors import ClientError
3131from typing_extensions import override
3232
33- from ..utils ._google_client_headers import get_tracking_headers
34- from ..utils ._google_client_headers import merge_tracking_headers
33+ from ..utils ._client_labels_utils import get_client_labels
3534from ..utils .context_utils import Aclosing
3635from ..utils .streaming_utils import StreamingResponseAggregator
3736from ..utils .variant_utils import GoogleLLMVariant
@@ -192,7 +191,7 @@ async def generate_content_async(
192191 if llm_request .config :
193192 if not llm_request .config .http_options :
194193 llm_request .config .http_options = types .HttpOptions ()
195- llm_request .config .http_options .headers = merge_tracking_headers (
194+ llm_request .config .http_options .headers = self . _merge_tracking_headers (
196195 llm_request .config .http_options .headers
197196 )
198197
@@ -303,7 +302,7 @@ def api_client(self) -> Client:
303302
304303 return Client (
305304 http_options = types .HttpOptions (
306- headers = get_tracking_headers (),
305+ headers = self . _tracking_headers (),
307306 retry_options = self .retry_options ,
308307 )
309308 )
@@ -316,6 +315,15 @@ def _api_backend(self) -> GoogleLLMVariant:
316315 else GoogleLLMVariant .GEMINI_API
317316 )
318317
318+ def _tracking_headers (self ) -> dict [str , str ]:
319+ labels = get_client_labels ()
320+ header_value = ' ' .join (labels )
321+ tracking_headers = {
322+ 'x-goog-api-client' : header_value ,
323+ 'user-agent' : header_value ,
324+ }
325+ return tracking_headers
326+
319327 @cached_property
320328 def _live_api_version (self ) -> str :
321329 if self ._api_backend == GoogleLLMVariant .VERTEX_AI :
@@ -331,7 +339,7 @@ def _live_api_client(self) -> Client:
331339
332340 return Client (
333341 http_options = types .HttpOptions (
334- headers = get_tracking_headers (), api_version = self ._live_api_version
342+ headers = self . _tracking_headers (), api_version = self ._live_api_version
335343 )
336344 )
337345
@@ -354,10 +362,8 @@ async def connect(self, llm_request: LlmRequest) -> BaseLlmConnection:
354362 ):
355363 if not llm_request .live_connect_config .http_options .headers :
356364 llm_request .live_connect_config .http_options .headers = {}
357- llm_request .live_connect_config .http_options .headers = (
358- merge_tracking_headers (
359- llm_request .live_connect_config .http_options .headers
360- )
365+ llm_request .live_connect_config .http_options .headers .update (
366+ self ._tracking_headers ()
361367 )
362368 llm_request .live_connect_config .http_options .api_version = (
363369 self ._live_api_version
@@ -441,6 +447,23 @@ async def _preprocess_request(self, llm_request: LlmRequest) -> None:
441447 llm_request .config .system_instruction = None
442448 await self ._adapt_computer_use_tool (llm_request )
443449
450+ def _merge_tracking_headers (self , headers : dict [str , str ]) -> dict [str , str ]:
451+ """Merge tracking headers to the given headers."""
452+ headers = headers or {}
453+ for key , tracking_header_value in self ._tracking_headers ().items ():
454+ custom_value = headers .get (key , None )
455+ if not custom_value :
456+ headers [key ] = tracking_header_value
457+ continue
458+
459+ # Merge tracking headers with existing headers and avoid duplicates.
460+ value_parts = tracking_header_value .split (' ' )
461+ for custom_value_part in custom_value .split (' ' ):
462+ if custom_value_part not in value_parts :
463+ value_parts .append (custom_value_part )
464+ headers [key ] = ' ' .join (value_parts )
465+ return headers
466+
444467
445468def _build_function_declaration_log (
446469 func_decl : types .FunctionDeclaration ,
0 commit comments