§
    ÚŽ’jK  ã                   ó2  — d Z ddlmZ ddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZ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mZ ddlmZ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' neZ$eZ%eZ' e(ddh¦  «        Z) G d„ de¦  «        Z*dS )z3The OpenAI Responses API chat model implementation.é    )ÚOrderedDict)Údatetime)ÚLiteralÚAnyÚAsyncGeneratorÚListÚTYPE_CHECKINGÚType)Ú	BaseModelÚFieldé   )Ú_generate_idé   )ÚChatModelBaseÚ_TOOL_CHOICE_LITERAL_MODES)ÚChatResponse)Ú	ChatUsage)ÚOpenAICredential)ÚFormatterBaseÚOpenAIResponseFormatter)ÚMsgÚThinkingBlockÚToolCallBlockÚ	TextBlock)Ú
ToolChoice)ÚResponse)ÚResponseStreamEvent)ÚAsyncStreamÚ
modalitiesÚaudioc                   óÜ  ‡ — e Zd ZU dZ G d„ de¦  «        ZdZed         ed<   	 	 	 	 	 	 	 	 d&de	de
dddedededededz  dee
ef         dz  ddfˆ fd„Zedeee         df         fd„¦   «         Z	 	 d'de
dee         dee         dz  dedz  dedeeedf         z  fd„Zded d!deedf         fd"„Zded d#defd$„Zdee         dz  dedz  deee         dz  e
ez  dz  f         fd%„Z ˆ xZ!S )(ÚOpenAIResponseModelaH  The OpenAI Responses API chat model.

    Compared with the Chat Completions API, the Responses API provides
    first-class streaming events for reasoning / thinking, text output
    and function-call arguments, which makes it a natural fit for models
    that expose chain-of-thought reasoning (e.g. ``o3``, ``o4-mini``).
    c                   óÐ   — e Zd ZU dZ edddd¬¦  «        Zedz  ed<    edd	d
¬¦  «        Ze	ed<    eddd¬¦  «        Z
ed         dz  ed<    eddddd¬¦  «        Zedz  ed<   dS )úOpenAIResponseModel.Parametersz1The parameters for the OpenAI Response API model.Nz
Max Tokensz$The maximum number of output tokens.r   )ÚdefaultÚtitleÚdescriptionÚgtÚ
max_tokensFÚThinkingz…Whether to enable reasoning for reasoning models (e.g. o3, o4-mini, gpt-5.5). Use reasoning_effort to control the depth of reasoning.)r%   r&   r'   Úthinking_enablezReasoning Effortz°Controls the depth of reasoning for reasoning models (e.g. o3, o4-mini, gpt-5.5). Supported values are model-dependent and may include: none, minimal, low, medium, high, xhigh.)ÚnoneÚminimalÚlowÚmediumÚhighÚxhighÚreasoning_effortÚTemperaturez#The temperature for the LLM output.r   )r%   r&   r'   ÚgeÚleÚtemperature)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r)   ÚintÚ__annotations__r+   Úboolr2   r   r6   Úfloat© ó    úVC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\model\_openai_response\_model.pyÚ
Parametersr$   (   s  € € € € € € Ø?Ð?à!& ØØØ>Øð	"
ñ "
ô "
ˆ
�C˜$‘Jð 	
ð 	
ñ 	
ð !& ØØð2ð	!
ñ !
ô !
ˆ˜ð 	
ð 	
ñ 	
ð ˆEØØ$ð'ð		
ñ 	
ô 	
ð 	ØÐGÔHÈ4ÑOð	
ð 	
ñ 	
ð %* EØØØ=ØØð%
ñ %
ô %
ˆ�U˜T‘\ð 	
ð 	
ñ 	
ð 	
ð 	
r@   rB   Úopenai_responseÚtypeNTr   ç      ð?é@ Ú
credentialÚmodelÚ
parametersz%OpenAIResponseModel.Parameters | NoneÚstreamÚmax_retriesÚretry_delayÚcontext_sizeÚ	formatterÚclient_kwargsÚreturnc
           	      óZ  •— t          ¦   «                              |||p|                      ¦   «         ||||¬¦  «         |pt          ¦   «         | _        |	pi | _        ddl}
 |
