
    nSj                    F    U d Z ddlmZ ddlmZ dZded<   ddZ	 dddZdS )u  Thinking-timeout detection and user-facing guidance for reasoning models.

When a known reasoning model (NVIDIA Nemotron 3 Ultra, OpenAI o1/o3,
Anthropic Opus 4.x thinking, DeepSeek R1, Qwen QwQ, xAI Grok reasoning)
hits a transport-layer error before the first content token arrives, the
upstream proxy has almost certainly idle-killed a long thinking stream —
not a true context overflow or a configuration error.  The user needs
distinct guidance for this case:

    "The model's thinking phase exceeded the upstream proxy's idle
     timeout before the first content token arrived.  This is a known
     issue with reasoning models behind cloud gateways (NVIDIA NIM,
     OpenAI, Anthropic, DeepSeek).  Workarounds in priority order:
     1. Set `providers.<provider>.models.<model>.stale_timeout_seconds: 900`
        in `~/.hermes/config.yaml` to extend the per-call timeout...
     2. Lower `reasoning_budget` or set `reasoning_effort: medium`...
     3. Use a smaller / faster reasoning model..."

The existing `_is_stream_drop` guidance at
``agent/conversation_loop.py:3464-3486`` fires for large-file-write
stream drops ("try execute_code with Python's open() for large files")
which is the WRONG advice for the thinking-timeout case.  This module
provides the detection and the message as standalone helpers so the
detection logic is unit-testable without driving the full retry loop,
and the message text can be regression-tested for spelling and accuracy.

Part 2 of Fixes #52310.
    )annotations)Optional)zbroken pipezerrno 32zremote protocolzconnection resetzconnection lostzpeer closedzserver disconnectedztuple[str, ...]_THINKING_TIMEOUT_SUBSTRINGS
classifiedobjectmodelstr	error_msgreturnboolc                    ddl m} t          | dd          }t          |dd          }|dk    rdS  ||          dS |pd                                t	          fd	t
          D                       S )
a  Return True when a reasoning model's thinking phase hit a transport kill.

    Args:
        classified: a :class:`agent.error_classifier.ClassifiedError` instance
            (duck-typed here to avoid an import cycle in unit tests).
        model: the model slug at failure time (e.g.
            ``"nvidia/nemotron-3-ultra-550b-a55b"``).
        error_msg: lowercased string representation of the underlying
            exception (typically ``str(api_error).lower()``).

    Returns True when ALL conditions hold:
        1. ``classified.reason == FailoverReason.timeout`` (the classifier
           override at ``agent/error_classifier.py:720-738`` ensures this
           is the case for reasoning models even on large sessions).
        2. ``api_error`` has no ``.status_code`` attribute set (transport
           disconnect, not an HTTP error).
        3. ``model`` is in the reasoning-model allowlist (reuses
           ``agent.reasoning_timeouts.get_reasoning_stale_timeout_floor``).
        4. ``error_msg`` contains one of the transport-kill substrings.

    Non-reasoning models always return False.  Non-transport errors
    (billing / rate_limit / auth / context_overflow / format_error)
    always return False.  HTTP-status errors always return False.
    r   )!get_reasoning_stale_timeout_floorreasonNvaluetimeoutF c              3      K   | ]}|v V  	d S N ).0perror_msg_lowers     A/home/ice/.hermes/hermes-agent/agent/thinking_timeout_guidance.py	<genexpr>z&is_thinking_timeout.<locals>.<genexpr>e   s(      JJqO#JJJJJJ    )agent.reasoning_timeoutsr   getattrloweranyr   )r   r   r
   r   r   reason_valuer   s         @r   is_thinking_timeoutr!   4   s    8 KJJJJJ
 Z400F67D11Ly  u )(//7u !B--//OJJJJ-IJJJJJJr   Nprovidermodel_labelOptional[str]c                "    |p|}d| d|  d| dS )a  Return the user-facing guidance string appended to ``_final_response``.

    Args:
        provider: provider slug (e.g. ``"nvidia"``, ``"openai"``).
        model: bare model slug the user would put in their config
            (e.g. ``"nemotron-3-ultra-550b-a55b"`` if the user uses
            NVIDIA direct, or the full ``"nvidia/nemotron-3-ultra-550b-a55b"``
            if they go through an aggregator).  Used verbatim in the
            config snippet so the user can copy-paste.
        model_label: optional short label for the model name in the
            prose (e.g. ``"Nemotron 3 Ultra"``).  Falls back to the
            slug if not provided.
    z

The model's thinking phase exceeded the upstream proxy's idle timeout before the first content token arrived. This is a known issue with reasoning models (like zt) behind cloud gateways (NVIDIA NIM, OpenAI, Anthropic, DeepSeek). Workarounds in priority order:
1. Set `providers.z.models.u  .stale_timeout_seconds: 900` in `~/.hermes/config.yaml` to extend the per-call timeout. (Hermes's built-in floor is 600s for known reasoning models — if you still see this after raising, the upstream cap is even shorter.)
2. Lower `reasoning_budget` or set `reasoning_effort: medium` on this model if the provider supports it.
3. Use a smaller / faster reasoning model if the task doesn't require deep thinking.r   )r"   r   r#   labels       r   build_thinking_timeout_guidancer'   h   sH       5E	!38	! 	!
 &	! 	!
 05	! 	! 	!r   )r   r   r   r	   r
   r	   r   r   r   )r"   r	   r   r	   r#   r$   r   r	   )	__doc__
__future__r   typingr   r   __annotations__r!   r'   r   r   r   <module>r,      s     : # " " " " "      1     1K 1K 1K 1Kj =A             r   