+
    iHàj$  ã                  ó  € R t ^ RIHt ^ RIt^ RIt^ RIHt ]P                  ! ]4      t	Rt
]! RR04      tRtR R ltR	 R
 ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR# ) aç  Durable request-local suppression for Anthropic thinking rejected by signature validation.

Canonical history stays untouched. We persist only fingerprints of rejected opaque
signature/data values, then filter those blocks from each rebuilt request copy. This is
needed beyond the immediate retry because context selection and process resume can rebuild
from canonical history later. The state belongs to one session (and is carried onto its
compression continuation); it applies only where the upstream signs the blocks.

The fingerprinting is deliberately coarse: one signature 400 marks every signed block in the
rejected request, so the session falls back to stripping that history (one cache miss, then
stable) while blocks produced later still replay. The 400's ``messages.N.content.M`` path indexes
the converted wire, but recovery only sees the pre-conversion ``api_messages``; system extraction,
tool-result folding and same-role merges shift both indexes, so targeting one block from that path
could suppress a valid block and resend the bad one.

Recovery covers every native model, including last-turn-only ones: their latest turn still carries
signed blocks in ordered carriers, which the old ``reasoning_details``-only repair left in place.
)ÚannotationsN)ÚAnyÚ_anthropic_rejected_thinkingÚthinkingÚredacted_thinkingc               ó    € V ^8„  d   QhRRRR/# )é   Úblockr   Úreturnú
str | None© )Úformats   "ÚD/home/ubuntu/.hermes/hermes-agent/agent/anthropic_thinking_replay.pyÚ__annotate__r   "   s   € ÷ Wñ W˜ð W 
ñ Wó    c                óv  € \        V \        4      '       d   V P                  R 4      \        9  d   R# V R ,          pT P                  VR8X  d   RMR4      pVR9   d   R# \        V\        4      '       d   TM
\        V4      p\        P                  ! V RV 2P                  RR4      4      P                  4       # )	ÚtypeNr   Ú	signatureÚdataÚ zutf-8Úreplace)NÚ r   )
Ú
isinstanceÚdictÚgetÚ_THINKING_TYPESÚstrÚreprÚhashlibÚsha256ÚencodeÚ	hexdigest)r	   ÚkindÚvalueÚpayloads   &   r   Ú_fingerprintr%   "   s”   € Ü�eœT×"Ò" e§i¡i°Ó&7¼Ô&NÙØ��=€DØ�I‰I T¨ZÔ%7‘k¸VÓD€EØ�ÔÙÜ! %¬×-Ò-‰e´4¸³;€GÜ�>Š>˜T˜F " W IÐ.×5Ñ5°g¸yÓIÓJ×TÑTÓVÐVr   c               ó    € V ^8„  d   QhRRRR/# )r   Úagentr   r
   Úboolr   )r   s   "r   r   r   -   s   € ÷ ñ  Cð ¨Dñ r   c                ó†   € ^ RI HpHp \        V RR4      R8H  ;'       d#    V! \        V RR4      \        V RR4      4      V9   # )z¾Signed-replay routes only (Anthropic and its cloud platforms, MiniMax): Kimi, DeepSeek and
third-party routes keep their own replay contract and the one-request ``reasoning_details`` repair.)ÚSIGNED_REPLAY_ROUTESÚanthropic_thinking_routeÚapi_modeNÚanthropic_messagesÚbase_urlÚmodel)Úagent.anthropic_thinking_policyr*   r+   Úgetattr)r'   r*   r+   s   &  r   Útracks_rejected_thinkingr2   -   sR   € ÷ _ä�5˜* dÓ+Ð/CÑC÷ ð ÑH`Ü��z 4Ó(¬'°%¸À$Ó*GóIà	ñIð r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú
session_dbr   Ú
session_idr
   úset[str]r   )r   s   "r   r   r   7   s&   € ÷ 
