+
    iHàj»K  ã            
       óú  € R t ^ RIt^ RIHt ^ RIHtHtHt ^ RIH	t	 ]! RR7       ! R R4      4       t
R	 R
 ltR R ltRBR R lltRCR R lltRBR R lltR R ltRDR R lltR R lt]! 0 REm4      t]! R04      t]! R04      tR R ltR R ltR t]! 0 RFm4      tR! R" ltR#R$R%R$/R& R' lltR(RR)R/R* R+ lltR, R- ltR. R/ ltR0 R1 lt R2 R3 lt!R4 R5 lt"R6 R7 lt#R8R9R:RR;RR<RR=R/R> R? llt$RGR@ RA llt%R# )HuJ  Anthropic prompt caching strategy â€” pure functions, no AIAgent dependency.

Default layout: 4 cache_control breakpoints â€” the static system prefix, the end of the
system prompt, and the last 2 non-system messages (without a static prefix: one system
breakpoint plus the last 3 messages). All markers share one TTL (5m or 1h).
N)Ú	dataclass)ÚAnyÚDictÚList)Úfind_stable_prefixT)Úfrozenc                   ó0   a € ] tR t^t o RtV 3R ltRtV tR# )ÚPromptCachePlanzARequest-local message and tool sections with their cache markers.c                ó~   <€ V ^8„  d   Qh/ S[ S[S[S[3,          ,          ;R&   S[ S[S[S[3,          ,          ;R&   # )é   ÚmessagesÚtools©ÚlistÚdictÚstrr   )ÚformatÚ__classdict__s   "€Ú9/home/ubuntu/.hermes/hermes-agent/agent/prompt_caching.pyÚ__annotate__ÚPromptCachePlan.__annotate__   s9   ø‡ ‚ ñ ‘4™™S˜•>Õ"Ñ"ñ	 ñ
 ‘‘S™#�X•ÕÑò ó    © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__)r   s   @r   r	   r	      s   ø‡ € áK÷ ƒ r   r	   c                óX   € V ^8„  d   QhR\         R,          R\         R,          R\        /# )r   ÚproviderNÚbase_urlÚreturn©r   Úbool)r   s   "r   r   r      s0   € ÷ 	Sñ 	S¼¸t½ð 	SÌsÐUYÍzð 	SÔ^bñ 	Sr   c                óŠ   € ^ RI Hp T! T ;'       g    RP                  4       P                  4       T;'       g    R4      '       * # )aY  Whether the envelope-layout route honors part-level markers on role:tool.

