
    sjڤ              
       (   d Z ddlZddlZddlZddlmZmZmZmZ  ej	        d          Z
dee         defdZddlmZmZmZmZmZ dd	lmZ dd
lmZmZ dedee         fdZdZdZdZd eD             Zdeeef         defdZdeeeef                  deeeef                  fdZdefdZ deeeef                  deeeef                  fdZ!dZ" ej	        dd#                    d e"D                        d          Z$dededee         fdZ%	 d-d ed!eeeeef                           d"edee         fd#Z&deeef         defd$Z'd%eeeeef                           defd&Z(d'edefd(Z) G d) d*e          Z*dd+l+m,Z,  e,d,e*           dS ).u   OpenAI Responses API (Codex) transport.

Delegates to the existing adapter functions in agent/codex_responses_adapter.py.
This transport owns format conversion and normalization — NOT client lifecycle,
streaming, or the _run_codex_stream() call path.
    N)AnyDictListOptionalz^(cron_.+)_\d{8}_\d{6}$
session_idreturnc                     t          | pd          }t                              |          }|r|                    d          n|S )a'  Normalize a physical session_id into a stable logical cache scope.

    Every non-cron session_id already identifies one conversation/agent
    instance (main run, a specific child/subagent, a sibling child, ...),
    so it is used unchanged. Only cron's per-fire timestamp needs stripping.
        )str_CRON_SESSION_ID_REmatchgroup)r   sidr   s      :/home/agent/.hermes/hermes-agent/agent/transports/codex.py_cache_scope_from_session_idr      sB     jB

C%%c**E"+5;;q>>>+    )ACTUAL_RELAY_EFFORTSXAI_GROK46_EFFORTSXAI_LEGACY_EFFORTSclamp_effortcodex_supported_efforts)ProviderTransport)NormalizedResponseToolCallvaluec                    | dS t          |                                           }|sdS t          |          dk    r|S t          j        |                    dd                                                    dd         }d| S )zCReturn a provider-safe cache key without changing session identity.N@   utf-8replaceerrors   pck_)r   striplenhashlibsha256encode	hexdigest)r   keydigests      r   _bounded_prompt_cache_keyr-   )   s    }t
e**



C t
3xx2~~
^CJJwyJAABBLLNNsPRsSF&??r   hermes_web_search)
web_searchsearch_fileshermes_c                 &    i | ]}t            | |S  )_RESERVED_TOOL_ALIAS_PREFIX.0names     r   
<dictcomp>r8   G   s5        #*D**D  r   paramsc                 (   	 ddl m}  ||                     d                    dS n# t          $ r Y nw xY w	 ddlm}  |t          |                     d          pd                                                    d	k    S # t          $ r Y d
S w xY w)a<  True when this Responses request targets an OpenCode endpoint.

    Matches the built-in opencode-zen/go providers, custom ``opencode-go-*`` /
    ``opencode-zen-*`` family providers, and any base_url hosted on
    opencode.ai (covers custom providers with arbitrary names pointing at
    the OpenCode gateway).
    r   )opencode_provider_familyproviderNTbase_url_hostnamebase_urlr
   zopencode.aiF)hermes_cli.modelsr;   get	Exceptionutilsr>   r   lower)r9   r;   r>   s      r   _is_opencode_responses_backendrE   M   s    >>>>>>##FJJz$:$:;;G4 H   ++++++  VZZ
%;%;%Ar!B!BCCIIKK}\\   uus   $) 
66AB 
BBresponse_toolsc                    g }| D ]}t          |t                    rU|                    d          t          v r9t          |          }t           |d          |d<   |                    |           l|                    |           |S )z:Alias OpenCode-reserved client function names on the wire.r7   )
isinstancedictrA   _OPENCODE_RESERVED_TOOL_NAMESr4   appendrF   	rewrittentoolaliaseds       r   #_rename_reserved_tools_for_opencoderP   d   s    &(I # #dD!! 	#dhhv&6&6:W&W&W4jjG!<Ld6lLLGFOW%%%%T""""r   c                      	 ddl m}   |             }|t          |dd          dk    S ddlm}  |            pd                                                                dk    S # t          $ r Y dS w xY w)	u  True when xAI Responses should use Grok's native ``web_search`` built-in.

    Delegates to the web-search registry's provider resolution (which reads
    ``web.search_backend`` / ``web.backend`` from config) and checks whether
    the resolved provider is xAI. Falls back to the legacy ``_get_search_backend``
    probe when the registry has no providers loaded. On any resolution failure,
    returns True (fail-closed to native — preserves the #48108 incomplete-hang
    fix rather than risk reintroducing it).
    r   )get_active_search_providerNr7   xai)_get_search_backendr
   T)agent.web_search_registryrR   getattrtools.web_toolsrT   r%   rD   rB   )rR   r<   rT   s      r   _xai_prefers_native_web_searchrX   q   s    HHHHHH--//8VT22e;;777777##%%+2244::<<EE   tts   &A# 9A# #
