Ë
    tPêj:(  ã                   óF  — U d Z ddlmZ ddlmZ ddlmZmZmZ ddlm	Z	 erddl
mZ ddlmZ eez  ZneZdZeed	<    G d
„ de«      ZeD � ci c]  } | j$                  | “Œ c} Zeed<   dddddœZeed<   dddœZeed<   dZeed<   dedz  dee   fd„Z G d„ d«      Zyc c} w )a{  OTEL GenAI ``gen_ai_latest_experimental`` semantic conventions.

Setting ``OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental`` switches the
emitted traces to the experimental OTEL GenAI conventions
(https://opentelemetry.io/docs/specs/semconv/gen-ai/). Concretely, versus the
default LiteLLM output:

Request span:

- name is ``{operation} {model}`` (e.g. ``chat gpt-4``) instead of
  ``litellm_request``; span kind is ``CLIENT``.
- ``gen_ai.operation.name`` is the actual operation (``chat`` /
  ``text_completion`` / ``embeddings``) instead of always ``chat``.
- the provider is reported as ``gen_ai.provider.name``; the superseded
  ``gen_ai.system`` and the legacy ``llm.is_streaming`` are dropped.
- adds ``gen_ai.request.{frequency_penalty,presence_penalty,top_k,seed}``,
  ``gen_ai.request.stop_sequences`` (a string array),
  ``gen_ai.request.stream`` (only when streaming),
  ``gen_ai.request.choice.count`` (only when n > 1), and
  ``gen_ai.usage.cache_{creation,read}.input_tokens``.
- the non-standard ``raw_gen_ai_request`` child span is no longer created.

Events:

- the per-message ``gen_ai.content.prompt`` / per-choice
  ``gen_ai.content.completion`` log events are replaced by a single
  ``gen_ai.client.inference.operation.details`` log event carrying
  ``gen_ai.input.messages`` / ``gen_ai.output.messages`` (message content
  included only when content capture is enabled).
é    )Údatetime)ÚEnum)ÚTYPE_CHECKINGÚAnyÚFinal)Ú
safe_dumps)ÚSpan)ÚOpenTelemetryConfigÚOTEL_SEMCONV_STABILITY_OPT_INÚ!OTEL_SEMCONV_STABILITY_OPT_IN_ENVc                   ó   — e Zd ZdZy)ÚOTELSemconvCategoryÚgen_ai_latest_experimentalN)Ú__name__Ú
__module__Ú__qualname__ÚGEN_AI_LATEST_EXPERIMENTAL© ó    ú|/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/integrations/opentelemetry_utils/gen_ai_semconv.pyr   r   5   s   „ Ø!=Ñr   r   Ú_SEMCONV_CATEGORY_BY_VALUEz gen_ai.request.frequency_penaltyzgen_ai.request.presence_penaltyzgen_ai.request.top_kzgen_ai.request.seed)Úfrequency_penaltyÚpresence_penaltyÚtop_kÚseedÚ_SEMCONV_REQUEST_ATTRIBUTESz(gen_ai.usage.cache_creation.input_tokensz$gen_ai.usage.cache_read.input_tokens)Úcache_creation_input_tokensÚcache_read_input_tokensÚ_SEMCONV_CACHE_TOKEN_ATTRIBUTESz)gen_ai.client.inference.operation.detailsÚ_INFERENCE_DETAILS_EVENT_NAMEÚrawNÚreturnc                 óŽ   — | s
t        «       S d„ | j                  d«      D «       D �ch c]  }|t        v r	t        |   ’Œ c}S c c}w )z‘Parse the comma-separated OTEL_SEMCONV_STABILITY_OPT_IN value into the
    set of recognized categories. Unknown tokens are ignored per the spec.c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­w©N)Ústrip)Ú.0Úparts     r   ú	<genexpr>z'parse_semconv_opt_in.<locals>.<genexpr>W   s   è ø€ Ò> t�d—j‘j—lÑ>ùs   ‚ú,)ÚsetÚsplitr   )r!   Útokens     r   Úparse_semconv_opt_inr.   P   sK   € ñ Ü‹uˆñ ?¨s¯y©y¸«~Ô>öàØÔ.Ñ.ô 	# 5Ó)òð ùò s   §Ac            
       ó6  — e Zd ZU dZerIded<   dedededdfd	„Z	de
