
    Pmj                      d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZmZmZmZ ddlmZ ddlmZ  ej        e          Zddddd	dUdZda ej        dej                  Z ej        d          ZdZdVdZdWdZdddXd Z d!d"dYd$Z!dZd[d)Z"d\d+Z#d]d.Z$	 d^d_d0Z%d^d`d3Z&h d4Z'h d5Z(d6Z)d7d8dad:Z*ddd;dd<dbd@Z+dddAdcdDZ,ddddEdddIZ-dedKZ.dedLZ/dfdOZ0ddPdgdTZ1dS )hu  Codex Responses API adapter.

Pure format-conversion and normalization logic for the OpenAI Responses API
(used by OpenAI Codex, xAI, GitHub Models, and other Responses-compatible endpoints).

Extracted from run_agent.py to isolate Responses API-specific logic from the
core agent loop. All functions are stateless — they operate on the data passed
in and return transformed results.
    )annotationsN)SimpleNamespace)AnyDictListOptionaldeterministic_call_id)DEFAULT_AGENT_IDENTITYFis_xai_responsesis_github_responsesis_codex_backendbase_urlr   boolr   r   r   Optional[str]returnstrc                ,    | rdS |rdS |rdS |rd| S dS )a  Stable identifier for the Responses endpoint that mints encrypted_content.

    ``reasoning.encrypted_content`` is sealed to the endpoint that issued it:
    replaying a Codex-minted blob against xAI (or vice versa) deterministically
    returns HTTP 400 ``invalid_encrypted_content``. Stamping the issuer on
    persisted reasoning items and filtering at replay time lets a single
    conversation switch models without poisoning history with un-decryptable
    reasoning blocks.
    xai_responsesgithub_responsescodex_backendzother:other r   s       C/home/thesage/.hermes/hermes-agent/agent/codex_responses_adapter.py_classify_responses_issuerr      sG        "!!  #""""7    z)(?:^|[\s>|])to=functions\.[A-Za-z_][\w.]*z7<\|(start|end|channel|message|constrain|return|call)\|>u   ｜textc                |   | rd| vsd| vr| S dt            dt            d}t          d | D                       st                              ||           S g }g }t	          |           D ]H\  }}t          j        |          dk    r|                    |           |                    |           Id                    |          }t          t          
                    |                    }|s| S g }d}	|D ]}
||
                                         }||
                                d	z
           d	z   }|                    | |	|                    |                    dt            |
                    d	           t            d           |}	|                    | |	d
                    d                    |          S )zCKeep Harmony source readable without emitting reserved wire tokens.<|z\1>c              3  F   K   | ]}t          j        |          d k    V  dS )CfN)unicodedatacategory).0chars     r   	<genexpr>z-_neutralize_harmony_tokens.<locals>.<genexpr>_   s2      CCd{#D))T1CCCCCCr   r$    r      N)_FULLWIDTH_PIPEany_HARMONY_CONTROL_TOKEN_REsub	enumerater%   r&   appendjoinlistfinditerstartendgroup)r   replacementvisible_charsoriginal_positionsindexr(   visible_textmatchesresultoriginal_cursormatchoriginal_startoriginal_ends                r   _neutralize_harmony_tokensrC   Y   s    3d??coo<<</<<<KCCdCCCCC @(,,[$???  "M$&  ) )t%%--T"""!!%((((77=))L,55lCCDDG FO ' '+EKKMM:)%))++/:Q>d?>9:;;;M/M5;;q>>M?MMMNNN&
MM$''()))776??r   valuer   c                   t          | t                    rt          |           S t          | t          t          f          rd | D             S t          | t
                    rgi }|                                 D ]N\  }}t          |t                    r"t          |          |k    rt          d          t          |          ||<   O|S | S )zNeutralize JSON-like values; normalize tuples and reject unsafe keys.

    Rewriting an object key could desynchronize a tool schema from the executor
    contract, so a reserved token there is rejected explicitly instead.
    c                ,    g | ]}t          |          S r   )_neutralize_harmony_structure)r'   items     r   
<listcomp>z1_neutralize_harmony_structure.<locals>.<listcomp>   s!    FFF-d33FFFr   zaReserved Harmony tokens in a JSON object key cannot be neutralized without changing its contract.)	
isinstancer   rC   r3   tupledictitems
ValueErrorrG   )rD   
normalizedkeyrH   s       r   rG   rG      s     % 1)%000%$'' GFFFFFF% 	
 	B 	BIC#s## (B3(G(G3(N(N A   <DAAJsOOLr   userrolecontentrS   List[Dict[str, Any]]c                  |dk    rdnd}t          | t                    sg S g }| D ]}t          |t                    r|r|                    ||d           3t          |t                    sIt          |                    d          pd                                                                          }|dv rE|                    d          }t          |t                    r|r|                    ||d           |d	v r|                    d
          }|                    d          }t          |t                    r,|                    d          }	|                    d|          }n|}	t          |	t                    r|	sdd|	d}
t          |t                    r+|                                r|                                |
d<   |                    |
           |S )u  Convert chat-style multimodal content to Responses API input parts.

    Input:  ``[{"type":"text"|"image_url", ...}]`` (native OpenAI Chat format)
    Output: ``[{"type":"input_text"|"output_text"|"input_image", ...}]`` (Responses format)

    The ``role`` parameter controls the text content type:
    - ``"user"`` (default) → ``"input_text"``
    - ``"assistant"`` → ``"output_text"``

    The Responses API rejects ``input_text`` inside assistant messages and
    ``output_text`` inside user messages, so callers MUST pass the correct
    role for the message being converted.

    Returns an empty list when ``content`` is not a list or contains no
    recognized parts — callers fall back to the string path.
    	assistantoutput_text