OpenRouter/Nous Portal relocate a part-level ``cache_control`` onto the ``tool_result``
block; LiteLLM-style proxies copy parts verbatim, so it lands at ``tool_result.content[0]``
(non-retryable 400). There, role:tool carries no part markers and the budget reallocates.
)Ú_is_litellm_routeÚ )Úagent.agent_runtime_helpersr(   ÚstripÚlower)r"   r#   r(   s   && r   Ú*envelope_tool_part_cache_markers_supportedr-      s5   € õ >á  (§. .¨b×!7Ñ!7Ó!9×!?Ñ!?Ó!AÀ8Ç>À>ÈrÓRÔRÐRr   c                óÈ   € V ^8„  d   QhR\         \        \        \        3,          ,          R,          R\         \        \        \        3,          ,          R,          R\        /# )r   r   Nr   r$   ©r   r   r   r   r&   )r   s   "r   r   r   #   sO   € ÷ [ñ [¤$¤t¬C´¨H¥~Õ"6¸Õ"=ð [ÄdÌ4ÔPSÔUXÐPXÍ>ÕFZÐ]aÕFað [Ôfjñ [r   c                óð  € V'       d   R# T ;'       g    .  Uu. uF  p\        V\        4      '       g   K  VNK  	  pp\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   R# V Uu. uF  q"P                  R4      NK  	  ppVP	                  R4      ^8*  ;'       d:    \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       * # u upi u upi )aµ  True for a request no later call can read back from cache: no tools, no assistant/tool
turns, at most one user turn (compression summaries, titles, MoA synthesis). A marker there
only buys a cache write (1.25x input at 5m, 2x at 1h) that nothing ever reads. A caller that
already decorated the request (a MoA advisor's first iteration, whose prefix later
iterations replay) decided it will reuse it, so that decision wins over the shape.Fc              3   óp   "  € T F,  pR V9   ;'       g    \        VP                  R4      4      x € K.  	  R# 5i)Úcache_controlÚcontentN)Ú_has_part_markerÚget)Ú.0Úms   & r   Ú	<genexpr>Ú&is_one_shot_request.<locals>.<genexpr>,   s/   é € Ð
TÉtÈ!ˆ?˜aÑ×EÐEÔ#3°A·E±E¸)Ó4DÓ#EÔEËtùs   ‚6“#6TÚroleÚuserc              3   ó*   "  € T F	  qR9   x € K  	  R# 5i)Ú	assistantN)r=   Útoolr   )r6   Úrs   & r   r8   r9   /   s   é € Ð/ZÑTYÈqÐ5JÖ0JÓTYùs   ‚)Ú
isinstancer   Úanyr5   Úcount)r   r   r7   ÚmsgsÚroless   &&   r   Úis_one_shot_requestrE   #   sµ   € ÷ ÙØ—~�~ 2�~Ó=‘~�!¬°A´t×)<�AˆA‘~€DÐ=ß
ƒsÑ
TÉtÓ
T‡s‡s‚sÑ
TÉtÓ
T×TÒTÙÙ$(Ó)¡D˜q�U‰U�6Ž]¡D€EÐ)Ø�;‰;�vÓ !Ñ#×ZÐZ¯C«CÑ/ZÑTYÓ/Z¯C¯CªCÑ/ZÑTYÓ/ZÓ,ZÔ(ZÐZùò	 >ùò *s   ™C.¶C.Á>C3c                óJ   € V ^8„  d   QhR\         R\        R,          R\        /# )r   ÚtextÚcache_markerNr$   ©r   r   )r   s   "r   r   r   2   s%   € ÷ ñ ”Sð ¬¨t­ð ¼tñ r   c                 ó"   € R RRV /pVe   WR&   V# )ÚtyperG   r2   r   )rG   rH   Úparts   && r   Ú
_text_partrM   2   s#   € Ø˜& &¨$Ð/€DØÒØ ,ˆ_ÑØ€Kr   Fc          
      óL   € V ^8„  d   QhR\         R\         R\        R\        RR/# )r   ÚmsgrH   Únative_anthropicÚtool_part_markersr$   N©r   r&   )r   s   "r   r   r   9   s1   € ÷ 4ñ 4œTð 4´ð 4Ìð 4Ü+/ð4Ø;?ñ4r   c                óì  € V P                  RR4      pV P                  R4      pVR8X  d   V'       g   V'       g   R# VR8X  d	   V'       g   Ve   VR8X  d   VR9   d	   V'       d   WR&   R# R# \        V\        4      '       d%   \        W4      ;'       g    \	        WQ4      .V R&   R# \        V\
        4      '       d7   V'       d-   \        VR,          \        4      '       d   WR,          R&   R# R# R# R# )	zFAdd cache_control to a single message, handling all format variations.r:   r)   r3   r>   Nr2   )r>   r=   éÿÿÿÿ)r5   r@   r   Ú_scaffold_partsrM   r   r   )rO   rH   rP   rQ   r:   r3   s   &&&&  r   Ú_apply_cache_markerrV   9   sÅ   € ð �7‰7�6˜2Ó€DØ�g‰g�iÓ €Gàˆv„~×.×7HáØ�Œ×+°²À7ÈbÄ=ð Ð-Ô-×6FØ#/�Ó ñ 7Gä	�GœS×	!Ò	!ô )¨Ó;×bÐbÄ
