Ë
    áß²jVK  ã                   ó�   — d Z ddlZddlZddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZ  ej                  d«      Z G d„ d	«      Zy)
zóStreaming / interim-message delivery for ``AIAgent``.

Single-writer stream ownership, delta/reasoning hook fan-out, and interim assistant text dedup.
Extracted from ``run_agent.py``; every method resolves through ``AIAgent``'s MRO unchanged.
é    N)ÚAnyÚDictÚList)Úsanitize_context)Úflatten_message_text)Úredact_sensitive_textÚ	run_agentc            	       ód  — e Zd ZdZedefd„«       Zdedefd„Zddœded	edz  d
e	ddfd„Z
d3d„Zedefd„«       Zej                  deddfd„«       Zdeddfd„Zededefd„«       Zdedefd„Zdeee	f   dee   fd„Zdedefd„Zdeee	f   defd„Zdeee	f   defd„Zdedefd„Zdeddfd„Zdededee   ddfd„Zdeddfd„Zdeee	f   ddfd „Zd3d!„Zdefd"„Zd#edefd$„Z defd%„Z!d&eddfd'„Z"deee	f   fd(„Z#d3d)„Z$d*ed+ed,edz  ddfd-„Z%deddfd.„Z&deddfd/„Z'd0eddfd1„Z(defd2„Z)y)4ÚStreamDeliveryMixinz]Stream ownership, delta/reasoning hook fan-out and interim-text dedup (see module docstring).Úreturnc                 ó4   — | €y	  | |Ž  y# t         $ r Y yw xY w)zOCall ``cb(*args)`` if set, swallowing errors; True when it ran without raising.FT)Ú	Exception)ÚcbÚargss     ú:/home/ubuntu/.hermes/hermes-agent/agent/stream_delivery.pyÚ_call_quietlyz!StreamDeliveryMixin._call_quietly   s-   € ð ˆ:Øð	Ù�‰IØøÜò 	Ùð	ús   … ‹	–Útextc                 óŒ   — | j                   | j                  fD �cg c]  }| j                  ||«      ‘Œ }}t        |«      S c c}w )zUSend ``text`` to the display + TTS delta callbacks; True if at least one accepted it.)Ústream_delta_callbackÚ_stream_callbackr   Úany)Úselfr   r   Úresultss       r   Ú_deliver_to_stream_callbacksz0StreamDeliveryMixin._deliver_to_stream_callbacks!   sD   € à;?×;UÑ;UÐW[×WlÑWlÐ:mÖn°B�4×%Ñ% b¨$Õ/ÐnˆÐnÜ�7‹|Ðùò os   ›AN)ÚlabelÚeventr   Úfieldsc                óš   — 	 ddl m}  ||fi | j                  «       ¤|¤Ž y# t        $ r t        j                  d|xs |d¬«       Y yw xY w)zJBest-effort plugin stream hook enqueue; never raises into the stream path.r   )Úenqueue_plugin_stream_hookz%s plugin hook enqueue failedT©Úexc_infoN)Úagent.plugin_stream_hooksr   Ú_stream_hook_base_payloadr   ÚloggerÚdebug)r   r   r   r   r   s        r   Ú_enqueue_stream_hookz(StreamDeliveryMixin._enqueue_stream_hook&   sP   € ð	YÝLá& uÑ[°×0NÑ0NÓ0PÐ[ÐTZÓ[øÜò 	YÜ�L‰LÐ8¸%º.À5ÐSWˆLÖXð	Yús   ‚" ¢%A
Á	A
c                 ó   ‡ — t        ‰ dd«      }t        ‰ dd«      }d‰ _        dt        ddfˆ fd„}|�-|j                  «       } ||r|�|j	                  |«      n|«       |� ||j                  «       «       d‰ _        y)a  Reset tracking for text delivered during the current model response.

        Flushes the think scrubber's benign tail first, routed through the context scrubber (a span
        straddling the boundary must still be caught), then the context scrubber's own tail.
        Ú_stream_think_scrubberNÚ_stream_context_scrubberÚtailr   c                 óP   •— | r#‰j                  | «       ‰j                  | «       y y ©N)r   Ú_record_streamed_assistant_text)r*   r   s    €r   ÚdeliverzDStreamDeliveryMixin._reset_stream_delivery_tracking.<locals>.deliver:   s'   ø€ ÙØ×1Ñ1°$Ô7Ø×4Ñ4°TÕ:ð ó    Ú )ÚgetattrÚ_stream_reasoning_hooks_enabledÚstrÚflushÚfeedÚ _current_streamed_assistant_text)r   Úthink_scrubberÚctx_scrubberr.   Ú
