Ë
    uPêj@A  ã                   ó  — d Z ddlZddlmZmZmZmZmZmZ ddl	Z	ddl
mZ ddlmZ ddlmZmZ ddlmZ ddlmZ dd	lmZmZmZmZ erddlZdd
lmZ ddlmZm Z  ddl!m"Z" eZ#neZ#eZ eZeZ" G d„ de«      Z$ G d„ de«      Z%y)zÜ
Transformation for LangGraph API.

LangGraph provides streaming (/runs/stream) and non-streaming (/runs/wait) endpoints
for running agents.

Streaming endpoint: POST /runs/stream
Non-streaming endpoint: POST /runs/wait
é    N)ÚTYPE_CHECKINGÚAnyÚFinalÚOptionalÚUnionÚcast)Úverbose_logger)Úconvert_content_list_to_str)Ú
BaseConfigÚBaseLLMException©ÚLangGraphSSEStreamIterator)ÚAllMessageValues)ÚChoicesÚMessageÚModelResponseÚUsage)ÚLogging)ÚAsyncHTTPHandlerÚHTTPHandler©ÚCustomStreamWrapperc                   ó   — e Zd ZdZy)ÚLangGraphErrorz)Exception class for LangGraph API errors.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úo/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/langgraph/chat/transformation.pyr   r   (   s   „ Ú3r    r   c                   ó2  ‡ — e Zd ZdZˆ fd„Zdedz  dedz  deedz  edz  f   fd„Zdedee   fd	„Z	d
e
de
dedede
f
d„Z	 d/dedz  dedz  dede
de
dedz  defd„Zdede
defd„Zdee   dee
eef      fd„Zdedee   de
de
de
de
fd„Zde
defd„Zdedej*                  defd„Z	 	 	 d0dedededede
de
dedeedf   dz  dedz  d edz  defd!„Z	 	 	 d0dedededede
de
deded   dedz  d edz  defd"„Ze defd#„«       Z!e defd$„«       Z"	 	 d1dedej*                  d%e#ded&e
dee   de
de
d'd(dedz  dedz  de#fd)„Z$	 	 d1de
dedee   de
de
dedz  dedz  de
fd*„Z%d+ed,e&de
ejN                  z  de(fd-„Z)	 d/dedz  dedz  dedz  defd.„Z*ˆ xZ+S )2ÚLangGraphConfigzÉ
    Configuration for LangGraph API.

    LangGraph is a framework for building stateful, multi-actor applications with LLMs.
    It provides a streaming and non-streaming API for running agents.
    c                 ó$   •— t        ‰| �  di |¤Ž y )Nr   )ÚsuperÚ__init__)ÚselfÚkwargsÚ	__class__s     €r!   r&   zLangGraphConfig.__init__4   s   ø€ Ü‰ÑÑ"˜6Ó"r    Úapi_baseNÚapi_keyÚreturnc                 óN   — ddl m} |xs  |d«      xs d}|xs  |d«      }||fS )z‡
        Get LangGraph API base and key from params or environment.

        Returns:
            Tuple of (api_base, api_key)
        r   )Úget_secret_strÚLANGGRAPH_API_BASEzhttp://localhost:2024ÚLANGGRAPH_API_KEY)Úlitellm.secret_managers.mainr.   )r'   r*   r+   r.   s       r!   Ú$_get_openai_compatible_provider_infoz4LangGraphConfig._get_openai_compatible_provider_info7   s9   € õ 	@àÒ^™~Ð.BÓCÒ^ÐG^ˆàÒ@™^Ð,?Ó@ˆà˜Ð Ð r    Úmodelc                 ó   — dgS )zW
        LangGraph supports minimal OpenAI params since it's an agent runtime.
        Ústreamr   )r'   r3   s     r!   Úget_supported_openai_paramsz+LangGraphConfig.get_supported_openai_paramsJ   s   € ð ˆzÐr    Únon_default_paramsÚoptional_paramsÚdrop_paramsc                 ó   — |S )z8
        Map OpenAI params to LangGraph params.
        r   )r'   r7   r8   r3   r9   s        r!   Úmap_openai_paramsz!LangGraphConfig.map_openai_paramsP   s
   € ð Ðr    Úlitellm_paramsr5   c                 óV   — |€t        d«      ‚|j                  d«      }|r|› d�S |› d�S )z„
        Get the complete URL for the LangGraph request.

        Streaming: /runs/stream
        Non-streaming: /runs/wait
        z`api_base is required for LangGraph. Set it via LANGGRAPH_API_BASE env var or api_base parameter.ú/z/runs/streamz
/runs/wait)Ú
ValueErrorÚrstrip)r'   r*   r+   r3   r8   r<   r5   s          r!   Úget_complete_urlz LangGraphConfig.get_complete_url\   sI   € ð ÐÜØróð ð
 —?‘? 3Ó'ˆñ Ø�Z˜|Ð,Ð,à�Z˜zÐ*Ð*r    c                 ó‚   — |j                  d«      }|r|S d|v r%|j                  dd«      }t        |«      dk(  r|d   S |S )zŒ
        Get the assistant ID from model or optional_params.

        model format: "langgraph/assistant_id" or just "assistant_id"
        Úassistant_idr>   é   é   )ÚgetÚsplitÚlen)r'   r3   r8   rC   Úpartss        r!   Ú_get_assistant_idz!LangGraphConfig._get_assistant_idy   sO   € ð .×1Ñ1°.ÓAˆÙØÐð �%‰<Ø Ÿ;™; s¨AÓ.ˆEÜ�5‹z˜QŠØ˜Q‘x�Øˆr    Úmessagesc                 ó|  — g }|D ]´  }|j                  dd«      }|j                  dd«      }|dk(  rd}n|dk(  rd}n
|dk(  rd}nd}t        |t        «      rt        |«      }t        |t        «      st	        |«      }||dœ}|j                  d	«      }t        |t
        «      r|r||d	<   |j                  |«       Œ¶ |S )
a  
        Convert OpenAI-format messages to LangGraph format.

        OpenAI format: {"role": "user", "content": "..."}
        LangGraph format: {"role": "human", "content": "..."}

        Preserves per-message ``metadata`` when present (e.g. A2A ``skillId``).
        ÚroleÚuserÚcontentÚ ÚhumanÚ	assistantÚsystem)rM   rO   Úmetadata)rF   Ú
isinstanceÚlistr
   ÚstrÚdictÚappend)	r'   rK   Úlanggraph_messagesÚmsgrM   rO   Úlanggraph_roleÚlanggraph_messageÚmessage_metadatas	            r!   Ú%_convert_messages_to_langgraph_formatz5LangGraphConfig._convert_messages_to_langgraph_formatŠ   sã   € ð ;=ÐØò 	9ˆCØ—7‘7˜6 6Ó*ˆDØ—g‘g˜i¨Ó,ˆGð �vŠ~Ø!(‘Ø˜Ò$Ø!,‘Ø˜Ò!Ø!)‘à!(�ô ˜'¤4Ô(Ü5°cÓ:�ô ˜g¤sÔ+Ü˜g›,�ð 'Ø"ñ1Ðð  #Ÿw™w zÓ2ÐÜÐ*¬DÔ1Ñ6FØ0@Ð! *Ñ-à×%Ñ%Ð&7Õ8ð=	9ð@ "Ð!r    Úheadersc                 ó$  — | j                  ||«      }| j                  |«      }|d|idœ}|j                  dd«      }	|	r|j                  dd«      }
|
|d<   d|v r|d   |d<   d|v r|d   |d<   d	|v r|d	   |d	<   t        j                  d
|«       |S )a=  
        Transform the request to LangGraph format.

        LangGraph request format:
        {
            "assistant_id": "agent",
            "input": {
                "messages": [{"role": "human", "content": "..."}]
            },
            "stream_mode": "messages-tuple"  # for streaming
        }
        rK   )rC   Úinputr5   FÚstream_modezmessages-tupleÚconfigrT   Ú	thread_idzLangGraph request payload: %s)rJ   r_   rF   r	   Údebug)r'   r3   rK   r8   r<   r`   rC   rZ   Úpayloadr5   rc   s              r!   Útransform_requestz!LangGraphConfig.transform_request¶   sÑ   € ð( #×4Ñ4°U¸OÓLˆØ$(×$NÑ$NÈxÓ$XÐð )Ø Ð"4Ð5ñ*
ˆð '×*Ñ*¨8°UÓ;ˆÙØ!0×!4Ñ!4°]ÐDTÓ!UˆKØ%0ˆG�MÑ"ð �Ñ&Ø /°Ñ 9ˆG�HÑð ˜Ñ(Ø"1°*Ñ"=ˆG�JÑð ˜/Ñ)Ø#2°;Ñ#?ˆG�KÑ ä×ÑÐ<¸gÔFØˆr    Úresponse_jsonc                 óˆ  — |j                  dg «      }t        |t        «      re|rct        |«      D ]U  }t        |t        «      sŒ|j                  dd«      }|j                  dd«      }|dk(  s|dk(  sŒC|j                  dd«      c S  |j                  di «      }t        |t        «      rp|j                  dg «      }t        |t        «      rN|rLt        |«      D ]>  }t        |t        «      sŒ|j                  dd«      }|dk(  sŒ,|j                  dd«      c S  t        j                  d	«       t        j                  |«      S )
zì
        Extract content from LangGraph non-streaming response.

        Response format varies, but commonly:
        {
            "messages": [...],  # or could be in different structure
            "values": {...}
        }
        rK   ÚtyperP   rM   ÚairR   rO   Úvaluesz@Could not extract content from LangGraph response, returning raw)	rF   rU   rV   ÚreversedrX   r	   ÚwarningÚjsonÚdumps)r'   ri   rK   r[   Úmsg_typerM   rm   Úoutput_messagess           r!   Ú_extract_content_from_responsez.LangGraphConfig._extract_content_from_responseç   s!  € ð (×+Ñ+¨J¸Ó;ˆÜ�h¤Ô%©(ä Ó)ò 6�Ü˜c¤4Õ(Ø"Ÿw™w v¨rÓ2�HØŸ7™7 6¨2Ó.�DØ 4Ò'¨4°;Ó+>Ø"Ÿw™w y°"Ó5Ò5ð6ð &×)Ñ)¨(°BÓ7ˆÜ�fœdÔ#Ø%+§Z¡Z°
¸BÓ%?ˆOÜ˜/¬4Ô0±_Ü# OÓ4ò :�CÜ! #¤tÕ,Ø#&§7¡7¨6°2Ó#6˜Ø# tÓ+Ø#&§7¡7¨9°bÓ#9Ò9ð	:ô 	×ÑÐaÔbÜ�z‰z˜-Ó(Ð(r    Úraw_responsec                 ó   — t        ||¬«      S )z@
        Return a streaming iterator for SSE responses.
        )Úresponser3   r   )r'   r3   ru   s      r!   Úget_streaming_responsez&LangGraphConfig.get_streaming_response  s   € ô *°<ÀuÔMÐMr    Úcustom_llm_providerÚlogging_objÚdataÚclientr   Ú	json_modeÚsigned_json_bodyc                 ó´  — ddl m}m} ddlm} |�t        ||«      s	 |i ¬«      }t        j                  d|«       |j                  ||t        j                  |«      d|¬«      }|j                  dk7  r.t        |j                  t        |j                  «       «      ¬	«      ‚| j                  ||¬