A10A1c                     g }| D ]t}t          |t                    rH|                    d          dk    r/t          |          }t          |d<   |                    |           _|                    |           u|S )uJ   Rename client ``web_search`` → alias so xAI won't hijack it server-side.r7   r/   )rH   rI   rA   _XAI_CLIENT_WEB_SEARCH_ALIASrK   rL   s       r   !_rename_client_web_search_for_xair[      s    &(I # #dD!! 	#dhhv&6&6,&F&F4jjG:GFOW%%%%T""""r   )zgpt-5.5-prozgpt-5.5zgpt-5.4zgpt-5.2zgpt-5.1-codex-maxzgpt-5.1-codex-minizgpt-5.1-chat-latestzgpt-5.1-codexzgpt-5.1zgpt-5-codexzgpt-5zgpt-4.1z(?:^|[./:])(?:|c              #   >   K   | ]}t          j        |          V  d S N)reescaper5   s     r   	<genexpr>ra      s*      YY4ryYYYYYYr   z)(?:-\d{4}-\d{2}-\d{2})?$modelr?   c                    ddl m}  |t          |pd                                                    }|dk    rdS |                    d          }t          |          dk    o0|d         dk    o$t          |d	                   o|d
d         ddgk    }|sdS t          | pd                                                                                              dd          }t          
                    |          rdS dS )zAReturn ``24h`` for supported hosts/models (Bedrock Mantle, Meta).r   r=   r
   zapi.meta.ai24h.   zbedrock-mantler      Napiaws_-)rC   r>   r   rD   splitr&   boolr%   r    _EXTENDED_PROMPT_CACHE_MODEL_REsearch)rb   r?   r>   hostnamehostname_partsis_bedrock_mantle