input_texttyper   r[   r*   >   r   rY   rX   r   >   	image_urlinput_imager\   detailurlr]   r[   r\   )rJ   r3   r   r1   rL   getstriplower)rT   rS   	text_type	convertedpartptyper   	image_refr^   r_   
image_parts              r    _chat_content_to_responses_partsrj      s    " "&!4!4,Igt$$ 	&(I ) )dC   	 D  )T!B!BCCC$%% 	DHHV$$*++113399;;99988F##D$$$ D D  )T!B!BCCC000--IXXh''F)T**  mmE**"x88c3'' s 2?c)R)RJ&#&& 66<<>> 6'-||~~
8$Z(((r    )seprl   c                  | dS t          | t                    r| S t          | t                    r*g }d}| D ]}t          |t                    r|r|                    |           /t          |t                    sEt          |                    d          pd                                                                          }|dv rB|                    d          }t          |t                    r|r|                    |           |dv r|dz  }|                    |                                          }|rd	| d
|dk    rdnd d}|r| d| n|}|S 	 t          |           S # t          $ r Y dS w xY w)u  Flatten message content to a plain-text summary.

    Multimodal messages arrive as a list of ``{type:"text"|"image_url", ...}``
    parts from the API server.  Several consumers want a plain string:

    - Logging, spinner previews, and trajectory files (the default ``sep=" "``).
    - External memory providers, which feed the text to regexes
      (``sanitize_context``) and text APIs — a raw list crashes the sync with
      ``expected string or bytes-like object, got 'list'`` (use ``sep="\n"``).

    Text parts are joined with ``sep``; images become a ``[N image(s)]`` marker
    so the turn isn't recorded as if the attachment never existed.  Returns an
    empty string for empty lists and ``str(content)`` for unexpected scalar
    types.
    Nr*   r   r[   >   r   rY   rX   r   >   r\   r]   r+   [z images]rk   )
rJ   r   r3   r1   rL   ra   rb   rc   r2   	Exception)	rT   rl   	text_bitsimage_countrf   rg   r   summarynotes	            r   _summarize_user_message_for_logrv      s     r'3 '4   !	 	! 	!D$$$  +$$T***dD)) ((.B//5577==??E===xx''dC(( +T +$$T***666q ((9%%++-- 	?L{LL1A1A##rLLLD-4>)))))$G7||   rrs   E, ,
E:9E:fn_name	argumentsr;   intc                $    t          | ||          S )u  Generate a deterministic call_id from tool call content.

    Thin wrapper over the single policy owner
    ``agent.message_sanitization.deterministic_call_id`` (audit F4) — kept
    as a module-level name because run_agent and tests import it from here.
    Deterministic IDs prevent cache invalidation — random UUIDs would
    make every API call's prefix unique, breaking OpenAI's prompt cache.
    r	   )rw   rx   r;   s      r   _deterministic_call_idr{     s     !)U;;;r   call_idc                    t          |           t          k    r| S t          j        |                     dd                                                    dd         }d| S )ug  Keep a ``call_id`` within the Responses API's 64-char limit (#73492).

    The codex app-server namespaces MCP tool call ids as
    ``codex_mcp__<server>__<tool>_<codex_call_id>``; with an ``exec-<uuid>``
    component the built-in ``hermes-tools`` server already overflows 64 chars,
    and the Responses API rejects the whole payload with a non-retryable HTTP
    400 that then replays every turn — permanently bricking the session.

    Sibling defect to #10788 (which clamped ``input[*].id``), applied here to
    ``call_id``. The surrogate is a pure, deterministic function of the
    original, so the ``function_call`` and its matching ``function_call_output``
    — which carry the same original id — map to the same surrogate and stay
    paired without correlating the two items. Short ids pass through unchanged,
    preserving prompt-cache prefixes.
    utf-8replace)errorsN    call_)len_MAX_RESPONSES_ITEM_ID_LENGTHhashlibsha256encode	hexdigest)r|   digests     r   _clamp_responses_call_idr     s`      7||444^GNN79NEEFFPPRRSVTVSVWF6r   raw_id#tuple[Optional[str], Optional[str]]c                4   t          | t                    sdS |                                 }|sdS d|v rI|                    dd          \  }}|                                pd}|                                pd}||fS |                    d          rd|fS |dfS )z8Split a stored tool id into (call_id, response_item_id).)NNr!   r+   Nfc_)rJ   r   rb   split
startswith)r   rD   r|   response_item_ids       r   _split_responses_tool_idr   #  s    fc"" zLLNNE z
e||$)KKQ$7$7!!--//)T+1133;t((( U{$;r   r   c                r   t          |t                    r+|                                }|                    d          r|S | pd                                }|                    d          r|S |                    d          r:t	          |          t	          d          k    rd|t	          d          d          S t          j        dd|          }|                    d          r|S |                    d          r:t	          |          t	          d          k    rd|t	          d          d          S |rd|dd          S |p(t          |pd          pt          j                    j	        }t          j        |                    d                                                    dd         }d| S )	zCBuild a valid Responses `function_call.id` (must start with `fc_`).r   r*   r   Nz[^A-Za-z0-9_-]0   r~      )rJ   r   rb   r   r   rer/   uuiduuid4hexr   sha1r   r   )r|   r   	candidatesource	sanitizedseedr   s          r   "_derive_responses_function_call_idr   4  s   
 "C(( $**,,	&& 	m""$$F !! -c&kkCLL&@&@,VCLLMM*,,,("f55IE"" G$$ 0Y#g,,)F)F/Ys7||}}-/// &%Yss^%%%DS)/R00DDJLL4DD\$++g..//99;;CRC@F>>r   toolsOptional[List[Dict[str, Any]]]c                   | sdS g }| D ]}t          |t                    r|                    di           ni }|                    d          }t          |t                    r|                                sn|                    d||                    dd          d|                    ddi d	          d
           |pdS )zIConvert chat-completions tool schemas to Responses function-tool schemas.Nfunctionnamedescriptionr*   F
parametersobject)r[   
propertiesr[   r   r   strictr   )rJ   rL   ra   r   rb   r1   )r   re   rH   fnr   s        r   _responses_toolsr   U  s     t&(I  )3D$)?)?GTXXj"%%%Rvvf~~$$$ 	DJJLL 	66-44&&PR/S/STT
 
 	 	 	 	 r   >   
web_searchfile_searchlocal_shellcode_interpreterimage_generationweb_search_previewcomputer_use_preview>   	completed
incompletein_progress@   r   )defaultr   c                   t          | t                    rY|                                                                                     dd                              dd          }|t
          v r|S |S )a%  Normalize a Responses assistant message status for replay.

    The API accepts completed/incomplete/in_progress on replayed assistant
    output messages.  Preserve those exactly (modulo case/hyphen spelling) so
    incomplete Codex continuation turns don't get falsely marked completed.
    -_rk   )rJ   r   rb   rc   r   _RESPONSE_MESSAGE_STATUSES)rD   r   statuss      r   #_normalize_responses_message_statusr     se     % $$&&..sC88@@cJJ///MNr   T)r   r   replay_encrypted_reasoningcurrent_issuer_kindmessagesr   r   c          	     H  * g }t                      }| D ]}t          |t                    s|                    d          }|dk    r5|dv r|                    dd          }	t          |	t                    r=t          |	|          }
|dk    rdnd	*d                    *fd
|
D                       }ng }
|	t          |	          nd}|dk    r`|r|                    d          nd}d}t          |t                    r|D ]}t          |t                    r|                    d          r|                    d          }|r||v rH|                    d          }|.|,||k    r&t          st          
                    d||           dad |                                D             }|                    |           |r|                    |           d}|                    d          }d}t          |t                    r4|D ]0}t          |t                    s|                    d          dk    s|                    d          dk    rL|                    d          }t          |t                    swg }|D ]}t          |t                    st          |                    d          pd                                          }|dvrS|                    dd          }|d}t          |t                    st          |          }|                    d|d           |s)ddt          |                    d                    |d}|                    d          }|sZt          |t                    rE|                                r1|                                }t!          |          t"          k    r||d<   |                    d          }t          |t                    r+|                                r|                                |d<   |                    |           |dz  }2|dk    rnb|
