Ë
    uPêjªˆ  ã                   óZ  — d 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 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 ddlmZ ddlmZmZmZmZ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* ddl+m,Z, ddlm-Z- ddl$m.Z.  G d„ ded¬«      Z/ G d„ ded¬«      Z0 G d„ de«      Z1y)a¢  
OpenAI Responses API Handler for Unified Guardrails

This module provides a class-based handler for OpenAI Responses API format.
The class methods can be overridden for custom behavior.

Pattern Overview:
-----------------
1. Extract text content from input/output (both string and list formats)
2. Create async tasks to apply guardrails to each text segment
3. Track mappings to know where each response belongs
4. Apply guardrail responses back to the original structure

Responses API Format:
---------------------
Input: Union[str, List[Dict]] where each dict has:
  - role: str
  - content: Union[str, List[Dict]] (can have text items)
  - type: str (e.g., "message")

Output: response.output is List[GenericResponseOutputItem] where each has:
  - type: str (e.g., "message")
  - id: str
  - status: str
  - role: str
  - content: List[OutputText] where OutputText has:
    - type: str (e.g., "output_text")
    - text: str
é    )ÚSequence)ÚTYPE_CHECKINGÚAnyÚFinalÚUnionÚcast)ÚResponseFunctionToolCall)ÚFunctionToolParam)Ú	BaseModel)ÚReadOnlyÚ	TypedDict)Úverbose_proxy_logger)Ú-OpenAiResponsesToChatCompletionStreamIterator)ÚBaseTranslation)Ú LiteLLMCompletionResponsesConfig)ÚAllMessageValuesÚChatCompletionToolCallChunkÚChatCompletionToolParamÚOpenAIMcpServerToolÚResponsesAPIStreamEvents)ÚGenericResponseOutputItemÚOutputFunctionToolCallÚ
OutputText)ÚGenericGuardrailAPIInputs)ÚCustomGuardrail)ÚLogging)ÚUserAPIKeyAuth)ÚResponseInputParam)ÚResponsesAPIResponsec                   ó>   — e Zd ZU dZeee      ed<   eedz     ed<   y)ÚResponseOutputEnvelopezODict form of a Responses API response, as far as guardrail write-back reads it.ÚoutputNÚmodel)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   ÚobjectÚ__annotations__Ústr© ó    ú€/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/openai/responses/guardrail_translation/handler.pyr!   r!   E   s$   … ÙYà�X˜fÑ%Ñ&Ó&Ø�C˜$‘JÑÔr,   r!   F)Útotalc                   ó2   — e Zd ZU dZee   ed<   ee   ed<   y)ÚResponsesStreamChunkzPResponses API streaming event, as far as the accumulated-stream helpers read it.ÚtypeÚtextN)r$   r%   r&   r'   r   r*   r)   r+   r,   r-   r0   r0   L   s   … ÙZà
�3‰-ÓØ
�3‰-Ôr,   r0   c                   óâ  — e Zd ZdZdedee   dz  fd„Z	 d.dedddd	deee	f   fd
„Z
dedee   fd„Zdeeez     dee   ddfd„Zdee   deeee	f      fd„Zdeeee	f      deeee	f      deeee	f      fd„Zdedeeee	f      dee   dz  ddfd„Zdededee   dee   deeeedz  f      ddfd„Zdedee   deeeedz  f      ddfd„Z	 	 	 d/dedef   dddd	d d!d"edz  dedef   fd#„Z	 	 	 d/d$ee   dddd	d d!d"edz  dee   fd%„Zd$ee   defd&„Zd$ee   defd'„Z dddefd(„Z!	 d.d)e	d*edee   dee   deeeef      d+ee"   dz  ddfd,„Z#dedef   dee   deeeef      ddfd-„Z$y)0ÚOpenAIResponsesHandlera  
    Handler for processing OpenAI Responses API with guardrails.

    This class provides methods to:
    1. Process input (pre-call hook)
    2. Process output response (post-call hook)

    Methods can be overridden to customize behavior for different message formats.
    ÚdataÚreturnNc                 óŽ   — |j                  d«      }|€yt        j                  ||¬«      }|rt        t        t
           |«      S dS )zÖ
        Convert Responses API request data to OpenAI-spec structured messages.

        Transforms `input` (string or ResponseInputParam) and optional
        `instructions` into chat completion messages.
        ÚinputN)r8   Úresponses_api_request)Úgetr   Ú)transform_responses_api_input_to_messagesr   Úlistr   )Úselfr5   Ú