«      } |||||¬«      }|j!                  |ddd|i¬«       |S )zF
        Get a CustomStreamWrapper for synchronous streaming.
        r   )r   Ú_get_httpx_clientr   )Úparamsz$Making sync streaming request to: %sT©r`   r{   r5   rz   éÈ   ©Ústatus_codeÚmessage©r3   ru   ©Úcompletion_streamr3   ry   rz   rP   úfirst stream response receivedÚcomplete_input_dict©rb   r+   Úoriginal_responseÚadditional_args)Ú&litellm.llms.custom_httpx.http_handlerr   r€   Úlitellm.utilsr   rU   r	   rf   Úpostrp   rq   r…   r   rW   Úreadrx   Ú	post_call)r'   r3   ry   rz   r*   r`   r{   rK   r|   r}   r~   r   r€   r   rw   r‰   Ústreaming_responses                    r!   Úget_sync_custom_stream_wrapperz.LangGraphConfig.get_sync_custom_stream_wrapper  sî   € ÷ 	
õ 	6àˆ>¤¨F°KÔ!@Ù&¨bÔ1ˆFä×ÑÐCÀXÔNð !Ÿ+™+ØØÜ—‘˜DÓ!ØØ#ð &ó 
ˆð ×Ñ 3Ò&Ü ¨X×-AÑ-AÌ3ÈxÏ}É}ËÓK_Ô`Ð`ð $(×#>Ñ#>ÀUÐYaÐ#>Ó#bÐá$7Ø/ØØ 3Ø#ô	%
Ðð 	×ÑØØØ>Ø2°DÐ9ð	 	ô 	
ð "Ð!r    c              ƒ   ó  K  — ddl m}m} ddlm} |�t        ||«      s |t        t        d«      i ¬«      }t        j                  d|«       |j                  ||t        j                  |«      d|¬	«      ƒ d{  –—† }|j                  d
k7  r6t        |j                  t        |j!                  «       ƒ d{  –—† «      ¬«      ‚| j#                  ||¬«      } |||||¬«      }|j%                  |ddd|i¬«       |S 7 Œ�7 ŒG­w)zG
        Get a CustomStreamWrapper for asynchronous streaming.
        r   )r   Úget_async_httpx_clientr   NÚ	langgraph)Úllm_providerr�   z%Making async streaming request to: %sTr‚   rƒ   r„   r‡   rˆ   rP   rŠ   r‹   rŒ   )r�   r   r—   r�   r   rU   r   r   r	   rf   r‘   rp   rq   r…   r   rW   Úareadrx   r“   )r'   r3   ry   rz   r*   r`   r{   rK   r|   r}   r~   r   r—   r   rw   r‰   r”   s                    r!   Úget_async_custom_stream_wrapperz/LangGraphConfig.get_async_custom_stream_wrapperP  s  è ø€ ÷ 	
