
    i3|                         d Z ddlZddlZddlZddlZddlmZmZmZm	Z	m
Z
 ddlmZ ddlZddlmZ ddlmZmZ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  G d de      Zy)OpenAI provider implementation.    N)AnyDictListOptionalUnion)unquote_to_bytes)OpenAI)AttachmentRefFunctionCallOutputEventMessageMessageBlockMessageBlockTypeMessageRoleToolCallPayload)ToolSpec)ModelProvider)ModelResponse)
TokenUsagec                      e Zd ZdZdZdZdZd Z	 dBdej                  de
e   de
e   d	ee
e      d
ef
dZded
efdZded
efdZded
dfdZde
e   d	ee
e      deeef   d
eeef   fdZde
e   d	ee
e      deeef   d
eeef   fdZded
ee   fdZded
eeef   fdZded
eeef   fdZde
eeef      d
eee
eeef      f   fdZded
efdZ de
e   ded
dfdZ!ded
ee   fdZ"ded
eeef   fdZ#ded
e
eeef      fdZ$de
e%   d e&d
e
eeef      fd!Z'd"e%d e&d
eeef   fd#Z(d$ed%ee)   d
eeef   fd&Z*d%ee)   d"e%d
eeef   fd'Z+d"e%d
ee   fd(Z,d"e%d
ee   fd)Z-d%e)d
ee   fd*Z.d+ed
ee/   fd,Z0ded
efd-Z1ded
ee   fd.Z2d/e
e   d
e3e
e%   e
e4   f   fd0Z5d1ed
e%fd2Z6d1ed
ee4   fd3Z7d4d5d6ed7ed8ed
efd9Z8d1ed:ed
efd;Z9d1ed
eeef   fd<Z:d=ed>ee   d
efd?Z;ded
eeef   fd@Z<de
e   ded
dfdAZ=y)COpenAIProviderr   i@ i   c                     | j                   r!t        | j                  | j                         S t        | j                        S )z
        Create and return the OpenAI client.
        
        Returns:
            OpenAI client instance with token tracking if available
        )api_keybase_url)r   )r   r
   r   )selfs    Y/Users/bowang/.openclaw/workspace/ChatDev/runtime/node/agent/providers/openai_provider.pycreate_clientzOpenAIProvider.create_client$   s<     == 
      Nclientconversationtimeline
tool_specsreturnc                    | j                  |      }|rz| j                  |||      } |j                  j                  j                  di |}| j                  |       | j                  ||       | j                  |      }	t        |	|      S | j                  |||      }	  |j                  j                  di |}| j                  |       | j                  ||       | j                  |      }	t        |	|      S # t        $ r}
| j                  |||      } |j                  j                  j                  di |}| j                  |       | j                  ||       | j                  |      }	t        |	|      cY d}
~
S d}
~
ww xY w)zO
        Call the OpenAI model with the given messages and parameters.
        )messageraw_responseN )_is_chat_completions_mode_build_chat_payloadchatcompletionscreate_track_token_usage_append_chat_response_output_deserialize_chat_responser   _build_request_payload	responses_append_response_output_deserialize_response	Exception)r   r   r    r!   r"   kwargsis_chatrequest_payloadresponser%   enew_request_payloads               r   
call_modelzOpenAIProvider.call_model5   s{    008"66|ZQWXO5v{{..55HHH##H---hA55h?G xHH 55h
FS	I.v''..AAH##H-((8<00:G xHH 	I"&":":<U["\5v{{..55L8KLH##H---hA55h?G xHH	Is    "AC? ?	FA9FFFc                 j    | j                   j                  d      }|dk(  ry|dk(  ryt        |d       S )zNDetermine if we should use standard chat completions instead of responses API.protocolr*   Tr1   F)paramsgethasattr)r   r   r=   s      r   r(   z(OpenAIProvider._is_chat_completions_mode[   s:    ;;??:.v{"6;///r   r8   c                 ^   t        |dd      s
t               S dt        dt        ffd} |d      } |d      } |d      } |d	      }||n|xs d
}||n|xs d
} |d      }	|	|xs d
|xs d
z   }	|xs d
|xs d
|xs d
|xs d
|	xs d
d}
t        |xs d
|xs d
|	xs d
|
      S )z
        Extract token usage from the OpenAI API response.
        
        Args:
            response: OpenAI API response from the model call
            
        Returns:
            TokenUsage instance with token counts
        usageNnamer#   c                 x    t        |       rt        |       S t        t              rj	                  |       S y Nr@   getattr