È7Ó@aÐ?bˆˆI‹Ü	�GœT×	"Ò	"§w´:¸gÀb½kÌ4×3PÒ3PØ'3���OÓ$ñ 4Q¡wÑ	"r   c                óX   € V ^8„  d   QhR\         R\         R,          R\        R,          /# )r   rO   rH   Nr$   )r   r   )r   s   "r   r   r   P   s.   € ÷ mñ mœð m¬T°D­[ð mÄDÈ4ÅKñ mr   c                óæ   € V P                  R4      pV P                  R4      R8X  d"   \        V\        4      '       d   \        V4      MRpVf   R# \	        W14      \	        V\        V4      R 4      .# )z¥``[scaffold, tail]`` parts of a string user message with a registered scaffold, the
marker (if any) on the scaffold; ``find_stable_prefix`` keeps the tail non-blank.r3   r:   r;   N)r5   r@   r   r   rM   Úlen)rO   rH   r3   Úprefixs   &&  r   rU   rU   P   sk   € ð �g‰g�iÓ €GØ,/¯G©G°F«O¸vÔ,EÌ*ÐU\Ô^a×JbÒJbÔ Ô(Ðhl€FØ’>ˆ4Ðl¬
°6Ó(HÌ*ÐU\Ô]`ÐagÓ]hÐ]iÐUjÓJkÐ'lÐlr   c                ó`   € V ^8„  d   QhR\         \        \        \        3,          ,          RR/# )r   r   r$   Nr   )r   s   "r   r   r   X   s'   € ÷ 4ñ 4¬¬T´#´s°(­^Õ(<ð 4Àñ 4r   c                óœ   € \        V 4       F<  w  r\        V\        4      '       g   K  \        V4      ;p'       g   K2  / VCRV/CW&   K>  	  R# )a	  Send every registered scaffold message as [scaffold, tail] parts, marked or not (in place).

Provider caches key on content, and two text parts are different content from one string:
a skill message split while it held a breakpoint must keep the same parts after the rolling
marker window moves past it, or the next request re-writes the whole scaffold (#81867).
Each hit refreshes the scaffold's registry LRU slot, so a scaffold still in history stays
registered and the failover stripper can still recognise its split.
r3   N)Ú	enumerater@   r   rU   )r   ÚirO   Úpartss   &   r   Ú_split_unmarked_scaffoldsr`   X   sG   € ô ˜HÖ%‰ˆÜ�cœ4× Ô ¬¸sÓ/CÐ&C e×&CÐ&CØ3˜SÐ3 )¨UÑ3ˆH‹Kó &r   c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r   rO   rP   rQ   r$   rR   )r   s   "r   r   r   f   s/   € ÷ Bñ Bœ4ð B´4ð BÌDð BÔ\`ñ Br   c                ó  € V'       d   R# V P                  R4      R8X  d   V'       g   R# V P                  R4      p\        V\        4      '       d    V'       d   \        VR,          \        4      # \        V\        4      ;'       d    VR8g  # )aP  True if a marker on this message is actually honored by the provider.

Native Anthropic honors every message; the envelope layout only honors markers inside
content parts (empty content wastes a breakpoint) and ``tool_part_markers=False`` excludes
role:tool too (400). Must agree with :func:`_apply_cache_marker` (marks the LAST part).
Tr:   r>   Fr3   r)   rT   )r5   r@   r   r   r   )rO   rP   rQ   r3   s   &&& r   Ú_can_carry_markerrc   f   s�   € ÷ ÙØ
‡w�wˆvƒ˜&Ô ×):ÙØ�g‰g�iÓ €GÜ,6°wÄ×,EÒ,EÏ'Œ:�g˜b•k¤4Ó(ð  BÔWaÐbiÔknÓWo÷  XBð  XBÐt{ð  @Bñ  uBð  Br   c                óR   € V ^8„  d   QhR\         R\        \         \         3,          /# )r   Úttlr$   rI   )r   s   "r   r   r   u   s&   € ÷ Xñ X”sð Xœt¤C¬ H�~ñ Xr   c                ó$   € V R8X  d   RRRR/# RR/# )zCBuild a cache_control marker dict for the given TTL ('5m' or '1h').Ú1hrK   Ú	ephemeralre   r   )re   s   &r   Ú_build_markerri   u   s!   € à14¸´ˆF�K ¨Ð-ÐWÀ6È;ÐBWÐWr   úopencode-gozminimax-m2.5c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Úmodelr$   ©r   )r   s   "r   r   r   ‰   s   € ÷ <ñ <”sð <œsñ <r   c                ó€   € T ;'       g    RP                  4       P                  R^4      R,          P                  4       # )zABare model id, tolerating aggregator prefixes (``vendor/model``).r)   Ú/rT   )r+   Úrsplitr,   ©rm   s   &r   Ú_flat_modelrs   ‰   s2   € à�KˆK�R×ÑÓ ×'Ñ'¨¨QÓ/°Õ3×9Ñ9Ó;Ð;r   c                ó0   € V ^8„  d   QhR\         R\        /# rl   r%   )r   s   "r   r   r   Ž   s   € ÷ +ñ +œð +¤ñ +r   c                ó<   € RT ;'       g    RP                  4       9   # )zZTrue when ``model`` names a Qwen-family model (shared with anthropic_prompt_cache_policy).Úqwenr)   )r,   rr   s   &r   Úis_qwen_modelrw   Ž   s   € à�e—k�k˜r×(Ñ(Ó*Ñ*Ð*r   Úautoc                ó>   € V ^8„  d   QhR\         R,          R\         /# )r   ÚsourceNr$   rn   )r   s   "r   r   r   ž   s"   € ÷ Uñ U¤c¨D¥jð U´Sñ Ur   c                ól   € T ;'       g    RP                  4       P                  4       \        9   d   R# R# )z¨The tier ``auto`` resolves to for a session source: ``5m`` for machine-paced sources,
``1h`` for everything a human types into (cli, tui, desktop, messaging platforms).r)   Ú5mrg   )r+   r,   ÚMACHINE_PACED_SOURCES)rz   s   &r   Úauto_cache_ttl_for_sourcer~   ž   s0   € ð —L�L˜b×'Ñ'Ó)×/Ñ/Ó1Ô5JÔJˆ4ÐTÐPTÐTr   rm   r)   r"   c                óV   € V ^8„  d   QhR\         R,          R\         R\         R\         /# )r   re   Nrm   r"   r$   rn   )r   s   "r   r   r   ¤   s3   € ÷ `ñ `œS 4�Zð `´3ð `Äsð `ÔTWñ `r   c               óâ   € V R8w  d   T ;'       g    R# T;'       g    RP                  4       pV\        9   d   \        V4      \        9   d   R# R# \	        V4      '       g   V\
        9   d   R# R# )u  Clamp a requested cache TTL to what the destination route supports (``None`` â†’ ``5m``).

Qwen/Alibaba routes drop ``1h`` (â†’ ``5m``) except on ``MEASURED_1H_PROVIDERS`` minus
``NO_1H_TIER_MODELS``; that check runs BEFORE the generic Qwen clamp, which would swallow it.
rg   r|   r)   )r,   ÚMEASURED_1H_PROVIDERSrs   ÚNO_1H_TIER_MODELSrw   ÚALIBABA_FAMILY_PROVIDERS)re   rm   r"   Úprovider_lowers   &$$ r   Úeffective_cache_ttlr…   ¤   sj   € ð ˆd„{Ø�{ˆ{�dÐØ—n�n "×+Ñ+Ó-€NØÔ.Ô.Ü" 5Ó)Ô->Ô>ˆtÐHÀDÐHÜ  ×'Ò'¨>Ô=UÔ+Uˆ4Ð_Ð[_Ð_r   Úmark_suffixÚfallback_to_wholec                óz   € V ^8„  d   QhR\         R\         R\        R,          R\        R\        R\        R\        /# )	r   ÚmessagerH   Ústatic_system_prefixNrP   r†   r‡   r$   )r   r   r&   Úint)r   s   "r   r   r   ²   sJ   € ÷ ñ ÜðÜ!%ðÜ=@À4½Zðäðä)-ðäIMðô 	ñr   c               ó”  € V P                  R4      p\        V\        4      '       dŠ   V'       d‚   \        V\        4      '       dl   VP                  V4      '       dU   V\	        V4      R pVP                  4       '       d0   \        W!4      \        Yt'       d   TMR4      .V R&   V'       d   ^# ^# M
V'       g   ^ # \        WVR7       ^# )u©  Mark the static system prefix (and optionally the full prompt); returns markers applied.

The stored system prompt stays one string, split only in the request. ``mark_suffix=False``
is the tool-cache-plan layout (suffix budget spent on the tools array); ``fallback_to_whole=
False`` marks nothing when the split is impossible. When the prompt IS the prefix the whole
message is one block â€” never an empty text block (400).
r3   N©rP   )r5   r@   r   Ú
startswithrY   r+   rM   rV   )r‰   rH   rŠ   rP   r†   r‡   r3   Úsuffixs   &&&$$$  r   Ú_apply_system_cache_markersr�   ²   sº   € ð �k‰k˜)Ó$€GÜÐ&¬×,Ò,×1EÌ*ÐU\Ô^a×JbÒJbÐgn×gyÑgyð  {O÷  hPò  hPØœÐ1Ó2Ð3Ð4ˆØ�<‰<�>Š>Ü",Ð-AÓ"PÜ",¨VÆ[±\ÐVZÓ"[ð"]ˆG�IÑç#�1Ð*¨Ð*ð ÷ ÙÜ˜Ð@PÕQÙr   c                ó0   € V ^8„  d   QhR\         R\        /# )r   r3   r$   )r   r&   )r   s   "r   r   r   Ê   s   € ÷ uñ uœcð u¤dñ ur   c                 óš   € \        V \        4      ;'       d5    \        ;QJ d    R  V  4       F  '       g   K   R# 	  R# ! R  V  4       4      # )c              3   ó\   "  € T F"  p\        V\        4      ;'       d    R V9   x € K$  	  R# 5i©r2   N©r@   r   ©r6   rL   s   & r   r8   Ú#_has_part_marker.<locals>.<genexpr>Ë   s+   é € Ð,tÑlsÐdh¬Z¸¼dÓ-C×-_Ð-_ÈÐ[_ÑH_Ô-_Ólsùs   ‚,ž,TF)r@   r   rA   )r3   s   &r   r4   r4   Ê   s<   € Ü�gœtÓ$×tÐt¯«Ñ,tÑlsÓ,t¯¬ÐtªÐt¨Ñ,tÑlsÓ,tÓ)tÐtr   c                ó    € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          /# )r   Úapi_messagesr$   r   )r   s   "r   r   r   Î   s7   € ÷ &ñ &´´T¼#¼s¸(µ^Õ0Dð &ÌÌdÔSVÔX[ÐS[ÍnÕI]ñ &r   c                óx  € V  EF%  p\        V\        4      '       g   K  VP                  RR4       VP                  R4      p\        V\        4      '       g   KW  VP                  R4      pVR8H  ;'       dK    \        V4      ^8H  ;'       d5    \        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      pT;'       d!    RV^ ,          9   ;'       d    RV^,          9  p\        V4      '       de   V UUUu. uFO  p\        V\        4      '       d5   RV9   d.   VP                  4        UUu/ uF  w  rxVR8w  g   K  WxbK  	  uppMTNKQ  	  uppp;q!R&   T;'       d5    \        ;QJ d    R	 V 4       F  '       d   K   RM	  RM! R	 V 4       4      p	V	'       g   EK§  R
P                  R V 4       4      p
T;'       g'    T;'       d    \        V
4      V^ ,          R,          8H  p\        V4      ^8X  g#   VR8X  d   \        V4      ^8X  g   V'       g   EK!  W¡R&   EK(  	  V # u uppi u upppi )aó  Remove ``cache_control`` markers and undo decoration-produced list shapes (in place).

Used before re-decorating after a mid-turn failover. Flattening to a string is restricted
to the exact shapes :func:`apply_anthropic_cache_control` produces from string content
(single text part, two-part system split, two-part skill split) so the ``""``-join is
byte-exact. Marker removal is copy-on-write on part dicts: parts can alias caller-held
lists and stripping must never rewrite the stored transcript.
r2   Nr3   r:   r;   c              3   óB   "  € T F  p\        V\        4      x € K  	  R # 5i©Nr•   )r6   Úps   & r   r8   Ú0strip_anthropic_cache_control.<locals>.<genexpr>ß   s   é € Ð@fÑ^eÐYZÄÈAÌt×ATÐATÓ^eùs   ‚FTc              3   ó  "  € T F  p\        V\        4      ;'       dc    VP                  R R4      R8H  ;'       dF    \        VP                  R4      \        4      ;'       d    \	        VP                  4       4      R R08*  x € K�  	  R# 5i)rK   rG   N)r@   r   r5   r   ÚsetÚkeysr–   s   & r   r8   rž   è   s‡   é € ð +
ágnÐ_cô �tœTÓ"÷ [ð [ t§x¡x°¸Ó'?À6Ñ'I÷ [ð [Ü˜4Ÿ8™8 FÓ+¬SÓ1÷[ð [Ü69¸$¿)¹)»+Ó6FÈ6ÐSYÐJZÑ6Zô[Ûgnùs   ‚B	žB	»&B	Á"'B	r)   c              3   ó2   "  € T F  qR ,          x € K  	  R# 5i)rG   Nr   r–   s   & r   r8   rž   î   s   é € Ð:±'¨$˜fŸš³'ùs   ‚rG   Úsystem)r@   r   Úpopr5   r   rY   Úallr4   ÚitemsÚjoinr   )r™   rO   r3   r:   Ú	user_pairÚfirst_part_markedrL   ÚkÚvÚplain_text_partsÚjoinedÚskill_splits   &           r   Ústrip_anthropic_cache_controlr¯   Î   sù  € ô ˆÜ˜#œt×$Ò$ÙØ�‰� Ô&Ø—'‘'˜)Ó$ˆÜ˜'¤4×(Ò(ÙØ�w‰w�v‹ˆØ˜F‘N×fÐf¤s¨7£|°qÑ'8×fÐf¿S»SÑ@fÑ^eÓ@f¿S¿SºSÑ@fÑ^eÓ@fÓ=fˆ	ð &×mÐm¨/¸WÀQ½ZÑ*G×mÐmÈOÐcjÐklÕcmÑLmÐÜ˜G×$Ò$ñ ]dõ(á\cÐTX”:˜d¤D×)Ò)¨oÀÔ.Eð #'§*¡*¤,ÔG¡,™$˜!°!°Ñ2F”�’¡,ÓGØKOòPÙ\có(ð ˆG˜)‘nð #÷ 
ð 
§s£sñ +
ágnó+
§s§s¢sñ +
ágnó+
ó (
Ð÷  ÚØ—‘Ñ:±'Ó:Ó:ˆð (×kÐk¨I×,jÐ,jÔ:LÈVÓ:TÐX_Ð`aÕXbÐciÕXjÑ:jˆÜˆw‹<˜1Ô ¨Ô!1´c¸'³lÀaÔ6GÏKÊKØ#�	ŒNñ9 ð: Ðùó Hùô(s   Ä5H5
Ä8H/ÅH/Å
H5
È/H5
c                ó    € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          /# )r   r   r$   r   )r   s   "r   r   r   ÷   s4   € ÷ ñ ¤d¬4´´S°­>Õ&:ð ¼tÄDÌÌcÈÅNÕ?Sñ r   c                óö   € \        V 4       Fi  w  r\        V\        4      '       g   K  RV9   g(   \        VP                  R4      \        4      '       g   KK  \        \        V4      .4      ^ ,          W&   Kk  	  V # )a•  Re-canonicalise planner output before re-planning (in place on the list, copy-on-write per message).