normalizeds          r   +_default_prompt_cache_retention_for_requestrt      s"   
 ('''''  X^!4!455;;==H =  u^^C((NNq  	11!11	1"##	1 1225%.0	   tU[b!!''))//1199#sCCJ&--j99 u4r   r
   instructionstoolsscope_idc                 &   | s|sdS d}|r4t          d |D             d           }t          j        |ddd	          }| d
| pd d
| }t          j        |                    dd                                                    dd         }d| S )u  Content-address the prompt cache key within a logical cache scope.

    Returns ``pck_<sha256[:24]>`` of (scope_id + instructions + sorted tool
    schemas), or None when there is nothing static to key on. The cache key
    is a routing hint only — never a correctness boundary — so two requests
    sharing a scope, system prompt, and tool set intentionally resolve to the
    same warm prefix bucket.

    ``scope_id`` (pass ``_cache_scope_from_session_id(session_id)``) keeps
    unrelated sessions — independent conversations, main vs. child/subagent,
    sibling children — from concentrating onto the same bucket merely because
    their static prefix matches (see #78941), while still letting recurring
    cron fires of one job share a stable key across their timestamped
    session_ids (the original #51395/#52295 fix this built on). Sorting tools
    by name keeps the hash insertion-order independent.
    Nr
   c              3   D   K   | ]}t          |t                    |V  d S r^   )rH   rI   r6   ts     r   ra   z%_content_cache_key.<locals>.<genexpr>   s1      551At!4!45Q555555r   c                 t    t          |                     d          p|                     d          pd          S )Nr7   typer
   )r   rA   )r{   s    r   <lambda>z$_content_cache_key.<locals>.<lambda>   s,    #aeeFmmBquuV}}BCC r   )r+   TF),:)	sort_keysensure_ascii
separators r   r    r!   r#   r$   )sortedjsondumpsr'   r(   r)   r*   )ru   rv   rw   
tools_partsorted_toolscontentr,   s          r   _content_cache_keyr      s    *   tJ 
55555CC
 
 
 ZDu
 
 


 CC|1rCCzCCG^GNN79NEEFFPPRRSVTVSVWF&??r   c                 
   ddl m} t          |                     d          pd                                                                          }|dk    rdS  |t          |                     d          pd          d          S )	a  Return True for Microsoft Foundry's OpenAI-compatible Responses API.

    Matched on the registered provider id first, then on the endpoint host.
    Host matching goes through ``base_url_host_matches`` rather than a
    substring test, so a path or query segment carrying the Foundry domain
    (``https://proxy.example.com/.services.ai.azure.com/v1``) is not
    misclassified as Foundry.
    r   )base_url_host_matchesr<   r
   zazure-foundryTr?   zservices.ai.azure.com)rC   r   r   rA   r%   rD   )r9   r   r<   s      r   _is_azure_foundry_responsesr      s     ,+++++6::j))/R006688>>@@H?""t  FJJz""(b))+B  r   messagesc                    ddl m ddt          dt          dt          ffdt                      t	          | pd          D ]}t          |t                    s d	S |                    d
          }|dk    r6|dk    r) |                    d                    }|s d	S |z  e|dk    r d	S t          fd|                    d          pg D                       c S d	S )uz  Return True when ``messages`` end on a tool result awaiting a follow-up.

    Azure Foundry only rejects the *post-tool follow-up* payload — the shape
    where a prior assistant ``function_call`` and its ``function_call_output``
    are replayed alongside an encrypted ``reasoning`` item (HTTP 400
    invalid_payload). Detecting that shape here keeps reasoning suppression
    scoped to the failing turn, so ordinary (non-tool) Foundry multi-turn
    continuity is left unchanged.

    The test is on the *trailing* messages, not on the history as a whole.
    Scanning the whole history for any tool call plus any tool result makes
    the predicate sticky: one tool call early in a conversation would then
    suppress reasoning on every later turn, including plain user follow-ups
    that Foundry accepts. The rejected payload is specifically the turn whose
    last item is a tool result, so that is what this matches: the final
    non-system message is a ``tool`` result, and the assistant message that
    issued its ``tool_call_id`` is present.

    Tool-call identity is resolved the same way
    ``_chat_messages_to_responses_input`` resolves it, because the pairing
    that matters is the one that reaches the wire. A stored tool call can
    carry the function call id in ``call_id``, in ``id``, or in a composite
    ``"call_x|fc_y"`` id, and a bare ``fc_``-prefixed ``id`` is a response
    item id that the converter turns into ``call_<rest>``. Matching only
    ``id`` would miss the ``id=fc_… / call_id=call_…`` shape that resumed
    legacy sessions and host-fed histories still use, and let the rejected
    payload through.
    r   )_split_responses_tool_idNrawexplicitr   c                 6    |           \  }}|r|hnt                      }t          |t                    r;|                                r'|                    |                                           |sPt          | t                    r;|                                 r'|                    |                                            t          |t                    r?|                    d          r*|dd         r |                    d|dd                     |S )z>Every call id a stored tool id could pair on, converter-order.fc_   Ncall_)setrH   r   r%   add
startswith)r   r   embedded_call_iditem_ididsr   s        r   	_pair_idsz'_is_post_tool_replay.<locals>._pair_ids"  s   $<$<S$A$A!'$4?  #%%h$$ 	&)9)9 	&GGHNN$$%%% 	!z#s++ 	!		 	!GGCIIKK   gs## 	+(:(:5(A(A 	+gabbk 	+GG)GABBK))***
r   r3   FrolesystemrN   tool_call_id	assistantc              3      K   | ]N}t          |t                     |                    d           |                    d                    z  V  OdS )idcall_idNrH   rI   rA   )r6   callr   trailings     r   ra   z'_is_post_tool_replay.<locals>.<genexpr>@  sn       
 
$%%
yy$)1D1DEEE
 
 
 
 
 
r   
tool_callsr^   )	agent.codex_responses_adapterr   r   r   reversedrH   rI   rA   any)r   msgr   r   r   r   r   s       @@@r   _is_post_tool_replayr     s`   : GFFFFF
 
s 
c 
S 
 
 
 
 
 
 uuHB'' 
 
#t$$ 	55wwv86>>)CGGN3344C uuOH ;55 
 
 
 
 
--3
 
 
 
 
 	
 	
 	
 5r   context_managementc                 J    t          | t                    ot          |           S )uR  Is THIS request natively compacted?

    True only when the caller's eligibility gate
    (``native_compaction.native_compaction_context_management``) produced a
    non-empty payload. Every native-compaction side effect on the wire —
    sending ``context_management``, replaying a ``type: "compaction"``
    checkpoint, restructuring the input around it — hangs off this one
    predicate, so a checkpoint that outlives the gate (model swapped out of
    the gpt-5.6 family, compression disabled, rejection kill switch, resumed
    session) cannot keep reshaping requests on its own.
    )rH   listrm   )r   s    r   _native_compaction_activer   I  s#     ($//LD9K4L4LLr   c                      e Zd ZU dZdZee         ed<   edefd            Z	de
eef         defdZdee
eef                  defd	Zd
ee
eef                  defdZ	 ddedee
eef                  d
eee
eef                           de
eef         fdZdedefdZdedefdZdddddededededef
dZdedefdZdS )ResponsesApiTransportzyTransport for api_mode='codex_responses'.

    Wraps the functions extracted into codex_responses_adapter.py (PR 1).
    N_last_issuer_kindr   c                     dS )Ncodex_responsesr3   )selfs    r   api_modezResponsesApiTransport.api_modee  s      r   r9   c                     ddl m}  ||                    d          du |                    d          du |                    d          du |                    d                    S )	z>Classify the current Responses endpoint from transport params.r   )_classify_responses_issueris_xai_responsesTis_github_responsesis_codex_backendr?   )r   r   r   r?   )r   r   rA   )r   r9   r   s      r   _resolve_issuer_kindz*ResponsesApiTransport._resolve_issuer_kindi  s|    LLLLLL))#ZZ(:;;tC &

+@ A AT I#ZZ(:;;tCZZ
++	
 
 
 	
r   r   c                 >   ddl m} |                     |          }|| _         |||                    d          du |                    d          du t          |                    dd                    |t          |                    d                              S )	z:Convert OpenAI chat messages to Responses API input items.r   )!_chat_messages_to_responses_inputr   Tr   replay_encrypted_reasoningr   r   r   r   current_issuer_kindnative_compaction_eligible)r   r   r   r   rA   rm   r   )r   r   kwargsr   issuers        r   convert_messagesz&ResponsesApiTransport.convert_messagess  s    SSSSSS**622!'00#ZZ(:;;tC &

+@ A AT I'+

7>>( ( !''@

/00( (
 
 
 	
r   rv   c                 $    ddl m}  ||          S )zBConvert OpenAI tool schemas to Responses API function definitions.r   )_responses_tools)r   r   )r   rv   r   s      r   convert_toolsz#ResponsesApiTransport.convert_tools  s%    BBBBBB&&&r   rb   c           
         ddl m}m} ddlm} |                    dd          }|}	|sg|re|d                             d          dk    rFt          |d                             d          pd                                          }|d	d
         }	|s|}|                    d          du }
|                    d          du }|                    d          du }t          |                    dd                    }|r t          |          rt          |	          rd}|                    d          }t          |          }|                     |          }|| _        d}d}|                    d          }|rLt          |t                    r7|                    d          du rd}n|                    d          r|d         }|                    dd          r ddlm}  ||          rt$          nt&          }nV|                    d          pd                                                                dk    rt*          }nt-          |          }t/          ||          } ||          }|r`|r^t1          d |D                       }|rCt3                      r&d |D             }|                    ddi           |}nt7          |          }|rt9          |          rt;          |          }|| ||	||
|||          dd}|r||d<   d |d!<   d|d"<   |r||d<   |                    d#          }t=          |                    d$          p|          }t?          |||          p|}|
s	|s|r||d%<   tA          ||                    d&                    }|r|!                    d'|           |r%|r#dd(lm"} |rd)gng |d*<    ||          rd|i|d+<   n=|r2|
r|                    d,          }|||d+<   n|d d-|d+<   |rd)gng |d*<   n	|
s|sg |d*<   |                    d.          } | r|#                    |            d%|v r3tI          |d%                   }!|!r|!|d%<   n|%                    d%d
           |r@ddlm}  ||          r|                    d/          d0k    s|%                    d/d
           |                    d1|                    d1                    }"t          |"tL          tN          f          rRt          |"t                    s=dtO          |"          cxk     rtO          d2          k     rn ntO          |"          |d1<   n|%                    d1d
           |r|                    d%          ptI          |          }#|s|#r}|                    d3          }$i }%t          |$t                    r1|%#                    d4 |$(                                D                        |rt          |          |%d#<   |#r|#|%d5<   |%|d3<   |                    d6          }&|&|s|&|d7<   |r|r|                    d3          }$i }%t          |$t                    r1|%#                    d8 |$(                                D                        ||%d9<   |%|d3<   |                    d:          }'i }(t          |'t                    r|(#                    |'           |(!                    d%|                    d%|                     |(|d:<   |                    d:          })t          |)t                    r7d%|)v r3tI          |)d%                   }!|!r|!|)d%<   n|)%                    d%d
           |S );ui  Build Responses API kwargs.

        Calls convert_messages and convert_tools internally.

        params:
            instructions: str — system prompt (extracted from messages[0] if not given)
            reasoning_config: dict | None — {effort, enabled}
            session_id: str | None — transcript/session id; drives the Codex
                ``session_id`` header, and is the cache-scope fallback when no
                ``cache_scope_id`` is given
            cache_scope_id: str | None — rotation-stable logical scope id
                (compression-lineage root; see agent/prompt_cache_scope.py).
                Preferred over session_id when deriving the prompt_cache_key
                content hash and the xAI x-grok-conv-id header; the Codex
                x-client-request-id header mirrors the resulting body key.
                Keeps the cache warm across context-compression session
                rotation (#79017)
            max_tokens: int | None — max_output_tokens
            timeout: float | None — per-request timeout forwarded to the SDK
            request_overrides: dict | None — extra kwargs merged in
            provider: str | None — provider name for backend-specific logic
            base_url: str | None — endpoint URL
            base_url_hostname: str | None — hostname for backend detection
            is_github_responses: bool — Copilot/GitHub models backend
            is_codex_backend: bool — chatgpt.com/backend-api/codex
            is_xai_responses: bool — xAI/Grok backend
            github_reasoning_extra: dict | None — Copilot reasoning params
        r   )r   r   )DEFAULT_AGENT_IDENTITYru   r
   r   r   r   r   Nr   Tr   r   r   Fr   mediumreasoning_configenabledeffort)is_grok_46_familyr<   actualc              3   r   K   | ]2}t          |t                    o|                    d           dk    V  3dS )r7   r/   Nr   rz   s     r   ra   z5ResponsesApiTransport.build_kwargs.<locals>.<genexpr>  sT       ( ( 1d##Ef(E( ( ( ( ( (r   c                 n    g | ]2}t          |t                    r|                    d           dk    0|3S )r7   r/   r   rz   s     r   
<listcomp>z6ResponsesApiTransport.build_kwargs.<locals>.<listcomp>#  sI           *1d 3 3 89f8U8U 8U8U8Ur   r}   r/   r   )rb   ru   inputstorerv   autotool_choiceparallel_tool_callsr   cache_scope_idprompt_cache_keyr?   prompt_cache_retention)grok_supports_reasoning_effortzreasoning.encrypted_contentinclude	reasoninggithub_reasoning_extra)r   summaryrequest_overridesservice_tierprioritytimeoutinfextra_headersc                 V    i | ]&\  }}|r|	t          |          t          |          'S r^   r   r6   r+   r   s      r   r8   z6ResponsesApiTransport.build_kwargs.<locals>.<dictcomp>  sD        *U" (-'8  HHc%jj'8'8'8r   zx-client-request-id
max_tokensmax_output_tokensc                 V    i | ]&\  }}|r|	t          |          t          |          'S r^   r   r   s      r   r8   z6ResponsesApiTransport.build_kwargs.<locals>.<dictcomp>  sD       &C $)#4 C#e**#4#4#4r   zx-grok-conv-id
extra_body))r   r   r   	run_agentr   rA   r   r%   rm   r   r   r   r   r   rH   rI   agent.model_metadatar   r   r   rD   r   r   r   r   rX   rK   r[   rE   rP   r   r   rt   
setdefaultr   updater-   popintfloatitems)*r   rb   r   rv   r9   r   r   r   ru   payload_messagesr   r   r   r   r   native_compaction_activeissuer_kindreasoning_effortreasoning_enabledr   r   
_supportedrF   has_client_web_searchfilteredr   r   _cache_scope	cache_keycache_retentionr   github_reasoningr   bounded_cache_keyr   final_cache_keyexisting_extra_headersmerged_extra_headersr   existing_extra_bodymerged_extra_bodyr   s*                                             r   build_kwargsz"ResponsesApiTransport.build_kwargs  s	   F	
 	
 	
 	
 	
 	
 	
 	

 	544444zz."55# 	0 0HQKOOF33x??"8A;??9#=#=#CDDJJLL#+ABB<  	21L$jj)>??4G!::&899TA!::&899TA%)JJ3T::&
 &
" & 
	3*Ef*M*M 
	3 $$455 3-2*
 $ZZ(<== $==O#P#P  //77!, $ !::&899 	>
+;T B B 	>##I..%77$)!!!%%h// >#3H#=  ::(%00 	8>>>>>>
 '8&7&>&> (""' J jj$$*113399;;xGG .JJ
 177J'(8*EE))%00,  	W 	W$' ( ('( ( ( % %! % 	W133 W   #1     H OOV\$:;;;%-NN%F~%V%VN
  	Q<VDD 	Q@PPN (66 !1$7+E$/+C   
 
  	1,F7O$*F=!,0F()# 	>+=F'(ZZ--
 4JJ'((6J
 
 '.,
 
  	
 # 	3+; 	3	 	3)2F%&EJJz""
 
  	I6HHH 	#!1 	#KKKKKK 4NU.//SU 9 .-e44 C'/1A&B{# 	#" #)::.F#G#G #/*:F;'1Af&U&U{#7QY233WY y!! % 	#-= 	# "F9"JJ':;; 	-MM+,,,'' 9&AS:T U U  5->)**

-t444  	1>>>>>> "!%((1JJ~..*<<

>4000 **Y

9(=(=>>we--	(w--	( E'NN1111U5\\11111 %gF9JJy$''' 	? %jj);<<g@YZf@g@gO ?_ ?)/O)D)D&79$4d;; (// .D.J.J.L.L      I9<Z(6" RBQ()>?*>'ZZ--
!*:!*4F&'  	5
  	5%+ZZ%@%@"35 0$77 $++ *@*F*F*H*H     6B !12&:F?# #)**\":":02-t44 >!(()<===(("FJJ/A9$M$M   $5F< ZZ--
j$'' 	9,>*,L,L 9*EW:X Y Y  91B
-..14888r   responsec                    ddl m} |                    d          p| j        } |||          \  }}d}|r|j        rg }|j        D ]}i }	t          |d          r|j        r
|j        |	d<   t          |d          r|j        r
|j        |	d<   t          |d          r|j        j	        nt          |d	d
          }
