
    j                        d Z ddlmZ ddlZddlmZmZ ddlmZ e G d d                      Z	e G d d	                      Z
e G d
 d                      ZddZddZdS )u  Shared types for normalized provider responses.

These dataclasses define the canonical shape that all provider adapters
normalize responses to.  The shared surface is intentionally minimal —
only fields that every downstream consumer reads are top-level.
Protocol-specific state goes in ``provider_data`` dicts (response-level
and per-tool-call) so that protocol-aware code paths can access it
without polluting the shared type.
    )annotationsN)	dataclassfield)Anyc                      e Zd ZU dZded<   ded<   ded<    edd	          Zd
ed<   edd            Zedd            Z	edd            Z
edd            Zedd            ZdS )ToolCallu_  A normalized tool call from any provider.

    ``id`` is the protocol's canonical identifier — what gets used in
    ``tool_call_id`` / ``tool_use_id`` when constructing tool result
    messages.  May be ``None`` when the provider omits it; the agent
    fills it via ``_deterministic_call_id()`` before storing in history.

    ``provider_data`` carries per-tool-call protocol metadata that only
    protocol-aware code reads:

    * Codex: ``{"call_id": "call_XXX", "response_item_id": "fc_XXX"}``
    * Gemini: ``{"extra_content": {"google": {"thought_signature": "..."}}}``
    * Others: ``None``
    
str | Noneidstrname	argumentsNFdefaultreprdict[str, Any] | Noneprovider_datareturnc                    dS )Nfunction selfs    5/usr/local/lib/hermes-agent/agent/transports/types.pytypezToolCall.type-   s    z    c                    | S )z=Return self so tc.function.name / tc.function.arguments work.r   r   s    r   r   zToolCall.function1   s	     r   c                :    | j         pi                     d          S )zSCodex call_id from provider_data, accessed via getattr by _build_assistant_message.call_idr   getr   s    r   r   zToolCall.call_id6   s      "(b--i888r   c                :    | j         pi                     d          S )z*Codex response_item_id from provider_data.response_item_idr   r   s    r   r"   zToolCall.response_item_id;   s!     "(b--.@AAAr   c                :    | j         pi                     d          S )u  Gemini extra_content (thought_signature) from provider_data.

        Gemini 3 thinking models attach ``extra_content`` with a
        ``thought_signature`` to each tool call.  This signature must be
        replayed on subsequent API calls — without it the API rejects the
        request with HTTP 400.  The chat_completions transport stores this
        in ``provider_data["extra_content"]``; this property exposes it so
        ``_build_assistant_message`` can ``getattr(tc, "extra_content")``
        uniformly.
        extra_contentr   r   s    r   r$   zToolCall.extra_content@   s      "(b--o>>>r   )r   r   )r   r   r   r	   )r   r   )__name__
__module____qualname____doc____annotations__r   r   propertyr   r   r   r"   r$   r   r   r   r   r      s          NNNIIINNN+05E+J+J+JMJJJJ    X    X 9 9 9 X9 B B B XB ? ? ? X? ? ?r   r   c                  L    e Zd ZU dZdZded<   dZded<   dZded<   dZded<   dS )	Usagez!Token usage from an API response.r   intprompt_tokenscompletion_tokenstotal_tokenscached_tokensN)	r&   r'   r(   r)   r/   r*   r0   r1   r2   r   r   r   r-   r-   O   s]         ++MLMr   r-   c                      e Zd ZU dZded<   ded<   ded<   dZded	<   dZd
ed<    edd          Zded<   e	dd            Z
e	d             Ze	d             Ze	d             ZdS )NormalizedResponseu  Normalized API response from any provider.

    Shared fields are truly cross-provider — every caller can rely on
    them without branching on api_mode.  Protocol-specific state goes in
    ``provider_data`` so that only protocol-aware code paths read it.

    Response-level ``provider_data`` examples:

    * Anthropic: ``{"reasoning_details": [...]}``
    * Codex: ``{"codex_reasoning_items": [...], "codex_message_items": [...]}``
    * Others: ``None``
    r	   contentzlist[ToolCall] | None
tool_callsr   finish_reasonN	reasoningzUsage | NoneusageFr   r   r   r   c                >    | j         pi }|                    d          S )Nreasoning_contentr   r   pds     r   r;   z$NormalizedResponse.reasoning_contentr   "    %2vv)***r   c                >    | j         pi }|                    d          S )Nreasoning_detailsr   r<   s     r   r@   z$NormalizedResponse.reasoning_detailsw   r>   r   c                >    | j         pi }|                    d          S )Ncodex_reasoning_itemsr   r<   s     r   rB   z(NormalizedResponse.codex_reasoning_items|   s"    %2vv-...r   c                >    | j         pi }|                    d          S )Ncodex_message_itemsr   r<   s     r   rD   z&NormalizedResponse.codex_message_items   s"    %2vv+,,,r   r%   )r&   r'   r(   r)   r*   r8   r9   r   r   r+   r;   r@   rB   rD   r   r   r   r4   r4   Y   s           %%%% I    E+05E+J+J+JMJJJJ
 + + + X+ + + X+ / / X/ - - X- - -r   r4   r
   r	   r   r   r   r   provider_fieldsr   c                    t          |t                    rt          j        |          nt	          |          }|rt          |          nd}t          | |||          S )zBuild a ``ToolCall``, auto-serialising *arguments* if it's a dict.

    Any extra keyword arguments are collected into ``provider_data``.
    N)r
   r   r   r   )
isinstancedictjsondumpsr   r   )r
   r   r   rE   args_strr=   s         r   build_tool_callrL      s[     )39d(C(CWtz)$$$YH"1	;o			tBrKKKKr   reasonmappingdict[str, str]c                6    | dS |                     | d          S )zTranslate a provider-specific stop reason to the normalised set.

    Falls back to ``"stop"`` for unknown or ``None`` reasons.
    Nstop)r    )rM   rN   s     r   map_finish_reasonrR      s"    
 ~v;;vv&&&r   )
r
   r	   r   r   r   r   rE   r   r   r   )rM   r	   rN   rO   r   r   )r)   
__future__r   rI   dataclassesr   r   typingr   r   r-   r4   rL   rR   r   r   r   <module>rV      s*    # " " " " "  ( ( ( ( ( ( ( (       9? 9? 9? 9? 9? 9? 9? 9?x         *- *- *- *- *- *- *- *-dL L L L' ' ' ' ' 'r   