j        d| j        j	         
                    ¦   «         | j        j        | j        j        dœ| j        ¤Ž| _        dS )aº  Initialize the OpenAI Responses API chat model.

        Args:
            credential (`OpenAICredential`):
                The OpenAI credential used to authenticate API calls.
            model (`str`):
                The OpenAI model name, e.g. ``o3`` or ``o4-mini``.
            parameters (`OpenAIResponseModel.Parameters | None`, defaults             to `None`):
                The OpenAI Responses API parameters. When ``None``, the
                default parameters will be used.
            stream (`bool`, defaults to `True`):
                Whether to enable streaming output.
            max_retries (`int`, defaults to `3`):
                The maximum number of retries for the OpenAI Responses API.
            retry_delay (`float`, defaults to `1.0`):
                Seconds to sleep between retry attempts.
            context_size (`int`, defaults to `200000`):
                The model context size used for context compression.
            formatter (`FormatterBase | None`, defaults to `None`):
                The formatter that converts ``Msg`` objects to the format
                required by the OpenAI Responses API. When ``None``, an
                ``OpenAIResponseFormatter`` instance will be used.
            client_kwargs (`dict[str, Any] | None`, defaults to `None`):
                Extra keyword arguments forwarded to ``openai.AsyncClient``
                (e.g. ``timeout``, ``default_headers``, ``http_client``).
        )rG   rH   rI   rJ   rK   rL   rM   r   N)Úapi_keyÚorganizationÚbase_urlr?   )ÚsuperÚ__init__rB   r   rN   rO   ÚopenaiÚAsyncClientrG   rR   Úget_secret_valuerS   rT   Úclient)ÚselfrG   rH   rI   rJ   rK   rL   rM   rN   rO   rW   Ú	__class__s              €rA   rV   zOpenAIResponseModel.__init__T   sË   ø€ õN 	‰Œ×ÒØ!ØØ!Ð6 T§_¢_Ñ%6Ô%6ØØ#Ø#Ø%ð 	ñ 	
ô 	
ð 	
ð #Ð?Õ&=Ñ&?Ô&?ˆŒØ*Ð0¨bˆÔàˆˆˆà*<¨&Ô*<ð +
Ø”OÔ+×<Ò<Ñ>Ô>ØœÔ5Ø”_Ô-ð+
ð +
ð Ô ð	+
ð +
ˆŒˆˆr@   .c                 ó>   — dd l }|j        |j        |j        |j        fS )Nr   )rW   ÚAPIConnectionErrorÚAPITimeoutErrorÚRateLimitErrorÚInternalServerError)ÚclsrW   s     rA   Ú_get_retryable_exceptionsz-OpenAIResponseModel._get_retryable_exceptions�   s/   € àˆˆˆð Ô%ØÔ"ØÔ!ØÔ&ð	
ð 	
r@   Ú
model_nameÚmessagesÚtoolsÚtool_choiceÚgenerate_kwargsc              ‹   ó�  K  — | j                              |¦  «        ƒ d{V —†}||| j        dœ}| j        j        �| j        j        |d<   | j        j        �| j        j        |d<   | j        j        r| j        j        rd| j        j        i|d<   |                     d„ | 	                    ¦   «         D ¦   «         ¦  «         |  
                    ||¦  «        \  }}	|�||d<   |	�|	|d	<   t          j        ¦   «         }
 | j        j        j        d
i |¤Žƒ d{V —†}| j        r|                      |
|¦  «        S |                      |
|¦  «        S )a#  Call the OpenAI Responses API.

        Args:
            model_name (`str`):
                The model name to use for this call.
            messages (`list`):
                A list of input items for the Responses API.
            tools (`list[dict]`, default `None`):
                The tools JSON schemas.
            tool_choice (`ToolChoice | None`, optional):
                Controls which (if any) tool is called by the model.
            **generate_kwargs (`Any`):
                Extra keyword arguments forwarded to the API.

        Returns:
            `ChatResponse | AsyncGenerator[ChatResponse, None]`:
                A ``ChatResponse`` when streaming is disabled, or an async
                generator of ``ChatResponse`` objects when streaming is
                enabled.
        N)rH   ÚinputrJ   Úmax_output_tokensr6   ÚeffortÚ	reasoningc                 ó,   — i | ]\  }}|t           v¯||“ŒS r?   )Ú_RESPONSES_UNSUPPORTED_KWARGS)Ú.0ÚkÚvs      rA   ú