input_dataÚmessagess       r-   Úget_structured_messagesz.OpenAIResponsesHandler.get_structured_messages^   sN   € ð !ŸH™H WÓ-ˆ
ØÐØÜ:×dÑdØØ"&ô
ˆñ :BŒt”DÔ)Ñ*¨HÓ5ÐKÀtÐKr,   Úguardrail_to_applyr   Úlitellm_logging_objzLiteLLMLoggingObj | Nonec              ƒ   ó¬  K  — |j                  d«      }g }|€|S | j                  |«      }t        |t        «      rÕt	        |g¬«      }g }d|v r/|d   r*t        |d   «      }| j                  |d   |«       |r||d<   |r||d<   |j                  d«      }	|	r|	|d<   |j                  ||d|¬«      ƒ d{  –—† }
|
j                  d	g «      }|r|d
   n||d<   | j                  |||
j                  d«      «       t        j                  d«       |S t        |t
        «      s|S g }g }g }t        |j                  d«      xs g «      }t        |«      D ]  \  }}| j                  |||||¬«       Œ d|v r|d   r| j                  |d   |«       |r¦t	        |¬«      }|r||d<   |r||d<   |r||d<   |j                  d«      }	|	r|	|d<   |j                  ||d|¬«      ƒ d{  –—† }
|
j                  d	g «      }| j                  |||
j                  d«      «       | j                  |||¬«      ƒ d{  –—†  t        j                  d|«       |S 7 �Œ™7 Œo7 Œ!­w)z‡
        Process input by applying guardrails to text content.

        Handles both string input and list of message objects.
        r8   N©ÚtextsÚtoolsÚstructured_messagesr#   Úrequest©ÚinputsÚrequest_dataÚ
input_typeÚlogging_objrE   r   z,OpenAI Responses API: Processed string input)ÚmessageÚmsg_idxÚtexts_to_checkÚimages_to_checkÚtask_mappingsÚimages)r?   Ú	responsesrR   z2OpenAI Responses API: Processed input messages: %s)r:   r@   Ú
isinstancer*   r   r<   Ú_extract_and_transform_toolsÚapply_guardrailÚ _apply_guardrailed_tools_to_datar   ÚdebugÚ	enumerateÚ_extract_input_text_and_imagesÚ#_apply_guardrail_responses_to_input)r=   r5   rA   rB   r>   Útools_to_checkrG   rJ   Úoriginal_toolsr#   Úguardrailed_inputsÚguardrailed_textsrP   rQ   rR   Úoriginal_tools_listrO   rN   s                     r-   Úprocess_input_messagesz-OpenAIResponsesHandler.process_input_messagesn   sÚ  è ø€ ð >B¿X¹XÀgÓ=Nˆ
Ø?AˆØÐØˆKà%)×%AÑ%AÀ$Ó%GÐô �j¤#Ô&Ü.°j°\ÔBˆFØ68ˆNð ˜$‰ 4¨¢=Ü!% d¨7¡mÓ!4�Ø×1Ñ1°$°w±-ÀÔPÙ!Ø&4�F˜7‘OÙ"Ø0C�Ð,Ñ-à—H‘H˜WÓ%ˆEÙØ"'��w‘à'9×'IÑ'IØØ!Ø$Ø/ð	 (Jó (÷ "Ðð !3× 6Ñ 6°wÀÓ CÐÙ4EÐ-¨aÒ0È:ˆD�‰MØ×1Ñ1°$¸ÐHZ×H^ÑH^Ð_fÓHgÔhÜ ×&Ñ&Ð'UÔVØˆKô ˜*¤dÔ+ØˆKà+-ˆØ,.ˆØ=?ˆÜ>BÀ4Ç8Á8ÈGÓCTÒCZÐXZÓ>[Ðô !*¨*Ó 5ò 	ÑˆG�WØ×/Ñ/ØØØ-Ø /Ø+ð 0õ ð	ð �d‰?˜t Gš}Ø×-Ñ-¨d°7©m¸^ÔLñ Ü.°^ÔDˆFÙØ#2��xÑ ÙØ"0��w‘Ù"Ø0C�Ð,Ñ-à—H‘H˜WÓ%ˆEÙØ"'��w‘Ø'9×'IÑ'IØØ!Ø$Ø/ð	 (Jó (÷ "Ðð !3× 6Ñ 6°wÀÓ CÐØ×1Ñ1ØØ#Ø"×&Ñ& wÓ/ôð ×:Ñ:Ø#Ø+Ø+ð ;ó ÷ ð ô 	×"Ñ"Ð#WÐYcÔdàˆðO"ùð`"øðús8   ‚B2IÂ4IÂ5D+IÇ IÇ!AIÈ0IÈ1IÉIÉIc                 ól  — g }|j                  d«      xs g D ]™  }t        |t        «      sŒ|j                  d«      dv r/|j                  d«      r|j                  t	        |d   «      «       ŒV|j                  d«      dk(  sŒk|j                  d«      sŒ}|j                  t	        |d   «      «       Œ› |S )z{Extract tool names from Responses API request (tools[].name for function
        and custom, tools[].server_label for mcp).rF   r1   )ÚfunctionÚcustomÚnameÚmcpÚserver_label)r:   rU   ÚdictÚappendr*   )r=   r5   ÚnamesÚtools       r-   Úextract_request_tool_namesz1OpenAIResponsesHandler.extract_request_tool_namesÛ   sž   € ð #%ˆØ—H‘H˜WÓ%Ò+¨ò 	8ˆDÜ˜d¤DÔ)ØØ�x‰x˜ÓÐ#9Ñ9¸d¿h¹hÀvÔ>NØ—‘œS  f¡Ó.Õ/Ø—‘˜&Ó! UÓ*¨t¯x©x¸Õ/GØ—‘œS  nÑ!5Ó6Õ7ð	8ð ˆr,   rF   r]   c                 ó¨   — |�Pt        |t        «      r?t        j                  |«      \  }}|j	                  t        t        t           |«      «       yyy)zö
        Extract and transform tools from Responses API format to Chat Completion format.

        Uses the LiteLLM transformation function to convert Responses API tools
        to Chat Completion tools that can be passed to guardrails.
        N)rU   r<   r   Ú6transform_responses_api_tools_to_chat_completion_toolsÚextendr   r   )r=   rF   r]   Útransformed_toolsÚ_s        r-   rV   z3OpenAIResponsesHandler._extract_and_transform_toolsè   sS   € ð Ð¤¨E´4Ô!8ô
 1×gÑgÐhmÓnñØ!Øà×!Ñ!¤$¤tÔ,CÑ'DÐFWÓ"XÕYð "9Ðr,   Úguardrailed_toolsc                 ó,   — t        j                  |«      S )z|
        Remap guardrail-returned tools (Chat Completion format) back to
        Responses API request tool format.
        )r   Ú<transform_chat_completion_tool_params_to_responses_api_tools)r=   rs   s     r-   Ú$_remap_tools_to_responses_api_formatz;OpenAIResponsesHandler._remap_tools_to_responses_api_formatû   s   € ô
 0×lÑlØó