|
t          k    rd}
n|
t          v rt          |
         }
|                    t          t          |d          r|j        n|
pd|
t          |d          r|j        j        nt          |dd          |	pd                     i }	|r!t          |d          r|j        r
|j        |	d<   |r!t          |d          r|j        r
|j        |	d<   |r!t          |d          r|j        r
|j        |	d<   t)          |r|j        nd||pd|rt          |d          r|j        ndd|	pd          S )z=Normalize Codex Responses API response to NormalizedResponse.r   )_normalize_codex_responser   )r   Nr   response_item_idfunctionr7   r
   r/   r   	argumentsz{})r   r7   r  provider_datacodex_reasoning_itemscodex_message_itemsreasoning_detailsstopr   )r   r   finish_reasonr   usager  )r   r  rA   r   r   hasattrr   r  r  r7   rV   rZ   _RESERVED_ALIAS_TO_NAMErK   r   r   r  r  r  r  r   r   r   )r   r  r   r  r   r   r  r   tcr  r7   s              r   normalize_responsez(ResponsesApiTransport.normalize_response  s   	
 	
 	
 	
 	
 	
 jj//I43I66x[YYY]
 	3> 	Jn   "2y)) :bj :/1zM),2122 Lr7J L8:8KM"45+22z+B+B_r{''PRTZ\^H_H_ 777'DD 444248D!!( 'D 1 1Eruu7>r:7N7Nrbk33T[\^`kmqTrTr"/"74	# # #      	O73 788 	OS=V 	O585NM12 	K73 566 	K3;R 	K363JM/0 	G73 344 	G9N 	G141FM-.!#&0CKKD!'16'*RwsK/H/HRcmmd'/4
 
 
 	
r   c                 f   |dS t          |dd          }t          |t                    r|st          t          |dd          pd                                                                          }t          |dd          }t          |t                    rIt          |                    d          pd                                                                          }nDt          t          |dd          pd                                                                          }|dk    o|d	k    S d
S )u  Check Codex Responses API response has valid output structure.

        Returns True only if response.output is a non-empty list. Also treats
        terminal content-filter incomplete responses as valid: the Responses API
        may return status=incomplete with incomplete_details.reason='content_filter'
        and no output items. That is a provider refusal signal, not a malformed
        response, and must reach normalization so the agent loop can use the
        content-policy / fallback path instead of invalid-response retries.

        Does NOT check output_text fallback — the caller handles that with
        diagnostic logging for stream backfill recovery.
        NFoutputstatusr
   incomplete_detailsreason
incompletecontent_filterT)rV   rH   r   r   r%   rD   rI   rA   )r   r  r  r  r   r!  s         r   validate_responsez'ResponsesApiTransport.validate_response6  s%    58T22&$'' 	Iv 	I8R88>B??EEGGMMOOF!(3G!N!N,d33 ^/33H==CDDJJLLRRTTW%72FFL"MMSSUU[[]]\)Hf8H.HHtr   Fallow_streamr   sanitize_harmony_tokens
api_kwargsr&  r   r'  c                `   ddl m}  |||||          }d|v r3t          |d                   }|r||d<   n|                    dd           |                    d          }t          |t                    r7d|v r3t          |d                   }|r||d<   n|                    dd           |S )a(  Validate and sanitize Codex API kwargs before the call.

        Normalizes input items, strips unsupported fields, validates structure.
        ``sanitize_harmony_tokens`` is enabled only for the ChatGPT Codex
        backend, which rejects literal reserved Harmony wire tokens in text.
        r   )_preflight_codex_api_kwargsr%  r   Nr   )r   r*  r-   r   rA   rH   rI   )	r   r(  r&  r   r'  r*  rs   boundedr   s	            r   preflight_kwargsz&ResponsesApiTransport.preflight_kwargsP  s     	NMMMMM00% 3$;	
 
 

 ++/
;M0NOOG 918
-..14888^^L11
j$'' 	9,>*,L,L/
;M0NOOG 918
-..14888r   
raw_reasonc                 <    ddddd}|                     |d          S )aK  Map Codex response.status to OpenAI finish_reason.

        Codex uses response.status ('completed', 'incomplete') +
        response.incomplete_details.reason for granular mapping.
        This method handles the simple status string; the caller
        should check incomplete_details separately for 'max_output_tokens'.
        r  length)	completedr"  failed	cancelled)rA   )r   r-  _MAPs      r   map_finish_reasonz'ResponsesApiTransport.map_finish_reasonu  s2      "	
 
 xx