<dictcomp>z1OpenAIResponseModel._call_api.<locals>.<dictcomp>Ó   s4   € ð ð ð á�A�qØÕ9Ð9Ð9ð �1à9Ð9Ð9r@   rf   rg   r?   )rN   ÚformatrJ   rI   r)   r6   r+   r2   ÚupdateÚitemsÚ_format_toolsr   ÚnowrZ   Ú	responsesÚcreateÚ_parse_stream_responseÚ_parse_completion_response)r[   rd   re   rf   rg   rh   Úformatted_messagesÚ
api_kwargsÚ	fmt_toolsÚfmt_tool_choiceÚstart_datetimeÚresponses               rA   Ú	_call_apizOpenAIResponseModel._call_api›   s£  è è € ð8 $(¤>×#8Ò#8¸Ñ#BÔ#BÐBÐBÐBÐBÐBÐBÐð  Ø'Ø”kð&
ð &
ˆ
ð Œ?Ô%Ð1Ø.2¬oÔ.HˆJÐ*Ñ+àŒ?Ô&Ð2Ø(,¬Ô(CˆJ�}Ñ%ð ŒOÔ+ð	à”Ô0ð	ð
 ˜$œ/Ô:ð'ˆJ�{Ñ#ð 	×Òðð à+×1Ò1Ñ3Ô3ðñ ô ñ	
ô 	
ð 	
ð &*×%7Ò%7¸¸{Ñ%KÔ%KÑ"ˆ	�?ØÐ Ø"+ˆJ�wÑØÐ&Ø(7ˆJ�}Ñ%å!œ™œˆØ5˜œÔ.Ô5ÐCÐC¸
ÐCÐCÐCÐCÐCÐCÐCÐCˆàŒ;ð 	IØ×.Ò.¨~¸xÑHÔHÐHà×.Ò.¨~¸xÑHÔHÐHr@   r�   r‚   z AsyncStream[ResponseStreamEvent]c                ó2  K  — d}t          ¦   «         }t          ¦   «         }t          ¦   «         }t          ¦   «         }|2 3 d{V —†}|j        }	t          g d|¬¦  «        }
|	dk    r|
                     |j        |¬¦  «         �n||	dk    r|
                     |j        |¬¦  «         �nX|	dk    r@|j        }t          |dd¦  «        d	k    r"|j	        t          |d
d¦  «        pdf||j
        <   �n|	dk    r6|j        }||v r*||         \  }}|
                     |||j        pd¬¦  «         nÖ|	dk    rÐ|j        }|j        rn|j        }t          |dd¦  «        }t          |j        |j        t%          j        ¦   «         |z
                       ¦   «         |rt          |dd¦  «        nd¬¦  «        }t          |dg ¦  «        D ]B}t          |dd¦  «        dk    r+t          |dd¦  «        }|r|
                     d||¬¦  «         ŒC|
