§
    ~ŠtjÛR  ã                   óè   — d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZmZ ddlmZ dd	lmZ  ej        e¦  «        Zg d
¢Z G d„ de¦  «        Zdedefd„Zddœdeddfd„ZdS )u  Transform Strands OTEL spans into LangSmith-compatible formats.

This module wraps the standard OTLPSpanExporter and intercepts spans before export,
remapping attributes, span names, and structure to align with LangSmith's expected
OTEL ingest schema.

Strands emits GenAI message data as span events (gen_ai.user.message,
gen_ai.assistant.message, gen_ai.choice, etc.), which is non-standard â€” the OTEL
GenAI semantic conventions define these as Log Events, not span events.  This
exporter flattens those span events into span attributes (gen_ai.prompt,
gen_ai.completion) that LangSmith's server-side OTEL ingest can consume directly.
é    N)ÚSequence)ÚAny)ÚOTLPSpanExporter)ÚReadableSpan)ÚBatchSpanProcessorÚConsoleSpanExporterÚSimpleSpanProcessorÚSpanExporterÚSpanExportResult)ÚStrandsTelemetry)Úrebuild_readable_span)ÚLangSmithSpanExporterÚcreate_langsmith_exporterÚsetup_langsmith_telemetryc                   ó  — e Zd ZU dZdeddfd„Zdee         defd„Z	d(d„Z
d)d
edefd„ZdddddœZeeef         ed<   ddiZeeef         ed<   ddddddœZeeef         ed<   h d£Zee         ed<   dedefd„Zddœdedeeef         deeef         dz  deeef         fd „Zeddœd!ee         deeef         dz  deeef         fd"„¦   «         Zed#edefd$„¦   «         Zed#edefd%„¦   «         Zed&edefd'„¦   «         ZdS )*r   a?  Span exporter that reformats Strands OTEL spans for LangSmith compatibility.

    Wraps a delegate exporter (typically OTLPSpanExporter pointed at LangSmith's
    OTEL endpoint) and transforms each span before forwarding it.

    Args:
        delegate: The underlying SpanExporter to forward transformed spans to.
    ÚdelegateÚreturnNc                 ó   — || _         dS )zƒInitialize the exporter.

        Args:
            delegate: The underlying SpanExporter to forward transformed spans to.
        N)Ú	_delegate)Úselfr   s     úl/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/integrations/strands_agents/exporter.pyÚ__init__zLangSmithSpanExporter.__init__3   s   € ð "ˆŒˆˆó    Úspansc                 ó$  — g }|D ]r}	 |                      |                      |¦  «        ¦  «         Œ,# t          $ r: t                               d|j        d¬¦  «         |                      |¦  «         Y Œow xY w| j                             |¦  «        S )zÈTransform spans and forward them to the delegate exporter.

        Args:
            spans: The batch of spans to export.

        Returns:
            The result from the delegate exporter.
        z/Failed to transform span %r, exporting originalT)Úexc_info)ÚappendÚ_transform_spanÚ	ExceptionÚloggerÚwarningÚnamer   Úexport)r   r   ÚtransformedÚspans       r   r#   zLangSmithSpanExporter.export;   s·   € ð ˆØð 		)ð 		)ˆDð)Ø×"Ò" 4×#7Ò#7¸Ñ#=Ô#=Ñ>Ô>Ð>Ð>øÝð )ð )ð )Ý—’ØEØ”IØ!ð ñ ô ð ð
 ×"Ò" 4Ñ(Ô(Ð(Ð(Ð(ð)øøøð Œ~×$Ò$ [Ñ1Ô1Ð1s   ˆ(1±AA5Á4A5c                 ó8   — | j                              ¦   «          dS )z Shut down the delegate exporter.N)r   Úshutdown)r   s    r   r'   zLangSmithSpanExporter.shutdownQ   s   € àŒ×ÒÑ!Ô!Ð!Ð!Ð!r   é0u  Útimeout_millisc                 ó6   — | j                              |¦  «        S )z¹Force flush the delegate exporter.

        Args:
            timeout_millis: Maximum time to wait for flush to complete.

        Returns:
            True if flush succeeded.
        )r   Úforce_flush)r   r)   s     r   r+   z!LangSmithSpanExporter.force_flushU   s   € ð Œ~×)Ò)¨.Ñ9Ô9Ð9r   ÚllmÚchainÚtool)ÚchatÚinvoke_agentÚexecute_toolÚexecute_event_loop_cycleÚ_OPERATION_TO_RUN_TYPEr2   Ú_SPAN_NAME_TO_RUN_TYPEÚuserÚ	assistantÚsystem)úgen_ai.user.messageúgen_ai.assistant.messageúgen_ai.system.messageúgen_ai.tool.messageúgen_ai.choiceÚ_EVENT_ROLE_MAP>   r<   r;   r8   r:   r9   Ú_MESSAGE_EVENTSr%   c                 ó¶  — |j         rt          |j         ¦  «        ni }|                     dd¦  «        }t          |t          ¦  «        r|nd}|                     dd¦  «        }t          |t          ¦  «        r|nd}|                     dd¦  «        }t          |t          ¦  «        r|nd}i }	|r|r||	|<   g }