lñ 
l¨sð 
lÀð 
lÈñ 
lr   c                ó–  € \        V RR4      pV'       d   \        V4      '       g   \        4       #  V! V\        . 4      p\        T\        4      '       d5   T Uu0 uF'  p\        T\        4      '       g   K  T'       g   K%  TkK)  	  up# \        4       #   \         d%    \
        P                  RRR7       \        4       u # i ; iu upi )z7The persisted rejection fingerprints of ``session_id``.Úget_session_model_config_valueNz-Anthropic thinking suppression restore failedT©Úexc_info)
r1   ÚcallableÚsetÚ_MODEL_CONFIG_KEYÚ	ExceptionÚloggerÚdebugr   Úlistr   )r4   r5   ÚgetterÚrawr#   s   &&   r   Úrejected_thinking_fingerprintsrD   7   s¦   € ä�ZÐ!AÀ4ÓH€FßœX f×-Ò-Ü‹uˆðÙ�ZÔ!2°BÓ7ˆô LVÐVYÔ[_×K`ÒK`™sÓG™s�e¤j°¼×&<ŒEÄ�EˆE™sÑGÐkÔfiÓfkÐkøô ô Ü�‰ÐDÈtˆÔTÜ‹uŠðüò Hs#   ²B ÁCÁ7CÂCÂ,CÃCc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úholderr   r4   r5   r
   r6   r   )r   s   "r   r   r   D   s/   € ÷ Bñ B cð B°sð BÈð BÐPXñ Br   c                óŒ   € \        V RR4      p\        V\        4      '       d   V^ ,          V8X  d
   V^,          # \        W4      # )zž``holder``'s in-memory fingerprints for ``session_id``, else the persisted ones. The in-memory
set is authoritative: it outlives a failed or disabled persist.r   N)r1   r   ÚtuplerD   )rF   r4   r5   Úcacheds   &&& r   Úsession_rejected_thinkingrJ   D   s@   € ô �VÐ;¸TÓB€FÜ�&œ%× Ò  V¨A¥Y°*Ô%<Ø�a�yÐÜ)¨*ÓAÐAr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r'   r   r5   Úrejectedr6   r
   ÚNoner   )r   s   "r   r   r   M   s.   € ÷ Uñ U�ð U #ð U°ð U¸dñ Ur   c                ó^   € W3V n         \        V R R4      pVe   V P                   Vn         R# R# )Úcontext_compressorN)r   r1   )r'   r5   rL   Ú
compressors   &&& r   Ú_bindrQ   M   s7   € ð +5Ð)?€EÔ&Ü˜Ð 4°dÓ;€JØÒØ27×2TÑ2Tˆ
Ö/ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   r'   r   r
   r6   r   )r   s   "r   r   r   V   s   € ÷ ñ �Sð ˜Xñ r   c                óh   € \        V R R4      p\        V \        V RR4      V4      p\        WV4       V# )r5   NÚ_session_db)r1   rJ   rQ   )r'   r5   rL   s   &  r   Ú	_rejectedrU   V   s7   € ä˜ ¨dÓ3€JÜ(¨´¸¸}ÈdÓ0SÐU_Ó`€HÜ	ˆ%˜XÔ&Ø€Or   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r'   r   rL   r6   r
   rM   r   )r   s   "r   r   r   ^   s&   € ÷ 
Uñ 
U�Cð 
U 8ð 
U°ñ 
Ur   c                ó4  € \        V R R4      '       d   R# \        \        V RR4      RR4      p\        V RR4      pV'       d   \        V4      '       g   R#  V! V\        \        V4      /4       R#   \         d    \
        P                  RRR7        R# i ; i)	Ú_persist_disabledFNrT   Úpatch_session_model_configr5   z-Anthropic thinking suppression persist failedTr9   )r1   r;   r=   Úsortedr>   r?   r@   )r'   rL   Úpatcherr5   s   &&  r   Ú_persistr\   ^   s‰   € ÜˆuÐ)¨5×1Ò1ÙÜ”g˜e ]°DÓ9Ð;WÐY]Ó^€GÜ˜ ¨dÓ3€JßœX g×.Ò.ÙðUÙ�
Ô.´°xÓ0@ÐAÖBøÜô UÜ�‰ÐDÈtˆ×TðUús   ÁA1 Á1"BÂBc               ó    € V ^8„  d   QhRRRR/# )r   Úmessager   r
   r   r   )r   s   "r   r   r   k   s   € ÷ 	7ñ 	7¨ð 	7°*ñ 	7r   c                ó2  € ^ RI Hp V! V 4      w  r#V Uu. uF\  pVP                  R4      R8X  g   K  \        VP                  R4      \        4      '       g   KB  VR,          '       g   KS  VR,          NK^  	  ppV'       d   RP                  V4      # R# u upi )é    )Úassistant_replay_carrierr   r   z

N)Úagent.anthropic_message_convertra   r   r   r   Újoin)r^   ra   Ú_Úcarrierr	   Úreadables   &     r   Ú_mirrored_readable_thinkingrg   k   s•   € ÝHá)¨'Ó2�J€Añ óáˆEØ�9‰9�VÓ 
Ñ*ô 	ä/9¸%¿)¹)ÀJÓ:OÔQT×/Uô 	àZ_Ð`j×ZkÑZkô 	ˆˆj×ÐÙð ð ÷
 %-ˆ6�;‰;�xÓ Ð6°$Ð6ùòs   •B²"BÁBÁ*Bc               ó$   € V ^8„  d   QhRRRRRR/# )r   r^   r   rL   zset[str] | Noner
   Úintr   )r   s   "r   r   r   w   s!   € ÷ "ñ " Sð "°Oð "Èñ "r   c                óŠ  € \        V \        4      '       g   ^ # V P                  R4      R8X  d   \        V 4      MRp^ p\         F¼  pV P                  V4      p\        V\
        4      '       g   K,  . pV Fh  p\        V4      p\        V\        4      '       d4   VP                  R4      \        9   d   Ve   Ve   W�9   d   V^,          pKW  VP                  V4       Kj  	  V'       d   W`V&   Kª  V P                  VR4       K¾  	  V'       d8   Ve4   R F-  pV P                  V4      V8X  g   K  V P                  VR4       K/  	  V# )z½Drop rejected thinking blocks (every thinking block when ``rejected`` is None) from one request