j        s|r||
_        |
W V — �Œ×6 dS )a«  Parse the OpenAI Responses API streaming response.

        Each event yields only the *delta* content produced by that event so
        that the base ``ChatModelBase.__call__`` can accumulate the full
        response. Because the Responses API only returns the upstream
        response id on the final ``response.completed`` event, we assign a
        locally-generated ``response_id`` up-front so every delta chunk
        carries a stable id.

        Args:
            start_datetime (`datetime`):
                The start datetime of the response generation.
            response (`AsyncStream[ResponseStreamEvent]`):
                The OpenAI Responses API async stream object.

        Yields:
            `ChatResponse`:
                Incremental ``ChatResponse`` objects with ``is_last=False``.
                The base class ``__call__`` accumulates them and emits the
                final ``is_last=True`` chunk.
        NF)ÚcontentÚis_lastÚidz%response.reasoning_summary_text.delta)Úblock_idzresponse.output_text.deltazresponse.output_item.addedrD   Úfunction_callÚnameÚ Úunknownz&response.function_call_arguments.delta)rˆ   rŠ   rj   zresponse.completedÚinput_tokens_detailsÚcached_tokensr   ©Úinput_tokensÚoutput_tokensÚtimeÚcache_input_tokensÚoutputrm   r‡   )Úthinkingrˆ   Úreasoning_item_id)r   r   rD   r   Úappend_thinkingÚdeltaÚappend_textÚitemÚgetattrÚcall_idr‡   Úitem_idÚappend_tool_callr‚   Úusager   r�   r‘   r   rx   Útotal_secondsr…   )r[   r�   r‚   rŸ   Úresponse_idÚtext_idÚthinking_idÚtool_call_mappingÚeventÚ
event_typeÚ	delta_resrš   r�   rœ   rŠ   ÚrespÚuÚdetailsÚoutput_itemr–   s                       rA   r{   z*OpenAIResponseModel._parse_stream_responseè   sÞ  è è € ð4 #'ˆÝ'™>œ>ˆÝ#‘~”~ˆÝ'™>œ>ˆõ #.¡-¤-Ðà#ð R	 ð R	 ð R	 ð R	 ð R	 ð R	 ð R	 �%ØœˆJÝ$ØØØðñ ô ˆIð ÐDÒDÐDð
 ×)Ò)Ø”KØ(ð *ñ ô ð ñ ð
 Ð;Ò;Ð;Ø×%Ò% e¤k¸GÐ%ÑDÔDÐDÑDàÐ;Ò;Ð;Ø”z�Ý˜4 ¨Ñ.Ô.°/ÒAÐAð œÝ  f¨bÑ1Ô1Ð>°Yð2Ð% d¤gÑ.ùð
 ÐGÒGÐGØœ-�ØÐ/Ð/Ð/Ø$5°gÔ$>‘M�G˜TØ×.Ò.Ø!(Ø!Ø#œkÐ/¨Rð /ñ ô ð øð Ð3Ò3Ð3Ø”~�Ø”:ð Øœ
�AÝ% aÐ)?ÀÑFÔF�GÝ%Ø%&¤^Ø&'¤oÝ&œl™nœn¨~Ñ=×LÒLÑNÔNð #ð,­7Ø#Ø+Øñ,ô ,ð ,ð ðñ ô �Eõ& $+¨4°¸2Ñ#>Ô#>ð ð �KÝ˜{¨F°DÑ9Ô9¸[ÒHÐHÝ,3°KÀÀtÑ,LÔ,LÐ)Ø,ð Ø%×5Ò5Ø)+Ø)4Ø2Cð 6ñ ô ð øð Ô ð   Eð  Ø"'�	”Ø����ùðe $˜8˜8s   ¿Hr   c                 óž  — g }|j         D �]"}t          |dd¦  «        }|dk    rit          |dd¦  «        }d                     d„ t          |dg ¦  «        D ¦   «         ¦  «        }|s|r%|                     t	          d||¬	¦  «        ¦  «         Œƒ|d
k    rSt          |dg ¦  «        D ]@}t          |dd¦  «        dk    r)|                     t          d|j        ¬¦  «        ¦  «         ŒAŒÜ|dk    r@|                     t          |j        |j	        t          |dd¦  «        pd¬¦  «        ¦  «         �Œ$d}	|j
        rn|j
        }