isinstancedictr?   )rC   rB   s    r   _getz0OpenAIProvider.extract_token_usage.<locals>._gets   s5    ud#ud++%&yy&r   prompt_tokenscompletion_tokensinput_tokensoutput_tokensr   total_tokens)rK   rL   rM   rN   rO   )rM   rN   rO   metadata)rG   r   strr   )r   r8   rJ   rK   rL   rM   rN   resolved_inputresolved_outputrO   rP   rB   s              @r   extract_token_usagez"OpenAIProvider.extract_token_usagee   s    '40<	s 	s 	 _- !45N+_-)5)A}GYXY+8+D-J[J`_`N+*/aO4HqIL +/a!2!7a*/a,1(-A
 ',1).Q%*	
 	
r   c                 |   t        | j                  dd      }|sy| j                  |      }|j                  dk(  r|j                  dk(  r|j
                  syt        | j                  dd      }||_        | j                  |_        |j                  |_        d|_	        |j                  || j                  |d       y)z:Record token usage if a tracker is attached to the config.token_trackerNr   node_idALLopenai)provider)rG   configrT   rM   rN   rP   rW   
model_nameworkflow_idrZ   record_usage)r   r8   rV   rB   rW   s        r   r-   z!OpenAIProvider._track_token_usage   s    _dC((2"u':':a'?$++y%8??)55!""7DOOUX"Vr   
raw_paramsc                    t        |      }|j                  dd      }|j                  dd      }|||}g }|D ]'  }| j                  |      }	|	|j                  |	       ) |s
ddddgdg}| j                  ||j                  d	d
      |j                  dd      d}
|||
d<   n-| j
                  j                  d      r| j
                  d   |
d<   |j                  dd      }g }t        |t              r|j                  |       n|t        d      |r|j                  d |D               |r||
d<   |j                  dd      }|||
d<   n|r|
j                  dd       |
j                  |       |
S )z8Construct the Responses API payload from event timeline.
max_tokensNmax_output_tokensuser
input_text typetextrolecontenttemperatureffffff?timeouti,  )modelinputrl   rn   toolsz)params.tools must be a list when providedc              3   <   K   | ]  }|j                           y wrE   )to_openai_dict).0specs     r   	<genexpr>z8OpenAIProvider._build_request_payload.<locals>.<genexpr>   s     M*$ 3 3 5*   tool_choiceauto)rI   pop_serialize_timeline_itemappendr\   r>   r?   rH   listextend
ValueError
setdefaultupdate)r   r!   r"   r_   r>   ra   rb   input_messagesitem
serializedpayload
user_toolsmerged_toolsrx   s                 r   r0   z%OpenAIProvider._build_request_payload   s    j!ZZd3
"JJ':DA$)? *$&D66t<J%%%j1 
  #)5r BCN __#!::mS9zz)S1	#
 (+<G'([[__01+/;;7J+KG'(ZZ.
"$j$'
+#HIIM*MM+GGjj5"%0GM"}f5 	vr   c           	         t        |      }|j                  dd      }|j                  dd      }|||}g }|D ]'  }| j                  |      }	|	|j                  |	       ) |sdddg}| j                  ||j                  dd      d	}
|||
d<   n-| j
                  j                  d      r| j
                  d   |
d<   |j                  d
d      }g }t        |t              r|j                  |       |rD|D ]?  }|j                  d|j                  |j                  |j                  xs di ddd       A |r||
d
<   |j                  dd      }|||
d<   n|r|
j                  dd       |
j                  |       |
S )z0Construct standard Chat Completions API payload.rb   Nra   rc   re   ri   rl   rm   )ro   messagesrl   rq   functionobject)rg   
properties)rC   description
parameters)rg   r   rx   ry   )rI   rz   _serialize_message_for_chatr|   r\   r>   r?   rH   r}   r~   rC   r   r   r   r   )r   r    r"   r_   r>   rb   ra   r   r   r   r   r   r   ru   rx   s                  r   r)   z"OpenAIProvider._build_chat_payload   s    j!"JJ':DAZZd3
"3"?*J  D99$?J%
+ !
 !'B78H __ !::mS9#

 !$.GL![[__\*%)[[%>W\"ZZ.
"$j$'
+"##& $		'+'7'7&*oo&](Z\9]!%  # +GGjj5"%0GM"}f5vr   r   c                 n   t        |t              r| j                  |      S t        |t              r| j	                  |      S t        |t
              rc|j                  d      }|j                  d      }|j                  d      }|r.|s|r*|t        |t              r| j                  |      |dS ||dS y )Nrj   rk   