r|                    d|
d           nG|                                r|                    d|d           n|r|                    ddd           |                    d           }t          |t                    r]|D ]Y}t          |t                    s|                    d!i           }|                    d"          }t          |t                    r|                                snt%          |                    d                    \  } }!|                    d#          }"t          |"t                    r|"                                s| }"t          |"t                    r|"                                st          |!t                    rP|!                    d$          r;t!          |!          t!          d$          k    rd%|!t!          d$          d          }"nAt          |                    d&d'                    }#t)          ||#t!          |                    }"|"                                }"|                    d&d'          }$t          |$t                    rt+          j        |$d(          }$n$t          |$t                    st          |$          }$|$                                pd'}$|                    d)t/          |"          ||$d*           [|
r|                    ||
d           n|                    ||d           S|d+k    r2|                    d,          }%t%          |%          \  }"}&t          |"t                    r|"                                s=t          |%t                    r(|%                                r|%                                }"t          |"t                    r|"                                s|                    d          }'t          |'t                    rt          |'d-          }(|(r|(})nd})nt          |'pd          })|                    d.t/          |"          |)d/           |S )0ux
  Convert internal chat-style messages to Responses input items.

    ``is_xai_responses`` is kept for transport signature compatibility but
    no longer suppresses encrypted reasoning replay.  Earlier (PR #26644,
    May 2026) we believed xAI's OAuth/SuperGrok ``/v1/responses`` surface
    rejected replayed ``encrypted_content`` reasoning items minted by
    prior turns, and we stripped them.  That decision was wrong — xAI
    explicitly relies on Hermes threading encrypted reasoning back across
    turns for cross-turn coherence (the whole point of their partnership
    integration).  We now replay encrypted reasoning on every Responses
    transport (xAI, native Codex, custom relays) and let xAI tell us
    explicitly if a specific surface ever rejects a payload.

    ``replay_encrypted_reasoning`` is the per-session kill switch.  Some
    OpenAI-compatible relays accept the request but later reject the
    replayed encrypted blob with HTTP 400 ``invalid_encrypted_content``;
    when that happens the retry loop calls
    ``AIAgent._disable_codex_reasoning_replay`` which both strips cached
    items from the conversation history and threads ``replay_enabled=False``
    through this converter so subsequent turns send no reasoning items.

    ``is_github_responses`` drops the ``id`` field from replayed
    ``codex_message_items`` regardless of length. The Copilot backend
    (api.githubcopilot.com/responses) binds these ids to a specific
    backend "connection" — credential-pool rotation, a gateway restart,
    or routine load-balancer churn between turns all invalidate it — and
    rejects a stale id with HTTP 401 "input item ID does not belong to
    this connection" even for short ids (see #32716). ``phase``/
    ``status``/``content`` are still replayed; only ``id`` is unsafe to
    reuse across a Copilot connection.

    ``current_issuer_kind`` enables a per-item cross-issuer guard. The
    Responses API's ``encrypted_content`` blob is decryptable only by the
    endpoint that minted it — replaying a Codex-issued blob against xAI
    (or vice versa) always yields HTTP 400 ``invalid_encrypted_content``
    and breaks every subsequent turn in the same session.  When this
    argument is provided and a reasoning item carries an ``_issuer_kind``
    stamp from a different endpoint, the item is dropped from the replayed
    input.  Legacy items without a stamp are still replayed
    (backwards-compatible).  The two guards compose:
    ``replay_encrypted_reasoning=False`` is the session-wide kill switch
    (drops ALL replay); ``current_issuer_kind`` is the per-item filter
    that runs only when replay is still enabled.
    rS   system>   rQ   rW   rT   r*   rR   rW   rX   rY   c              3  v   K   | ]3}|                     d           k    |                     dd          V  4dS )r[   r   r*   N)ra   )r'   prd   s     r   r)   z4_chat_messages_to_responses_input.<locals>.<genexpr>  sO       ' '*+fQZ@Z@ZAEE&"%%@Z@Z@Z@Z' 'r   Ncodex_reasoning_itemsFencrypted_contentid_issuer_kindu   Dropping reasoning item minted by %s while calling %s — encrypted_content is sealed to its issuer. This happens when a session switches model providers mid-conversation.Tc                "    i | ]\  }}|d v	||S ))r   r   r   )r'   kvs      r   