g }d}g }|j        D �]J}|j        }|j         rt          |j         ¦  «        ni }|dk    rÉ|dk    rŽ|                     dd	¦  «        }	 t          |t          ¦  «        rt          j        |¦  «        n|}n# t          j	        t          f$ r |}Y nw xY wt          j        d
|                      |¦  «        ||dœ¦  «        }ŒÁ|                      |||	¬¦  «        }|r||d<   |                     |¦  «         Œö|| j        v r6|                      |||	¬¦  «        }|r||d<   |
                     |¦  «         �Œ5|                     |¦  «         �ŒLt          |¦  «        }|
rt          j        d|
i¦  «        |d<   |�||d<   n|rt          j        |d         ¦  «        |d<   | j                             |¦  «        }|s| j                             |j        ¦  «        }|r||d<   |dk    r|                     d¦  «        r
d|d<   d|d<   t%          |||¬¦  «        S )uö  Flatten span events into prompt/completion attributes.

        Strands attaches GenAI message data as span events.  LangSmith expects
        them as JSON-serialized span attributes instead.  Each message object
        gets a ``role`` field injected when one can be inferred from the event
        name and isn't already present in the payload.

        All conversation history (user, system, tool, and intermediate assistant
        messages) is placed into ``gen_ai.prompt``.  Only the final
        ``gen_ai.choice`` event â€” the model's actual response â€” goes into
        ``gen_ai.completion``.

        Args:
            span: The original Strands span.

        Returns:
            A new ReadableSpan with the message attributes added.
        zgen_ai.operation.nameÚ zgen_ai.tool.call.idzgen_ai.tool.nameNr<   r1   Úmessageú[]r.   )ÚroleÚcontentr"   Útool_call_id©Útool_id_to_namerE   Úmessageszgen_ai.promptzgen_ai.completionéÿÿÿÿzlangsmith.span.kindr,   zgen_ai.systemÚamazon_bedrockzlangsmith.metadata.ls_providerr/   z langsmith.metadata.ls_model_type)Ú