tool_callsrj   rk   r   )	rH   r   r   r   ._serialize_function_call_output_event_for_chatrI   r?   r}   _transform_blocks_for_chat)r   r   rj   rk   r   s        r   !_serialize_timeline_item_for_chatz0OpenAIProvider._serialize_timeline_item_for_chat   s    dG$33D99d34FFtLLdD!HHV$Txx	*W((<0Z'Z#NXY`bfNg$"A"A'"J%/ mt%/ 
 r   r%   c                    |j                   j                  }|j                         }|r|j                   t        j                  k(  r|j                         }n+| j                  | j                  ||j                               }||d}|j                  r|j                  |d<   |j                  r|j                  |d<   |j                  r+|j                  D cg c]  }|j                          c}|d<   |S c c}w )z=Convert internal Message to standard Chat Completions schema.ri   rC   tool_call_idr   )rj   valueblocksr   TOOLtext_contentr   _serialize_blocksrC   r   r   rs   )r   r%   
role_valuer   rk   r   tcs          r   r   z*OpenAIProvider._serialize_message_for_chat2  s    \\''
!)9)99**,G55d6L6LVU\UaUa6bcG #
 <<%llGFO&-&:&:GN#CJCUCU$VCURR%6%6%8CU$VGL! %Ws   C6eventc                     |j                   xs d}|j                  r"dj                  d |j                  D              }d|j                  xs d|dS )z8Convert tool result to standard Chat Completions schema.re   
c              3   <   K   | ]  }|j                           y wrE   )describe)rt   bs     r   rv   zPOpenAIProvider._serialize_function_call_output_event_for_chat.<locals>.<genexpr>L  s     H4Gqajjl4Grw   tool	tool_call)rj   r   rk   )output_textoutput_blocksjoincall_id)r   r   rh   s      r   r   z=OpenAIProvider._serialize_function_call_output_event_for_chatG  sS      &BIIHE4G4GHHT !MM8[
 	
r   r   c           	      H   g }|D ]y  }|j                  dd      }|dv r%|j                  d|j                  dd      d       >|dv r'|j                  dd|j                  dd      id	       i|j                  |       { t        |      d
k(  r|d   d   dk(  r|d   d   S |S )zMConvert Responses block types to Chat block types (e.g., input_text -> text).rg   re   )rd   r   rh   rf   )input_imageoutput_image	image_urlurl)rg   r      r   )r?   r|   len)r   r   transformedblockb_types        r   r   z)OpenAIProvider._transform_blocks_for_chatT  s    ,.EYYvr*F66""FEIIfb<Q#RS::""KueiiXcegNhFi#jk ""5)  {q [^F%;v%Eq>&))r   c           	         | j                  |d      xs g }|st        t        j                  d      S |d   }| j                  |d      }g }| j                  |d      }|rt	        |      D ]  \  }}| j                  |d      xs i }	| j                  |	d      xs d}
| j                  |	d	      xs d}t        |t              st        |      }| j                  |d
      }|s| j                  |