<dictcomp>z5_chat_messages_to_responses_input.<locals>.<dictcomp>  s4     + + +)-A#$,B#B#B !"1#B#B#Br   codex_message_itemsr   r[   message>   r   rX   r   rZ   r   r[   rS   r   rT   phaser+   rS   rT   
tool_callsr   r   r|   r   r   rx   {}ensure_asciifunction_callr[   r|   r   rx   tooltool_call_idrQ   function_call_outputr[   r|   output)setrJ   rL   ra   r3   rj   r2   r   _CROSS_ISSUER_WARN_EMITTEDloggerwarningrM   r1   addrb   r   r   r   r   r   r{   jsondumpsr   )+r   r   r   r   r   rM   seen_item_idsmsgrS   rT   content_partscontent_textcodex_reasoninghas_codex_reasoningriitem_iditem_issuerreplay_itemr   replayed_message_itemsraw_itemraw_content_partsnormalized_content_partsrf   	part_typer   stripped_idr   r   tcr   rw   embedded_call_idembedded_response_item_idr|   	_raw_argsrx   raw_tool_call_idr   tool_contentre   output_valuerd   s+                                             @r   !_chat_messages_to_responses_inputr     sa	   h #%EM b b#t$$ 	wwv8(((ggi,,G'4(( K @t T T T-1[-@-@MMl	!ww ' ' ' '/<' ' '     !#/6/Bs7|||{"" 2CGG3444  
 ',#ot44 +7- *7 *7%b$// )7BFF;N4O4O )7&(ffTllG& )7m+C+C ( +-&&*@*@K 3 ?$/$;$/3F$F$F (B !F$*NN)U )45H%& %& %& BF$> (+ +13+ + +K "LL555& ; - 1 1' : : :26/ '*gg.C&D&D#)*&1488 .4$7 -4 -4)(D99 %$#<<//9<<V@T@TXc@c@c$,4LL,C,C))*;TBB %$350$5 c cD#-dD#9#9 ) ((+DHHV,<,<,B(C(C(I(I(K(KI(0GGG (#'88FB#7#7D#|')#-dC#8#8 1'*4yy4;;]\`<a<abbbb7 %$ %.$/&I(,,W_J`J`&a&a'?	' ' #+,,t"4"4 3@ *7C 8 8@ !(@
 +2--//K";//3PPP4?D 1 (W 5 5%eS11 Aekkmm A38;;==K0[111.!3..)A--" 
GLL+-!P!PQQQQ!'')) GLL+,!O!OPPPP( G LL+"!E!EFFF WW\22
j$// '( & &)"d33 %$VVJ33"$&&..)'377 %w}} %$F^FF4LLG GC(*C #%&&"3"3)'377 7w}} 7&6G)'377 	aw}} 	a *+Dc J Ja$=$H$H$O$Oa %((A$B$BSZZ$O$O*Z2KCPUJJKK2X*Z*Z,/{D0I0I,J,J	*@)UXY^U_U_*`*`")--//$&FF;$=$=	%i66 7(,
95(Q(Q(QII!+Is!;!; 7(+II$-OO$5$5$=	$3'?'H'H$+)2	& &       Fd}EEFFFFd|DDEEE6>>"ww~6612BCCJGQgs++ 77==?? 7.44 79I9O9O9Q9Q 7.4466Ggs++ 7==??  779--L,-- 	7< v  	  &#,LL#%LL"<#5266LL.3G<<&     Lr   r   sanitize_harmony_tokens	raw_itemsr   c                  t          | t                    st          d          |rt          nd }g }t	                      }t          |           D 
]9\  }}t          |t                    st          d| d          |                    d          }|dk    rg|                    d          }	|                    d          }
t          |	t                    r|		                                st          d| d	          t          |
t                    r|
	                                st          d| d
          |                    dd          }t          |t                    rt          j        |d          }n$t          |t                    st          |          } ||	                                pd          }|                    d|		                                |
	                                |d           |dk    r5|                    d          }	t          |	t                    r|		                                st          d| d          |                    dd          }|d}t          |t                    rZg }|D ]#}t          |t                    s|                    d          }|dk    rN|                    d          }t          |t                    r#|r!|                    d ||          d           |dk    r|                    d          }t          |t                    rq|rod|d}|                    d          }t          |t                    r+|	                                r|	                                |d<   |                    |           %|                    d|		                                |r|ndd           t          |t                    st          |          }|                    d|		                                 ||          d           |dk    r|                    d          }t          |t                    r|r|                    d          }t          |t                    r|r||v rQ|                    |           d|d}|                    d           }t          |t                    r|rt          |          n||d <   ng |d <   |                    |           |d!k    rW|                    d"          }|d#k    rt          d| d$          |                    d%          }t          |t                    st          d| d&          g }t          |          D ]\  }}t          |t                    st          d| d'| d          |                    d          }|d(vrt          d| d'| d)|d*          |                    dd          }|d}t          |t                    st          |          }|                    d+ ||          d           |st          d| d,          d!d#t          |                    d-                    |d.}|                    d          }|sZt          |t                    rE|	                                r1|	                                }t!          |          t"          k    r||d<   |                    d/          }t          |t                    r+|	                                r|	                                |d/<   |                    |           &|                    d"          }|d0v r|                    d%d          }|d}t          |t                    rk|d#k    rd+nd} g }!t          |          D ]4\  }}t          |t                    r$|r!|!                    |  ||          d           ?t          |t                    st          d| d1| d2          t          |                    d          pd          	                                                                }|d3v r_|                    dd          }t          |t                    st          |pd          }|!                    |  ||          d           |d4v r|                    dd          }"|                    d          }t          |"t                    r-|"                    d5d          }|"                    d|          }n|"}t          |t                    st          |pd          }d|d}#t          |t                    r+|	                                r|	                                |#d<   |!                    |#           
