§
    øžyj°  ã                  óX   — d Z ddlmZ ddlZddlmZmZmZ dd„Zdd„Z	dd„Z
ddœdd„ZdS )ub  Gateway session stall notification policy (#72016 item 2).

Consumes the shared activity observation contract from
``agent.session_activity`` / ``AIAgent.get_activity_summary()``
(#72039) as the **single progress source**. This module owns only the
notify-once policy for "pending inbound + stale progress"; it does not
invent a parallel progress clock from turn-start or inbound event
timestamps.

Boundaries (keep separate):
- ``gateway/shutdown_watchdog.py`` â€” process / event-loop liveness
- ``gateway/delivery_ledger.py`` â€” outbound delivery obligations
- Pending inbound here is a stall *policy gate* (queued follow-up exists),
  not an outbound obligation and not a progress timestamp.

Notification / timeout / kill / retry policy stay in their own components;
the shared contract remains observation-only (timestamp + bounded
description + provenance).
é    )ÚannotationsN)ÚAnyÚMappingÚOptionalÚtimeout_secondsÚfloatÚidle_secondsúOptional[float]Úhas_pending_inboundÚboolÚalready_notifiedÚreturnc                ó6   — | dk    rdS |sdS |rdS |€dS || k    S )zAReturn True when a stall warning should be sent for this session.r   F© )r   r	   r   r   s       ú;/home/ragecks/.hermes/hermes-agent/gateway/session_stall.pyÚ&should_emit_session_stall_notificationr      sD   € ð ˜!ÒÐØˆuØð ØˆuØð ØˆuØÐØˆuØ˜?Ò*Ð*ó    c                ó.   — |sdS | dk    rdS |€dS || k     S )zEReturn True when a prior stall notice may be cleared (episode ended).Tr   NFr   )r   r	   r   s      r   Ú'should_clear_session_stall_notificationr   .   s7   € ð ð ØˆtØ˜!ÒÐØˆtàÐØˆuØ˜/Ò)Ð)r   Ústrc                óN   — t          dt          | dz  ¦  «        ¦  «        }d|› d�S )zEUser-facing stall warning (ASCII minutes; matches issue #72016 copy).é   é<   u4   âš ï¸� Agent session appears stalled (last activity z min ago). Try /new to reset.)ÚmaxÚint)r	   Úminss     r   Ú!format_session_stall_notificationr   ?   s9   € åˆq•#�l bÑ(Ñ)Ô)Ñ*Ô*€Dð	¸tð 	ð 	ð 	ðr   )ÚnowÚactivityúOptional[Mapping[str, Any]]r   c               ó2  — | sdS |                       d¦  «        }|�H	 t          |¦  «        }t          j        |¦  «        r
|dk     rdS |S n# t          t
          f$ r d}Y nw xY w|                       d¦  «        }|€|                       d¦  «        }|€dS 	 t          |¦  «        }n# t          t
          f$ r Y dS w xY wt          j        |¦  «        sdS |€&ddl}t          |                     ¦   «         ¦  «        }nt          |¦  «        }||z
  }|dk     rdS |S )u^  Idle seconds from a shared activity snapshot only (#72039 contract).

    Prefers ``seconds_since_activity`` when present and finite; otherwise
    derives from ``last_activity_at`` / ``last_activity_ts``. Returns
    ``None`` when there is no usable progress timestamp â€” callers must
    not fall back to turn-start or pending-inbound clocks.
    NÚseconds_since_activityr   g        Úlast_activity_atÚlast_activity_ts)Úgetr   ÚmathÚisfiniteÚ	TypeErrorÚ
ValueErrorÚtime)r   r   ÚelapsedÚidleÚtsÚwhenÚ_timeÚclocks           r   Ú*resolve_session_idle_seconds_from_activityr1   H   sd  € ð ð Øˆtà�lŠlÐ3Ñ4Ô4€GØÐð	Ý˜‘>”>ˆDõ Œ}˜TÑ"Ô"ð Ø˜!’8�8Ø˜3Ø�ðøõ �:Ð&ð 	ð 	ð 	ØˆDˆDˆDð	øøøð 
�ŠÐ(Ñ	)Ô	)€BØ	€zØ�\Š\Ð,Ñ-Ô-ˆØ	€zØˆtðÝ�R‰yŒyˆˆøÝ•zÐ"ð ð ð ØˆtˆtðøøøåŒ=˜ÑÔð Øˆtà
€{ØÐÐÐå�e—j’j‘l”lÑ#Ô#ˆˆå�c‘
”
ˆØ�4‰<€DØˆa‚x€xØˆsØ€Ks#   �A ÁA!Á A!ÂB% Â%B:Â9B:)
r   r   r	   r
   r   r   r   r   r   r   )r   r   r	   r
   r   r   r   r   )r	   r   r   r   )r   r    r   r
   r   r
   )Ú__doc__Ú
__future__r   r&   Útypingr   r   r   r   r   r   r1   r   r   r   ú<module>r5      s³   ððð ð( #Ð "Ð "Ð "Ð "Ð "à €€€Ø )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )ð+ð +ð +ð +ð&*ð *ð *ð *ð"ð ð ð ð  ð1ð 1ð 1ð 1ð 1ð 1ð 1ð 1r   