|d|       }|j                  t        ||
|d              t        t        j                  | j                  |d      xs d|      S )z4Convert Chat Completions output to internal Message.choicesre   ri   r   r%   r   r   rC   	argumentsid
tool_call_fallback_prefixr   function_namer   rg   rk   r   )
	_get_attrr   r   	ASSISTANT	enumeraterH   rQ   _build_tool_call_idr|   r   )r   r8   r   choicemsgr   tc_dataidxr   f_datar   r   r   s                r   r/   z)OpenAIProvider._deserialize_chat_responsef  sF   ..95; 5 5rBBnnVY/,.
..l3$W-RJ7=2 $vv > D" NN6;?E2	!)S1 #II..T2"66}icmnqmras6tG!!/"/'#	#  .  &&NN3	28b!
 	
r   c                    |j                   d   j                  }d|j                  xs dd}t        |dd      rg |d<   t	        |j
                        D ]  \  }}|j                  j                  }|j                  j                  xs d}t        |t              st        |      }|j                  xs | j                  ||d|       }	|d   j                  |	d	||d
d        |j                  |       y)zKAdd chat response to timeline, preserving tool_calls (Chat API compatible).r   	assistantre   ri   r   Nr   r   r   )rC   r   )r   rg   r   )r   r%   rk   rG   r   r   r   rC   r   rH   rQ   r   r   r|   )
r   r!   r8   r   assistant_msgr   r   r   r   r   s
             r   r.   z+OpenAIProvider._append_chat_response_output  s    q!)){{(b

 3d+*,M,'$S^^4R " 0 0KK117R	!)S1 #II%%y4#;#;M9hrsvrwfx#;#yl+22!& -%.!4  5 	&r   c                     t        |t              r| j                  |      S t        |t              r| j	                  |      S |S rE   )rH   r    _serialize_message_for_responsesr   %_serialize_function_call_output_event)r   r   s     r   r{   z'OpenAIProvider._serialize_timeline_item  s>    dG$88>>d34==dCCr   c                     |j                   j                  }| j                  |      }||d}|j                  r|j                  |d<   |j                  r|j                  |d<   |S )z3Convert internal Message to Responses input schema.ri   rC   r   )rj   r   _serialize_content_blocksrC   r   )r   r%   r   content_blocksr   s        r   r   z/OpenAIProvider._serialize_message_for_responses  sb    \\''
77@%#
 <<%llGFO&-&:&:GN#r   c                     |j                         }|s6|j                         }|j                  t        j                  u rdnd}||dgS | j                  ||j                        S )Nr   rd   rf   )r   r   rj   r   r   r   )r   r%   r   rh   
block_types        r   r   z(OpenAIProvider._serialize_content_blocks  s]    !'')D*1,,+:O:O*OUaJ'677%%fgll;;r   rj   c                 Z    g }|D ]#  }|j                  | j                  ||             % |S rE   )r|   _serialize_block)r   r   rj   r   r   s        r   r   z OpenAIProvider._serialize_blocks  s2    +-
Ed33E4@A r   r   c                    |j                   t        j                  u r)|t        j                  u rdnd}||j
                  xs ddS |j                  }|j                   t        j                  u r(|t        j                  u rdnd}| j                  ||      S |j                   t        j                  u r(|t        j                  u rdnd}| j                  ||      S |j                   t        j                  u r(|t        j                  u rd	nd
}| j                  ||      S |j                   t        j                  u r@| j                  |      }||t        j                  u rdnd}||dS | j                  ||      S d|j                         dS )Nr   rd   re   rf   r   r   output_audioinput_audiooutput_videoinput_video)rg   r   TEXTr   r   rh   
attachmentIMAGE_serialize_media_blockAUDIOVIDEOFILE_maybe_inline_text_file_serialize_file_blockr   )r   r   rj   content_typer   
media_typeinline_texts          r   r   zOpenAIProvider._serialize_block  sy   ::)...,0K4I4I,I=|L$

(b 
 %%
::)///+/;3H3H+HmJ..z:FF::)///+/;3H3H+HmJ..z:FF::)///+/;3H3H+HmJ..z:FF::)...66u=K&048M8M0M}S_('  --j%@@ !NN$
 	
