§
    ÷žyj  ã                  ó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     €úE/home/ragecks/.hermes/hermes-agent/agent/thinking_timeout_guidance.pyú	<genexpr>z&is_thinking_timeout.<locals>.<genexpr>e   s(   øè è € ÐJÐJ¨ˆq�OÐ#Ð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Ô0€FÝ˜6 7¨DÑ1Ô1€LØ�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   € ð  Ð ˜5€Eð	!à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   