attributesÚevents)rK   ÚdictÚgetÚ
isinstanceÚstrrL   r"   ÚjsonÚloadsÚJSONDecodeErrorÚ	TypeErrorÚdumpsÚ_extract_tool_outputÚ_event_to_messager   r>   r3   r4   r   )r   r%   Ú
span_attrsÚoperation_rawÚ	operationÚtool_call_id_rawrE   Útool_name_rawÚ	tool_namerG   Úinput_messagesÚoutput_messagesÚtool_output_completionÚremaining_eventsÚeventr"   ÚattrsÚrawrD   ÚmsgÚ	new_attrsÚrun_types                         r   r   z%LangSmithSpanExporter._transform_span„   s’  € ð& /3¬oÐE•T˜$œ/Ñ*Ô*Ð*À2ˆ
Ø"ŸšÐ'>ÀÑCÔCˆÝ%/°½sÑ%CÔ%CÐK�M�MÈˆ	à%Ÿ>š>Ð*?ÀÑDÔDÐÝ+5Ð6FÍÑ+LÔ+LÐTÐ'Ð'ÐRTˆØ"ŸšÐ'9¸2Ñ>Ô>ˆÝ%/°½sÑ%CÔ%CÐK�M�MÈˆ	ð
 +-ˆØð 	6˜ð 	6Ø,5ˆO˜LÑ)à/1ˆØ02ˆØ-1ÐØ&(Ðà”[ð '	/ñ '	/ˆEØ”:ˆDØ.3Ô.>ÐF•D˜Ô)Ñ*Ô*Ð*ÀBˆEà�Ò&Ð&Ø Ò.Ð.ð  Ÿ)š) I¨tÑ4Ô4�Cð&Ý5?ÀÅSÑ5IÔ5IÐ"R¥$¤*¨S¡/¤/ /Ès˜˜øÝ Ô0µ)Ð<ð &ð &ð &Ø"%˜˜˜ð&øøøå-1¬Zà$*Ø'+×'@Ò'@ÀÑ'IÔ'IØ$-Ø,8ð	ð ñ.ô .Ð*Ð*ð ×0Ò0Ø˜e°_ð 1ñ ô �Cð $ð ;Ø.:˜˜NÑ+Ø#×*Ò*¨3Ñ/Ô/Ð/Ð/Ø˜Ô-Ð-Ð-Ø×,Ò,Ø˜%°ð -ñ ô �ð  ð 7Ø*6�C˜Ñ'Ø×%Ò% cÑ*Ô*Ð*Ñ*ð !×'Ò'¨Ñ.Ô.Ð.Ñ.õ %)¨Ñ$4Ô$4ˆ	Øð 	RÝ)-¬°ZÀÐ4PÑ)QÔ)QˆI�oÑ&Ø!Ð-Ø-CˆIÐ)Ñ*Ð*Øð 	MÝ-1¬Z¸ÈÔ8KÑ-LÔ-LˆIÐ)Ñ*ð
 Ô.×2Ò2°9Ñ=Ô=ˆØð 	BØÔ2×6Ò6°t´yÑAÔAˆHØð 	8Ø/7ˆIÐ+Ñ,ð �uÒÐ §¢¨Ñ!?Ô!?ÐØ:JˆIÐ6Ñ7Ø<BˆIÐ8Ñ9å$Ø˜YÐ/?ð
ñ 
ô 
ð 	
s   Ä+D;Ä;EÅErF   Ú
event_namerc   rG   c                óX  — | j                              |d¦  «        }|dk    r|                     dd¦  «        }n|                     dd¦  «        }	 t          |t          ¦  «        rt	          j        |¦  «        n|}n# t          j        t          f$ r |}Y nw xY w|dk    r.t          |t          ¦  «        r|  	                    ||pi ¬¦  «        S t          |t          ¦  «        r‰g }|D ]‚}|�Vt          |t          ¦  «        rAd	|v r=|d	         }	|	                     d
d¦  «        |	                     dd¦  «        }}
|
r|r|||
<   |                     |                      |¦  «        ¦  «         Œƒ|}|dk    r|                      |¦  «        }||dœ}d|v r|d         |d<   d|v r|d         |d<   |S )a’  Convert a span event into a message dict, injecting ``role`` if missing.

        For ``gen_ai.choice`` events the content lives under the ``message``
        key; for all other events it lives under ``content``.  In both cases
        the value may be a JSON-encoded string that we parse back so the final
        attribute is cleanly nested.

        Args:
            event_name: The OTEL event name (e.g. ``gen_ai.user.message``).
            attrs: The event's attribute dict.
            tool_id_to_name: Optional mapping of tool-call IDs to tool names.

        Returns:
            A message dict with at least ``role`` and ``content`` keys.
        Úunknownr<   rA   rB   rD   r;   rF   NÚtoolUseÚ	toolUseIdr@   r"   ©rC   rD   ÚidrE   Úfinish_reason)r=   rN   rO   rP   rQ   rR   rS   rT   ÚlistÚ_flatten_tool_result_messagerM   r   Ú_convert_content_blockÚ_stringify_tool_content)r   rh   rc   rG   rC   rd   rD   Ú	convertedÚblockÚtuÚtidÚtnamere   s                r   rW   z'LangSmithSpanExporter._event_to_message÷   s  € ð, Ô#×'Ò'¨