t          d| d1| d)|                    d          d*          |                    ||!d6           	t          |t                    st          |          }|                    | ||          d6           
"t          d| d7|d8|d9          |S ):Nz4Codex Responses input must be a list of input items.c                    | S Nr   )r   s    r   <lambda>z._preflight_codex_input_items.<locals>.<lambda>  s    $ r   zCodex Responses input[] must be an object.r[   r   r|   r   z#] function_call is missing call_id.z ] function_call is missing name.rx   r   Fr   r   r   z*] function_call_output is missing call_id.r   r*   rY   r   rZ   r]   r\   r`   r^   r   	reasoningr   r   r[   r   rt   r   rS   rW   z+] message items must have role='assistant'.rT   z&] message item must have content list.z] message content[>   r   rX   ] has unsupported type .rX   z3] message item must contain at least one text part.r   r   r   >   rQ   rW   z
].content[z] must be an object or string.>   r   rY   rX   >   r\   r]   r_   r   z#] has unsupported item shape (type=z, role=z).)rJ   r3   rN   rC   r   r0   rL   ra   r   rb   r   r   r1   r   rG   r   r   r   rc   )$r   r   r   sanitize_textrO   seen_idsidxrH   	item_typer|   r   rx   r   cleanedrf   rg   r   r_   entryr^   	encryptedr   reasoning_itemrt   rS   rT   normalized_contentpart_idxr   normalized_itemr   r   rd   	validatedrh   ri   s$                                       r   _preflight_codex_input_itemsr    s}    i&& QOPPP #	"" 
 (*JEEHy)) T
 T
	T$%% 	QOcOOOPPPHHV$$	''hhy))G88F##Dgs++ d7==?? d !b#!b!b!bcccdC(( a

 a !_#!_!_!_```d33I)T** + JyuEEE			3// +	NN	%ioo&7&7&?4@@I+&}} JJLL!*	    ...hhy))Ggs++ k7==?? k !i#!i!i!ijjjXXh++F~
 &$''  13" 2 2D%dD11 !  HHV,,E,,#xx//%dC00 `T `#NNL--X\J]J]+^+^___-//"hh{33%c3// 2C 2=JY\4]4]E%)XXh%7%7F)&#66 A6<<>> A28,,..h#NN5111!! 6#*==??-4"<''"    fc** %V2&}}+mF33    ##!455I)S)) 2i 2((4..gs++ * *(** LL)))')22 2 ((9--gt,, 3 3%5g>>>$ #9-- 13N9-!!.111	!!88F##D{"" !j#!j!j!jkkkhhy))Ggt,, g !e#!e!e!efff!#"+G"4"4 ` `$!$-- $ffffff   !HHV,,	$;;;$wwwwwirwww   xx++<D!$,, %t99D"))=--X\J]J]*^*^____% t !r#!r!r!rsss!#=dhhx>P>PQQ-	/ /O hhtnnG'8w,,8 MMOO8
 &mmoo{##'DDD,7OD)HHW%%E%%% 9%++-- 9+0;;==(o...xx(((hhy"--G'4(( * .2[-@-@MMl	24	&/&8&8    NHd!$,, ! _%,,iW[I\I\-]-]^^^ %dD11 (lSllHlll     0 0 6B77==??EEGGE EEE#xx33)$44 3#&tzr??D!(()]]SWEXEX)Y)YZZZZ">>>$(HH["$=$=	!%(!3!3%i66 ,"+--r":":C%.]]8V%D%DFF"+C)#s33 1"%ciR..C>KZ]5^5^
%fc22 Bv||~~ B39<<>>Jx0!((4444(zSzzHzzeiememnteueuzzz   !!4I"F"FGGGgs++ 'g,,tg8N8NOOPPPkSkkYkkaekkk
 
 	
 r   )allow_streamr   r   
api_kwargsr  Dict[str, Any]c          	        ' t           t                    st          d          h d} fd|D             }|r3t          dd                    t	          |                     d                               d          }t          |t                    r|                                st          d          |                                }                     d	          }|d
}t          |t                    st          |          }|                                pt          }|rt          |          }t                               d          ||          }                     d          }	d }
|	t          |	t                    st          d          g }
t          |	          D ]\  }}t          |t                    st          d| d          |                    d          }|t          v r#|
                    t          |                     o|dk    r)t          d| d|                    d          d          |                    d          }|                    d          }t          |t                    r|                                st          d| d          t          |t                    st          d| d          |                    dd
          }|d
}t          |t                    st          |          }|                    dd          }t          |t                    st          |          }|
                    d|                                |||d           |r|
t!          |
          }
                     dd          }|durt          d          h d'|||dd}|