r   r   r   c                 ,   d|i}|s|S dddddddj                  |      }|j                  r|j                  |d<   |S |j                  r|r|j                  ||<   |S |j                  r+|r)| j	                  |j                  |j
                        ||<   |S )Nrg   r   	audio_url	video_url)r   r   r   r   r   r   file_id)r?   remote_file_iddata_uri
local_path_make_data_uri_from_path	mime_type)r   r   r   r   url_keys        r   r   z%OpenAIProvider._serialize_media_block  s    
 $*:"6N ''&'&'
 #j/ 	 $$!+!:!:GI
 	   W)22GG  ""w#<<Z=R=RT^ThThiGGr   c                 <   ddi}|r|j                   r|j                   |d<   nS|j                  }|s2|j                  r&| j                  |j                  |j                        }|r||d<   nt        d      |j                  r|j                  |d<   |S t        d      )Nrg   
input_filer   	file_dataz7Attachment missing file_id or data for input_file blockfilenamez+File block requires an attachment reference)r   r   r   r   r   r   rC   )r   r   r   r   r   s        r   r   z$OpenAIProvider._serialize_file_block  s    
 $*<"8((%/%>%>	"%..J$9$9#<<Z=R=RT^ThThiH+3GK($%^__&0oo
#  JKKr   c                    |j                   }|sy|j                  xs dj                         }|j                  xs dj                         }|dv xs |j	                  d      }|j                  d      s|sy|j                  ry| j                  |      }|yd|v xs |j	                  d      }|rdnd	}|r| j                  n| j                  }	t        | ||	      }
d
}t        |      |
kD  r|d|
 }d}|j                  xs |j                  xs |rdnd}|rd|
z  nd}|r
d| d| | S |j                  xs d}d| d| d| d| S )zGInline local text/* attachments to avoid unsupported file-type uploads.Nre   >   application/jsonapplication/jsonlapplication/ndjsonapplication/x-ndjson)z.jsonz.jsonlz.ndjsonztext/ztext/csvz.csvcsv_inline_char_limittext_inline_char_limitFTzattachment.csvzattachment.txtz!

[truncated after %d characters]z
CSV file 'z':
ztext/*zText file 'z' (z):
```text
z
```)r   r   lowerrC   endswith
startswithr   _read_attachment_textCSV_INLINE_CHAR_LIMITTEXT_INLINE_CHAR_LIMITrG   r   attachment_id)r   r   r   mimerC   is_jsonrh   is_csv
limit_attrdefault_limitlimit	truncateddisplay_namesuffixmime_displays                  r   r   z&OpenAIProvider._maybe_inline_text_file  s    %%
$$*113%2,,. 
 
 ;
 ]]9: 	 (G$$))*5<t#<t}}V'<06,<T
6<22$B]B]j-8	t9u<DI!x**B*Bx[aGWgwBK6>QS~T$x@@!++7x\N#l^=eTZS[\\r   c                 $    | j                  |      S )z5Backward compatible alias for older call sites/tests.)r   )r   r   s     r   _maybe_inline_csvz OpenAIProvider._maybe_inline_csvB  s    ++E22r   c                    d }|j                   r| j                  |j                         }ne|j                  rYt        j                  j                  |j                        r0	 t        |j                  d      5 }|j                         }d d d        |y 	 |j                  d      S # 1 sw Y   xY w# t        $ r Y y w xY w# t        $ r |j                  dd      cY S w xY w)Nrbutf-8replace)errors)r   _decode_data_urir   ospathexistsopenreadOSErrordecodeUnicodeDecodeError)r   r   
data_byteshandles       r   r   z$OpenAIProvider._read_attachment_textF  s    &*
..z/B/BCJ""rww~~j6K6K'L*//6&!'J 7 	@$$W-- 76  " 	@$$WY$??	@s<   !B1 7B%B1 C  %B.*B1 1	B=<B= CCr   c                     |j                  d      sy |j                  d      \  }}}|sy d|v r	 t        j                  |      S t        |      S # t        t
        j                  f$ r Y y w xY w)Ndata:,z;base64)r   	partitionbase64	b64decoder   binasciiErrorr	   )r   r   header_datas        r   r  zOpenAIProvider._decode_data_uriW  sw    ""7+",,S14''--  %% / s   A A,+A,c                    t        |dg       xs g }g }g }|D ]  }| j                  |d      }|dk(  ri| j                  |d      xs d}|dk7  r6| j                  |d      xs g }| j                  |      \  }	}