t          |
dd¦  «        }t          |
j        |
j        t          j        ¦   «         |z
                       ¦   «         |rt          |dd¦  «        nd¬¦  «        }	|d|	dœ}t          |dd¦  «        }|r||d<   t#          di |¤ŽS )a‚  Parse the OpenAI Responses API non-streaming response.

        Args:
            start_datetime (`datetime`):
                The start datetime of the response generation.
            response (`Response`):
                The OpenAI Responses API response object.

        Returns:
            `ChatResponse`:
                A single ``ChatResponse`` with ``is_last=True``.
        rD   Nrm   r‡   ú c              3   óZ   K  — | ]&}t          |d d¦  «        ¯t          |d d¦  «        V — Œ'dS )Útextr‹   N)r›   )rp   Úss     rA   ú	<genexpr>zAOpenAIResponseModel._parse_completion_response.<locals>.<genexpr>w  sT   è è € ð ,ð ,àÝ˜q &¨"Ñ-Ô-ð,Ý˜A˜v rÑ*Ô*ð,ð ,ð ,ð ,ð ,ð ,r@   Úsummaryr•   )rD   r•   r–   Úmessager…   Úoutput_textr¯   )rD   r¯   r‰   Ú	argumentsr‹   z{})r‡   rŠ   rj   r�   rŽ   r   r�   T)r…   r†   rŸ   r?   )r”   r›   ÚjoinÚappendr   r   r¯   r   rœ   rŠ   rŸ   r   r�   r‘   r   rx   r    r   )r[   r�   r‚   Úcontent_blocksrš   Ú	item_typer–   Úcombined_summaryÚpartrŸ   r©   rª   Úresp_kwargsr¡   s                 rA   r|   z.OpenAIResponseModel._parse_completion_response_  sl  € ð" KMˆà”Oð #	ñ #	ˆDÝ  f¨dÑ3Ô3ˆIà˜KÒ'Ð'Ý$+¨D°$¸Ñ$=Ô$=Ð!Ø#&§8¢8ð ,ð ,å$ T¨9°bÑ9Ô9ð,ñ ,ô ,ñ $ô $Ð ð $ð Ð'8ð Ø"×)Ò)Ý%Ø!+Ø%5Ø.?ðñ ô ñô ð øð ˜iÒ'Ð'Ý# D¨)°RÑ8Ô8ð ð �DÝ˜t V¨TÑ2Ô2°mÒCÐCØ&×-Ò-Ý%¨6¸¼	ÐBÑBÔBñô ð øðð ˜oÒ-Ð-Ø×%Ò%Ý!Øœ<Ø!œYÝ% d¨K¸Ñ<Ô<ÐDÀðñ ô ñô ð ùð ˆØŒ>ð 	Ø”ˆAÝ˜aÐ!7¸Ñ>Ô>ˆGÝØœ^ØœoÝ”l‘n”n ~Ñ5×DÒDÑFÔFð ð$¥7ØØ#Øñ$ô $ð $ð ðñ ô ˆEð &ØØð'
ð '
ˆõ
 ˜h¨¨dÑ3Ô3ˆØð 	,Ø +ˆK˜ÑåÐ*Ð*˜kÐ*Ð*Ð*r@   c                 óÔ   — |r|r|                       ||¦  «         d}|rd„ |D ¦   «         }|s|dfS |j        }|t          vr|d|dœfS |j        r|d|d„ |j        D ¦   «         dœfS ||fS )aß  Validate and format tools and tool_choice for the Responses API.

        The full ``tools`` list is always sent unchanged to maximise prompt
        cache hits.  When ``tool_choice.tools`` restricts the callable
        subset, the ``allowed_tools`` tool_choice format is used instead of
        filtering the schemas list.

        Args:
            tools (`list[dict] | None`, optional):
                The raw tool schemas.
            tool_choice (`ToolChoice | None`, optional):
                The tool choice configuration.

        Returns:
            `tuple[list[dict] | None, str | dict | None]`:
                A tuple of ``(formatted_tools, formatted_tool_choice)``
                ready for the Responses API.
        Nc                 ó&   — g | ]}d di|d         ¥‘ŒS )rD   Úfunctionr?   )rp   Útools     rA   ú