fd
„Zdee   ez  dee   fd„Zdee   dee   fd„Zdedefd„Zdeeef   fd„Zede
fd„«       Zededefd„«       Zdededdfd„Zdeddfd„Zdedededeeef   fd„Zdedededdfd„Zy)ÚOTELGenAISemconvMixinaX  OTEL GenAI ``gen_ai_latest_experimental`` semantic-convention behavior.

    Mixed into ``OpenTelemetry`` (its only host). Every member is internal to
    the OTEL integration; the leading underscore marks "subsystem-internal",
    not "class-private" (the host lives in a sibling module).

    Members the host calls (the mixin -> host contract):

    - ``_gen_ai_semconv_latest_experimental`` -- opt-in gate; guards every
      semconv code path in ``opentelemetry.py``.
    - ``_gen_ai_operation_name`` -- LiteLLM ``call_type`` -> spec
      ``gen_ai.operation.name``.
    - ``_set_semconv_request_attributes`` /
      ``_set_semconv_cache_token_attributes`` -- add the ``gen_ai.request.*``
      / ``gen_ai.usage.cache_*`` span attributes.
    - ``_emit_inference_details_event`` -- emit the consolidated event.

    Helpers the host must provide (declared under ``TYPE_CHECKING`` below):
    ``config``, ``safe_set_attribute``, ``_capture_in_event``,
    ``_transform_messages_to_otel_semantic_conventions``,
    ``_transform_choices_to_otel_semantic_conventions``, ``_to_ns``,
    ``_otel_log_types``.
    r
   ÚconfigÚspanÚkeyÚvaluer"   Nc                  ó   — y r%   r   )Úselfr2   r3   r4   s       r   Úsafe_set_attributez(OTELGenAISemconvMixin.safe_set_attributex   ó   � r   c                  ó   — y r%   r   ©r6   s    r   Ú_capture_in_eventz'OTELGenAISemconvMixin._capture_in_eventz   r8   r   Úmessagesc                  ó   — y r%   r   )r6   r<   s     r   Ú0_transform_messages_to_otel_semantic_conventionszFOTELGenAISemconvMixin._transform_messages_to_otel_semantic_conventions|   r8   r   Úchoicesc                  ó   — y r%   r   )r6   r?   s     r   Ú/_transform_choices_to_otel_semantic_conventionszEOTELGenAISemconvMixin._transform_choices_to_otel_semantic_conventions~   r8   r   Údtc                  ó   — y r%   r   )r6   rB   s     r   Ú_to_nszOTELGenAISemconvMixin._to_ns€   r8   r   c                  ó   — y r%   r   r:   s    r   Ú_otel_log_typesz%OTELGenAISemconvMixin._otel_log_types‚   r8   r   c                 óN   — t         j                  | j                  j                  v S )z“Whether the ``gen_ai_latest_experimental`` opt-in is active.

        Every semconv behavior is gated on this; ``False`` => legacy output.
        )r   r   r1   Úsemconv_stability_opt_inr:   s    r   Ú#_gen_ai_semconv_latest_experimentalz9OTELGenAISemconvMixin._gen_ai_semconv_latest_experimental„   s   € ô #×=Ñ=ÀÇÁ×AeÑAeÐeÐer   Úkwargsc                 óP   — | j                  dd«      xs d}|x}d|v r y}d|v ry	 y)z§Map a LiteLLM ``call_type`` to spec ``gen_ai.operation.name``.

        Substring match (e.g. ``aembedding`` -> ``embeddings``); defaults to
        ``chat``.
        Ú	call_typeÚ Ú	embeddingÚ