ð 	
r,   r^   Úremappedc                 ó  — |s|S g }d}|D ]_  }t        |t        «      r%|j                  d«      dv r|j                  |«       Œ8|t	        |«      k  sŒG|j                  ||   «       |dz  }Œa |j                  ||d «       |S )aK  
        Merge remapped guardrailed tools with original tools that were not sent
        to the guardrail (e.g. web_search, web_search_preview), preserving order.
        Tools a guardrail appended (``remapped`` longer than ``original_tools``)
        have no original slot and are kept so an injected tool is not dropped.
        r   r1   )Ú
web_searchÚweb_search_previewé   N)rU   ri   r:   rj   Úlenrp   )r=   r^   rw   ÚresultÚjrl   s         r-   Ú_merge_tools_after_guardrailz3OpenAIResponsesHandler._merge_tools_after_guardrail  s�   € ñ ØˆOØ13ˆØˆØ"ò 		ˆDÜ˜$¤Ô%¨$¯(©(°6Ó*:ð ?ñ +ð —‘˜dÕ#à”s˜8“}Ó$Ø—M‘M (¨1¡+Ô.Ø˜‘F‘Að		ð 	�‰�h˜q˜r�lÔ#Øˆr,   c                 óV   — |�'| j                  |«      }| j                  ||«      |d<   yy)z`Remap guardrailed tools to Responses API format and merge with original, then set data['tools'].NrF   )rv   r   )r=   r5   r^   rs   rw   s        r-   rX   z7OpenAIResponsesHandler._apply_guardrailed_tools_to_data!  s6   € ð Ð(Ø"×GÑGÐHYÓZˆHØ ×=Ñ=¸nÈhÓWˆD�ŠMð )r,   rN   rO   rP   rQ   rR   c                 ó>  — |j                  dd«      }|€yt        |t        «      r%|j                  |«       |j                  |df«       yt        |t        «      rÃt        |«      D ]´  \  }}t        |t        «      sŒ|j                  dd«      }	|	�-|j                  |	«       |j                  |t        |«      f«       |j                  d«      dk(  sŒm|j                  di «      }
t        |
t        «      sŒ�|
j                  d«      }|sŒ¤|j                  |«       Œ¶ yy)z�
        Extract text content and images from an input message.

        Override this method to customize text/image extraction logic.
        ÚcontentNr2   r1   Ú	image_urlÚurl)r:   rU   r*   rj   r<   rZ   ri   Úint)r=   rN   rO   rP   rQ   rR   r‚   Úcontent_idxÚcontent_itemÚtext_strrƒ   r„   s               r-   r[   z5OpenAIResponsesHandler._extract_input_text_and_images,  s  € ð !Ÿ™ Y°Ó5ˆØˆ?Øä�gœsÔ#à×!Ñ! 'Ô*Ø× Ñ  '¨4 Õ1ä˜¤Ô&ä-6°wÓ-?ò <Ñ)�˜\Ü˜l¬DÕ1à+×/Ñ/°¸Ó=�HØÐ+Ø&×-Ñ-¨hÔ7Ø%×,Ñ,¨g´s¸;Ó7GÐ-HÔIð $×'Ñ'¨Ó/°;Ó>Ø$0×$4Ñ$4°[À"Ó$E˜	Ü% i´Õ6Ø"+§-¡-°Ó"6˜CÚ"Ø /× 6Ñ 6°sÕ ;ñ<ð 'r,   r?   rT   c              ƒ   ól  K  — t        |«      D ]¢  \  }}||   }t        t        |d   «      }t        t        dz  |d   «      }||   j                  dd«      }	|	€ŒLt	        |	t
        «      r|€	|||   d<   Œgt	        |	t        «      sŒx|€Œ{t	        ||   d   |   t        «      sŒ•|||   d   |   d<   Œ¤ y­w)z‰
        Apply guardrail responses back to input messages.

        Override this method to customize how responses are applied.
        r   Nr{   r‚   r2   )rZ   r   r…   r:   rU   r*   r<   ri   )