õ 	6àˆ>¤¨FÐ4DÔ!EÙ+¼¼cÀ;Ó9OÐXZÔ[ˆFä×ÑÐDÀhÔOð !'§¡ØØÜ—‘˜DÓ!ØØ#ð !,ó !
÷ 
ˆð ×Ñ 3Ò&Ü ¨X×-AÑ-AÌ3ÐU]×UcÑUcÓUe×OeÓKfÔgÐgð $(×#>Ñ#>ÀUÐYaÐ#>Ó#bÐá$7Ø/ØØ 3Ø#ô	%
Ðð 	×ÑØØØ>Ø2°DÐ9ð	 	ô 	
ð "Ð!ð;
øð Pfús%   ‚A7C?Á9C;Á:;C?Â5C=Â6AC?Ã=C?c                  ó   — y)z8Indicates that this config has custom streaming support.Tr   ©r'   s    r!   Úhas_custom_stream_wrapperz)LangGraphConfig.has_custom_stream_wrapper‹  s   € ð r    c                  ó   — y)z}
        LangGraph does not use a stream param in request body.
        Streaming is determined by the endpoint URL.
        Fr   r�   s    r!   Ú%supports_stream_param_in_request_bodyz5LangGraphConfig.supports_stream_param_in_request_body�  s   € ð r    Úmodel_responseÚrequest_dataÚencodingztiktoken.Encoding | Nonec                 ó  — 	 |j                  «       }t        j                  d|«       | j                  |«      }t	        |d¬«      }t        dd|¬«      }|g|_        ||_        	 ddlm	}  |d|¬	«      } |d|d