|
|d<                        d           }t          |t                    r||d <                        d!          }t          |t                    r||d!<                        d"          }t          |t                    r+|                                r|                                |d"<                        d#          }t          |t"          t$          f          r|d$k    rt#          |          |d#<                        d%          }t          |t"          t$          f          rQt          |t                    s<d$t%          |          cxk     rt%          d&          k     rn nt%          |          |d%<                        d'          }t          |t"          t$          f          rt%          |          |d'<   d(D ]}                     |          }||||<                        d)          }|t          |t                    st          d*          i }|                                D ]d\  }}t          |t                    r|                                st          d+          |@t          |          ||                                <   e|r||d)<                        d,          } | 8t          | t                    st          d-          | rt          |           |d,<   |rI                     d.          }!|!|!d/urt          d0          |!d/u rd/|d.<   '                    d.           nd. v rt          d1          t                               d          pd
                                          }"|"                    d2          }#|#rD|                    d          r/	 d$d3lm}$  |$|d                   \  |d<   }%n# t2          $ r Y nw xY wt	          'fd4 D                       }&|&r&t          d5d                    |&           d          |S )6Nz'Codex Responses request must be a dict.>   inputmodelinstructionsc                    g | ]}|v|	S r   r   )r'   rP   r  s     r   rI   z/_preflight_codex_api_kwargs.<locals>.<listcomp>  s#    @@@s#Z*?*?s*?*?*?r   z3Codex Responses request missing required field(s): z, r  r  z;Codex Responses request 'model' must be a non-empty string.r  r*   r  r   r   z=Codex Responses request 'tools' must be a list when provided.zCodex Responses tools[r  r[   r   r  r   r   z] is missing a valid name.z] is missing valid parameters.r   r   Fr   storez6Codex Responses contract requires 'store' to be false.>   r  r  r  r   includetimeoutr  
extra_bodytemperaturetool_choicer  service_tierextra_headersprompt_cache_keymax_output_tokensparallel_tool_callsprompt_cache_retention)r  r  r  r  r  r  r$  r'  r   r   infr"  )r#  r(  r&  r)  r%  z:Codex Responses request 'extra_headers' must be an object.zGCodex Responses request 'extra_headers' keys must be non-empty strings.r!  z7Codex Responses request 'extra_body' must be an object.streamTz/Codex Responses 'stream' must be true when set.zKCodex Responses stream flag is only allowed in fallback streaming requests.)zgrok-z
x-ai/grok-)strip_slash_enumc              3  $   K   | ]
}|v|V  d S r  r   )r'   rP   allowed_keyss     r   r)   z._preflight_codex_api_kwargs.<locals>.<genexpr>s  s-      MMS5L5L5L5L5L5LMMr   z2Codex Responses request has unsupported field(s): )rJ   rL   rN   r2   sortedra   r   rb   r   rC   r  r3   r0   _RESPONSES_BUILTIN_TOOL_TYPESr1   r   rG   ry   floatrM   r   rc   r   tools.schema_sanitizerr,  rq   )(r  r  r   r   requiredmissingr  r  normalized_inputr   normalized_toolsr  r   	tool_typer   r   r   r   r  rO   r  r  r$  r'  r   r"  passthrough_keyvalr%  normalized_headersrP   rD   r!  r+  model_name_for_provider_checkis_xai_modelr,  r   
unexpectedr.  s(   `                                      @r   _preflight_codex_api_kwargsr>    s    j$'' DBCCC111H@@@@h@@@G nltyyY_`gYhYhOiOilllmmmNN7##EeS!! X XVWWWKKMME>>.11LlC(( )<((%%''A+AL @1,??3w/ 7   NN7##E%&& 	^\]]]"5)) .	 .	ICdD)) U !S#!S!S!STTT((I 999 ''T

333J&& !k#!k!kVZV^V^_eVfVf!k!k!klll88F##D,//JdC(( [

 [ !Y#!Y!Y!YZZZj$// _ !]#!]!]!]^^^((="55K" k3// /!+..XXh..Ffd++ &f##& JJLL#.$",      K#3#?89IJJNN7E**EEQRRR  L $!	" "J #.
7 {++I)T"" ,"+
;nnY''G'4   ( '
9>>.11L,$$ :););)=)= :%1%7%7%9%9
>" #':;;#c5\22 A7H17L7L*-.?*@*@
&'nnY''G7S%L))/7D))/ g----u----- %g
9..//K+U|,, 7$)+$6$6
=! . . nn_--?*-J'NN?33M -.. 	[YZZZ-/'--// 	9 	9JCc3'' lsyy{{ l !jkkk}.1%jjsyy{{++ 	=*<J'--J*d++ 	XVWWW  	8'+J'7'7J|$ h))&"4"4NOOOT>>#'Jx """"	Z		fggg %(
w(?(?(E2$F$F$L$L$N$N!0;;<STTL 
w// 	??????%5%5j6I%J%J"Jw 	 	 	D	 MMMMzMMMMMJ 
Y:AVAVYYY
 
 	
 s   <^ 
^'&^'rH   c                T   t          | dd          }t          |t                    sdS g }|D ]U}t          |dd          }|dvrt          |dd          }t          |t                    r|r|                    |           Vd                    |                                          S )z<Extract assistant text from a Responses message output item.rT   Nr*   r[   >   r   rX   r   getattrrJ   r3   r   r1   r2   rb   )rH   rT   chunksrf   rg   r   s         r   _extract_responses_message_textrC    s    dIt,,Ggt$$ rF    fd++///tVT**dC   	 T 	 MM$776??  """r   c                   t          | dd          }t          |t                    rmg }|D ]?}t          |dd          }t          |t                    r|r|                    |           @|r'd                    |                                          S t          | dd          }t          |t                    r|r|                                S dS )zAExtract a compact reasoning text from a Responses reasoning item.rt   Nr   
r*   r@  )rH   rt   rB  rf   r   s        r   !_extract_responses_reasoning_textrF    s    dIt,,G'4   - 	$ 	$D4..D$$$ $ $d### 	-99V$$**,,,4&&D$  zz||2r   	error_objresponse_statusc                   d}d}t          | t                    r+|                     d          }|                     d          }n$| "t          | dd          }t          | dd          }t          |t                    r!t	          |                                          n$|r!t	          |                                          nd}t          |t                    r!t	          |                                          n$|r!t	          |                                          nd}|r	|r| d| S |r|S |r|S | rt	          |           S d| dS )ac  Build a human-readable error string from a Responses ``response.error`` payload.

    The OpenAI Responses API carries failure details under ``response.error``
    on terminal ``response.failed`` events, in the shape
    ``{"code": "rate_limit_exceeded", "message": "Slow down", "param": ...}``.
    Earlier code only surfaced ``message``, which left users staring at bare
    strings like ``"Slow down"`` while the failure mode (rate limit vs
    context-length vs internal_error vs model-overloaded) was hidden in
    ``code``. We now prefix ``code`` when both are present so consumers can
    distinguish failure modes without parsing the bare message.

    Falls back to ``code`` alone when ``message`` is empty, and to a stable
    default referencing the response status when no error payload is
    available at all. Adapted from anomalyco/opencode#28757.
    Ncoder   r*   z: zResponses API returned status '')rJ   rL   ra   rA  r   rb   )rG  rH  rJ  r   code_strmessage_strs         r   _format_responses_errorrN    s_   " DG)T"" 6}}V$$--	**		y&$//)Y55$.tS$9$9bs4yy   UY@aD		@Q@Q@Q_aH*4Wc*B*Bq#g,,$$&&&ahIpWI[I[I]I]I]npK ,K ,++k+++    9~~?_????r   )issuer_kindresponserO  tuple[Any, str]c                  t          | dd          }t          |t                    r'|                                                                }nd}t          | dd          }d}t          |t
                    rIt          |                    d          pd                                                                          }nF|Dt          t          |dd          pd                                                                          }|dk    o|dk    }t          | dd          }t          |t                    r|st          | d	d          }t          |t                    r|                                rxt          	                    d