r=   r?   rT   rR   Útask_idxÚguardrail_responseÚmappingrO   Úcontent_idx_optionalr‚   s
             r-   r\   z:OpenAIResponsesHandler._apply_guardrail_responses_to_inputT  sÖ   è ø€ ô -6°iÓ,@ò 	dÑ(ˆHÐ(Ø# HÑ-ˆGÜœ3 ¨¡
Ó+ˆGÜ#'¬¨d©
°G¸A±JÓ#?Ð à˜wÑ'×+Ñ+¨I°tÓ<ˆGØˆØä˜'¤3Ô'Ð,@Ð,Hà/A�˜Ñ! )Ò,ä˜G¤TÕ*Ð/CÑ/Oä˜h wÑ/°	Ñ:Ð;OÑPÔRVÕWØQc�H˜WÑ% iÑ0Ð1EÑFÀvÒNñ!	dùs   ‚BB4ÂB4Â	B4Â#B4Úresponser   Úuser_api_key_dictzUserAPIKeyAuth | NonerK   c           	   ƒ   ó8  K  — g }g }g }g }	t        |t        «      r|j                  dg «      }
n4t        |d«      r|j                  xs g }
nt        j                  d«       |S |
st        j                  d«       |S t        |
«      D ]  \  }}| j                  |||||	|¬«       Œ |s|rÕ|€d|i}n	d|vr||d<   d|vr| j                  |«      }|r||d<   t        |¬«      }|r||d	<   |r||d
<   d}t        |t        «      r|j                  d«      }nt        |d«      rt        |dd«      }|r||d<   |j                  ||d|¬«      ƒ d{  –—† }|j                  dg «      }| j                  |||	¬«      ƒ d{  –—†  t        j                  d|«       |S 7 ŒJ7 Œ­w)a  
        Process output response by applying guardrails to text content and tool calls.

        Args:
            response: LiteLLM ResponsesAPIResponse object
            guardrail_to_apply: The guardrail instance to apply
            litellm_logging_obj: Optional logging object
            user_api_key_dict: User API key metadata to pass to guardrails

        Returns:
            Modified response with guardrail applied to content

        Response Format Support:
            - response.output is a list of output items
            - Each output item can be:
              * GenericResponseOutputItem with a content list of OutputText objects
              * ResponseFunctionToolCall with tool call data
            - Each OutputText object has a text field
        r"   z1OpenAI Responses API: No output found in responsez.OpenAI Responses API: Empty output in response©Úoutput_itemÚ