think_tails   `    r   Ú_reset_stream_delivery_trackingz3StreamDeliveryMixin._reset_stream_delivery_tracking/   s�   ø€ ô ! Ð'?ÀÓFˆÜ˜tÐ%?ÀÓFˆà/3ˆÔ,ð	;œ#ð 	; $õ 	;ð Ð%Ø'×-Ñ-Ó/ˆJÙ±ZÀLÐD\�L×%Ñ% jÔ1ÐblÔmØÐ#Ù�L×&Ñ&Ó(Ô)Ø02ˆÕ-r/   c                 óF   — t        | dd«      }|rdj                  |«      S dS )a  Visible assistant text streamed so far this turn. Backed by a list of pieces: ``+=`` on a string
        attribute copies the whole reply on every delta (quadratic). Hot-path emptiness checks look at
        ``_streamed_assistant_text_parts`` so they do not join per token.Ú_streamed_assistant_text_partsNr0   )r1   Újoin)r   Úpartss     r   r6   z4StreamDeliveryMixin._current_streamed_assistant_textO   s(   € ô
 ˜Ð>ÀÓEˆÙ!&ˆr�w‰w�u‹~Ð.¨BÐ.r/   Úvaluec                 ó(   — |r	|g| _         y g | _         y r,   )r<   )r   r?   s     r   r6   z4StreamDeliveryMixin._current_streamed_assistant_textW   s   € á9>¨u¨gˆÕ+ÀBˆÕ+r/   c                 ó    — t        |t        «      r>|r;| j                  «       s*t        | dd«      }|€	g x}| _        |j                  |«       yyyy)zaAccumulate visible assistant text emitted through stream callbacks (superseded writers excluded).r<   N)Ú
isinstancer3   Ú_stream_writer_supersededr1   r<   Úappend)r   r   r>   s      r   r-   z3StreamDeliveryMixin._record_streamed_assistant_text[   sQ   € ä�dœCÔ ¡T°$×2PÑ2PÔ2RÜ˜DÐ"BÀDÓIˆEØˆ}Ø>@Ð@�˜Ô;Ø�L‰L˜Õð	 3S TÐ r/   c                 óp   — t        | t        «      r%t        j                  dd| «      j	                  «       S dS )Nz\s+Ú r0   )rB   r3   ÚreÚsubÚstrip)r   s    r   Ú_normalize_interim_visible_textz3StreamDeliveryMixin._normalize_interim_visible_textc   s,   € ä4>¸tÄSÔ4IŒr�v‰v�f˜c 4Ó(×.Ñ.Ó0ÐQÈrÐQr/   Úcontentc           	      óì   — | j                  | j                  |xs d«      «      }| j                  | j                  t        | dd«      xs d«      «      }t        |xr |«      xr |j	                  |«      S )Nr0   r6   )rJ   Ú_strip_think_blocksr1   ÚboolÚ
startswith)r   rK   Úvisible_contentÚstreameds       r   Ú_interim_content_was_streamedz1StreamDeliveryMixin._interim_content_was_streamedg   sv   € Ø×>Ñ>¸t×?WÑ?WÐX_ÒXeÐceÓ?fÓgˆØ×7Ñ7Ø×$Ñ$¤W¨TÐ3UÐWYÓ%ZÒ%`Ð^`Óaó
ˆô
 �OÒ0¨Ó1ÒZ°o×6PÑ6PÐQYÓ6ZÐZr/   Úassistant_msgc                 ó$  — t        | dd«      r|j                  d«      nd}g }t        |t        «      r|ndD ]Ö  }t        |t        «      r|j                  d«      dk7  rŒ(|j                  d«      |j                  d	«      }}t        |t
        «      r1|j                  «       j                  «       d
k7  st        |t        «      sŒŒdj                  d„ |D «       «      j                  «       }| j                  |«      }|sŒÆ|j                  |«       ŒØ |S )zíVisible Codex commentary (``phase=commentary`` items), one string per message item.

        ``phase=analysis`` stays hidden (scratchpad); with ``display.show_commentary=false``
        commentary stays on the reasoning channel.
        Úshow_commentaryTÚcodex_message_itemsN© ÚtypeÚmessageÚphaserK   Ú
commentaryr0   c              3   óÒ   K  — | ]_  }t        |t        «      rM|j                  d «      dk(  r9t        |j                  d«      t        «      r|d   j	                  «       r|d   –— Œa y­w)rX   Úoutput_textr   N)rB   ÚdictÚgetr3   rI   )Ú.0Úparts     r   ú	<genexpr>zKStreamDeliveryMixin._extract_codex_interim_visible_parts.<locals>.<genexpr>~   sX   è ø€ ò Ø!%Ü˜d¤DÔ)¨d¯h©h°vÓ.>À-Ò.OÜ˜tŸx™x¨Ó/´Ô5¸$¸v¹,×:LÑ:LÔ:Nð �V•ñùs   ‚A%A')r1   r_   rB   Úlistr^   r3   rI   Úlowerr=   Ú_visible_commentaryrD   )r   rS   ÚitemsÚmessagesÚitemrZ   Úcontent_partsÚvisibles           r   Ú$_extract_codex_interim_visible_partsz8StreamDeliveryMixin._extract_codex_interim_visible_partsp   sû   € ô =DÀDÐJ[Ð]aÔ<b�×!Ñ!Ð"7Ô8ÐhlˆØ ˆÜ'¨¬tÔ4‘E¸"ò 	)ˆDÜ˜d¤DÔ)¨T¯X©X°fÓ-=ÀÒ-JØØ#'§8¡8¨GÓ#4°d·h±h¸yÓ6I�=ˆEÜ˜e¤SÔ)¨U¯[©[«]×-@Ñ-@Ó-BÀlÒ-RÔZdÐerÔtxÔZyØØ—g‘gñ Ø)6ôó ÷ ‰e‹gð	 ð
 ×.Ñ.¨wÓ7ˆGÚØ—‘ Õ(ð	)ð ˆr/   c                 ó^   — | j                  |«      j                  «       }|rt        |«      S |S )zKThink-stripped, redacted commentary text ("" when nothing visible remains).)rM   rI   r   ©r   r   rj   s      r   re   z'StreamDeliveryMixin._visible_commentaryˆ   s.   € à×*Ñ*¨4Ó0×6Ñ6Ó8ˆÙ18Ô$ WÓ-ÐE¸gÐEr/   c                 ó^   — dj                  | j                  |«      «      j                  «       S )z=All visible Codex commentary joined, for comparison/fallback.ú

)r=   rk   rI   ©r   rS   s     r   Ú#_extract_codex_interim_visible_textz7StreamDeliveryMixin._extract_codex_interim_visible_text�   s%   € à�{‰{˜4×DÑDÀ]ÓSÓT×ZÑZÓ\Ð\r/   c                 ó–   — | j                  |«      xs7 | j                  t        |j                  d«      «      «      j	                  «       S )u   Assistant text eligible for interim delivery: structured Codex commentary first â€” a response can
        hold commentary AND a partial final answer while tools are pending, and treating content as
        progress leaks the answer early â€” else top-level content (may be a parts list).rK   )rq   rM   r   r_   rI   rp   s     r   Ú_interim_assistant_visible_textz3StreamDeliveryMixin._interim_assistant_visible_text‘   sE   € ð
 ×4Ñ4°]ÓCò dØ×'Ñ'Ô(<¸]×=NÑ=NÈyÓ=YÓ(ZÓ[×aÑaÓcð	
r/   c                 ól   — | j                  |«      }t        |«      xr |t        | dt        «       «      v S ©NÚ_delivered_interim_texts)rJ   rN   r1   Úset©r   r   Ú
normalizeds      r   Ú_interim_text_was_deliveredz/StreamDeliveryMixin._interim_text_was_deliveredš   s5   € Ø×9Ñ9¸$Ó?ˆ
Ü�JÓÒb J´'¸$Ð@ZÔ\_Ó\aÓ2bÐ$bÐbr/   c                 ó¶   — | j                  |«      }|rFt        t        | dd «      t        «      st        «       | _        | j                  j                  |«       y y ru   )rJ   rB   r1   rw   rv   Úaddrx   s      r   Ú_record_delivered_interim_textz2StreamDeliveryMixin._record_delivered_interim_textž   sL   € Ø×9Ñ9¸$Ó?ˆ
ÙÜœg dÐ,FÈÓMÌsÔSÜ03³�Ô-Ø×)Ñ)×-Ñ-¨jÕ9ð r/   rj   Úalready_streamedÚrecordc                ó¶   — t        | dd«      }|€y	  |||¬«       |D ]  }| j                  |«       Œ y# t        $ r t        j	                  dd¬«       Y yw xY w)zkHand ``visible`` to ``interim_assistant_callback`` and mark ``record`` delivered; swallows callback errors.Úinterim_assistant_callbackN)r~   z interim_assistant_callback errorTr    )r1   r}   r   r$   r%   )r   rj   r~   r   r   ra   s         r   Ú_deliver_interimz$StreamDeliveryMixin._deliver_interim¥   si   € ä�TÐ7¸Ó>ˆØˆ:Øð	LÙˆwÐ)9Õ:Øò :�Ø×3Ñ3°DÕ9ñ:øäò 	LÜ�L‰LÐ;ÀdˆLÖKð	Lús   ’"5 µ AÁAc                 ó¾   — t        | dd«      �t        |t        «      sy| j                  |«      }|r|dk(  s| j	                  |«      ry| j                  |d|g¬«       y)z>Deliver a completed live Codex commentary message immediately.r�   Nú(empty)F©r~   r   )r1   rB   r3   re   rz   r‚   rm   s      r   Ú_fire_streamed_codex_commentaryz3StreamDeliveryMixin._fire_streamed_codex_commentary±   sb   € ä�4Ð5°tÓ<ÐDÌJÐW[Ô]`ÔLaØØ×*Ñ*¨4Ó0ˆÙ˜' YÒ.°$×2RÑ2RÐSZÔ2[ØØ×Ñ˜g¸ÀwÀiÐÕPr/   c                 óþ  — t        |t        «      sy| j                  |«      }i }|D ]2  }| j                  |«      }|sŒ||vsŒ| j	                  |«      rŒ.|||<   Œ4 t        |j                  «       «      }|rdj                  |«      j                  «       n| j                  |«      }|r|dk(  s| j	                  |«      ry| j                  |«      }| j                  d||¬«       | j                  |||xs |g¬«       y)uÚ   Surface a real mid-turn assistant commentary message to the UI layer. Does NOT set
        ``_response_was_previewed`` ("the final response was shown") â€” the CLI would then suppress a
        different final summary.Nro   r„   Úon_interim_message)r   r~   r…   )rB   r^   rk   rJ   rz   rc   Úvaluesr=   rI   rs   rR   r&   r‚   )	r   rS   Úcommentary_partsÚpendingra   ÚkeyÚundelivered_partsrj   r~   s	            r   Ú_emit_interim_assistant_messagez3StreamDeliveryMixin._emit_interim_assistant_messageº   s  € ô ˜-¬Ô.ØØ×DÑDÀ]ÓSÐà"$ˆØ$ò 	$ˆDØ×6Ñ6°tÓ<ˆCÚ�s 'Ò)°$×2RÑ2RÐSWÕ2XØ#�˜’ð	$ô ! §¡Ó!1Ó2ÐÙ<L�&—+‘+Ð/Ó0×6Ñ6Ô8ÐRV×RvÑRvð  xEó  SFˆÙ˜' YÒ.°$×2RÑ2RÐSZÔ2[ØØ×=Ñ=¸gÓFÐØ×!Ñ!Ð"6¸WÐWgÐ!ÔhØ×Ñ˜gÐ8HÐQbÒQoÐgnÐfoÐÕpr/   c                 óÞ   — t        | dd«      €t        j                  «       | _        t        | dd«      €t        j                  «       | _        dD ]  }t        | |«      rŒt        | |d«       Œ y)a  Lazily create the single-writer guard fields (#65991).

        The fields are normally set unconditionally in ``agent_init`` (``_STREAM_STATE``), so every
        ``__init__``-built agent shares ONE lock from birth and the lazy path below is never taken by
        two threads. Only agents constructed via ``AIAgent.__new__`` (test doubles, legacy/partially-
        initialized instances) skip that path; claiming/checking the writer must not crash those, so
        initialize the fields on first use.
        Ú_stream_writer_lockNÚ_stream_writer_tls)Ú_stream_writer_tokenÚ_stream_writer_droppedr   )r1   Ú	threadingÚLockr�   Úlocalr‘   ÚhasattrÚsetattr)r   Úattrs     r   Ú_ensure_stream_writer_statez/StreamDeliveryMixin._ensure_stream_writer_stateÏ   sg   € ô �4Ð.°Ó5Ð=Ü'0§~¡~Ó'7ˆDÔ$Ü�4Ð-¨tÓ4Ð<Ü&/§o¡oÓ&7ˆDÔ#ØFò 	'ˆDÜ˜4 Õ&Ü˜˜d AÕ&ñ	'r/   c                 ó¶   — | j                  «        | j                  5  | j                  dz   x| _        }ddd«       | j                  _        |S # 1 sw Y   ŒxY w)aª  Claim exclusive ownership of the delta sink for this stream attempt; returns its writer token.

        Every attempt (each provider path, each retry) claims right before consuming; claiming bumps
        the shared token, so an earlier attempt still alive on another thread is superseded and its
        late chunks fenced out. Stored per-thread: a thread that never claimed can never be fenced.

        See #65991.
        é   N)rš   r�   r’   r‘   Útoken©r   r�   s     r   Ú_claim_stream_writerz(StreamDeliveryMixin._claim_stream_writerà   s]   € ð 	×(Ñ(Ô*Ø×%Ñ%ñ 	NØ04×0IÑ0IÈAÑ0MÐMˆDÔ%¨÷	Nà(-ˆ×ÑÔ%Øˆ÷	Nð 	Nús   �AÁAr�   c                 ó"   — |t        | d|«      k(  S )uÍ   True when ``token`` is still the active writer, so a stream loop can bail the instant it is superseded.

        active writer â€” i.e. no newer stream attempt has claimed the sink since (#65991).
        r’   ©r1   rž   s     r   Ú_stream_writer_is_currentz-StreamDeliveryMixin._stream_writer_is_currentï   s   € ð
 œ Ð&<¸eÓDÑDÐDr/   c                 ó^   — t        t        | dd«      dd«      }|duxr |t        | d|«      k7  S )uö   True when this thread claimed the sink but a newer attempt has since claimed it (never for a non-claimer).

        stream attempt has since claimed it â€” i.e. this thread is a stale writer whose chunks must be
        dropped (#65991).
        r‘   Nr�   r’   r¡   rž   s     r   rC   z-StreamDeliveryMixin._stream_writer_supersededö   s<   € ô œ Ð&:¸DÓAÀ7ÈDÓQˆØ˜DÐ ÒZ U¬g°dÐ<RÐTYÓ.ZÑ%ZÐZr/   Úwherec                 óÖ   — 	 t        t        | dd«      «      dz   | _        | j                  }|dk(  s||dz
  z  dk(  rt        j                  d||«       yy# t        $ r
 d| _        Y ŒGw xY w)z<Record + log that a superseded stream's delta was discarded.r“   r   rœ   u™   Dropped delta from a superseded stream writer at %s (discarded=%d this turn) â€” a stale stream tried to write into the turn after a retry superseded it.N)Úintr1   r“   r   r$   Úwarning)r   r¤   Ú_ns      r   Ú_note_dropped_stream_writerz/StreamDeliveryMixin._note_dropped_stream_writerÿ   s~   € ð	,Ü*-¬g°dÐ<TÐVWÓ.XÓ*YÐ\]Ñ*]ˆDÔ'ð ×(Ñ(ˆØ�Š7�r˜R !™V‘}¨Ò*Ü�N‰Nð8ð �rõ	ð +øô	 ò 	,Ø*+ˆDÖ'ð	,ús   ‚A ÁA(Á'A(c                 óÒ   — t        | dd«      xs dt        t        | dd«      xs d«      | j                  xs d| j                  xs d| j                  xs d| j
                  xs ddœS )NÚ_current_turn_idr0   Ú_api_call_countr   Úcli)Úturn_idÚ	iterationÚ
session_idÚmodelÚproviderÚsurface)r1   r¦   r°   r±   r²   Úplatform©r   s    r   r#   z-StreamDeliveryMixin._stream_hook_base_payload  se   € ä˜tÐ%7¸Ó<ÒBÀÜœW TÐ+<¸aÓ@ÒEÀAÓFØŸ/™/Ò/¨RØ—Z‘ZÒ% 2ØŸ™Ò+¨Ø—}‘}Ò-¨ñ
ð 	
r/   c                 ó&   — | j                  d«       y )NÚon_stream_start©r&   rµ   s    r   Ú_emit_stream_startz&StreamDeliveryMixin._emit_stream_start  s   € Ø×!Ñ!Ð"3Õ4r/   Ú
final_textÚfinishedÚerrorc                ó.   — | j                  d|||¬«       y )NÚon_stream_end)rº   r»   r¼   r¸   )r   rº   r»   r¼   s       r   Ú_emit_stream_endz$StreamDeliveryMixin._emit_stream_end  s   € Ø×!Ñ! /¸jÐS[ÐchÐ!Õir/   c                 óL  — | j                  «       r| j                  d«       yt        t        | dd«      xr |xr |j	                  «       «      }|rd| _        d|z   }t        |t        «      r|t        | dd«      }t        | dd«      }|�|j                  |«      n| j                  |«      }|�|j                  |«      n
t        |«      }|st        | dd«      s|j                  d	«      }|sy| j                  |«      }| j                  d
|d¬«       |r| j                  |«       yy)z;Fire all registered stream delta callbacks (display + TTS).Ú_fire_stream_deltaNÚ_stream_needs_breakFro   r(   r)   r<   Ú
Úon_stream_deltar   )ÚdeltaÚkind)rC   r©   rN   r1   rI   rÂ   rB   r3   r5   rM   r   Úlstripr   r&   r-   )r   r   Úprepended_breakr7   ÚscrubberÚ	delivereds         r   rÁ   z&StreamDeliveryMixin._fire_stream_delta  s,  € ð ×)Ñ)Ô+à×,Ñ,Ð-AÔBØô œw tÐ-BÀEÓJÒdÈtÒdÐX\×XbÑXbÓXdÓeˆÙØ',ˆDÔ$Ø˜D‘=ˆDÜ�dœCÔ ô % TÐ+CÀTÓJˆNä˜tÐ%?ÀÓFˆHØ0>Ð0J�>×&Ñ& tÔ,ÐPT×PhÑPhÐimÓPnˆDØ*2Ð*>�8—=‘= Ô&ÔDTÐUYÓDZˆDñ #¬7°4Ð9YÐ[_Ô+`Ø—{‘{ 4Ó(�ÙØØ×5Ñ5°dÓ;ˆ	Ø×!Ñ!Ð"3¸4ÀfÐ!ÔMÙØ×0Ñ0°Õ6ð r/   c                 óD  — | j                  «       r| j                  d«       y| j                  | j                  |«       t	        | dd«      }|€	 ddlm}  |«       }|| _
        |r| j                  d	d