<listcomp>z5OpenAIResponseModel._format_tools.<locals>.<listcomp>Ï  s4   € ð ð ð Ø=A�˜Ð8 t¨JÔ'7Ð8ðð ð r@   r¿   ©rD   rŠ   Úallowed_toolsc                 ó   — g | ]}d |dœ‘ŒS )r¿   rÂ   r?   )rp   rŠ   s     rA   rÁ   z5OpenAIResponseModel._format_tools.<locals>.<listcomp>ß  s0   € ð ð ð àð (°Ð6Ð6ðð ð r@   )rD   Úmoderf   )Ú_validate_tool_choicerÅ   r   rf   )r[   rf   rg   r   rÅ   s        rA   rw   z!OpenAIResponseModel._format_tools³  sâ   € ð. ð 	;˜5ð 	;Ø×&Ò& {°EÑ:Ô:Ð:àˆ	Øð 	ðð ØEJðñ ô ˆIð ð 	#Ø˜d�?Ð"àÔˆàÕ1Ð1Ð1Ø z¸4Ð@Ð@Ð@Ð@àÔð 	ØØ'Øðð à +Ô 1ðñ ô ðð ð ð ð ˜$ˆÐr@   )NTr   rE   rF   NN)NN)"r7   r8   r9   r:   r   rB   rD   r   r<   r   Ústrr=   r;   r>   r   Údictr   rV   ÚclassmethodÚtupler
   Ú	Exceptionrc   Úlistr   r   r   r   rƒ   r   r{   r|   rw   Ú__classcell__)r\   s   @rA   r"   r"      s½  ø€ € € € € € ðð ð'
ð '
ð '
ð '
ð '
�Yñ '
ô '
ð '
ðR (9€Dˆ'Ð#Ô
$Ð8Ð8Ñ8Ø%ð ?CØØØ Ø"Ø*.Ø/3ð:
ð :
à$ð:
ð ð:
ð <ð	:
ð
 ð:
ð ð:
ð ð:
ð ð:
ð ! 4Ñ'ð:
ð ˜C ˜H”~¨Ñ,ð:
ð 
ð:
ð :
ð :
ð :
ð :
ð :
ðx ð
¨%°°Y´ÀÐ0DÔ*Eð 
ð 
ð 
ñ „[ð
ð $(Ø)-ðKIð KIàðKIð �s”)ðKIð �DŒz˜DÑ ð	KIð
   $Ñ&ðKIð ðKIð 
˜ |°TÐ'9Ô:Ñ	:ðKIð KIð KIð KIðZu à ðu ð 5ðu ð 
˜ dÐ*Ô	+ð	u ð u ð u ð u ðnR+à ðR+ð ðR+ð 
ð	R+ð R+ð R+ð R+ðh2à�DŒz˜DÑ ð2ð   $Ñ&ð2ð 
ˆt�DŒz˜DÑ  #¨¡*¨tÑ"3Ð3Ô	4ð	2ð 2ð 2ð 2ð 2ð 2ð 2ð 2r@   r"   N)+r:   Úcollectionsr   r   Útypingr   r   r   r   r	   r
   Úpydanticr   r   Ú_utils._commonr   Ú_baser   r   Ú_model_responser   Ú_model_usager   rG   r   rN   r   r   r³   r   r   r   r   rÀ   r   Úopenai.types.responsesr   r   rW   r   Ú	frozensetro   r"   r?   r@   rA   ú<module>r×      sË  ðà 9Ð 9Ø #Ð #Ð #Ð #Ð #Ð #Ø Ð Ð Ð Ð Ð Ø JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ Jà %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à *Ð *Ð *Ð *Ð *Ð *Ø =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø *Ð *Ð *Ð *Ð *Ð *Ø $Ð $Ð $Ð $Ð $Ð $Ø *Ð *Ð *Ð *Ð *Ð *Ø ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CØ Ð Ð Ð Ð Ð àð Ø/Ð/Ð/Ð/Ð/Ð/Ø:Ð:Ð:Ð:Ð:Ð:Ø"Ð"Ð"Ð"Ð"Ð"Ð"à€HØÐØ€Kð !* 	¨<¸Ð*AÑ BÔ BÐ ðFð Fð Fð Fð F˜-ñ Fô Fð Fð Fð Fr@   