embeddingsÚtext_completionÚchat)Úget)rJ   rL   Úss      r   Ú_gen_ai_operation_namez,OTELGenAISemconvMixin._gen_ai_operation_nameŒ   s?   € ð "Ÿ:™: k°2Ó6Ò<¸"ˆ	ØÙ�k QÑ&�Ø#ØÐ'¨1Ñ,Ø(ØØr   Úoptional_paramsc           	      óú  — t         j                  «       D ]-  \  }}|j                  |«      }|€Œ| j                  |||¬«       Œ/ |j                  d«      }|�>t	        |t
        «      r|n|g}|j                  d|D �cg c]  }t        |«      ‘Œ c}«       |j                  d«      r| j                  |dd¬«       |j                  d«      }	t	        |	t        «      r|	d	kD  r| j                  |d
|	¬«       yyyc c}w )zØAdd ``gen_ai.request.*`` span attributes from ``optional_params``.

        Covers the sampling params plus the conditionally-required
        ``stop_sequences`` / ``stream`` / ``choice.count`` per the spec.
        N©r2   r3   r4   Ústopzgen_ai.request.stop_sequencesÚstreamzgen_ai.request.streamTÚné   zgen_ai.request.choice.count)	r   ÚitemsrR   r7   Ú
isinstanceÚlistÚset_attributeÚstrÚint)
r6   r2   rU   Ú
source_keyÚsemconv_keyr4   rX   Ú	stop_listrS   rZ   s
             r   Ú_set_semconv_request_attributesz5OTELGenAISemconvMixin._set_semconv_request_attributesœ   s  € ô (C×'HÑ'HÓ'Jò 	QÑ#ˆJ˜Ø#×'Ñ'¨
Ó3ˆEØÑ Ø×'Ñ'¨T°{È%Ð'ÕPð	Qð
 &×)Ñ)¨&Ó1ˆØÐô (2°$¼Ô'=™tÀDÀ6ˆIØ×ÑÐ>ÐQZÖ@[ÈAÄÀQÅÒ@[Ô\ð ×Ñ˜xÔ(Ø×#Ñ#¨Ð3JÐRVÐ#ÔWð
 #×&Ñ& sÓ+ˆÜ�aœÔ ! a¢%Ø×#Ñ#¨Ð3PÐXYÐ#ÕZð #(Ðùò A\s   Á=C8
c                 óâ   — |sy|j                  d«      xs i j                  d«      xs i }t        j                  «       D ]-  \  }}|j                  |«      }|sŒ| j                  |||¬«       Œ/ y)z�Add ``gen_ai.usage.cache_*.input_tokens`` from the usage object.

        No-op when the payload or the usage values are missing/zero.
        NÚmetadataÚusage_objectrW   )rR   r   r\   r7   )r6   r2   Ústandard_logging_payloadÚusagerb   rc   r4   s          r   Ú#_set_semconv_cache_token_attributesz9OTELGenAISemconvMixin._set_semconv_cache_token_attributes¹   su   € ñ
 (ØØ0×4Ñ4°ZÓ@ÒFÀB×KÑKÈNÓ[ÒaÐ_aˆÜ'F×'LÑ'LÓ'Nò 	QÑ#ˆJ˜Ø—I‘I˜jÓ)ˆEÚØ×'Ñ'¨T°{È%Ð'ÕPñ	Qr   Úresponse_objÚproviderc                 ó&  — t         || j                  |«      dœ}| j                  «       s|S | j                  |j	                  d«      xs g «      }| j                  |j	                  dg «      «      }|rt        |«      |d<   |rt        |«      |d<   |S )zÞBuild the attribute payload for the inference-details event.

        Always includes provider/operation; input/output messages are added
        only when content capture is enabled and non-empty. Mixin-internal.
        )Ú
event_namezgen_ai.provider.namezgen_ai.operation.namer<   r?   zgen_ai.input.messageszgen_ai.output.messages)r    rT   r;   r>   rR   rA   r   )r6   rJ   rl   rm   ÚattrsÚinput_messagesÚoutput_messagess          r   Ú_build_inference_details_attrsz4OTELGenAISemconvMixin._build_inference_details_attrsÆ   s    € ô 8Ø$,Ø%)×%@Ñ%@ÀÓ%Hñ(
ˆð
 ×%Ñ%Ô'ØˆLà $× UÑ UÐV\×V`ÑV`ÐakÓVlÒVrÐprÓ sˆØ!%×!UÑ!UÐVb×VfÑVfÐgpÐrtÓVuÓ!vˆÙÜ-7¸Ó-GˆEÐ)Ñ*ÙÜ.8¸Ó.IˆEÐ*Ñ+Øˆr   c                 ó   — | j                  «       \  }} || j                  t        j                  «       «      |j                  |j
                  |j                  |j                  dd| j                  |||«      ¬«      }|j                  |«       y)zØEmit the consolidated ``gen_ai.client.inference.operation.details``
        log event, correlated to the request span via ``parent_ctx``.

        Replaces the legacy per-message / per-choice content events.
        ÚINFON)Ú	timestampÚtrace_idÚspan_idÚtrace_flagsÚseverity_numberÚseverity_textÚbodyÚ