output_idxrP   rQ   rR   Útool_calls_to_checkNrŽ   Úlitellm_metadatarD   rS   Ú
tool_callsr#   rI   rE   ©rŽ   rT   rR   z3OpenAI Responses API: Processed output response: %s)rU   ri   r:   Úhasattrr"   r   rY   rZ   Ú_extract_output_text_and_imagesÚ'transform_user_api_key_dict_to_metadatar   ÚgetattrrW   Ú$_apply_guardrail_responses_to_output)r=   rŽ   rA   rB   r�   rK   rP   rQ   r”   rR   Úresponse_outputr“   r’   Úuser_metadatarJ   Úresponse_modelr_   r`   s                     r-   Úprocess_output_responsez.OpenAIResponsesHandler.process_output_responseq  sÿ  è ø€ ð8 ,.ˆØ,.ˆØHJÐØ68ˆô
 �h¤Ô%Ø&Ÿl™l¨8°RÓ8‰OÜ�X˜xÔ(Ø&Ÿo™oÒ3°‰Oä ×&Ñ&Ð'ZÔ[ØˆOáÜ ×&Ñ&Ð'WÔXØˆOô (1°Ó'Aò 	Ñ#ˆJ˜Ø×0Ñ0Ø'Ø%Ø-Ø /Ø+Ø$7ð 1õ ð	ñ Ñ0ð Ð#Ø *¨HÐ5‘à \Ñ1Ø/7�L Ñ,ð "¨Ñ5Ø'+×'SÑ'SÐTeÓ'f�Ù Ø7D�LÐ!3Ñ4ä5¸NÔKˆFÙØ#2��xÑ Ù"Ø':��|Ñ$à)-ˆNÜ˜(¤DÔ)Ø!)§¡¨gÓ!6‘Ü˜ 7Ô+Ü!(¨°7¸DÓ!A�ÙØ"0��w‘à.@×.PÑ.PØØ)Ø%Ø/ð	 /Qó /÷ )Ðð (:×'=Ñ'=¸gÀrÓ'JÐð ×;Ñ;Ø!Ø+Ø+ð <ó ÷ ð ô 	×"Ñ"Ð#XÐZbÔcàˆð%)øðús$   ‚E	FÅFÅ-FÅ9FÅ:FÆFÚresponses_so_farc           	   ƒ   ój  K  — |s|S |d   }t        |t        «      st        |d«      s|S |j                  d«      dk(  �r"|j                  d«      xs i }t        |d«      s|S |j                  d«      xs g }g }	g }
g }t	        |«      D ]  \  }}| j                  |||	g ||
¬«       Œ |	s|
r´|€i }d|vr||d<   d	|vr| j                  |«      }|r||d	<   t        |	¬
«      }|
rt        t        t           |
«      |d<   |j                  d«      }|r||d<   |j                  ||d|¬«      ƒ d{  –—† }|j                  dg «      }| j                  |||¬«      ƒ d{  –—†  |S |j                  d«      dk(  r¨t        j                  |«      }|j                  d   j                   j"                  }|rlt        «       }t        t        t           |«      |d<   t        |d«      r|j$                  r|j$                  |d<   |j                  ||�|ni d|¬«      ƒ d{  –—†  |S | j'                  |«      }|rwt        |g¬
«      }t        |j                  d«      t        «      r!|j                  di «      j                  d«      nd}|r||d<   |j                  ||�|ni d|¬«      ƒ d{  –—†  |S 7 �Œ}7 �ŒR7 Œ˜7 Œ­w)aF  
        Process output streaming response by applying guardrails to text content.

        Mirrors the Chat Completions handler pattern: extract text from the final
        chunk, apply the guardrail, then write the result back in-place so the
        caller sees the modified content (e.g. PII tokens replaced).

        For ``response.completed`` events (the normal end-of-stream signal) we
        use the same per-item extraction + task-mapping approach as
        ``process_output_response`` so that unmasking / blocking works correctly
        for every output item.
        éÿÿÿÿr:   r1   zresponse.completedrŽ   r"   r‘   Nr•   rD   r–   r#   rI   rE   r—   zresponse.output_item.doner   )rU   ri   r˜   r:   rZ   r™   rš   r   r   r<   r   rW   rœ   r   Ú*translate_responses_chunk_to_openai_streamÚchoicesÚdeltar–   r#   Úget_streaming_string_so_far)r=   r¡   rA   rB   r�   rK   Úfinal_chunkÚresponse_objÚoutputsrP   r”   rR   r“   r’   rž   rJ   rŸ   r_   r`   Úmodel_response_streamr–   Ústring_so_farÚfallback_inputss                          r-   Ú!process_output_streaming_responsez8OpenAIResponsesHandler.process_output_streaming_responseÞ  sE  è ø€ ñ(  Ø#Ð#à-¨bÑ1ˆô ˜;¬Ô-´¸ÀeÔ1LØ#Ð#ð �?‰?˜6Ó"Ð&:Ó:Ø:E¿/¹/È*Ó:UÒ:[ÐY[ˆLÜ˜<¨Ô/Ø'Ð'Ø/;×/?Ñ/?ÀÓ/IÒ/OÈRˆGà/1ˆNØLNÐØ:<ˆMä+4°WÓ+=ò Ñ'�
˜KØ×4Ñ4Ø +Ø)Ø#1Ø$&Ø"/Ø(;ð 5õ ðñ Ñ!4ØÐ'Ø#%�LØ \Ñ1Ø/;�L Ñ,Ø%¨\Ñ9Ø+/×+WÑ+WÐXiÓ+j�MÙ$Ø;H˜Ð%7Ñ8ä2¸ÔH�Ù&Ü+/´Ô5PÑ0QÐSfÓ+g�F˜<Ñ(Ø!-×!1Ñ!1°'Ó!:�Ù!Ø&4�F˜7‘Oà2D×2TÑ2TØ!Ø!-Ø)Ø 3ð	 3Uó 3÷ -Ð"ð ,>×+AÑ+AÀ'È2Ó+NÐ!ð
 ×?Ñ?Ø)Ø/Ø"/ð @ó ÷ ð ð $Ð#ð
 �?‰?˜6Ó"Ð&AÒAä=×hÑhÐitÓuð "ð !6× =Ñ =¸aÑ @× FÑ F× QÑ QˆJÙÜ2Ó4�Ü'+¬DÔ1LÑ,MÈzÓ'Z��|Ñ$ÜÐ0°'Ô:Ð?T×?ZÒ?ZØ&;×&AÑ&A�F˜7‘OØ(×8Ñ8Ø!Ø1=Ð1I¡ÈrØ)Ø 3ð	 9ó ÷ ð ð $Ð#ð  $×?Ñ?Ð@PÓQˆÙÜ%>ÀmÀ_Ô%UˆOä@JÈ;Ï?É?Ð[eÓKfÔhlÔ@m�—‘ 