°IÑ>Ô>ˆð ˜Ò(Ð(Ø—)’)˜I tÑ,Ô,ˆCˆCà—)’)˜I tÑ,Ô,ˆCð	Ý)3°C½Ñ)=Ô)=ÐF•d”j ‘o”o�oÀ3ˆGˆGøÝÔ$¥iÐ0ð 	ð 	ð 	ØˆGˆGˆGð	øøøð Ð.Ò.Ð.µ:¸gÅtÑ3LÔ3LÐ.Ø×4Ò4ØØ /Ð 5°2ð 5ñ ô ð õ �g�tÑ$Ô$ð 	 ØˆIØ ð 
Eð 
E�à#Ð/Ý" 5­$Ñ/Ô/ð 0à! UÐ*Ð*à˜yÔ)�BØ!#§¢¨°RÑ!8Ô!8¸"¿&º&ÀÈÑ:LÔ:L˜�CØð 5˜uð 5Ø/4˜¨Ñ,Ø× Ò  ×!<Ò!<¸UÑ!CÔ!CÑDÔDÐDÐDØˆGàÐ.Ò.Ð.Ø×2Ò2°7Ñ;Ô;ˆGà'+¸Ð@Ð@ˆð �5ˆ=ˆ=Ø"'¨¤+ˆC�Ñð ˜eÐ#Ð#Ø#(¨Ô#9ˆC�Ñ àˆ
s   Á+A< Á<BÂBÚcontent_blocksc                ó:  — d}g }g }| D ]´}t          |t          ¦  «        rˆd|v r„|d         }|s|                     dd¦  «        }|                     dg ¦  «        D ]L}t          |t          ¦  «        r d|v r|                     |d         ¦  «         Œ7|                     |¦  «         ŒMŒŸ|                     |¦  «         Œµ|rd                     |¦  «        }n|}dt
                               |¦  «        dœ}	|pi                      |d¦  «        }
|
r|
|	d	<   |r||	d
<   |	S )a  Flatten Bedrock ``toolResult`` content blocks into a LangSmith tool message.

        Bedrock tool results arrive as::

            [
                {
                    "toolResult": {
                        "toolUseId": "x",
                        "status": "success",
                        "content": [{"text": "..."}],
                    }
                }
            ]

        LangSmith expects tool messages as::

            {"role": "tool", "name": "my_tool", "tool_call_id": "x", "content": "..."}

        If there are multiple toolResult blocks they are joined with newlines.
        Non-toolResult blocks are converted normally and appended.

        Args:
            content_blocks: The parsed content block list from the event.
            tool_id_to_name: Optional mapping of tool-call IDs to tool names.

        Returns:
            A flat tool message dict.
        r@   Ú