Every list-content message is stripped, not just marked ones: an UNMARKED skill split (outside
the previous request's marker window) left as two parts would get the new breakpoint on its
volatile tail instead of the scaffold. A shallow copy suffices because the strip is
copy-on-write on content parts.
r2   r3   )r]   r@   r   r5   r   r¯   )r   r^   rO   s   &  r   Ú_strip_prior_decorationr²   ÷   s^   € ô ˜HÖ%‰ˆÜ�cœ4× Ô  o¸Ô&<Ä
È3Ï7É7ÐS\ÓK]Ô_c×@dÔ@dÜ7¼¸c»¸ÓDÀQÕGˆH‹Kñ &ð €Or   c                ó®   € V ^8„  d   QhR\         \        \        \        3,          ,          R,          R\         \        \        \        3,          ,          /# )r   r   Nr$   r   )r   s   "r   r   r     s>   € ÷ ñ ¬d´4¼¼S¸µ>Õ.BÀTÕ.Ið ÌdÔSWÔX[Ô]`ÐX`ÕSaÕNbñ r   c                ó¬   € \         P                  ! T ;'       g    . 4      pV F-  p\        V\        4      '       g   K  VP	                  RR4       K/  	  V# )zBReturn copied tools without request-local Anthropic cache markers.r2   N)ÚcopyÚdeepcopyr@   r   r¤   )r   Úcleanedr>   s   &  r   Ú"strip_anthropic_tool_cache_controlr¸     sB   € ä�mŠm˜EŸK˜K RÓ(€GÛˆÜ�dœD×!Ô!Ø�H‰H�_ dÖ+ñ ð €Nr   c                ó¬   € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          R\        /# )r   r   r   r$   )r   r   r   r   r‹   )r   s   "r   r   r     sA   € ÷ pñ p¤4¬¬S´#¨X­Õ#7ð pÄÄTÌ#ÌsÈ(Å^Õ@Tð pÔY\ñ pr   c           	     ó   € V  UUu. uFS  p\        V\        4      '       g   K  \        VP                  R4      \        4      '       g   KB  VR,           F  q3NK  	  KU  	  ppp\	        R . V OVOVO 4       4      # u uppi )z=Count the wire-visible cache markers in a request-local plan.r3   c              3   óh   "  € T F(  p\        V\        4      '       g   K  R V9   g   K$  ^x € K*  	  R# 5ir”   r•   )r6   Úitems   & r   r8   Ú'_count_cache_markers.<locals>.<genexpr>  s(   é € ÐoÑ8�T¼JÀtÌT×<RŒqÐWfÐjnÑWn�qŠqÓ8ùs   ‚2Ÿ2¨
2)r@   r   r5   r   Úsum)r   r   r7   r�   r_   s   &&   r   Ú_count_cache_markersr¿     sq   € á Ôu™�1¤J¨q´$×$7ŒQ¼JÀqÇuÁuÈYÓGWÔY]×<^ŒQÐhiÐjs×htÐhtÐcdŠQÑht‰Q™€EÑuÜÑoÐ8˜xÐ8¨%Ð8°%Ñ8ÓoÓoÐoùó vs   †A:£"A:Á
A:c                óŠ   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        R\         \
        ,          /# )r   r   rP   r$   )r   r   r   r   r&   r‹   )r   s   "r   r   r     s6   € ÷ "ñ "´d¼4ÄÄSÀ½>Õ6Jð "Ôaeð "ÔjnÔorÕjsñ "r   c               óö  a € R V 3R llp. p^ pV\        S 4      8  EdZ   S V,          p\        V\        4      '       d   VP                  R4      R8X  d   V^,          pKQ  VP                  R4      pVR8X  dp   VP                  R4      '       dY   V! V^,           4      pWt^,           8”  d9   \	        S V^,
          ,          V4      '       d   VP                  V^,
          4       TpKØ  VR8X  d   V! V4      pKé  VR8H  ;'       d    V^,           \        S 4      8  ;'       g"    VR8H  ;'       d    VP                  R	4      R