¨BÓ/×3Ñ3°GÔ<Ðswð ñ Ø+9� Ñ(Ø$×4Ñ4Ø&Ø-9Ð-E™\È2Ø%Ø/ð	 5ó ÷ ð ð  Ððy-ùðùð*øð*úsJ   ‚D*J3Ä,J)Ä--J3ÅJ,ÅB;J3ÈJ/ÈBJ3Ê"J1Ê#J3Ê,J3Ê/J3Ê1J3c                 óÎ   — |syt         j                  j                  t         j                  j                  t         j                  j                  h}|d   j                  d«      |v S )z3
        Check if the streaming has ended.
        Fr£   r1   )r   ÚRESPONSE_COMPLETEDÚvalueÚRESPONSE_FAILEDÚRESPONSE_INCOMPLETEr:   )r=   r¡   Úterminal_typess      r-   Ú_check_streaming_has_endedz1OpenAIResponsesHandler._check_streaming_has_endedb  s[   € ñ  Øä$×7Ñ7×=Ñ=Ü$×4Ñ4×:Ñ:Ü$×8Ñ8×>Ñ>ð!
ˆð
   Ñ#×'Ñ'¨Ó/°>ÐAÐAr,   c           	      ój   — dj                  |D �cg c]  }|j                  dd«      ‘Œ c}«      S c c}w )zB
        Get the string so far from the responses so far.
        Ú r2   )Újoinr:   )r=   r¡   rŽ   s      r-   r§   z2OpenAIResponsesHandler.get_streaming_string_so_faro  s-   € ð �w‰wÐAQÖR°X˜Ÿ™ V¨RÕ0ÒRÓSÐSùÒRs   �0c                 ó"  — t        |d«      r|j                  €y|j                  D ]Ø  }t        |t        «      r2	 t	        j
                  |j                  «       «      }|j                  r|}t        |t        t        f«      sŒ\t        |t        «      r|j                  n|j                  dg «      }|sŒ�|D ]G  }t        |t        «      r|j                  sŒ   yt        |t        «      sŒ4|j                  d«      sŒF  y ŒÚ y# t        $ r Y Œçw xY w)z‡
        Check if response has any text content to process.

        Override this method to customize text content detection.
        r"   Fr‚   Tr2   )r˜   r"   rU   r   r   Úmodel_validateÚ