|j                  |	       |j                  |
       |dk(  r!|j	                  | j                  |             |dv s| j                  |      }|s|j	                  |        |s=| j                  |      }|r*|j	                  t        t        j                  |	             t        t        j                  |xs d
|      S )z1Convert Responses API output to internal Message.outputrg   r%   rj   r   rk   image_generation_call>   r   function_callrh   re   r   )rG   r   _parse_output_contentr~   r|   _parse_image_generation_call_parse_tool_call_extract_fallback_textr   r   r   r   r   r   )r   r8   r   assistant_blocksr   r   	item_typer   content_itemsparsed_blocksparsed_callsparsed_callfallback_texts                r   r3   z$OpenAIProvider._deserialize_responsed  sJ   (B7=2/1,.
!DtV4II%!^^D&9H[
, $tY ? E2.2.H.H.W+| ''6!!,/55 ''(I(I$(OP<<"33D9%%k2 ""   77AM ''5E5J5JQ^(_`&&$*!
 	
r   c                 p    t        |dd      }|sy	 t        |dd      S # t        $ r Y yt        $ r Y yw xY w)zHReturn the concatenated output text without triggering Responses errors.r)  Nr   )rG   	TypeErrorAttributeError)r   r8   r)  s      r   r0  z%OpenAIProvider._extract_fallback_text  sG    8T2	8]D99 	 		s    	555r3  c                    g }g }|D ]L  }| j                  |d      }|dv r?|j                  t        t        j                  | j                  |d      xs d             Y|dv ro|j                  t        t        j
                  t        | j                  |d      xs d| j                  |d      | j                  |d	      xs i 
                   |dv r&| j                  |      }|s|j                  |       |j                  t        t        j                  t        | j                  |d      xs d      | j                  |                   O ||fS )Nrg   >   rh   r   rh   re   r,  >   imager   r   image_base64rP   r   r   rP   rg   r   >   r   r+  )rg   rh   r'  )r   r|   r   r   r   r   r   r/  DATArQ   _maybe_to_dict)r   r3  r   r   part	part_typeparseds          r   r-  z$OpenAIProvider._parse_output_content  s<    &(,.
!DtV4I33l+;+@+@t~~VZ\bGcGigijk77 -33#0*...t*D*J%)^^D.%I%)^^D*%E%K$	 <<..t4%%f- -22 f!=!CD!006) "6 z!!r   r   c           	         | j                  |d      xs d}|dk7  rt        d| d      | j                  |d      }|st        d      | j                  |d      xs d}d	| }t        t        j                  t        ||d
di            S )Nstatusre   	completedz,Image generation call not completed (status=)resultz+Image generation call returned empty resultr   zdata:image/png;base64,sourcer*  r>  r?  )r   RuntimeErrorr   r   r   r   )r   r   rF  	image_b64r   r   s         r   r.  z+OpenAIProvider._parse_image_generation_call  s    28b[ !MfXUVWXXNN7H5	LMMw5;+I;7!''$+!"$;<
 	
r   c                    | j                  |d      xs i }| j                  |d      xs | j                  |d      xs d}| j                  |d      xs | j                  |d      xs d}|sy t        |t        t        f      r	 dd l}|j                  |d      }nt        |      }| j                  |d      xs | j                  |d	      xs d}|s| j                  ||      }t        |||d
      S # t        $ r t        |      }Y cw xY w)Nr   rC   re   r   r   F)ensure_asciir   r   r   )
r   rH   rI   r}   jsondumpsr4   rQ   r   r   )r   r   function_payloadr   r   rO  arguments_strr   s           r   r/  zOpenAIProvider._parse_tool_call  s   >>':>D"'7@iDNNSZ\bDcigiNN#3[AoT^^T[]hEiomo	i$./ $