|d¬«       yy# t        $ r t        j                  dd¬«       Y yw xY w)zYFire reasoning callback if registered; superseded writers are fenced like content deltas.Ú_fire_reasoning_deltaNr2   r   )Ústream_reasoning_deltas_enabledz4reasoning on_stream_delta plugin hook enqueue failedTr    rÄ   zreasoning on_stream_deltaÚ	reasoning)r   rÅ   rÆ   )rC   r©   r   Úreasoning_callbackr1   r"   rÍ   r   r$   r%   r2   r&   )r   r   ÚenabledrÍ   s       r   rÌ   z)StreamDeliveryMixin._fire_reasoning_delta@  s±   € à×)Ñ)Ô+ð ×,Ñ,Ð-DÔEØØ×Ñ˜4×2Ñ2°DÔ9ô ˜$Ð AÀ4ÓHˆØˆ?ðÝUá9Ó;�ð 4;ˆDÔ0ÙØ×%Ñ%Ð&7Ð?ZÐbfÐmxÐ%Õyð øô	 ò Ü—‘ÐSÐ^b�ÔcÙðús   ÁA< Á< BÂBÚ	tool_namec                 ó<   — | j                  | j                  |«       y)zgNotify the display layer that the model is generating tool call arguments (spinner for large payloads).N)r   Útool_gen_callback)r   rÑ   s     r   Ú_fire_tool_gen_startedz*StreamDeliveryMixin._fire_tool_gen_startedW  s   € à×Ñ˜4×1Ñ1°9Õ=r/   c                 ó¬   — 	 ddl m}  |«       ry	 | j
                  duxs t        | dd«      duS # t        $ r t        j	                  dd¬«       Y ŒAw xY w)z4Return True if any streaming consumer is registered.r   )Úhas_stream_observer_hooksTz(plugin stream hook consumer check failedr    Nr   )r"   rÖ   r   r$   r%   r   r1   )r   rÖ   s     r   Ú_has_stream_consumersz)StreamDeliveryMixin._has_stream_consumers[  sf   € ð	TÝKá(Ô*Øð +ð ×)Ñ)°Ð5Òl¼ÀÐGYÐ[_Ó9`ÐhlÐ9lÐløô ò 	TÜ�L‰LÐCÈdˆLÖSð	Tús   ‚0 ° AÁA)r   N)*Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstaticmethodrN   r   r3   r   r   r&   r:   Úpropertyr6   Úsetterr-   rJ   rR   r   r   rk   re   rq   rs   rz   r}   r‚   r†   rŽ   rš   r¦   rŸ   r¢   rC   r©   r#   r¹   r¿   rÁ   rÌ   rÔ   r×   rW   r/   r   r   r      s×  „ Ùgàð Dò ó ðð°ð ¸ó ð
 GKò Y¨#ð Y¸¸t¹ð YÐVYð YÐ^bó Yó3ð@ ð/°#ò /ó ð/ð &×,Ñ,ðG°cð G¸dò Gó -ðGð°Cð ¸Dó ð ðR¨cð R°cò Ró ðRð[°Sð [¸Tó [ðÀ$ÀsÈCÀxÁ.ð ÐUYÐZ]ÑU^ó ð0F¨ð F°ó Fð
]ÀÀcÈ3ÀhÁð ]ÐTWó ]ð
¸TÀ#ÀsÀ(¹^ð 
ÐPSó 
ðc°ð c¸ó cð:°3ð :¸4ó :ð
L¨ð 
LÀ$ð 
LÐPTÐUXÑPYð 
LÐ^bó 
LðQ°Cð Q¸Dó Qðq¸TÀ#ÀsÀ(¹^ð qÐPTó qó*'ð" có ðE¨sð E°tó Eð[¨4ó [ð°ð ¸ó ð 
¨4°°S°©>ó 
ó5ðj¨cð j¸Tð jÈ#ÐPTÉ*ð jÐY]ó jð7 sð 7¨tó 7ðBz¨#ð z°$ó zð.>°ð >¸ó >ð	m tô 	mr/   r   )rÛ   ÚloggingrG   r”   Útypingr   r   r   Úagent.memory_managerr   Úagent.message_contentr   Úagent.redactr   Ú	getLoggerr$   r   rW   r/   r   ú<module>rå      sF   ðñó
 Û 	Û ß "Ñ "å 1Ý 6Ý .ð 
ˆ×	Ñ	˜;Ó	'€÷Qmò Qmr/   