model_dumpr‚   Ú	Exceptionri   r:   r   r2   )r=   rŽ   r’   Úgeneric_response_output_itemr‚   r‡   s         r-   Ú_has_text_contentz(OpenAIResponsesHandler._has_text_contentu  s   € ô �x Ô*¨h¯o©oÐ.EØà#Ÿ?™?ò 	,ˆKÜ˜+¤yÔ1ðÜ3L×3[Ñ3[Ð\g×\rÑ\rÓ\tÓ3uÐ0Ø3×;Ò;Ø&B˜ô ˜+Ô(AÄ4Ð'HÕIô " +Ô/HÔIð  ×'Ò'à$Ÿ™¨°BÓ7ð ò
 Ø(/ò ,˜ä% l´JÔ?Ø+×0Ó0Ú'+Ü'¨´dÕ;Ø+×/Ñ/°Õ7Ú'+ñ,ð	,ð. øô# !ò Ùðús   º1DÄ	DÄDr’   r“   r”   c                 ól  — t        |t        «      s+t        |t        «      rTt        |d«      rHt	        |d«      dk(  r9|�6t        j                  ||¬«      }|j                  t        t        |«      «       yt        |t        «      rZ|j                  d«      dk(  rF|�C	 t        di |¤Ž}t        j                  ||¬«      }|j                  t        t        |«      «       yyd}	t        |t        «      r?	 |j                  «       }
t        j                   |
«      }|j"                  r|j"                  }	n$t        |t        «      r|j                  dg «      }	ny|	syt%        j&                  d|«       t)        |	«      D ]u  \  }}t        |t*        «      r|j,                  }n#t        |t        «      r|j                  d«      }nŒF|sŒI|j                  |«       |j                  |t/        |«      f«       Œw y# t        $ r Y yw xY w# t        $ r* t        |d«      r|j"                  r|j"                  }	nY yY ŒÞw xY w)	z¨
        Extract text content, images, and tool calls from a response output item.

        Override this method to customize text/image/tool extraction logic.
        r1   Úfunction_callN)Útool_call_itemÚindexr‚   z0OpenAI Responses API: Processing output item: %sr2   r+   )rU   r   r   r˜   r›   r   Ú@convert_response_function_tool_call_to_chat_completion_tool_callrj   r   r   ri   r:   r	   r¼   r»   r   rº   r‚   r   rY   rZ   r   r2   r…   )r=   r’   r“   rP   rQ   rR   r”   Útool_call_dictÚtool_call_objr‚   Úoutput_item_dumpr½   r†   r‡   Útext_contents                  r-   r™   z6OpenAIResponsesHandler._extract_output_text_and_images—  s  € ô  �kÔ#9Ô:Ü�{¤IÔ.Ü˜ VÔ,Ü˜ VÓ,°Ò?à"Ð.ä4×uÑuØ'2Ø(ôð ð $×*Ñ*¬4Ô0KÈ^Ó+\Ô]ØÜ˜¤TÔ*¨{¯©¸vÓ/FÈ/Ò/Yà"Ð.ðÜ+CÑ+RÀkÑ+R�MÜ%E÷  &Gñ  &GØ'4Ø(ô&�Nð (×.Ñ.¬tÔ4OÐQ_Ó/`Ôañ ð 9=ˆÜ�k¤9Ô-ð