t          |                                                     t          dddt          d	|                                          g          g}|| _        n-|rt          dddg           g}|| _        nt          d          |dv r0t          | dd          }t          ||          }	t          |	          g }
g }g }g }g }|dv }|dv }d}d}d}h d}|D ]}t          |dd          }t          |dd          }t          |t                    r'|                                                                }nd}|dv r||vrd}d}|dk    r t          |dd          }d}d}t          |t                    r5|                                                                }|dv rd}d}n|dv rd}t          |          }|r|r|                    |           n|
                    |           ddt#          |          d	|dgd}t          |dd          }t          |t                    r|r||d<   |r||d<   |                    |           v|dk    rYd}t%          |          }|r|                    |           t          |dd          }t          |t                    r|rd|d} |r|| d <   t          |dd          }t          |t                    r2|                    d!          rt          	                    d"|           3t          |t                    r|r|| d<   t          |d#d          }!t          |!t                    rJg }"|!D ]@}#t          |#d$d          }$t          |$t                    r|"                    d%|$d           A|"| d#<   |                    |            |d&k    rr|dv rt          |d'd          pd}%t          |d(d)          }&t          |&t                    st)          j        |&d*          }&t          |d+d          }'t          |dd          }(t-          |(          \  })}*t          |'t                    r|'                                r|'n|)}+t          |+t                    r|+                                st/          |%|&t          |                    }+|+                                }+t          |(t                    r|(nd},t1          |+|,          },|                    t          |+|+|,d,t          |%|&-          .                     O|d/k    rjt          |d'd          pd}%t          |d0d)          }&t          |&t                    st)          j        |&d*          }&t          |d+d          }'t          |dd          }(t-          |(          \  })}*t          |'t                    r|'                                r|'n|)}+t          |+t                    r|+                                st/          |%|&t          |                    }+|+                                }+t          |(t                    r|(nd},t1          |+|,          },|                    t          |+|+|,d,t          |%|&-          .                     d1                    d2 |