toolResultrl   rD   Útextú
r.   rm   r"   rE   )rO   rM   rN   r   Újoinr   rs   )ry   rG   rE   Ú
text_partsÚother_blocksru   ÚtrÚnestedÚflat_contentre   r]   s              r   rq   z2LangSmithSpanExporter._flatten_tool_result_messageF  ss  € ðD ˆØ "ˆ
Ø"$ˆà#ð 	+ð 	+ˆEÝ˜%¥Ñ&Ô&ð +¨<¸5Ð+@Ð+@Ø˜<Ô(�Ø#ð ;Ø#%§6¢6¨+°rÑ#:Ô#:�Là Ÿfšf Y°Ñ3Ô3ð 4ð 4�FÝ! &­$Ñ/Ô/ð 4°F¸fÐ4DÐ4DØ"×)Ò)¨&°¬.Ñ9Ô9Ð9Ð9à$×+Ò+¨FÑ3Ô3Ð3Ð3ð	4ð ×#Ò# EÑ*Ô*Ð*Ð*àð 	(Ø $§	¢	¨*Ñ 5Ô 5ˆLˆLà'ˆLð Ý,×DÒDÀ\ÑRÔRð
ð 
ˆð
 %Ð*¨×/Ò/°¸bÑAÔAˆ	Øð 	$Ø#ˆC�‰KØð 	/Ø".ˆC�ÑØˆ
r   rD   c                 óœ  — t          | t          ¦  «        r| S t          | t          ¦  «        räg }| D ]­}t          |t          ¦  «        r3d|v r/t	          |¦  «        dk    r|                     |d         ¦  «         ŒJ	 |                     t          j        |d¬¦  «        ¦  «         Œu# t          t          f$ r% |                     t          |¦  «        ¦  «         Y Œªw xY w|r0t	          |¦  «        dk    rd 
                    |¦  «        n|d         S 	 t          j        | d¬¦  «        S # t          t          f$ r t          | ¦  «        cY S w xY w)a%  Extract plain-text output from tool result content blocks.

        Strands tool spans emit their output as a list of content blocks
        (e.g. ``[{"text": "Hippopotamus"}]``). This extracts the text and
        returns it as a plain string for ``gen_ai.completion`` on tool spans.
        r|   é   F©Úensure_asciir}   r   )rO   rP   rp   rM   Úlenr   rQ   rU   rT   Ú
ValueErrorr~   )rD   r   ru   s      r   rV   z*LangSmithSpanExporter._extract_tool_output‹  sr  € õ �g�sÑ#Ô#ð 	ØˆNå�g�tÑ$Ô$ð 	WØ$&ˆJØ ð 6ð 6�Ý˜e¥TÑ*Ô*ð 6¨v¸¨¨Å3ÀuÁ:Ä:ÐQRÂ?À?Ø×%Ò% e¨F¤mÑ4Ô4Ð4Ð4ð6Ø"×)Ò)­$¬*°UÈÐ*OÑ*OÔ*OÑPÔPÐPÐPøÝ%¥zÐ2ð 6ð 6ð 6Ø"×)Ò)­#¨e©*¬*Ñ5Ô5Ð5Ð5Ð5ð6øøøàð WÝ03°J±´À!Ò0CÐ0C�t—y’y Ñ,Ô,Ð,ÈÐTUÌÐVð	 Ý”:˜g°EÐ:Ñ:Ô:Ð:øÝ�:Ð&ð 	 ð 	 ð 	 Ý�w‘<”<ÐÐÐð	 øøøs$   Á<)B&Â&3CÃCÄD( Ä( EÅ
Ec                 óª   — t          | t          ¦  «        r| S 	 t          j        | d¬¦  «        S # t          t
          f$ r t          | ¦  «        cY S w xY w)ay  Ensure tool message content is a string.

        Strands emits tool-call inputs as JSON-serialized objects in
        ``gen_ai.tool.message`` events. After parsing event payloads for the
        rest of the exporter, convert those tool inputs back to strings so
        LangSmith receives tool message content as either a plain string or a
        stringified object.
        Fr†   )rO   rP   rQ   rU   rT   r‰   )rD   s    r   rs   z-LangSmithSpanExporter._stringify_tool_content¨  sg   € õ �g�sÑ#Ô#ð 	ØˆNð	 Ý”:˜g°EÐ:Ñ:Ô:Ð:øÝ�:Ð&ð 	 ð 	 ð 	 Ý�w‘<”<ÐÐÐð	 øøøs   ™/ ¯ AÁAru   c                 ó†  — t          | t          ¦  «        s| S d| v rt          | ¦  «        dk    rd| d         dœS d| v rL| d         }|                     di ¦  «        }d|                     dd¦  «        |                     dd¦  «        d	œS d