95
 I  	NM..)4[wPT8U[Y[..}mLG'#	
 	
  / #I/s   C5 5DDr   r   r   r   r   c                    |xs |}| d|xs d j                  d      }t        j                  |      j                         d d }| d| S )N:re   r     r&  )encodehashlibmd5	hexdigest)r   r   r   r   baser   digests          r   r   z"OpenAIProvider._build_tool_call_id  s[    /F!IO,-44W=W%//1"15q!!r   keyc                 v    t        ||      rt        ||      S t        |t              r|j	                  |      S y rE   rF   )r   r   r\  s      r   r   zOpenAIProvider._get_attr  s5    7C 7C((gt$;;s##r   c                     t        |d      r	 |j                         S t        |t              r|S i S # t        $ r i cY S w xY w)N
model_dump)r@   r_  r4   rH   rI   )r   r   s     r   rA  zOpenAIProvider._maybe_to_dict  sL    7L)))++ gt$N		  	s   2 A A r  r   c           	      ^   |xs d}t         j                  j                  |      }|| j                  kD  rt	        d| d| d| j                   d      t        |d      5 }t        j                  |j                               j                  d      }d d d        d| d	 S # 1 sw Y   xY w)
Nzapplication/octet-streamzAttachment 'z' is z  bytes; exceeds inline limit of z bytesr  r  r  z;base64,)
r  r  getsizeMAX_INLINE_FILE_BYTESr   r  r!  	b64encoder  r  )r   r  r   r  	file_sizer  encodeds          r   r   z'OpenAIProvider._make_data_uri_from_path  s    66GGOOD)	t111tfE)4TUYUoUoTppvw  $&&v{{}5<<WEG tfHWI.. s    3B##B,c                    |j                   |j                  xs |j                  xs dd}|j                  r/| j	                  |j                  t
        j                        |d<   |S |j                  xs d}d|dg|d<   |S )Nr   )rg   r   r)  re   rd   rf   )rg   r   r   r   r   r   r   r   )r   r   r   rh   s       r   r   z4OpenAIProvider._serialize_function_call_output_event  s    
 JJ}}J(;(;J{#
  $ 6 6u7J7JKL\L\ ]GH  $$*D ) !GH r   c                 F    t        |dd       }|sy |j                  |       y )Nr)  )rG   r~   )r   r!   r8   r)  s       r   r2   z&OpenAIProvider._append_response_output  s"    8T2r   rE   )>__name__
__module____qualname____doc__r   r   rb  r   rY   Clientr   r   r   r   r   r   r;   boolr(   r   rT   r-   r   rQ   r0   r)   r   r   r   r   r   r   r/   r.   r{   r   r   r   r   r   r   r   r   r   r   r  r   bytesr  r3   r0  tupler   r-  r.  r/  r   r   rA  r   r   r2   r'   r   r   r   r      s   )#$,, 04$I$I 7m$I s)	$I
 T(^,$I 
$IL0 0 0.
C .
J .
`W3 W4 W$;s); T(^,; cN	;
 
c3h;z:7m: T(^,: cN	:
 
c3h:xc hsm $7 tCH~ *
D[ 
`dehjmem`n 
d38n1E %PSUYZ^_bdg_gZhUiPiJj $ 
3  
7  
D'T#Y '# 'RV '6S Xc]  DcN < <T$sCx.=Q <\(: + RVW[\_ad\dWeRf  
l  
+  
$sTWx.  
D ]+ 
c3h	4]+  
c3h	.&]\ &]hsm &]P3| 3 3@ @(3- @"& &% & 
c  
g  
Ds x} !"Cy!" 
tL!4#88	9!"F
C 
L 
$
 
0I 
2 al " " "Z] "ps " 3 3 c d38n 	/S 	/Xc] 	/s 	/& 
c3h( S	  S  T  r   r   )rk  r!  rW  r#  r  typingr   r   r   r   r   urllib.parser	   rY   r
   entity.messagesr   r   r   r   r   r   r   entity.tool_specr   runtime.node.agentr   r   utils.token_trackerr   r   r'   r   r   <module>rv     sN    %    	 3 3 )     & , , *~ ] ~ r   