F+++r   r^   )__name__
__module____qualname____doc__r   r   r   __annotations__propertyr   r   r   r   r   r   r   r  r   r  rm   r$  rI   r,  r4  r3   r   r   r   r   X  s          (,x}+++!# ! ! ! X!
4S> 
c 
 
 
 

d38n)= 
C 
 
 
 
$'4S#X#7 'C ' ' ' ' 15	q qq tCH~&q T#s(^,-	q 
c3hq q q qf7
3 7
=O 7
 7
 7
 7
r# $    < #$)(-# # ## 	#
 "# "&# 
# # # #J,C ,C , , , , , ,r   r   )register_transportr   )r
   )-r8  r'   r   r_   typingr   r   r   r   compiler   r   r   agent.reasoning_effortr   r   r   r   r   agent.transports.baser   agent.transports.typesr   r   r-   rZ   rJ   r4   r  rm   rE   rP   rX   r[   _EXTENDED_PROMPT_CACHE_MODELSjoinrn   rt   r   r   r   r   r   agent.transportsr;  r3   r   r   <module>rD     s      				 , , , , , , , , , , , ,
 !bj!;<< 	,Xc] 	,s 	, 	, 	, 	,              4 3 3 3 3 3 ? ? ? ? ? ? ? ?S Xc]    &  3  !? '  -   4S> d    .
T#s(^8L 
QUVZ[^`c[cVdQe 
 
 
 
    2
d4S>6J 
tTXY\^aYaTbOc 
 
 
 
!  #-"* chhYY;XYYYYY      # #  c]   @ $ $$Dc3h()$ $ c]	$ $ $ $NS#X 4    (C8Dc3h,@#A Cd C C C CLM# M$ M M M Mk, k, k, k, k,- k, k, k,^ 0 / / / / /  $&; < < < < <r   