| v rK| d
         }d|                     dd¦  «        |                     dd¦  «        |                     di ¦  «        dœS d| v rd| d         }d|                     dd¦  «        dœ}d|v r|d         |d<   d|v r.|d         }t          |t          ¦  «        rd„ |D ¦   «         }||d<   |S | S )a~  Convert a single Bedrock/Converse content block to LangSmith format.

        Bedrock uses implicit typing (the key name *is* the type)::

            {"text": "hello"}
            {"reasoningContent": {"reasoningText": {"text": "...", "signature": "..."}}}
            {"toolUse": {"toolUseId": "x", "name": "f", "input": {...}}}
            {"toolResult": {"toolUseId": "x", "status": "success", "content": [...]}}

        LangSmith expects explicit ``type`` fields::

            {"type": "text", "text": "hello"}
            {"type": "thinking", "thinking": "...", "signature": "..."}
            {"type": "tool_use", "id": "x", "name": "f", "input": {...}}
            {
                "type": "tool_result",
                "tool_use_id": "x",
                "status": "success",
                "content": [...],
            }

        Unrecognised blocks are returned as-is.
        r|   r…   )Útyper|   ÚreasoningContentÚreasoningTextÚthinkingr@   Ú	signature)rŒ   r�   r�   rk   Útool_userl   r"   Úinput)rŒ   rn   r"   r’   r{   Útool_result)rŒ   Útool_use_idÚstatusrD   c                 óB   — g | ]}t                                |¦  «        ‘ŒS © )r   rr   )Ú.0Úbs     r   ú