9   pV'       g#   \	        WQ4      '       d   VP                  V4       V^,          pEKj  V# )z<Select legal ends of completed tool runs and ordinary turns.c                ó0   € V ^8„  d   QhR\         R\         /# )r   Ústartr$   )r‹   )r   s   "r   r   Ú=_completed_transaction_endpoint_indexes.<locals>.__annotate__  s   € ÷ ñ œSð ¤Sñ r   c                 ó¶   <€ T pV\        S4      8  dF   \        SV,          \        4      '       d)   SV,          P                  R 4      R8X  d   V^,          pKU  V# )r:   r>   )rY   r@   r   r5   )rÃ   Úendr   s   & €r   Ú_tool_run_endÚ>_completed_transaction_endpoint_indexes.<locals>._tool_run_end  sK   ø€ ØˆØ”C˜“MÔ!¤j°¸#µÄ×&EÒ&EÈ(ÐSVÍ-×J[ÑJ[Ð\bÓJcÐgmÔJmØ�1�HŠCØˆ
r   r:   r£   r=   Ú
tool_callsr>   r;   r3   )Nr)   )rY   r@   r   r5   rc   Úappend)	r   rP   rÇ   Ú	endpointsÚindexr‰   r:   Ú
result_endÚ	open_turns	   f$       r   Ú'_completed_transaction_endpoint_indexesrÏ     sO  ø€ ÷ð ð €IØ€EØ
”#�h“-Õ
Ø˜5•/ˆÜ˜'¤4×(Ò(¨G¯K©K¸Ó,?À8Ô,KØ�Q�JˆEÙØ�{‰{˜6Ó"ˆà�;Ô 7§;¡;¨|×#<Ò#<Ù& u¨q¥yÓ1ˆJØ A�IÔ%Ô*;¸HÀZÐRSÅ^Õ<TÐVf×*gÒ*gØ× Ñ  ¨a¥Ô0ØˆEÙà�6Œ>Ù! %Ó(ˆEÙà˜V‘^×AÐA¨°­	´C¸³MÑ(A÷ Jð JØ�KÑ×HÐH G§K¡K°	Ó$:¸jÑ$Hð 	çÔ.¨w×IÒIØ×Ñ˜UÔ#Ø��
‹ØÐr   Ú	cache_ttlr|   rP   rŠ   Údirect_native_tool_cacherQ   c                ó  € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          R,          R\        R\        R\        R,          R\        R\        R	\
        /# )