D                                                       }-|-sNt5          | d	          r>|r|r:t          | d	d          }t          |t                    r|                                }-d}.|-rC|sAt6                              |-          r'd}.t                              d3|-dd4                    d}-|d5k    r|-s|s|rd6                    |          }/|/                    d7          }0|0d8k    r|/|0t          d7          z   d         }1|1                    d9          }2|2d8k    r
|1d|2         }1|1                                }1|1rMt                              d:t          |1                     |1}-|/d|0                                         }3|3r|3gng }t          |-||r'd6                    |                                          nddd|pd|pd;          }4|rd<}5n2|rd}5n-|.rd}5n(|rd}5n#|s|r|sd}5n|s|s|r|-s|dk    r|d=vrd>}5nd}5nd>}5|4|5fS )?ar  Normalize a Responses API object to an assistant_message-like object.

    ``issuer_kind`` (when provided) is stamped onto each reasoning item the
    response yields, so future replays can detect when the active endpoint
    differs from the one that minted the encrypted_content blob and drop
    the item instead of triggering HTTP 400 invalid_encrypted_content.
    r   Nincomplete_detailsr*   reasonr   content_filterr   rX   z`Codex response has empty output but output_text is present (%d chars); synthesizing output item.r   rW   r   rZ   r   z&Responses API returned no output items>   failed	cancellederror>   queuedr   r   >   rY  r   F>   mcp_callcomputer_callweb_search_callfile_search_calllocal_shell_callcode_interpreter_callimage_generation_callr[   Tr   >   analysis
commentary>   finalfinal_answerr   r  r   r  r   rs_tmp_z@Skipping transient Codex reasoning item during normalization: %srt   r   summary_textr   r   rx   r   r   r|   r   )r   rx   )r   r|   r   r[   r   custom_tool_callr  rE  c                    g | ]}||S r   r   )r'   r   s     r   rI   z-_normalize_codex_response.<locals>.<listcomp>  s    :::!:A:::r   zCodex response contains leaked tool-call text in assistant content (no structured function_call items). Treating as incomplete so the continuation path can re-elicit a proper tool call. Leaked snippet: %ri,  r   z

z
<response>z</response>zxAI response delivered its final answer inside the reasoning channel (<response> delimiter); promoting %d chars to assistant content.)rT   r   r  reasoning_contentreasoning_detailsr   r   r   )r   r   r   stop) rA  rJ   r   rb   rc   rL   ra   r3   r   debugr   r   r   RuntimeErrorrN  rC  r1   r   rF  r   r   r   r   r{   r   r2   hasattr_TOOL_CALL_LEAK_PATTERNsearchr   rfindfind)6rP  rO  rH  rS  incomplete_reason"response_incomplete_content_filterr   out_textrG  	error_msgr   reasoning_partsreasoning_items_rawmessage_items_rawr   has_incomplete_items saw_streaming_or_item_incompletesaw_commentary_phasesaw_final_answer_phasesaw_reasoning_item_SERVER_SIDE_TOOL_CALL_TYPESrH   r  item_status
item_phasenormalized_phaseis_commentary_phasemessage_textraw_message_itemr   reasoning_textr  r   rt   raw_summaryrf   r   rw   rx   raw_call_idraw_item_idr   r   r|   r   
final_textleaked_tool_call_textjoined_reasoningmarkersalvagedclosingreasoning_prefixassistant_messagefinish_reasons6                                                         r   _normalize_codex_responser    sY    h$77O/3'' )//117799 +?FF$d++ a 2 6 6x @ @ FBGGMMOOUUWW		'(:Hb I I ORPPVVXX^^``<'Q,=AQ,Q ' Xx..Ffd## I6 I 8]D99h$$ 	I)9)9 	ILL,-01A1A-B-B   &[(m(..BRBRSSST   F %HOO/ 
	I
 &[b   F %HOOGHHH111Hgt44	+IGG	9%%%!M!#O02.0J*.UU'6:S'S$ "&$ $ $   C CD&$//	dHd33k3'' 	%++--3355KKK BBB!===#' /3,	!! w55J#"'*c** 2#-#3#3#5#5#;#;#=#= #'AAA+/(*.''%)BBB-1*:4@@L ; ' 7#**<8888!((666%'A+NN)6 M MN	4 4  "$d33gs++ 5 5-4$T*# A0@$W-!(()9:::+%%!%>tDDN 7&&~666  &94@@I)S)) 5i 5$/iPP
  ;/:H^,!$d33gs++ 0B0B90M0M LLZ   gs++ - -%,HTN!$	488gt,, 6"$K ' W W&tVT::%dC00 W'..PT/U/UVVV*5HY'#**8444/))EEEdFB//52Gk488Ii-- F JyuEEE	!$	488K!$d33K":;"G"Ga%/S%A%AokFWFWFYFYokk_oGgs++ V7==?? V0)S__UUmmooG.8c.J.JT{{PTA'K[\\o!1(gKKK       ,,,dFB//52Ggt44Ii-- F JyuEEE	!$	488K!$d33K":;"G"Ga%/S%A%AokFWFWFYFYokk_oGgs++ V7==?? V0)S__UUmmooG.8c.J.JT{{PTA'K[\\o!1(gKKK      ::}:::;;AACCJ*Hm,,* &* /E*
 8]B77h$$ 	*!))J& " * )@)G)G
)S)S  $U tt		
 	
 	
 
" 	&& 	' 	'  	'
 ";;77!''55R<<'\1B1B(B(C(CDHmmM22G"}}#HWH-~~''H 	Q5 MM	   &
#3GVG#<#B#B#D#D 8H"P#3"4"4b':IS&++o..44666t19T-5    #$	+ !(	 $	) $
 "6 @V $
  4F PZ   k))k B
 /
 /

 #MM(MMm++r   )
r   r   r   r   r   r   r   r   r   r   )r   r   r   r   )rD   r   r   r   )rT   r   rS   r   r   rU   )rT   r   rl   r   r   r   )r   )rw   r   rx   r   r;   ry   r   r   )r|   r   r   r   )r   r   r   r   r  )r|   r   r   r   r   r   )r   r   r   r   )rD   r   r   r   r   r   )r   rU   r   r   r   r   r   r   r   r   r   rU   )r   r   r   r   r   r   r   rU   )
r  r   r  r   r   r   r   r   r   r  )rH   r   r   r   )rG  r   rH  r   r   r   )rP  r   rO  r   r   rQ  )2__doc__
__future__r   r   r   loggingr   r%   r   typesr   typingr   r   r   r   agent.message_sanitizationr
   agent.prompt_builderr   	getLogger__name__r   r   r   compile
IGNORECASErp  r.   r,   rC   rG   rj   rv   r{   r   r   r   r   r0  r   r   r   r   r  r>  rC  rF  rN  r  r   r   r   <module>r     s|    # " " " " "    				      ! ! ! ! ! ! , , , , , , , , , , , , < < < < < < 7 7 7 7 7 7		8	$	$
 # %""     : #  %"*0M   'BJ>   # # # #L   6 CI 0 0 0 0 0 0f AD - - - - - -h	< 	< 	< 	< 	<   ,   & '+    B    <! ! !  HGG  !#  GR      " # %'+)-[ [ [ [ [ [J	 !&$)	f f f f f fX  %$)T T T T T Tv# # # #"   "'@ '@ '@ '@b "&f, f, f, f, f, f, f, f,r   