Ø*5×*@Ñ*@Ó*BÐ Ü6O×6^Ñ6^Ð_oÓ6pÐ,Ø/×7Ò7Ø:×BÑB�Gøô ˜¤TÔ*Ø!—o‘o i°Ó4‰GàáØä×"Ñ"Ð#UÐWbÔcô *3°7Ó);ò 	EÑ%ˆK˜ä˜,¬
Ô3Ø+×0Ñ0‘Ü˜L¬$Ô/Ø+×/Ñ/°Ó7‘àâØ×%Ñ% lÔ3Ø×$Ñ$ j´#°kÓ2BÐ%CÕDñ	Eøô; !ò ØØðûô ò ä˜;¨	Ô2°{×7JÒ7JØ)×1Ñ1‘Gáñ ðús%   ÂAG1 Ã2=H  Ç1	G=Ç<G=È .H3È2H3c              ƒ   ó’  K  — t        |t        «      r|j                  dg «      }nt        |d«      r|j                  xs g }nyt        |«      D �]ã  \  }}||   }t        t        |d   «      }t        t        |d   «      }	|t        |«      k\  rŒA||   }
t        |
t        «      rd|
j                  sŒc|	t        |
j                  «      k  sŒ||
j                  |	   }t        |t        «      r||_        Œ£t        |t        «      sŒ´||d<   Œºt        |
t        «      rª	 t        j                  |
j                  «       «      }|j                  rx|	t        |j                  «      k  r`|j                  |	   }t        |t        «      rA||_        t        |
d«      r.|
j                  r"|
j                  |	   }t        |d«      r||_        �Œtt        |
t        «      s�Œ†|
j                  dg «      }|s�Œœ|	t        |«      k  s�Œ¬t        ||	   t        «      r
|||	   d<   �ŒÉt        ||	   d«      s�ŒÚ|||	   _        �Œæ y# t         $ r Y �Œôw xY w­w)zŠ
        Apply guardrail responses back to output response.

        Override this method to customize how responses are applied.
        r"   Nr   r{   r2   r‚   )rU   ri   r:   r˜   r"   rZ   r   r…   r|   r   r‚   r   r2   r   rº   r»   r¼   )r=   rŽ   rT   rR   r�   rŠ   r‹   rŒ   r“   r†   r’   r‡   Úgeneric_itemÚoriginal_contentr‚   s                  r-   rœ   z;OpenAIResponsesHandler._apply_guardrail_responses_to_outputê  s  è ø€ ô �h¤Ô%Ø&Ÿl™l¨8°RÓ8‰OÜ�X˜xÔ(Ø&Ÿo™oÒ3°‰Oàä,5°iÓ,@ó '	GÑ(ˆHÐ(Ø# HÑ-ˆGÜœc 7¨1¡:Ó.ˆJÜœs G¨A¡JÓ/ˆKàœS Ó1Ò1Øà)¨*Ñ5ˆKô ˜+Ô'@ÔAØ×&Ó&¨;¼¸[×=PÑ=PÓ9QÓ+QØ#.×#6Ñ#6°{Ñ#C�LÜ! ,´
Ô;Ø,>˜Õ)Ü# L´$Õ7Ø/A˜ VÒ,Ü˜K¬Ô3ðÜ#<×#KÑ#KÈK×LbÑLbÓLdÓ#e�LØ#×+Ò+°¼cÀ,×BVÑBVÓ>WÒ0WØ'3×';Ñ';¸KÑ'H˜Ü% l´JÔ?Ø0B˜LÔ-ä& {°IÔ>À;×CVÒCVØ3>×3FÑ3FÀ{Ñ3SÐ 0Ü#*Ð+;¸VÔ#DØ<NÐ$4Ô$9ùô ˜K¬Ö.Ø%Ÿ/™/¨)°RÓ8�Û˜{¬S°«\Ô9Ü! '¨+Ñ"6¼Ô=Ø7I˜ Ñ,¨VÓ4Ü  ¨Ñ!5°vÖ>Ø4F˜ Ñ,Ö1ñO'	Gøô> !ò ÚðüsU   ‚B/IÂ2IÃ7IÄIÄB'H7ÇIÇIÇ+IÇ;,IÈ)IÈ7	IÉ IÉIÉI)N)NNN)%r$   r%   r&   r'   ri   r<   r   r@   r*   r(   rb   rm   r
   r   r   rV   r   rv   r   rX   r…   Útupler[   r\   r   r!   r    r®   r   r0   Úboolrµ   r§   r¾   r   r™   rœ   r+   r,   r-   r4   r4   S   sý  „ ñðL¨Dð L°TÐ:JÑ5KÈdÑ5Ró Lð( ;?ñ	kàðkð .ðkð 8ð	kð
 
ˆc�6ˆkÑ	ókðZ¨tð ¸¸S¹	ó ðZàÐ%Ð(;Ñ;Ñ<ðZð Ð4Ñ5ðZð 
ó	Zð&
ÀdÈ3Áið 
ÐTXÐY]Ð^aÐciÐ^iÑYjÑTkó 
ðà˜T # v +Ñ.Ñ/ðð �t˜C ˜KÑ(Ñ)ðð 
ˆd�3˜�;ÑÑ	 ó	ð:	Xàð	Xð ˜T # v +Ñ.Ñ/ð	Xð  Ð 7Ñ8¸4Ñ?ð		Xð
 
ó	Xð&<àð&<ð ð&<ð ˜S™	ð	&<ð
 ˜c™ð&<ð ˜E # s¨T¡z /Ñ2Ñ3ð&<ð 
ó&<ðPdàðdð ˜‘9ðdð ˜E # s¨T¡z /Ñ2Ñ3ð	dð
 
ódðB ;?Ø59Ø$(ñkàÐ.Ð0FÐFÑGðkð .ðkð 8ð	kð
 3ðkð ˜T‘kðkð 
Ð%Ð'=Ð=Ñ	>ókðb ;?Ø59Ø$(ñB à˜s™)ðB ð .ðB ð 8ð	B ð
 3ðB ð ˜T‘kðB ð 
ˆc‰óB ðHB¸8ÐDXÑ;Yð BÐ^bó BðT¸HÐEYÑ<Zð TÐ_bó Tð Ð*@ð  ÀTó  ðR IMñQEàðQEð ðQEð ˜S™	ð	QEð
 ˜c™ðQEð ˜E # s (™OÑ,ðQEð "Ð"=Ñ>ÀÑEðQEð 
óQEðf:GàÐ.Ð0FÐFÑGð:Gð ˜‘9ð:Gð ˜E # s (™OÑ,ð	:Gð
 
ô:Gr,   r4   N)2r'   Úcollections.abcr   Útypingr   r   r   r   r   Ú2openai.types.responses.response_function_tool_callr	   Ú!openai.types.responses.tool_paramr
   Úpydanticr   Útyping_extensionsr   r   Úlitellm._loggingr   ÚIlitellm.completion_extras.litellm_responses_transformation.transformationr   Ú<litellm.llms.base_llm.guardrail_translation.base_translationr   ÚBlitellm.responses.litellm_completion_transformation.transformationr   Úlitellm.types.llms.openair   r   r   r   r   Úlitellm.types.responses.mainr   r   r   Úlitellm.types.utilsr   Ú%litellm.integrations.custom_guardrailr   Ú*litellm.litellm_core_utils.litellm_loggingr   ÚLiteLLMLoggingObjÚlitellm.proxy._typesr   r   r   r!   r0   r4   r+   r,   r-   ú<module>rÞ      s‹   ðñõ< %ß 9Õ 9å WÝ ?Ý ß 1å 1õõ Yõ÷õ ÷ñ õ
 :áÝEÝWÝ3Ý<Ý8ô ˜Y¨eõ  ô˜9¨Eõ ôQG˜_õ QGr,   