<listcomp>z@LangSmithSpanExporter._convert_content_block.<locals>.<listcomp>ö  s4   € ð ð ð ØLMÕ-×DÒDÀQÑGÔGðð ð r   )rO   rM   rˆ   rN   rp   )ru   ÚrcÚreasoning_textrv   r�   rt   r‚   s          r   rr   z,LangSmithSpanExporter._convert_content_block¹  s¬  € õ2 ˜%¥Ñ&Ô&ð 	ØˆLà�Uˆ?ˆ?�s 5™zœz¨Qš˜Ø"¨E°&¬MÐ:Ð:Ð:à Ð&Ð&ØÐ)Ô*ˆBØŸVšV O°RÑ8Ô8ˆNà"Ø*×.Ò.¨v°rÑ:Ô:Ø+×/Ò/°¸RÑ@Ô@ðð ð ð ˜ÐÐØ�yÔ!ˆBà"Ø—f’f˜[¨"Ñ-Ô-ØŸš˜v rÑ*Ô*ØŸš ¨Ñ,Ô,ð	ð ð ð ˜5Ð Ð Ø�|Ô$ˆBà%Ø!Ÿvšv k°2Ñ6Ô6ð)ð )ˆIð ˜2ˆ~ˆ~Ø&(¨¤l�	˜(Ñ#Ø˜Bˆˆà˜Iœ�Ý˜f¥dÑ+Ô+ð ðð ØQWðñ ô �Fð (.�	˜)Ñ$ØÐð ˆr   )r   N)r(   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r   r   r   r#   r'   ÚintÚboolr+   r3   rM   rP   Ú__annotations__r4   r=   r>   Úsetr   r   rW   Ústaticmethodrp   rq   rV   rs   rr   r—   r   r   r   r   )   s÷  € € € € € € ðð ð" ð "°$ð "ð "ð "ð "ð2˜H \Ô2ð 2Ð7Gð 2ð 2ð 2ð 2ð,"ð "ð "ð "ð	:ð 	:¨#ð 	:¸$ð 	:ð 	:ð 	:ð 	:ð ØØØ$+ð	.ð .Ð˜D  c œNð ð ñ ð 	# Gð.Ð˜D  c œNð ð ñ ð  &Ø$/Ø!)Ø%Ø$ð'ð '€O�T˜#˜s˜(”^ð ð ñ ð!ð !ð !€O�S˜”Xð ð ñ ðq
 Lð q
°\ð q
ð q
ð q
ð q
ðp 26ðMð Mð MàðMð �C˜�HŒ~ðMð
 ˜c 3˜hœ¨$Ñ.ðMð 
ˆc�3ˆhŒðMð Mð Mð Mð^ ð 26ðBð Bð BØ˜Sœ	ðBð ˜c 3˜hœ¨$Ñ.ðBð 
ˆc�3ˆhŒð	Bð Bð Bñ „\ðBðH ð  cð  ¨cð  ð  ð  ñ „\ð ð8 ð ¨ð  °ð  ð  ð  ñ „\ð ð  ðC cð C¨cð Cð Cð Cñ „\ðCð Cð Cr   r   Úotlp_kwargsr   c                  ó:   — t          di | ¤Ž}t          |¬¦  «        S )aS  Create a LangSmithSpanExporter wrapping a standard OTLPSpanExporter.

    Keyword arguments are forwarded to OTLPSpanExporter (endpoint, headers, etc.).
    If not provided, the exporter will fall back to the standard OTEL_EXPORTER_OTLP_*
    environment variables.

    Returns:
        A ready-to-use LangSmithSpanExporter instance.
    ©r   r—   )r   r   )r¦   r   s     r   r   r     s(   € õ  Ð.Ð. +Ð.Ð.€HÝ ¨(Ð3Ñ3Ô3Ð3r   F)Úconsoler©   c                 ó  — t          ¦   «         }t          ¦   «         }|j                             t	          |¦  «        ¦  «         | rEt          t          ¦   «         ¬¦  «        }|j                             t          |¦  «        ¦  «         dS dS )aM  Wire up Strands telemetry with the LangSmith-compatible exporter.

    Call this instead of (or in addition to) the standard
    ``StrandsTelemetry().setup_otlp_exporter()`` flow.

    Args:
        console: If True, also add a ConsoleSpanExporter that prints transformed
                 spans to stdout (useful for debugging).
    r¨   N)r   r   Útracer_providerÚadd_span_processorr   r   r   r	   )r©   Ú	telemetryÚexporterÚconsole_exporters       r   r   r     s•   € õ !Ñ"Ô"€IÝ(Ñ*Ô*€HØÔ×0Ò0Õ1CÀHÑ1MÔ1MÑNÔNÐNàð 
Ý0Õ:MÑ:OÔ:OÐPÑPÔPÐØÔ!×4Ò4ÝÐ 0Ñ1Ô1ñ	
ô 	
ð 	
ð 	
ð 	
ð
ð 
r   )r    rQ   ÚloggingÚcollections.abcr   Útypingr   Ú5opentelemetry.exporter.otlp.proto.http.trace_exporterr   Úopentelemetry.sdk.tracer   Úopentelemetry.sdk.trace.exportr   r   r	   r
   r   Ústrands.telemetryr   Ú$langsmith._internal.otel._span_utilsr   Ú	getLoggerr�   r    Ú__all__r   r   r¢   r   r—   r   r   ú<module>rº      s‹  ððð ð €€€Ø €€€Ø $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð à RÐ RÐ RÐ RÐ RÐ RØ 0Ð 0Ð 0Ð 0Ð 0Ð 0ðð ð ð ð ð ð ð ð ð ð ð ð ð ð /Ð .Ð .Ð .Ð .Ð .à FÐ FÐ FÐ FÐ FÐ Fà	ˆÔ	˜8Ñ	$Ô	$€ðð ð €ðTð Tð Tð Tð T˜Lñ Tô Tð Tðx4¨Sð 4Ð5Jð 4ð 4ð 4ð 4ð 27ð 
ð 
ð 
¨$ð 
¸4ð 
ð 
ð 
ð 
ð 
ð 
r   