@@ -164,7 +164,9 @@ def _to_dict(value: object):
164
164
165
165
166
166
def _add_request_options_to_span (
167
- span : Span , config : Optional [GenerateContentConfigOrDict ], allow_list : AllowList
167
+ span : Span ,
168
+ config : Optional [GenerateContentConfigOrDict ],
169
+ allow_list : AllowList ,
168
170
):
169
171
if config is None :
170
172
return
@@ -208,7 +210,9 @@ def _add_request_options_to_span(
208
210
},
209
211
)
210
212
for key , value in attributes .items ():
211
- if key .startswith (GCP_GENAI_OPERATION_CONFIG ) and not allow_list .allowed (key ):
213
+ if key .startswith (
214
+ GCP_GENAI_OPERATION_CONFIG
215
+ ) and not allow_list .allowed (key ):
212
216
# The allowlist is used to control inclusion of the dynamic keys.
213
217
continue
214
218
span .set_attribute (key , value )
@@ -244,7 +248,9 @@ def _wrapped_config_with_tools(
244
248
if not config .tools :
245
249
return config
246
250
result = copy .copy (config )
247
- result .tools = [wrapped_tool (tool , otel_wrapper , ** kwargs ) for tool in config .tools ]
251
+ result .tools = [
252
+ wrapped_tool (tool , otel_wrapper , ** kwargs ) for tool in config .tools
253
+ ]
248
254
return result
249
255
250
256
@@ -267,10 +273,12 @@ def _create_completion_details_attributes(
267
273
) -> dict [str , Any ]:
268
274
attributes : dict [str , Any ] = {
269
275
gen_ai_attributes .GEN_AI_INPUT_MESSAGES : [
270
- dataclasses .asdict (input_message ) for input_message in input_messages
276
+ dataclasses .asdict (input_message )
277
+ for input_message in input_messages
271
278
],
272
279
gen_ai_attributes .GEN_AI_OUTPUT_MESSAGES : [
273
- dataclasses .asdict (output_message ) for output_message in output_messages
280
+ dataclasses .asdict (output_message )
281
+ for output_message in output_messages
274
282
],
275
283
}
276
284
if system_instructions :
@@ -463,43 +471,54 @@ def _maybe_log_completion_details(
463
471
system_instructions = to_system_instructions (
464
472
content = transformers .t_contents (system_content )[0 ]
465
473
)
466
- input_messages = to_input_messages (contents = transformers .t_contents (request ))
467
- output_messages = to_output_messages (candidates = response .candidates or [])
474
+ input_messages = to_input_messages (
475
+ contents = transformers .t_contents (request )
476
+ )
477
+ output_messages = to_output_messages (
478
+ candidates = response .candidates or []
479
+ )
468
480
469
481
span = None
470
482
if self ._content_recording_enabled in [
471
483
ContentCapturingMode .SPAN_ONLY ,
472
484
ContentCapturingMode .SPAN_AND_EVENT ,
473
485
]:
474
- completion_details_attributes = _create_completion_details_attributes (
475
- input_messages ,
476
- output_messages ,
477
- system_instructions ,
478
- as_str = True ,
486
+ completion_details_attributes = (
487
+ _create_completion_details_attributes (
488
+ input_messages ,
489
+ output_messages ,
490
+ system_instructions ,
491
+ as_str = True ,
492
+ )
479
493
)
480
494
span = trace .get_current_span ()
481
495
span .set_attributes (completion_details_attributes )
496
+
497
+ event = Event (
498
+ name = "gen_ai.client.inference.operation.details" ,
499
+ attributes = attributes ,
500
+ )
482
501
if self ._content_recording_enabled in [
483
502
ContentCapturingMode .EVENT_ONLY ,
484
503
ContentCapturingMode .SPAN_AND_EVENT ,
485
504
]:
486
- completion_details_attributes = _create_completion_details_attributes (
487
- input_messages ,
488
- output_messages ,
489
- system_instructions ,
490
- )
491
- attributes .update (completion_details_attributes )
492
- event = Event (
493
- name = "gen_ai.client.inference.operation.details" , attributes = attributes
494
- )
495
- self .completion_hook .on_completion (
496
- inputs = input_messages ,
497
- outputs = output_messages ,
498
- system_instruction = system_instructions ,
499
- span = span ,
500
- log_record = event ,
505
+ completion_details_attributes = (
506
+ _create_completion_details_attributes (
507
+ input_messages ,
508
+ output_messages ,
509
+ system_instructions ,
510
+ )
501
511
)
502
- self ._otel_wrapper .log_completion_details (event = event )
512
+ event .attributes .update (completion_details_attributes )
513
+
514
+ self .completion_hook .on_completion (
515
+ inputs = input_messages ,
516
+ outputs = output_messages ,
517
+ system_instruction = system_instructions ,
518
+ span = span ,
519
+ log_record = event ,
520
+ )
521
+ self ._otel_wrapper .log_completion_details (event = event )
503
522
504
523
def _maybe_log_system_instruction (
505
524
self , config : Optional [GenerateContentConfigOrDict ] = None
@@ -538,7 +557,9 @@ def _maybe_log_user_prompt(
538
557
total = len (contents )
539
558
index = 0
540
559
for entry in contents :
541
- self ._maybe_log_single_user_prompt (entry , index = index , total = total )
560
+ self ._maybe_log_single_user_prompt (
561
+ entry , index = index , total = total
562
+ )
542
563
index += 1
543
564
else :
544
565
self ._maybe_log_single_user_prompt (contents )
@@ -644,7 +665,9 @@ def _maybe_log_response_stats(self, response: GenerateContentResponse):
644
665
#
645
666
pass
646
667
647
- def _maybe_log_response_safety_ratings (self , response : GenerateContentResponse ):
668
+ def _maybe_log_response_safety_ratings (
669
+ self , response : GenerateContentResponse
670
+ ):
648
671
# TODO: Determine if there is a way that we can log
649
672
# the "prompt_feedback". This would be especially useful
650
673
# in the case where the response is blocked.
@@ -914,13 +937,18 @@ async def _response_async_generator_wrapper():
914
937
with trace .use_span (span , end_on_exit = True ):
915
938
try :
916
939
async for response in response_async_generator :
917
- if helper .sem_conv_opt_in_mode == _StabilityMode .DEFAULT :
940
+ if (
941
+ helper .sem_conv_opt_in_mode
942
+ == _StabilityMode .DEFAULT
943
+ ):
918
944
helper .process_response (response )
919
945
elif (
920
946
helper .sem_conv_opt_in_mode
921
947
== _StabilityMode .GEN_AI_LATEST_EXPERIMENTAL
922
948
):
923
- helper .process_completion (contents , response , config )
949
+ helper .process_completion (
950
+ contents , response , config
951
+ )
924
952
else :
925
953
raise ValueError (
926
954
f"Sem Conv opt in mode { helper .sem_conv_opt_in_mode } not supported."
@@ -966,12 +994,10 @@ def instrument_generate_content(
966
994
completion_hook ,
967
995
generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
968
996
)
969
- AsyncModels .generate_content_stream = (
970
- _create_instrumented_async_generate_content_stream (
971
- snapshot ,
972
- otel_wrapper ,
973
- completion_hook ,
974
- generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
975
- )
997
+ AsyncModels .generate_content_stream = _create_instrumented_async_generate_content_stream (
998
+ snapshot ,
999
+ otel_wrapper ,
1000
+ completion_hook ,
1001
+ generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
976
1002
)
977
1003
return snapshot
0 commit comments