r   r™   r   NrÐ   rP   rŠ   rÑ   rQ   r$   )r   r   r   r   r&   r	   )r   s   "r   r   r   9  sƒ   € ÷ Cñ CÜ”tœC¤˜H•~Õ&ðCÜ/3´D¼¼c¸µNÕ/CÀdÕ/JðCäðCä-1ðCäQTÐW[ÕQ[ðCô #ðCô @DðCô ñ	Cr   c          	     óÀ  € \        V4      pV'       d	   V'       g.   \        \        T ;'       g    . 4      W#WFR7      p\        W‡R7      # \	        \        T ;'       g    . 4      4      p	\        V4      p
V	'       dr   \        V	^ ,          \        4      '       dU   V	^ ,          P                  R4      R8X  d8   \        P                  ! V	^ ,          4      V	^ &   \        V	^ ,          W¤RRRR7       \        V
4      VR,          R&   \        V	RR	7      RR
  F5  p\        P                  ! W›,          4      W›&   \        W›,          V
RR	7       K7  	  \        V	4       \        W—R7      # )z Build copy-on-write cache sections for one resolved request destination
(``tool_part_markers=False`` keeps markers off role:tool parts on LiteLLM-style routes).)rÐ   rP   rŠ   rQ   )r   r   r:   r£   TF)rP   r†   r‡   r2   r�   NrT   éþÿÿÿ)r¸   Úapply_anthropic_cache_controlr   r	   r²   ri   r@   r   r5   rµ   r¶   r�   rÏ   rV   r`   )r™   r   rÐ   rP   rŠ   rÑ   rQ   Úplanned_toolsÚplanned_messagesr   ÚmarkerÚendpoints   &&$$$$$     r   Úbuild_prompt_cache_planrÚ   9  s#  € ô 7°uÓ=€Mß#¯=ä8Ü�×#Ð# Ó$°	Ø!5ô\Ðô Ð(8ÔNÐNä&¤t¨L×,>Ð,>¸BÓ'?Ó@€HÜ˜9Ó%€Fß”J˜x¨�{¬D×1Ò1°h¸qµk·o±oÀfÓ6MÐQYÔ6Yô —m’m H¨Q¥KÓ0ˆ�‰Ü# H¨Q¥K°Ø59ÀuÐ`eõ	gä)-¨f«€M�"Õ�oÑ&Ü;¸HÐW[Ô\Ð]_Ð]`ÓaˆÜ!Ÿ]š]¨8Õ+=Ó>ˆÑÜ˜HÕ.°È×Nñ bô ˜hÔ'ä HÔBÐBr   c                óÞ   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        R\        R\        R,          R\        R\         \        \        \        3,          ,          /# )r   r™   rÐ   rP   rŠ   NrQ   r$   r/   )r   s   "r   r   r   Y  s\   € ÷  ñ  Ü”tœC¤˜H•~Õ&ð Ü36ð ÜQUð ä �*ð ä@Dð ô 
Œ$Œs”Cˆx�.Õñ r   c           
     óD  € V '       g   V # \        \        V 4      4      p\        V4      p^ pV^ ,          P                  R4      R8X  d6   \        P
                  ! V^ ,          4      V^ &   \        V^ ,          WcVR7      p\        V4       UU	u. uF4  w  r‰V	P                  R4      R8w  g   K  \        W’VR7      '       g   K2  VNK6  	  p
