Ë
    áß²j™  ã                  ód   — d Z ddlmZ ddlZddlmZ dZdZdZdd„Z	efd	d
œ	 	 	 	 	 	 	 dd„Z
dd„Zy)u  Route bulk request payloads around the OpenAI SDK's request transform (#93650).

``responses.create`` and ``chat.completions.create`` both re-walk the whole request
body against their TypedDict/union param graph client-side, with the GIL held,
before any byte leaves the process. #93650 documents that walk wedging for 12+
hours on a ~1.4 MB conversation â€” starving the TTFB/stale watchdogs whose job is
to rescue this exact call; the hang is pre-network, so no socket kill helps.

Hermes assembles these payloads from JSON round-trips, so they are already wire
format and the walk has nothing to convert. The SDK merges ``extra_body`` into
the JSON body *after* the transform (``_base_client._build_request``), so moving
the bulk fields there skips the walk and yields the same request bytes.
é    )ÚannotationsN)ÚAny)ÚinputÚtools)Úmessagesr   ÚHERMES_CODEX_SDK_TRANSFORMc                óî   — | � t        | t        t        t        t        f«      ryt        | t
        «      r t        d„ | j                  «       D «       «      S t        | t        «      rt        d„ | D «       «      S y)ziTrue when ``value`` is purely JSON wire types; pydantic models / generators must keep the typed SDK path.Tc              3  ó\   K  — | ]$  \  }}t        |t        «      xr t        |«      –— Œ& y ­w©N)Ú
isinstanceÚstrÚ_is_plain_json_data)Ú.0ÚkeyÚitems      ú?/home/ubuntu/.hermes/hermes-agent/agent/sdk_transform_bypass.pyú	<genexpr>z&_is_plain_json_data.<locals>.<genexpr>"   s)   è ø€ ÒeÉ)È#Èt”:˜c¤3Ó'ÒEÔ,?ÀÓ,EÓEÑeùs   ‚*,c              3  ó2   K  — | ]  }t        |«      –— Œ y ­wr   )r   )r   r   s     r   r   z&_is_plain_json_data.<locals>.<genexpr>$   s   è ø€ Ò?°Ô& t×,Ñ?ùs   ‚F)	r   r   ÚintÚfloatÚboolÚdictÚallÚitemsÚlist)Úvalues    r   r   r      s_   € à€}œ
 5¬3´´U¼DÐ*AÔBØÜ�%œÔÜÑeÐW\×WbÑWbÓWdÔeÓeÐeÜ�%œÔÜÑ?¸Ô?Ó?Ð?Øó    F©Ú
keep_slotsc               óf  — t         j                  j                  t        d«      j	                  «       j                  «       dv r| S |D �ci c];  }t        | j                  |«      t        t        f«      rt        | |   «      r|| |   “Œ= }}|s| S | j                  «       D ��ci c]  \  }}|s||vr|||v r|rg n|n|“Œ }}}|j                  d«      }t        |t        «      rt        |«      ni }	i |	¥|j                  «       D ��
ci c]  \  }}
||	vsŒ||
“Œ c}
}¥|d<   |S c c}w c c}}w c c}
}w )uÖ  Move wire-format bulk ``fields`` into ``extra_body``.

    Returns ``request_kwargs`` itself when nothing is safe to move, so callers use
    the result unconditionally. ``keep_slots`` leaves an empty-list placeholder in
    the typed kwargs for each moved field: it satisfies ``@required_args``
    (``messages`` on chat.completions) and keeps the field's position in the JSON
    body, so the bytes â€” and therefore any byte-keyed prompt cache â€” are unchanged.
    Ú >   Ú1ÚonÚyesÚtrueÚ
extra_body)ÚosÚenvironÚgetÚESCAPE_HATCH_ENVÚstripÚlowerr   r   r   r   r   )Úrequest_kwargsÚfieldsr   ÚfÚmovedr   r   Úbypassedr&   ÚmergedÚvs              r   Úbypass_sdk_request_transformr4   (   sE  € ô 
‡z�z‡~�~Ô&¨Ó+×1Ñ1Ó3×9Ñ9Ó;Ð?YÑYØÐØ+1ö l aÜ˜>×-Ñ-¨aÓ0´4¼°,Ô?ÔDWÐXfÐghÑXiÔDjð �˜qÑ!Ñ!ð l€Eð láØÐà"0×"6Ñ"6Ó"8÷\Ù�C˜¹JÈ#ÐUZÑJZð °c¸U±l™J‘b©EÈÑMð \€Hñ \à—‘˜lÓ+€JÜ!+¨J¼Ô!=ŒT�*ÔÀ2€Fà^ Ð^¸E¿K¹K»M×*]±D°A°qÈQÐV\Ê_¨1¨a©4Ó*]Ð^€Hˆ\ÑØ€Oùòlùó\ùó
 +^s   Á	A D"Â"D'ÄD-ÄD-c                ó¦   — t        t        |dd«      dd«      }|�$t        |«      j                  j                  d«      s| S t	        | t
        d¬«      S )al  Chat-completions bypass, gated on the real OpenAI SDK.

    Only the SDK performs the transform and only the SDK merges ``extra_body``
    afterwards. Hermes also drives chat-shaped facades that are NOT the SDK (the
    in-process MoA aggregator, test stand-ins); handing those an ``extra_body`` they
    never merge would silently send an empty conversation.
    ÚchatNÚcompletionszopenai.Tr   )ÚgetattrÚtypeÚ
__module__Ú
startswithr4   ÚCHAT_COMPLETIONS_BYPASS_FIELDS)r-   Úclientr7   s      r   Ú!bypass_chat_sdk_request_transformr>   E   sP   € ô œ' &¨&°$Ó7¸ÈÓM€KØÐ¤$ {Ó"3×">Ñ">×"IÑ"IÈ)Ô"TØÐÜ'¨Ô8VÐcgÔhÐhr   )r   r   Úreturnr   )r-   r   r.   ztuple[str, ...]r   r   r?   r   )r-   r   r=   r   r?   r   )Ú__doc__Ú
__future__r   r'   Útypingr   ÚRESPONSES_BYPASS_FIELDSr<   r*   r   r4   r>   © r   r   ú<module>rE      sn   ðñõ #ã 	Ý ð -Ð Ø!6Ð ð 0Ð óð 6ðð ñ	Øðàðð ð	ð
 
óô:ir   