copy. Rebinds carrier keys on ``message`` only; the nested canonical lists are never mutated.ÚroleÚ	assistantNr   )Ú	reasoningÚreasoning_content)
r   r   r   rg   Ú	_CARRIERSrA   r%   r   ÚappendÚpop)	r^   rL   ÚmirrorÚremovedÚkeyÚblocksÚkeptr	   Úfingerprints	   &&       r   Ústrip_rejected_thinkingrx   w   s  € ô �gœt×$Ò$Ùà5<·[±[ÀÓ5HÈKÔ5WÔ(¨Ô1Ð]a€FØ€GßˆØ—‘˜SÓ!ˆÜ˜&¤$×'Ò'ÙØˆÛˆEÜ& uÓ-ˆKä˜5¤$×'Ò'Ø—I‘I˜fÓ%¬Ô8ØÒ%¨+Ò*AÀkÔF]à˜1•’à—‘˜EÖ"ñ ÷ Ø�C‹Là�K‰K˜˜TÖ"ñ% ÷, �6Ò%Û5ˆCØ�{‰{˜3Ó 6Ö)Ø—‘˜C Ö&ñ 6ð €Nr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r'   r   Úmessagesr
   ri   r   )r   s   "r   r   r   œ   s&   € ÷ Sñ S¨sð S¸cð SÀcñ Sr   c                óª   a€ \        V\        4      '       d   \        V 4      '       g   ^ # \        V 4      oS'       g   ^ # \	        V3R lV 4       4      # )zLFilter rejected thinking from a request copy rebuilt from canonical history.c              3  ó<   <"  € T F  p\        VS4      x € K  	  R # 5i©N©rx   ©Ú.0r^   rL   s   & €r   Ú	<genexpr>Ú6apply_rejected_thinking_suppression.<locals>.<genexpr>£   s   øé € ÐRÉ¸gÔ& w°×9Ð9Ëùó   ƒ)r   rA   r2   rU   Úsum)r'   rz   rL   s   &&@r   Ú#apply_rejected_thinking_suppressionr…   œ   s?   ø€ ä�h¤×%Ò%Ô-EÀe×-LÒ-LÙÜ˜Ó€HßÙÜÔRÉÓRÓRÐRr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r'   r   Úapi_messagesr
   ri   r   )r   s   "r   r   r   ¦   s&   € ÷ Wñ W cð W¸ð WÀñ Wr   c                ó"  a€ \        V\        4      '       g   ^ # V UUUu0 uFz  p\        V\        4      '       g   K  \         FU  p\        VP	                  V4      \        4      '       d   VP	                  V4      MR F  p\        V4      ;pf   K  VkK  	  KW  	  K|  	  pppp^ RIHp V! V R4       V'       g   \        R V 4       4      # \        V 4      oSP                  V4       \        V S4       \        V3R lV 4       4      # u upppi )zTFingerprint the rejected request and repair its retry copy without mutating history.N)Úset_usage_anchorc              3  ó:   "  € T F  p\        VR 4      x € K  	  R # 5ir}   r~   )r€   r^   s   & r   r�   Ú-remember_rejected_thinking.<locals>.<genexpr>»   s   é € ÐVÉ¸gÔ*¨7°D×9Ð9Ëùs   ‚c              3  ó<   <"  € T F  p\        VS4      x € K  	  R # 5ir}   r~   r   s   & €r   r�   r‹   ¿   s   øé € ÐVÉ¸gÔ& w°×9Ð9Ëùrƒ   r   )r   rA   r   ro   r   r%   Úagent.usage_anchorr‰   r„   rU   Úupdater\   )	r'   r‡   r^   rt   r	   rw   Úcurrentr‰   rL   s	   &&      @r   Úremember_rejected_thinkingr�   ¦   só   ø€ ä�l¤D×)Ò)Ùñ $õá#ˆGÜ�gœt×$ô 	÷ ˆCÜ*4°W·[±[ÀÓ5EÄt×*LÒ*L�g—k‘k #Ô&ÐRTÒTˆEÜ'¨Ó.Ð.ˆK÷ 	ˆñ Uñ	 	ñ ñ 	Ù#ð ò õ 4á�U˜DÔ!ßô ÑVÉÓVÓVÐVÜ˜Ó€HØ‡O�O�GÔÜˆU�HÔÜÔVÉÓVÓVÐVùô)s    D
½AD
ÂD
c               ó$   € V ^8„  d   QhRRRRRR/# )r   r'   r   Úold_session_idr   r
   rM   r   )r   s   "r   r   r   Â   s!   € ÷ ñ ¨cð À3ð È4ñ r   c                ó:  € \        V RR4      p\        V\        4      '       d"   V^ ,          V8X  d   \        V^,          4      pM\	        \        V RR4      V4      pV'       g   R# V\        V 4      ,          p\        V \        V RR4      V4       \        W4       R# )zºCompression publishes the child with the session's initial model_config while its retained
tail still holds the rejected canonical rows; carry the fingerprints onto ``agent.session_id``.r   NrT   r5   )r1   r   rH   r<   rD   rU   rQ   r\   )r'   r’   rI   rL   s   &&  r   Ú"carry_rejected_thinking_to_sessionr”   Â   s�   € ô �UÐ:¸DÓA€FÜ�&œ%× Ò  V¨A¥Y°.Ô%@Ü�v˜a•y“>‰ä1´'¸%ÀÐPTÓ2UÐWeÓfˆßÙØ”	˜%Ó Õ €HÜ	ˆ%”˜ ¨dÓ3°XÔ>ÜˆUÖr   )Úreasoning_detailsÚanthropic_content_blocksÚ_anthropic_content_blocks)Ú__doc__Ú
__future__r   r   ÚloggingÚtypingr   Ú	getLoggerÚ__name__r?   r=   Ú	frozensetr   ro   r%   r2   rD   rJ   rQ   rU   r\   rg   rx   r…   r�   r”   r   r   r   Ú<module>rŸ      s‰   ðñõ& #ã Û Ý ð 
×	Ò	˜8Ó	$€à2Ð Ù˜ZÐ)<Ð=Ó>€ØZ€	õWõõ
lõBõUõõ
Uõ	7õ"õJSõW÷8r   