pp	V
^V,
          ) R  F5  p\        P
                  ! W[,          4      W[&   \        W[,          WbVR7       K7  	  \        V4       V# u up	pi )a  Apply Anthropic cache-control markers to API messages.

With a matching ``static_system_prefix`` the prefix and full system prompt each get a
marker and the remaining two go to the latest cacheable non-system messages; otherwise
the legacy system-and-3 layout applies. Idempotent: prior decoration is stripped from a
per-message copy first, so a second call (or messages a prior call already planned) can never
accumulate past 4 markers (#90971). Returns a shallow list copy with deep copies of modified
messages.
r:   r£   r�   )rP   rQ   N)r²   r   ri   r5   rµ   r¶   r�   r]   rc   rV   r`   )r™   rÐ   rP   rŠ   rQ   r   rØ   Úbreakpoints_usedr^   r7   Únon_sysÚidxs   &&&&&       r   rÕ   rÕ   Y  s  € ÷ ØÐä&¤t¨LÓ'9Ó:€HÜ˜9Ó%€FàÐØ�…{‡��vÓ (Ô*Ü—m’m H¨Q¥KÓ0ˆ�‰Ü6°xÀµ{ÀFØHXôZÐô ' xÔ0ô qÑ0‘T�Q°A·E±E¸&³MÀXÑ4MŒqÜ$ QÐ]n×oÐo÷ ˆqÑ0€Gñ qà˜Ð-Õ-Ð.Ð/Ó0ˆÜŸš h¥mÓ4ˆ‰Ü˜H�M¨6Ðhy×zñ 1ô ˜hÔ'à€Oùóqs   ÂDÂ+DÃ Drœ   )FT)T>   ÚalibabaÚopencoderj   úopencode-zen>   ÚapiÚcronr>   ÚbatchÚkanbanÚoneshotÚwebhookÚsubagent)r|   FNT)&r   rµ   Údataclassesr   Útypingr   r   r   Úagent.prompt_cache_boundaryr   r	   r-   rE   rM   rV   rU   r`   rc   ri   Ú	frozensetrƒ   r�   r‚   rs   rw   ÚAUTO_CACHE_TTLr}   r~   r…   r�   r4   r¯   r²   r¸   r¿   rÏ   rÚ   rÕ   r   r   r   Ú<module>rï      sG  ðñó Ý !ß "Ñ "å :ñ �$Ô÷ ð  ó ð õ	Sõ[÷÷4÷.mõ4÷BõXñ %Ò%[Ó\Ð ñ
 " = /Ó2Ð ñ ˜~Ð.Ó/Ð õ<õ
+ð €Ù!Ò"nÓoÐ õUð`¸ð `ÈR÷ `ðà04ðàPT÷õ0uõ&õRõõpõ"ðJCàðCà49ðCà^bðCð &+ðCð GK÷C÷@ ñ  r   