attributes)
rF   rD   r   Únowrw   rx   ry   ru   rs   Úemit)	r6   rJ   rl   rm   Úotel_loggerÚ
parent_ctxÚ	LogRecordÚSeverityNumberÚ
log_records	            r   Ú_emit_inference_details_eventz3OTELGenAISemconvMixin._emit_inference_details_eventÜ   s€   € ð %)×$8Ñ$8Ó$:Ñ!ˆ	�>Ù%Ø—k‘k¤(§,¡,£.Ó1Ø×(Ñ(Ø×&Ñ&Ø"×.Ñ.Ø*×/Ñ/Ø ØØ×:Ñ:¸6À<ÐQYÓZô	
ˆ
ð 	×Ñ˜Õ$r   )r   r   r   Ú__doc__r   Ú__annotations__r	   r`   r   r7   Úboolr;   r^   Údictr>   rA   r   ra   rD   ÚtuplerF   ÚpropertyrI   ÚstaticmethodrT   re   rk   rs   r…   r   r   r   r0   r0   \   sT  … ññ0 Ø%Ó%àS¨4ÐS°cÐSÀ#ÐSÈ$ÓSà0 tÓ0àqÈTÐRVÉZÐZ]ÑM]ÐqÐbfÐgkÑblÓqàiÈ4ÐPTÉ:ÐiÐZ^Ð_cÑZdÓià2˜XÐ2¨#Ó2à9 U¨3°¨8¡_Ó9àðf°Tò fó ðfð ð tð °ò ó ðð[°Dð [È4ð [ÐTXó [ð:Q¸ð QÐ[_ó Qð°Tð Èð ÐY\ð ÐaeÐfiÐknÐfnÑaoó ð,%àð%ð ð%ð ð	%ð 
ô%r   r0   )r†   r   Úenumr   Útypingr   r   r   Ú*litellm.litellm_core_utils.safe_json_dumpsr   Úopentelemetry.tracer	   Ú_SpanÚ"litellm.integrations.opentelemetryr
   r   r‡   r   r4   r   r   r   r    r`   r+   r.   r0   )Úcategorys   0r   ú<module>r”      sâ   ðòõ> Ý ß ,Ñ ,å AáÝ1åFà�3‰;�Dà€Dð
 ,KÐ ! 5Ó Jô>˜$ô >ð
 ObÖ$bÀ( X§^¡^°XÑ%=Ò$bÐ ˜EÓ bð
 <Ø9Ø#Ø!ñ	&Ð ˜Uó ð $NØEñ*Ð  ó ð (SÐ ˜uÓ Rð	˜c D™jð 	¨SÐ1DÑ-Eó 	÷X%ò X%ùòE %cs   ÁB