¬«      }||z   }t        |||¬«      }t        |d|«       |S # t        $ r!}t        j                  d|«       Y d}~|S d}~ww xY w# t        $ r5}t        j                  d|«       t        d|› �|j                   ¬«      ‚d}~ww xY w)zS
        Transform the LangGraph response to LiteLLM ModelResponse format.
        zLangGraph response: %srR   )rO   rM   Ústopr   )Úfinish_reasonÚindexr†   )Útoken_counterzgpt-3.5-turbo)r3   rK   T)r3   ÚtextÚcount_response_tokens)Úprompt_tokensÚcompletion_tokensÚtotal_tokensÚusagez#Failed to calculate token usage: %sNz'Error processing LangGraph response: %szError processing response: )r†   r…   )rp   r	   rf   rt   r   r   Úchoicesr3   r�   r¨   r   ÚsetattrÚ	Exceptionro   Úerrorr   r…   )r'   r3   ru   r¡   rz   r¢   rK   r8   r<   r£   r+   r}   ri   rO   r†   Úchoicer¨   r«   r¬   r­   r®   Úes                         r!   Útransform_responsez"LangGraphConfig.transform_response˜  s2  € ð"(	Ø#/×#4Ñ#4Ó#6ˆMÜ× Ñ Ð!9¸=ÔIà!×@Ñ@ÀÓOˆGô %¨W¸;ÔGˆGô $°&ÀÈ7ÔSˆFð '- XˆNÔ"Ø#(ˆNÔ ðQÝ7á'4¸?ÐU]Ô'^�Ù$1¸ÈgÐmqÔ$rÐ!Ø&3Ð6GÑ&G�ä$Ø"/Ø&7Ø!-ô �ô
 ˜¨°Ô7ð "Ð!øô ò QÜ×&Ñ&Ð'LÈa×PÐPà!Ð!ûðQûô
 ò 	Ü× Ñ Ð!JÈAÔNÜ Ø5°a°SÐ9Ø(×4Ñ4ôð ûð	úsB   ‚A!C Á$;B! ÂC Â!	CÂ*CÃ C ÃCÃC Ã	DÃ0DÄDc                 ó$   — d|d<   |rd|› �|d<   |S )zI
        Validate and set up environment for LangGraph requests.
        zapplication/jsonzContent-TypezBearer ÚAuthorizationr   )r'   r`   r3   rK   r8   r<   r+   r*   s           r!   Úvalidate_environmentz$LangGraphConfig.validate_environmentÓ  s)   € ð #5ˆ�Ññ Ø)0°°	Ð':ˆG�OÑ$àˆr    Úerror_messager…   c                 ó   — t        ||¬«      S )Nr„   )r   )r'   r¹   r…   r`   s       r!   Úget_error_classzLangGraphConfig.get_error_classè  s   € Ü¨+¸}ÔMÐMr    c                  ó   — y)zZ
        LangGraph has native streaming support, so we don't need to fake stream.
        Fr   )r'   r3   r5   ry   s       r!   Úshould_fake_streamz"LangGraphConfig.should_fake_streamë  s   € ð r    )N)NNN)NN),r   r   r   r   r&   rW   Útupler2   rV   r6   rX   Úboolr;   rA   rJ   r   r   r_   rh   rt   ÚhttpxÚResponser   rx   ÚLiteLLMLoggingObjr   r   Úbytesr   r•   r   r›   Úpropertyrž   r    r   rµ   r¸   ÚintÚHeadersr   r»   r½   Ú__classcell__)r)   s   @r!   r#   r#   ,   s~  ø„ ñô#ð!à˜‘*ð!ð �t‘ð!ð 
ˆs�T‰z˜3 ™:Ð%Ñ	&ó	!ð&°ð ¸¸c¹ó ð
à ð
ð ð
ð ð	
ð
 ð
ð 
ó
ð& #ñ+à˜‘*ð+ð �t‘ð+ð ð	+ð
 ð+ð ð+ð �t‘ð+ð 
ó+ð: sð ¸Tð Àcó ð"*"¸dÐCSÑ>Tð *"ÐY]Ð^bÐcfÐhkÐckÑ^lÑYmó *"ðX/àð/ð Ð'Ñ(ð/ð ð	/ð
 ð/ð ð/ð 
ó/ðb")¸Dð ")ÀSó ")ðHNàðNð —n‘nðNð 
$ó	Nð& AEØ!%Ø)-ñ9"àð9"ð !ð9"ð 'ð	9"ð
 ð9"ð ð9"ð ð9"ð ð9"ð �kÐ#5Ð5Ñ6¸Ñ=ð9"ð ˜$‘;ð9"ð   $™,ð9"ð 
ó9"ðH 04Ø!%Ø)-ñ9"àð9"ð !ð9"ð 'ð	9"ð
 ð9"ð ð9"ð ð9"ð ð9"ð Ð+Ñ,ð9"ð ˜$‘;ð9"ð   $™,ð9"ð 
ó9"ðv ð¨4ò ó ðð ð°tò ó ðð$ #Ø!%ñ9àð9ð —n‘nð9ð &ð	9ð
 'ð9ð ð9ð Ð'Ñ(ð9ð ð9ð ð9ð -ð9ð �t‘ð9ð ˜$‘;ð9ð 
ó9ðD #Ø#ñàðð ðð Ð'Ñ(ð	ð
 ðð ðð �t‘ðð ˜‘*ðð 
óð*N¨Sð N¸sð NÈTÐTY×TaÑTaÑMað NÐfvó Nð +/ñ		à�T‰zð	ð �t‘ð	ð ! 4™Zð		ð
 
÷	r    r#   )&r   rp   Útypingr   r   r   r   r   r   rÀ   Úlitellm._loggingr	   Ú8litellm.litellm_core_utils.prompt_templates.common_utilsr
   Ú)litellm.llms.base_llm.chat.transformationr   r   Ú(litellm.llms.langgraph.chat.sse_iteratorr   Úlitellm.types.llms.openair   Úlitellm.types.utilsr   r   r   r   ÚtiktokenÚ*litellm.litellm_core_utils.litellm_loggingr   Ú_LiteLLMLoggingObjr�   r   r   r�   r   rÂ   r   r#   r   r    r!   ú<module>rÒ      sy   ðñó ß C× Cã å +õ÷ SÝ OÝ 6ß FÓ FáÛåXßTÝ1à*ÑàÐØ€KØÐØÐô4Ð%ô 4ôH�jõ Hr    