+
    jHàj<Õ  ã                  ó$  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIH t!H"t# ^ R	I$H%t% ^ R
I&H't' ^ RI(H)t) ^ RI*H+t+ ]PX                  ! R4      t-].! 4       t/].! 4       t0].! 4       t1].! 4       t2].! 4       t3].! 4       t4].! 4       t5].! 4       t6]Pn                  ]Pp                  Pn                  3t9Rt:] ! R R4      4       t;] ! R R4      4       t< ! R R]'])]+4      t=R# )u�  Gateway streaming consumer â€” bridges sync agent callbacks to async platform delivery.

on_delta() queues deltas from the agent's worker thread; the async run() task buffers,
rate-limits and progressively edits one platform message (send, then editMessageText;
draft/native transports are optional per adapter).
Credit: jobless0x (#774, #1312), OutThisLife (#798), clicksingh (#697).
)ÚannotationsN)Ú	dataclass)ÚAnyÚCallableÚOptional)ÚBasePlatformAdapter)Ú_custom_unit_to_cp)ÚDEFAULT_STREAMING_EDIT_INTERVALÚ"DEFAULT_STREAMING_BUFFER_THRESHOLDÚDEFAULT_STREAMING_CURSOR)Úis_intentional_silence_responseÚis_partial_silence_marker)Úensure_closed_code_fences)ÚStreamTransportMixin)ÚStreamFallbackMixin)ÚStreamThinkFilterMixinzgateway.stream_consumeru   â�¸ ç­‰å¾…å®¡æ‰¹ä¸­...c                  ó~   € ] tR t^<t$ Rt]tR]R&   ]t	R]R&   ]
tR]R&   RtR	]R
&   RtR]R&   RtR]R&   RtR]R&   RtR# )ÚStreamConsumerConfigz5Runtime config for a single stream consumer instance.ÚfloatÚedit_intervalÚintÚbuffer_thresholdÚstrÚcursorFÚboolÚbuffer_onlyç        Úfresh_final_after_secondsÚeditÚ	transportÚ Ú	chat_type© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú _DEFAULT_STREAMING_EDIT_INTERVALr   Ú__annotations__Ú#_DEFAULT_STREAMING_BUFFER_THRESHOLDr   Ú_DEFAULT_STREAMING_CURSORr   r   r   r   r!   Ú__static_attributes__r"   ó    Ú</home/ubuntu/.hermes/hermes-agent/gateway/stream_consumer.pyr   r   <   sQ   ‡ á?Ø;€M�5Ó;Ø?Ð�cÓ?Ø+€FˆCÓ+Ø€K�Óð (+Ð˜uÓ*ð €IˆsÓØ€Iˆs×r-   r   c                  ó°   € ] tR t^Ot$ RtRtR]R&   RtR]R&   RtR]R&   Rt	R]R	&   Rt
R]R
&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   ]R R l4       tRtR# )Ú_Tickz*Everything one drain of the queue decided.Fr   Úgot_doneÚgot_segment_breakÚ	got_flushNr   Úflush_eventÚgot_reopen_seedzOptional[tuple]Úapproval_boundaryúOptional[str]Úcommentary_textÚupdate_visibleÚdraft_final_fresh_sendc               ó   € V ^8„  d   QhRR/# ©é   Úreturnr   r"   )Úformats   "r.   Ú__annotate__Ú_Tick.__annotate__^   s   € ÷ añ a˜Dñ ar-   c                ó‚   € V P                   '       * ;'       d(    V P                  '       * ;'       d    V P                  RJ # )zDMid-stream tick: not finalizing, not a segment break, no commentary.N)r1   r2   r8   ©Úselfs   &r.   Ú
is_interimÚ_Tick.is_interim]   s6   € ð —=‘=Ô ×`Ð`¨×)?Ñ)?Ô%?×`Ð`ÀD×DXÑDXÐ\`ÐD`Ð`r-   r"   )r#   r$   r%   r&   r'   r1   r)   r2   r3   r4   r5   r6   r8   r9   r:   ÚpropertyrE   r,   r"   r-   r.   r0   r0   O   sv   ‡ á4Ø€HˆdÓØ#Ð�tÓ#Ø€IˆtÓØ€K�ÓØ!€O�TÓ!Ø)-Ð�Ó-Ø%)€O�]Ó)à €N�DÓ Ø#(Ð˜DÓ(àôaó ôar-   r0   c                  óX  € ] tR t^ct$ Rt^t]P                  ! ^14      tR]	R&   RxR R llt
R R ltR	 R
 ltR R lt]R R l4       tR R ltR R ltRRRR/R R llt]! R 4      t]! R 4      t]! R 4      t]! R 4      tR R ltR R ltR  R! ltRyR" R# l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 RzR0 R1 llt!R2 R3 lt"R{R4 R5 llt#R6 R7 lt$R8 R9 lt%R: R; lt&]'R< R= l4       t(R>R/R? R@ llt)RA RB lt*RyRC RD llt+RE RF lt,RG RH lt-RyRI RJ llt.RK RL lt/RM RN lt0RO RP lt1RQ RR lt2RS RT lt3RU RV lt4RW RX lt5RY RZ lt6R[ R\ lt7R] R^ lt8R_ R` lt9Ra Rb lt:Rc Rd lt;Re Rf lt<RgRh/Ri Rj llt=Rk Rl lt>Rm Rn lt?Ro Rp lt@Rq Rr ltARs Rt ltB]'Ru Rv l4       tCRwtDR# )|ÚGatewayStreamConsumera  Async consumer that progressively edits a platform message with streamed tokens.
Usage: ``agent.stream_delta_callback = consumer.on_delta``; ``create_task(consumer.run())``;
after the agent finishes ``consumer.finish()`` then ``await task`` for the final edit.r   Ú_draft_id_counterNc               ó8   € V ^8„  d   QhRRRRRRRRR	R
RRRRRR/# )r=   Úadapterr   Úchat_idr   ÚconfigzOptional[StreamConsumerConfig]ÚmetadatazOptional[dict]Úon_new_messagezOptional[callable]Úon_before_finalizezOptional[Callable[[], Any]]Úinitial_reply_to_idr7   Úrun_still_currentzOptional[Callable[[], bool]]r"   )r?   s   "r.   r@   Ú"GatewayStreamConsumer.__annotate__p   sd   € ÷ M,ñ M,àðM,ð ðM,ð /ð	M,ð
 !ðM,ð +ðM,ð 8ðM,ð +ðM,ð 8ñM,r-   c	                	ó  € Wn         W n        T;'       g    \        4       V n        W@n        WPn        W`n        Wpn        \        \        P                  ! 4       4      V n        T;'       g    R  V n        RV n        \        VRR4      RJ V n        RV n        \"        P$                  ! 4       V n        \)        4       V n        RV n        RV n        RV n        RV n        ^ V n        V P                  P6                  V n        . V n        . V n        RV n        RV n         RV n!        V PE                  4        RV n#        RV n$        ^ V n%        RV n&        RV n'        RV n(        ^ V n)        \T        V n+        RV n,        RV n-        RV n.        RV n/        R# )	c                 ó   € R # )Tr"   r"   r-   r.   Ú<lambda>Ú0GatewayStreamConsumer.__init__.<locals>.<lambda>…   s   € Ár-   TÚREQUIRES_EDIT_FINALIZEFç      @r   r    NÚApproval)0rL   rM   r   ÚcfgrO   Ú_on_new_messageÚ_on_before_finalizeÚ_initial_reply_to_idr   ÚuuidÚuuid4Ú_turn_idÚ_run_still_currentÚstream_deltas_enabledÚgetattrÚ_adapter_requires_finalizeÚ!_max_fallback_flood_retry_secondsÚqueueÚQueueÚ_queueÚsetÚ_preview_message_idsÚ_already_sentÚ_edit_supportedÚ_last_edit_timeÚ_last_edit_overflowedÚ_flood_strikesr   Ú_current_edit_intervalÚ_delivered_commentary_textsÚ_delivered_segment_textsÚ_in_think_blockÚ_think_bufferÚ_before_finalize_notifiedÚ_reset_message_stateÚ_use_draft_streamingÚ	_draft_idÚ_draft_failuresÚ_egress_declinedÚ_use_native_streamingÚ_native_stream_openedÚ_native_last_pushed_lenÚ_DEFAULT_BOUNDARY_PLACEHOLDERÚ_boundary_placeholderÚ_boundary_reasonÚ_boundary_reopenÚ_awaiting_reopen_after_boundaryÚ_reopen_seeded_eagerly)	rD   rL   rM   rN   rO   rP   rQ   rR   rS   s	   &&&&&&&&&r.   Ú__init__ÚGatewayStreamConsumer.__init__p   sx  € ð ŒØŒØ×3Ð3Ô1Ó3ˆŒØ Œð  .ÔØ#5Ô Ø$7Ô!ÜœDŸJšJ›LÓ)ˆŒà"3×"EÐ"E¹ˆÔð &*ˆÔ"ô +2°'Ð;SÐUZÓ*[Ð_cÐ*cˆÔ'à14ˆÔ.ä#(§;¢;£=ˆŒô /2«eˆÔ!Ø"ˆÔØ#ˆÔØ"ˆÔØ%*ˆÔ"ØˆÔØ&*§h¡h×&<Ñ&<ˆÔ#Ø68ˆÔ(Ø35ˆÔ%Ø$ˆÔØˆÔØ).ˆÔ&Ø×!Ñ!Ô#ð
 %*ˆÔ!Ø(,ˆŒØ ˆÔð !&ˆÔØ%*ˆÔ"Ø%*ˆÔ"Ø'(ˆÔ$ô &CˆÔ"Ø *ˆÔØ %ˆÔð 05ˆÔ,Ø&+ˆÖ#r-   c               ó   € V ^8„  d   QhRR/# ©r=   r>   ÚNoner"   )r?   s   "r.   r@   rT   ¿   s   € ÷ 'ñ ' dñ 'r-   c                óÐ   € RV n         RV n        R;V n        V n        RV n        RV n        RV n        RV n        \        4       V n	        . V n
        RV n        V P                  4        R# )zPPer-message (segment) state: fresh at construction and after each segment break.Nr    F)Ú_message_idÚ_message_created_tsÚ_accumulatedÚ_stream_ledgerÚ_last_sent_textÚ_fallback_final_sendÚ_fallback_prefixÚ#_fallback_preserve_partial_messagesrk   Ú_segment_preview_message_idsÚ_tool_progress_linesÚ_tool_progress_activeÚ_clear_turn_final_flagsrC   s   &r.   rx   Ú*GatewayStreamConsumer._reset_message_state¿   sj   € à*.ˆÔØ48ˆÔ ð 35Ð4ˆÔ˜DÔ/Ø!ˆÔØ$)ˆÔ!Ø "ˆÔà38ˆÔ0Ü69³eˆÔ)à/1ˆÔ!Ø+0ˆÔ"Ø×$Ñ$Ö&r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   Ñ   s   € ÷ )ñ )¨ñ )r-   c                óL   € RV n         RV n        RV n        RV n        RV n        R# )aÆ  Reset every turn-final delivery flag to "nothing delivered yet".
``_delivered_final_text`` is the cleaned turn-final payload the gateway compares to
the completed final_response before trusting the flags (a successful finalize edit
may carry a stale preview); None = legacy trust.  A payload-less
``_turn_split_delivery`` must NOT inherit legacy trust; ``_delivery_ambiguous`` (a
full-final send timed out but MAY have landed) is the only case that does.FN)Ú_final_response_sentÚ_final_content_deliveredÚ_delivered_final_textÚ_turn_split_deliveryÚ_delivery_ambiguousrC   s   &r.   r—   Ú-GatewayStreamConsumer._clear_turn_final_flagsÑ   s.   € ð %*ˆÔ!Ø(-ˆÔ%Ø48ˆÔ"Ø$)ˆÔ!ð
 $)ˆÖ r-   c               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   å   s   € ÷ 
ñ 
 Dñ 
r-   c                ó  € \        \        V P                  4      RR4      p\        V4      '       g   \        V P                  RR4      RJ #  V! V P                  \	        V P
                  4      4      RJ #   \         d     R# i ; i)zÛWhether THIS chat's transport treats the stream as the message: per-chat probe
first (a relay adapter's class attribute only reflects its primary identity), else
the legacy attribute; both on the CLASS (MagicMock-safe).Ústream_is_message_for_chatNÚdraft_stream_is_messageFT)re   ÚtyperL   Úcallabler   rM   Ú	Exception)rD   Úprobes   & r.   Ú_stream_is_messageÚ(GatewayStreamConsumer._stream_is_messageå   st   € ô œ˜TŸ\™\Ó*Ð,HÈ$ÓOˆÜ˜�ŠÜ˜4Ÿ<™<Ð)BÀEÓJÈdÐRÐRð	Ù˜Ÿ™¤s¨4¯<©<Ó'8Ó9¸TÐAÐAøÜô 	Úð	ús   Á'A4 Á4BÂBc               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   ò   s   € ÷ *ñ * tñ *r-   c                ó   € V P                   # )zJTrue only when native streaming is active (gates in-stream tool progress).)r}   rC   s   &r.   Úaccepts_tool_progressÚ+GatewayStreamConsumer.accepts_tool_progressñ   s   € ð ×)Ñ)Ð)r-   c               ó    € V ^8„  d   QhRRRR/# )r=   Úliner   r>   rŠ   r"   )r?   s   "r.   r@   rT   ö   s   € ÷ 4ñ 4 Sð 4¨Tñ 4r-   c                ó\   € V'       d$   V P                   P                  \        V34       R# R# )zTThread-safe: overlay a tool-progress line in the native bubble until the next delta.N)rj   ÚputÚ_TOOL_PROGRESS)rD   r°   s   &&r.   Úon_tool_progressÚ&GatewayStreamConsumer.on_tool_progressö   s   € çØ�K‰K�O‰Oœ^¨TÐ2Ö3ñ r-   c               ó   € V ^8„  d   QhRR/# )r=   r>   r   r"   )r?   s   "r.   r@   rT   û   s   € ÷ Oñ O¨ñ Or-   c                ó€   € RP                  V P                  4      pRP                  R V P                  V3 4       4      # )zFNative frame content: text, with any tool-progress lines below a rule.Ú
z

---
c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5i©Nr"   )Ú.0Úps   & r.   Ú	<genexpr>Ú?GatewayStreamConsumer._compose_frame_content.<locals>.<genexpr>þ   s   é € ÐNÑ+H aËA§¢Ó+Hùs   ‚	�
)Újoinr•   rŽ   )rD   Úprogresss   & r.   Ú_compose_frame_contentÚ,GatewayStreamConsumer._compose_frame_contentû   s8   € à—9‘9˜T×6Ñ6Ó7ˆØ×ÑÑN¨D×,=Ñ,=¸xÑ+HÓNÓNÐNr-   ÚfinalFÚexpect_editsc               ó$   € V ^8„  d   QhRRRRRR/# )r=   rÃ   r   rÄ   r>   zdict | Noner"   )r?   s   "r.   r@   rT      s"   € ÷ ñ ¨4ð Àtð ÐXcñ r-   c               óâ   € V P                   '       d   \        V P                   4      M/ pV P                  '       d   V P                  VR&   V'       d   RVR&   V'       d   RVR&   T;'       g    R# )uÕ   Per-send metadata.  ``final`` â†’ notify=True (Mattermost treats notify-worthy sends
as final when a broken thread root may fall back flat); ``expect_edits`` keeps
editable previews on Telegram's legacy send path.Úreply_to_message_idTrÄ   ÚnotifyN)rO   Údictr_   )rD   rÃ   rÄ   Úmetas   &$$ r.   Ú_metadata_for_sendÚ(GatewayStreamConsumer._metadata_for_send   s^   € ð '+§m§m mŒt�D—M‘MÔ"¸ˆØ×$×$Ð$Ø*.×*CÑ*CˆDÐ&Ñ'ßØ#'ˆD�Ñ ßØ!ˆD�‰NØ�|ˆ|�tÐr-   c                	ó   € V P                   # rº   )rm   rC   s   &r.   rW   ÚGatewayStreamConsumer.<lambda>  s
   € ¨×);Ò);r-   c                	ó   € V P                   # rº   )r›   rC   s   &r.   rW   rÎ     s
   € °×0IÒ0Ir-   c                	ó   € V P                   # rº   )rŒ   rC   s   &r.   rW   rÎ     s
   €  t×'7Ò'7r-   c                	ó   € V P                   # rº   )rœ   rC   s   &r.   rW   rÎ     s
   € °D×4QÒ4Qr-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT     s   € ÷ 	!ñ 	!¨tñ 	!r-   c              ƒ  óR  "  € V P                   '       d   R# RV n         V P                  ed   \        P                  ! \        4      ;_uu_ 4        V P                  4       p\
        P                  ! V4      '       d   VG Rj  x€L
  RRR4       R# R#  L  + '       g   i     R# ; i5i)z?Run the pre-finalize hook exactly once, swallowing hook errors.NT)rw   r^   Ú
contextlibÚsuppressr§   ÚinspectÚisawaitable)rD   Úresults   & r.   Ú_notify_before_finalizeÚ-GatewayStreamConsumer._notify_before_finalize  s|   é € à×)×)Ð)ÙØ)-ˆÔ&Ø×#Ñ#Ò/Ü×$Ò$¤Y×/Õ/Ø×1Ñ1Ó3�Ü×&Ò& v×.Ò.Ø —L�L÷ 0Ñ/ñ 0ñ !÷ 0×/Ð/üs0   ‚AB'Á2BÂ BÂBÂB'ÂBÂB$	Â	B'c               ó    € V ^8„  d   QhRRRR/# ©r=   Útextr   r>   rŠ   r"   )r?   s   "r.   r@   rT     s   € ÷ $ñ $¨ð $°ñ $r-   c                óä   € V'       g   R# V P                   '       d"   V P                   P                  4        RV n        V ;P                  V,          un        V ;P                  V,          un        R# )z=Append to the live buffer and the split-stable stream ledger.NF)r•   Úclearr–   rŽ   r�   ©rD   rÝ   s   &&r.   Ú_append_accumulatedÚ)GatewayStreamConsumer._append_accumulated  sP   € çÙØ×$×$Ð$Ø×%Ñ%×+Ñ+Ô-Ø).ˆDÔ&Ø×Ò˜TÕ!ÕØ×Ò˜tÕ#×r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   (  s   € ÷ 1ñ 1¨tñ 1r-   c                ó>  € V P                   ;'       g    V P                  pV P                  P                  '       dO   VP	                  V P                  P                  4      '       d$   VR\        V P                  P                  4      )  pV P                  VR7       R# )zëMark the turn final as delivered by a prior mid-stream edit.  Records what was
ACKED on the wire, not ``_accumulated``: a throttled stream's last ack may be an
older cursor-suffixed preview, which must not suppress the corrective send.N©Úrecord)r�   rŽ   r\   r   ÚendswithÚlenÚ_mark_final_delivered)rD   Úackeds   & r.   Ú_mark_skip_redundant_finalizeÚ3GatewayStreamConsumer._mark_skip_redundant_finalize(  sn   € ð ×$Ñ$×9Ð9¨×(9Ñ(9ˆØ�8‰8�?�?ˆ?˜uŸ~™~¨d¯h©h¯o©o×>Ò>ØÐ1œS §¡§¡Ó1Ð1Ð2ˆEØ×"Ñ"¨%Ð"Ö0r-   c               ó    € V ^8„  d   QhRRRR/# )r=   ræ   r7   r>   rŠ   r"   )r?   s   "r.   r@   rT   1  s   € ÷ 4ñ 4¨Mð 4ÀTñ 4r-   c                óP   € RV n         RV n        Ve   V P                  V4       R# R# )zISet both turn-final flags; ``record`` also records the delivered payload.TN)r›   rœ   Ú_record_turn_final_payload)rD   ræ   s   &&r.   ré   Ú+GatewayStreamConsumer._mark_final_delivered1  s-   € à$(ˆÔ!ð )-ˆÔ%ØÒØ×+Ñ+¨FÖ3ñ r-   c               ó    € V ^8„  d   QhRRRR/# ©r=   rÝ   r   r>   r"   )r?   s   "r.   r@   rT   >  s   € ÷ Vñ V Sð V¨Sñ Vr-   c                óf   € \        T P                  T;'       g    R4      4      P                  4       # )zONormalize like ``_send_or_edit`` output: directive strip + fence close + strip.r    )r   Ú_clean_for_displayÚstriprà   s   &&r.   Ú_display_payloadÚ&GatewayStreamConsumer._display_payload>  s'   € ä(¨×)@Ñ)@ÀÇÀÈÓ)LÓM×SÑSÓUÐUr-   c               ó    € V ^8„  d   QhRRRR/# rÜ   r"   )r?   s   "r.   r@   rT   B  s   € ÷ Añ A¨sð A°tñ Ar-   c                ó’   € V P                   '       d   V P                  '       d   V P                  pV P                  V4      V n        R# )uù   Record what the user actually saw as this turn's final answer.  On a split ``text``
is only the trailing chunk, so the un-truncated ``_stream_ledger`` is recorded â€” else
the gateway sees a mismatch and re-sends an answer the user already received.N)rž   r�   rö   r�   rà   s   &&r.   rï   Ú0GatewayStreamConsumer._record_turn_final_payloadB  s9   € ð ×$×$Ð$¨×)<×)<Ð)<Ø×&Ñ&ˆDØ%)×%:Ñ%:¸4Ó%@ˆÖ"r-   c               ó    € V ^8„  d   QhRRRR/# )r=   Ú
final_textr   r>   zOptional[bool]r"   )r?   s   "r.   r@   rT   J  s   € ÷ ;ñ ;°#ð ;¸.ñ ;r-   c                ój  € V P                  V4      pV'       g   R# V P                  e7   V P                  P                  4       V8H  ;'       g    V P                  V4      # V P                  '       d   R# V P
                  '       d   V P                  V4      '       d   R# V P                  '       d   R# R# )a~  Tri-state reconcile of the recorded turn-final payload against ``final_text`` (a
*successful* finalize edit can still carry a stale preview, so call success alone
must not confirm delivery).  True: recorded payload (or an earlier segment /
commentary) matches.  False: payload differs, or payload-less split.  None: nothing
recorded on a legacy/ambiguous path (caller trusts flags).NFT)rö   r�   rõ   Úhas_delivered_textrž   rm   rŸ   )rD   rü   Útargets   && r.   Údelivered_final_matchesÚ-GatewayStreamConsumer.delivered_final_matchesJ  s    € ð ×&Ñ& zÓ2ˆßÙØ×%Ñ%Ò1à×.Ñ.×4Ñ4Ó6¸&Ñ@÷ ;ð ;Ø×.Ñ.¨zÓ:ð<à×$×$Ð$Ùð ××Ð $×"9Ñ"9¸*×"EÒ"EÙà×/×/Ð/ˆtÐ:°UÐ:r-   c               ó    € V ^8„  d   QhRRRR/# ©r=   rÝ   r   r>   r   r"   )r?   s   "r.   r@   rT   h  s   € ÷ Mñ M sð M¨tñ Mr-   c                óD  a€ T P                  T;'       g    R4      P                  4       oV P                  4       .V P                  OV P                  O5p\        S4      ;'       d;    \        ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      # )zDReturn True if *text* was already delivered as visible chat content.r    c              3  óH   <"  € T F  qP                  4       S8H  x € K  	  R # 5irº   ©rõ   ©r»   Úsentrÿ   s   & €r.   r½   Ú;GatewayStreamConsumer.has_delivered_text.<locals>.<genexpr>m  ó   øé € Ð#LÁt¸t§J¡J£L°FÖ$:Ãtùó   ƒ"TF)rô   rõ   Ú_visible_prefixrs   rt   r   Úany©rD   rÝ   Úseenrÿ   s   && @r.   rþ   Ú(GatewayStreamConsumer.has_delivered_texth  s…   ø€ à×(Ñ(¨¯¨°Ó4×:Ñ:Ó<ˆØ×$Ñ$Ó&ð 0¨×)IÑ)Ið 0Ø×.Ñ.ñ0ˆä�F‹|×LÐL§£Ô#LÁtÓ#L§¤ÐL¢ÐL Ô#LÁtÓ#LÓ LÐLr-   c               ó    € V ^8„  d   QhRRRR/# r  r"   )r?   s   "r.   r@   rT   o  s   € ÷ 	Mñ 	M¨sð 	M°tñ 	Mr-   c                ó†  a€ T P                  T;'       g    R4      P                  4       o. V P                  OV P                  OpV P                  '       d    VP                  V P                  4       4       \        S4      ;'       d;    \        ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      # )ud  ``has_delivered_text`` restricted to deliveries that outlive the turn: commentary and
finalized segments always count; the visible prefix only once ``_already_sent`` (a draft frame
sets ``_last_sent_text`` but is ephemeral â€” a failed finalize send after it must still fall
back to the gateway's real final send, same gate as ``delivered_final_matches``).r    c              3  óH   <"  € T F  qP                  4       S8H  x € K  	  R # 5irº   r  r  s   & €r.   r½   ÚCGatewayStreamConsumer.has_durably_delivered_text.<locals>.<genexpr>x  r
  r  TF)	rô   rõ   rs   rt   rm   Úappendr  r   r  r  s   && @r.   Úhas_durably_delivered_textÚ0GatewayStreamConsumer.has_durably_delivered_texto  s•   ø€ ð
 ×(Ñ(¨¯¨°Ó4×:Ñ:Ó<ˆØR�×1Ñ1ÐR°D×4QÑ4QÐRˆØ××ÐØ�K‰K˜×,Ñ,Ó.Ô/Ü�F‹|×LÐL§£Ô#LÁtÓ#L§¤ÐL¢ÐL Ô#LÁtÓ#LÓ LÐLr-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   z  s   € ÷ &ñ & $ñ &r-   c                óD   € V P                   P                  \        4       R# )z>Finalize the current stream segment and start a fresh message.N)rj   r²   Ú_NEW_SEGMENTrC   s   &r.   Úon_segment_breakÚ&GatewayStreamConsumer.on_segment_breakz  s   € à�‰�‰œÖ%r-   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r=   Úplaceholderz
str | NoneÚreasonr   Úreopenr   r>   zasyncio.Futurer"   )r?   s   "r.   r@   rT   ~  s,   € ÷ /ñ /Ø%ð/Ø69ð/ØPTð/à	ñ/r-   c                ó  € Rp\         P                  ! \        4      ;_uu_ 4        \        P                  ! 4       pRRR4       V'       d   VP                  4       M\        P                  P                  4       pV P                  '       g   VP                  R4       V# T;'       g    \        V n        T;'       g    RV n        \        V4      V n        RR/pV P                   P#                  \$        WV34       WV3#   + '       g   i     LÉ; i)aû  Queue an interaction boundary (approval / clarify prompt) from sync context.
run() finalizes the current native stream (``placeholder`` when empty), then per
``reopen``: False (approval; unbounded waits) degrades to one send() at got_done;
True (clarify) keeps native enabled so post-prompt output re-opens a fresh stream.
Returns (Future, cancelled_flag); the Future resolves True once processed
(cancelled_flag is legacy, no longer read).  Without native streaming returns a
bare, already-resolved Future.NTr[   Ú	cancelledF)rÔ   rÕ   ÚRuntimeErrorÚasyncioÚget_running_loopÚcreate_futureÚ
concurrentÚfuturesÚFuturer}   Ú
set_resultr€   r�   r‚   r   rƒ   rj   r²   Ú_APPROVAL_BOUNDARY)rD   r  r  r   ÚloopÚboundary_futureÚcancelled_flags   &&&&   r.   Úclose_for_approval_promptÚ/GatewayStreamConsumer.close_for_approval_prompt~  sÍ   € ð ˆÜ× Ò ¤×.Õ.Ü×+Ò+Ó-ˆD÷ /ç26˜$×,Ñ,Ô.¼J×<NÑ<N×<UÑ<UÓ<WˆØ×)×)Ð)Ø×&Ñ& tÔ,Ø"Ð"à%0×%QÐ%QÔ4QˆÔ"Ø &× 4Ð 4¨*ˆÔÜ $ V£ˆÔØ% uÐ-ˆØ�‰�‰Ô+¨_ÐMÔNØÐ.Ð.÷ /×.ús   ¥C<Ã<D	c               ó    € V ^8„  d   QhRRRR/# rÜ   r"   )r?   s   "r.   r@   rT   —  s   € ÷ 1ñ 1 #ð 1¨$ñ 1r-   c                ó\   € V'       d$   V P                   P                  \        V34       R# R# )z7Queue a completed interim assistant commentary message.N)rj   r²   Ú_COMMENTARYrà   s   &&r.   Úon_commentaryÚ#GatewayStreamConsumer.on_commentary—  s   € çØ�K‰K�O‰Oœ[¨$Ð/Ö0ñ r-   c               ó    € V ^8„  d   QhRRRR/# )r=   Útimeoutr   r>   r   r"   )r?   s   "r.   r@   rT   œ  s   € ÷ 	:ñ 	:¨%ð 	:¸$ñ 	:r-   c                óÞ   € \         P                  ! 4       p V P                  P                  \        V34       TP                  \        R\        T4      4      R7      #   \
         d     R# i ; i)uê   Block the agent worker thread until everything queued so far is delivered:
``(_FLUSH, Event)`` barrier â€” run() drains earlier items (FIFO), finalizes the
segment, sets the event.  False on timeout (consumer task may not be running).Fr   )r7  )	Ú	threadingÚEventrj   r²   Ú_FLUSHr§   ÚwaitÚmaxr   )rD   r7  Úevts   && r.   Úflush_pending_syncÚ(GatewayStreamConsumer.flush_pending_syncœ  s[   € ô �oŠoÓˆð	Ø�K‰K�O‰OœV S˜MÔ*ð �x‰x¤ C¬¨w«Ó 8ˆxÓ9Ð9øô ô 	Úð	ús   —!A ÁA,Á+A,c               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   §  s   € ÷ 4ñ 4 dñ 4r-   c                ót   € V P                   ;'       d&    V P                  ;'       d    V P                  '       * # )zCNative stream, reopen requested after a boundary, nothing open yet.)r}   r„   r~   rC   s   &r.   Ú_reopen_seed_pendingÚ*GatewayStreamConsumer._reopen_seed_pending§  s8   € à×*Ñ*÷ 3ð 3¨t×/SÑ/S÷ 3ð 3Ø×2Ñ2Ô2ð	4r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   ¬  s   € ÷ *ñ * Tñ *r-   c                ót   € V P                  4       '       d"   V P                  P                  \        4       R# R# )zªThread-safe: request an EAGER native re-seed after a clarify answer.  No-op unless
reopen-pending, so a stray call can't open a spurious bubble mid-stream or on approval.N)rC  rj   r²   Ú_REOPEN_SEEDrC   s   &r.   Úrequest_reopen_seedÚ)GatewayStreamConsumer.request_reopen_seed¬  s(   € ð ×$Ñ$×&Ò&Ø�K‰K�O‰OœLÖ)ñ 'r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   ²  s   € ÷ Iñ I Tñ Ir-   c                óš   €  V P                   e   V P                  4        R# R#   \         d    \        P                  RRR7        R# i ; i)z8Fire the on_new_message callback, swallowing any errors.Nzon_new_message callback errorT©Úexc_info)r]   r§   ÚloggerÚdebugrC   s   &r.   Ú_notify_new_messageÚ)GatewayStreamConsumer._notify_new_message²  sG   € ð	IØ×#Ñ#Ò/Ø×$Ñ$Ö&ñ 0øäô 	IÜ�L‰LÐ8À4ˆL×Hð	Iús   ‚$ ¤"A
Á	A
c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   »  s   € ÷ "ñ " dñ "r-   c                ó°   € V e>   \         P                  ! \        4      ;_uu_ 4        V P                  4        RRR4       R# R#   + '       g   i     R# ; i)zÕWake a thread blocked in flush_pending_sync(), swallowing errors.  Every loop path
that consumed a ``_FLUSH`` barrier (incl. early ``continue``) must call this; a
missed set stalls the caller for the full timeout.N)rÔ   rÕ   r§   rk   )r4   s   &r.   Ú_signal_flushÚ#GatewayStreamConsumer._signal_flushº  s<   € ð
 Ò"Ü×$Ò$¤Y×/Õ/Ø—‘Ô!÷ 0Ñ/ñ #ß/×/Ð/ús   §AÁA	Úpreserve_no_editc               ó    € V ^8„  d   QhRRRR/# )r=   rV  r   r>   rŠ   r"   )r?   s   "r.   r@   rT   Ã  s   € ÷ "ñ "¸ð "Èñ "r-   c               	ól  € V'       d   V P                   R 8X  d   R# V P                  V P                  4      P                  4       pV'       d   V P                  P                  V4       V P                  4        V P                  '       d+   V P                  4       '       g   V P                  4        R# R# R# )Ú__no_edit__N)
rŒ   rô   r�   rõ   rt   r  rx   ry   r©   Ú_bump_draft_id)rD   rV  Ú	finalizeds   &$ r.   Ú_reset_segment_stateÚ*GatewayStreamConsumer._reset_segment_stateÃ  sŠ   € ß × 0Ñ 0°MÔ AÙà×+Ñ+¨D×,@Ñ,@ÓA×GÑGÓIˆ	ßØ×)Ñ)×0Ñ0°Ô;ð 	×!Ñ!Ô#ð ×$×$Ð$¨T×-DÑ-D×-FÒ-FØ×ÑÖ!ñ .GÑ$r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   Ó  s   € ÷ 6ñ 6 ñ 6r-   c                	ó~   € \        V 4      ;P                  ^,          un        \        V 4      P                  V n        R# )é   N)r¥   rJ   rz   rC   s   &r.   rZ  Ú$GatewayStreamConsumer._bump_draft_idÓ  s(   € ÜˆT‹
×$Ò$¨Õ)Õ$Ü˜d›×5Ñ5ˆŽr-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   ×  s   € ÷ <ñ <ÐW[ñ <r-   c           	   ƒ  ó   "  € V P                   ;'       g    Rp RpV P                  '       d   V P                  V4      G Rj  x€L
 pV P                  '       d   V P	                  4        RV n        MV P                  4        V P                  4        V P                  '       d,   \        P                  RV P                  V P                  4       \        P                  ! \        4      ;_uu_ 4        \!        T\"        4      '       d(   TP%                  4       '       g   TP'                  T4       RRR4       R#  Lõ  \         d#   p\        P                  RY54       Rp Rp?L”Rp?ii ; i  + '       g   i     R# ; i  \        P                  ! \        4      ;_uu_ 4        \!        T\"        4      '       d(   TP%                  4       '       g   TP'                  X4       RRR4       i   + '       g   i     i ; i; i5i)zãSerially process an interaction boundary dequeued by run().  The stream is never
kept open across a prompt: the WeCom finalize ack only confirms server receipt, and
after a long idle gap the client may stop tracking the stream.r[   TNzd[latency] Clarify boundary finalized, awaiting first post-answer delta to re-seed (chat=%s, turn=%s)z!%s boundary processing failed: %sF)r‚   r~   Ú_finalize_boundary_streamrƒ   Ú_close_native_stater„   Ú _degrade_native_to_buffered_sendr\  rN  ÚinforM   rb   r§   ÚwarningrÔ   rÕ   Ú
isinstanceÚ_FUTURE_TYPESÚdoner*  )rD   r-  r.  Ú_reasonÚboundary_okÚes   &&&   r.   Ú_handle_approval_boundaryÚ/GatewayStreamConsumer._handle_approval_boundary×  sm  é € ð ×'Ñ'×5Ð5¨:ˆð	<ØˆKØ×)×)Ð)Ø$(×$BÑ$BÀ7Ó$K×K�Ø×$×$Ð$ð ×(Ñ(Ô*Ø7;�Õ4ð ×5Ñ5Ô7Ø×%Ñ%Ô'Ø×$×$Ð$Ü—‘ð Nà ŸL™L¨$¯-©-ô9ô ×$Ò$¤Y×/Õ/Ü˜o¬}×=Ò=Ào×FZÑFZ×F\ÒF\Ø#×.Ñ.¨{Ô;÷ 0Ñ/ñ' Løô ô 	 Ü�N‰NÐ>ÀÔKØ�Kûð	 ú÷ 0×/Ð/û”×$Ò$¤Y×/Õ/Ü˜o¬}×=Ò=Ào×FZÑFZ×F\ÒF\Ø#×.Ñ.¨{Ô;÷ 0×/×/Ð/ÿs•   ‚G>š(D: ÁD8ÁD: ÁA	D: Â#+D: Ã"G>Ã0,E*ÄE*Ä.
G>Ä8D: Ä:E'ÅE"ÅE> Å"E'Å'E> Å*E;	Å5	G>Å>#G;Æ!,G(	ÇG(	Ç	G;Ç(G8Ç3G;Ç;G>c               ó    € V ^8„  d   QhRRRR/# )r=   rl  r   r>   r   r"   )r?   s   "r.   r@   rT   ö  s   € ÷ ñ °sð ¸tñ r-   c              ƒ  ó´  "  € V P                   ;'       g    V P                  p V P                  VRR7      G Rj  x€L
 '       d.   \        P	                  RWP
                  V P                  4       R#  \        P                  RWP
                  4        \        V P                  P                  V P
                  V4      G Rj  x€L
 RR4      '       d   R#  \        P                  R
WP
                  4       R#  L½  \         d!   p\        P                  RY4        Rp?L­Rp?ii ; i Le  \         d!   p\        P                  R	Y4        Rp?LzRp?ii ; i5i)z’Close the open native stream at a boundary; send() the pre-prompt text if that
fails.  False only when both finalize and the fallback send failed.T©ÚfinalizeNz0%s boundary: finalized stream (chat=%s, turn=%s)z %s boundary: finalize failed: %szY%s boundary: finalize not confirmed, falling back to send() for pre-prompt text (chat=%s)ÚsuccessFz*%s boundary: fallback send also failed: %sum   %s boundary: both finalize and fallback send failed (chat=%s) â€” pre-prompt text may not have been delivered)rŽ   r�   Ú_send_framerN  rO  rM   rb   r§   rh  re   rL   ÚsendÚerror)rD   rl  Úfinalize_textrn  Úsend_errs   &&   r.   rd  Ú/GatewayStreamConsumer._finalize_boundary_streamö  s,  é € ð ×)Ñ)×GÐG¨T×-GÑ-Gˆð	KØ×%Ñ% m¸dÐ%ÓC×CÖCÜ—‘ÐOØ$§l¡l°D·M±MôCáð Dô 	�‰ð Nà§¡ô	.ð	\Ü˜TŸ\™\×.Ñ.¨t¯|©|¸]ÓK×KÈYÐX]×^Ò^Ùð _ô 	�‰ð QàŸl™lô	,ñ ñ% Døô ô 	KÜ�N‰NÐ=¸w×JÑJûð	Kúñ Løäô 	\Ü�N‰NÐGÈ×[Ñ[ûð	\üs€   ‚!E¤C: ºC8»	C: Á+C: Á0#EÂ.D* ÃD(ÃD* Ã%EÃ8C: Ã:D%ÄD ÄEÄ D%Ä%EÄ(D* Ä*EÄ5EÅEÅEÅEc               ó    € V ^8„  d   QhRRRR/# rÜ   r"   )r?   s   "r.   r@   rT     s   € ÷ $ñ $˜Sð $ Tñ $r-   c                ó|   € V'       d   V P                   P                  V4       R# Vf   V P                  4        R# R# )zÈThread-safe callback from the agent's worker thread.  ``None`` signals a tool
boundary: the current message is finalized and subsequent text goes out as a new
message below any tool-progress messages.N)rj   r²   r  rà   s   &&r.   Úon_deltaÚGatewayStreamConsumer.on_delta  s-   € ÷ Ø�K‰K�O‰O˜DÖ!ØŠ\Ø×!Ñ!Ö#ñ r-   c               ó    € V ^8„  d   QhRRRR/# )r=   rü   r7   r>   rŠ   r"   )r?   s   "r.   r@   rT     s   € ÷ ñ  ð ¸$ñ r-   c                óŽ   € Ve"   V P                   P                  \        V34       V P                   P                  \        4       R# )zôSignal stream completion.  ``final_text`` is the AUTHORITATIVE completed
final_response (incl. post-stream augmentation the accumulator never saw); the drain
loop adopts it as the finalize payload.  Interrupt/error paths call ``finish()`` bare.N)rj   r²   Ú_FINAL_TEXTÚ_DONE)rD   rü   s   &&r.   ÚfinishÚGatewayStreamConsumer.finish  s/   € ð Ò!Ø�K‰K�O‰Oœ[¨*Ð5Ô6Ø�‰�‰œÖr-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT      s   € ÷ L'ñ L'˜4ñ L'r-   c              ƒ  ó8  "  € V P                  4       w  V n        V n        V P                  4       G Rj  x€L
    V P	                  4       '       g,   V P                  4       G Rj  x€L
   V P                  4        R# V P                  4       pVP                  e%   V P                  ! VP                  !  G Rj  x€L
  K„  VP                  '       d   V P                  4       G Rj  x€L
  K°  VP                  '       df   V P                  4        \        V P                  V P                   4      4      '       d,   V P#                  4       G Rj  x€L
   V P                  4        R# V P%                  V4      '       Ed   V P                   '       g%   V P&                  '       dð   V P(                  '       dÞ   V P+                  4       G Rj  x€L
  V P&                  '       g›   V P-                  4       '       d…   V P/                  V4      G Rj  x€L
 '       d    V P                  4        R# V P-                  4       '       d=   V P1                  VP2                  4       \4        P6                  ! R4      G Rj  x€L
  EK9  V P9                  V4      G Rj  x€L
  VP                  '       d-   V P;                  V4      G Rj  x€L
   V P                  4        R# VP<                  e$   V P?                  VP<                  4      G Rj  x€L
  VP@                  '       d   V PC                  V4      G Rj  x€L
  VPD                  '       d   V P1                  VP2                  4       \4        P6                  ! R4      G Rj  x€L
  EK:   EL@ EL ELÃ ELš EL7 ELÁ ELƒ EL EL LÜ Lš Lq L(  \4        PF                   d    T PI                  4       G Rj  x€L 
   M-\J         d!   p\L        PO                  RT4        Rp?MRp?ii ; iT P                  4        R#   T P                  4        i ; i5i)z@Async task that drains the queue and edits the platform message.Ngš™™™™™©?zStream consumer error: %s)(Ú_resolve_length_budgetÚ_len_fnÚ_safe_limitÚ_start_transportsrc   Ú_abandon_native_streamÚ_wake_flush_waitersÚ_drain_queuer6   ro  r5   Ú_eager_reopen_seedr1   Ú_flush_think_bufferÚ _is_intentional_silence_responserô   rŽ   Ú_suppress_silence_markerÚ_should_editr}   r–   Ú_seal_overflow_headsÚ_first_send_overflowsÚ_split_first_sendrT  r4   r$  ÚsleepÚ_push_updateÚ_finalize_turnr8   Ú_deliver_commentaryr2   Ú_end_segmentr3   ÚCancelledErrorÚ_on_cancelledr§   rN  rx  )rD   Útickrn  s   &  r.   ÚrunÚGatewayStreamConsumer.run   sD  é € à)-×)DÑ)DÓ)FÑ&ˆŒ�dÔ&Ø×$Ñ$Ó&×&Ð&ðH	'Øà×.Ñ.×0Ò0Ø×5Ñ5Ó7×7Ð7ØðF ×$Ñ$Ö&ðE ×(Ñ(Ó*�ð ×)Ñ)Ò5Ø×8Ò8¸$×:PÑ:PÑQ×QÐQÙØ×'×'Ð'Ø×1Ñ1Ó3×3Ð3Ùà—=—=�=Ø×,Ñ,Ô.ô 8¸×8OÑ8OÐPT×PaÑPaÓ8b×cÒcØ"×;Ñ;Ó=×=Ð=Øð` ×$Ñ$Ö&ð] ×$Ñ$ T×*Ó*Ø×%×%Ð%¨$×*D×*DÐ*DÈ×Ic×IcÐIcð ×3Ñ3Ó5×5Ð5ð  ×5×5Ð5¸$×:TÑ:T×:VÒ:VØ!%×!7Ñ!7¸Ó!=×=Ö=Ø"ðD ×$Ñ$Ö&ðC  ×5Ñ5×7Ò7ð
 !×.Ñ.¨t×/?Ñ/?Ô@Ü")§-¢-°Ó"5×5Ð5Ú$ð ×+Ñ+¨DÓ1×1Ð1à—=—=�=Ø×-Ñ-¨dÓ3×3Ð3Øð& ×$Ñ$Ö&ð# ×'Ñ'Ò3Ø×2Ñ2°4×3GÑ3GÓH×HÐHØ×)×)Ð)Ø×+Ñ+¨DÓ1×1Ð1ð —>—>�>Ø×&Ñ& t×'7Ñ'7Ô8ä—m’m DÓ)×)Ó)òE 	'ò
 8ò Rò 4ò >ò 6ò >ò 6ò 2ñ 4ñ Iá1ñ *øä×%Ñ%ô 	'Ø×$Ñ$Ó&×&Ó&Üô 	9Ü�L‰LÐ4°a×8Ñ8ûð	9úð ×$Ñ$Ö&øˆD×$Ñ$Õ&üs¿  ‚1P³M3´P¹N ÁN Á#M6Á$N Á)PÁ;;N Â6M9Â7N ÃN Ã"M<Ã#N Ã;AN ÅM?Å	N ÅPÅ N Å8N Æ
N ÆN Æ.N ÇNÇN ÇN Ç.N ÈNÈ	N ÈPÈ N È64N É*NÉ+N ÊNÊN ÊN Ê1NÊ2N Ê7PË	,N Ë5NË6N ÌN Ì NÌ!N Ì74N Í+NÍ,N Í3PÍ6N Í9N Í<N Í?N ÎN ÎN ÎN ÎN ÎN ÎN ÎN ÎN Î(O0Î>OÎ?O0ÏP ÏO0ÏO0ÏO+Ï&P Ï+O0Ï0P Ï3PÐPÐPc               ó   € V ^8„  d   QhRR/# )r=   r>   z tuple[Callable[[str], int], int]r"   )r?   s   "r.   r@   rT   p  s   € ÷ [ñ [Ð(Hñ [r-   c                ó®   € V P                  4       w  rV\        RV P                  4       V! V P                  P                  4      ,
          ^d,
          4      3# )z¢Per-chat length function (relay adapters differ per chat, e.g. utf16) + budget.
isinstance gate: MagicMock auto-attributes aren't callables; test doubles use len.iô  )Ú_fallback_len_budgetr=  Ú_raw_message_limitr\   r   )rD   Úlen_fnÚ_s   &  r.   rˆ  Ú,GatewayStreamConsumer._resolve_length_budgetp  sG   € ð ×-Ñ-Ó/‰	ˆØ”s˜3 × 7Ñ 7Ó 9¹FÀ4Ç8Á8Ç?Á?Ó<SÕ SÐVYÕ YÓZÐZÐZr-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   y  s   € ÷ 7ñ 7¨ñ 7r-   c              ƒ  óØ  "  € V P                  4       V n        V P                  '       dY   \        P                  RV P                  4       V P                  RRR7      G Rj  x€L
 '       d   RV n        RV n        R# RV n        V P                  4       V n        V P                  '       d>   V P                  4        \        P                  RV P                  V P                  4       R# R#  L‡5i)u¥   Resolve native/draft transport; native wins (adapters declaring it can't edit).
The empty seed frame shows "typing" before the first token; on failure â†’ edit path.z7Stream consumer using native-stream transport (chat=%s)z4Native streaming seed frame raised; disabling nativeTrL  NFzBStream consumer using native-draft transport (chat=%s draft_id=%s))Ú_resolve_native_streamingr}   rN  rO  rM   Ú_try_seed_framer~   ry   Ú_resolve_draft_streamingrZ  rz   rC   s   &r.   r‹  Ú'GatewayStreamConsumer._start_transportsy  sÉ   é € ð &*×%CÑ%CÓ%EˆÔ"Ø×%×%Ð%Ü�L‰LÐRÐTX×T`ÑT`ÔaØ×)Ñ)Ð*`Ø37ð *ó 9÷ 9ö 9à-1�Ô*Ø,1�Ô)ÙØ).ˆDÔ&Ø$(×$AÑ$AÓ$CˆÔ!ð ×$×$Ð$Ø×ÑÔ!Ü�L‰LÐ]ØŸ™ t§~¡~ö7ñ %ñ9ùs   ‚AC*Á C(Á!	C*Á+=C*Â)A C*c               ó   € V ^8„  d   QhRR/# )r=   r>   r0   r"   )r?   s   "r.   r@   rT   �  s   € ÷ &2ñ &2˜eñ &2r-   c                ó  € \        4       p  V P                  P                  4       pT\
        J d
   RTn        T# T\        J d
   RTn        T# T\        J d
   RTn
        T# \        T\        4      '       d   T'       d
   T^ ,          MRpT\        J d   T P                  T^,          4       K¢  T\        J d@   T P                   '       d,   T P"                  P%                  T^,          4       RT n        Ké  Kë  T\(        J d   T^,          T^,          3Tn        T# T\,        J d   T^,          Tn        T# T\0        J d   R;Tn        Tn        T^,          Tn        T# T P7                  T4       EKd    \        P                   d    Tu # i ; i)zÅDrain everything queued so far into one tick.  Control sentinels stop the drain
(they take effect this tick); _FINAL_TEXT / _TOOL_PROGRESS / text deltas fold into
state so simultaneous items batch.TN)r0   rj   Ú
get_nowaitrh   ÚEmptyrƒ  r1   r  r2   rG  r5   ri  Útupler‚  Ú_adopt_final_textr³   r}   r•   r  r–   r+  r6   r3  r8   r;  r3   r4   Ú_filter_and_accumulate)rD   rž  ÚitemÚkinds   &   r.   rŽ  Ú"GatewayStreamConsumer._drain_queue�  s]  € ô ‹wˆØðØ—{‘{×-Ñ-Ó/�ð ”u‹}Ø $�”Ø�Ø”|Ó#Ø)-�Ô&Ø�Ø”|Ó#Ø'+�Ô$Ø�Ü(¨¬u×5Ò5¿$�4˜–7ÀDˆDØ”{Ó"Ø×&Ñ& t¨A¥wÖ/ØœÓ'Ø×-×-Ð-Ø×-Ñ-×4Ñ4°T¸!µWÔ=Ø15�DÖ.ñ .ð Ô+Ó+Ø*.¨q­'°4¸µ7Ð);�Ô&Ø�ØœÓ$Ø'+¨A¥w�Ô$Ø�Øœ“à:>Ð>�” Ô!7Ø#'¨¥7�Ô Ø�à×+Ñ+¨D×1øô= —;‘;ô Ø’ðús   �E/ Å/F	ÆF	c               ó    € V ^8„  d   QhRRRR/# )r=   Ú	final_rawr   r>   rŠ   r"   )r?   s   "r.   r@   rT   ¸  s   € ÷ ,ñ ,¨3ð ,°4ñ ,r-   c                ó  € V P                   '       g'   V P                  '       g   V P                  '       g   R# V P                  '       gG   V P	                  V4      pV'       d,   W P	                  V P                   4      8w  d   Wn         Wn        R# V P
                  pV'       db   VP                  V4      '       dI   \        V4      \        V4      8”  d.   V ;P                   V\        V4      R ,          un         Wn        R# R# R# R# )up  Adopt the authoritative final (see finish()) as the finalize content â€” only if this
consumer streamed something (a no-stream turn keeps the gateway's final-send
ownership).  Split delivery: wholesale adoption would repeat sealed heads, refusing
makes the gateway resend the ENTIRE body â€” so append only the suffix when the final
strictly prefix-extends the ledger.N)rŽ   rŒ   r�   rž   rô   r�   Ú
startswithrè   )rD   r¹  Úfinal_payloadÚledgers   &&  r.   r³  Ú'GatewayStreamConsumer._adopt_final_text¸  sÇ   € ð ×!×!Ð! T×%5×%5Ð%5¸×9M×9MÐ9MÙØ×(×(Ð(Ø ×3Ñ3°IÓ>ˆMß ×2IÑ2IÈ$×J[ÑJ[Ó2\Ô!\Ø$-Ô!Ø&/Ô#ÙØ×$Ñ$ˆß�i×*Ñ*¨6×2Ò2´s¸9³~ÌÈFËÔ7SØ×Ò ¬3¨v«;¨<Ð!8Õ8ÕØ"+Öñ 8TÑ2‰6r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   Ë  s   € ÷ 4ñ 4¨$ñ 4r-   c              ƒ  ó  "  € V P                  4       '       g   R# V P                  R4      G Rj  x€L
 '       d?   RV n        ^ V n        RV n        RV n        \        P                  RV P                  4       R# V P                  4        R#  LZ5i)zâEager re-seed after a clarify answer (gate re-checked: state may have advanced).
Trade-off: WeCom's ~6-minute stream limit (errcode 846608, from the FIRST frame)
now starts at the reply instant; on expiry we degrade to send().Nz.Eager reopen seed raised, disabling native: %sTFzZ[latency] Eager re-seed after clarify answer (typing bubble reopened immediately, turn=%s))
rC  r«  r~   r   r„   r…   rN  rg  rb   rf  rC   s   &r.   r�  Ú(GatewayStreamConsumer._eager_reopen_seedË  s|   é € ð ×(Ñ(×*Ò*ÙØ×%Ñ%Ð&VÓW×WÖWØ)-ˆDÔ&Ø+,ˆDÔ(Ø38ˆDÔ0Ø*.ˆDÔ'Ü�K‰Kð HØIMÏÉöXð ×1Ñ1Ö3ñ Xùs   ‚-B¯B
°	BºABc               ó    € V ^8„  d   QhRRRR/# ©r=   rž  r0   r>   r   r"   )r?   s   "r.   r@   rT   Ü  s   € ÷ 8ñ 8 ð 8¨4ñ 8r-   c                ó€  € VP                   '       g   R# V P                  P                  '       d   R# V P                  '       d+   \	        V P
                  4      ;'       g    V P                  pMž\        P                  ! 4       V P                  ,
          p\	        W0P                  8¬  ;'       d    V P
                  ;'       gF    \        V P
                  4      V P                  P                  8¬  ;'       d    V P                  '       * 4      pT;'       d*    \        V P                  V P
                  4      4      '       * # )z/Decide whether this tick flushes an edit/frame.TF)rE   r\   r   r}   r   rŽ   r–   ÚtimeÚ	monotonicro   rr   rè   r   rq   Ú_is_partial_silence_markerrô   )rD   rž  Úshould_editÚelapseds   &&  r.   r“  Ú"GatewayStreamConsumer._should_editÜ  sü   € à��ˆÙØ�8‰8××ÐÙØ×%×%Ð%ä˜t×0Ñ0Ó1×OÐO°T×5OÑ5O‰Kä—n’nÓ&¨×)=Ñ)=Õ=ˆGô
  ×+FÑ+FÑ F× \Ð \È4×K\ÑK\÷  @ð  @Ü#& t×'8Ñ'8Ó#9¸T¿X¹X×=VÑ=VÑ#V÷ $?ð $?Ø+/×+>Ñ+>Ô'>óAˆKð
 ÷ 8ð 8Ô#=Ø×#Ñ# D×$5Ñ$5Ó6ó$8ô  8ð 	8r-   c               ó    € V ^8„  d   QhRRRR/# rÃ  r"   )r?   s   "r.   r@   rT   ó  s   € ÷ -ñ -¨Eð -°dñ -r-   c              ƒ  ó  "  € V P                  V P                  V P                  V P                  4      p\	        V4      ^8:  d2   V P                  V P                  V P                  V P                  4      pV P                  p\	        V4      ^8„  pVRR  F8  pV P                  WSVP                  R7      G Rj  x€L
 pVe   Wc8X  d   Rp MTpK:  	  V'       dB   VR,          pR\	        V4       R\	        V4       R2pVP                  V4      V n        RV n
        RV n        RV n        RV n        \        P                  ! 4       V n        VP                  '       d‡   V P                  '       * ;'       g&    V P#                  V P                  RR	7      G Rj  x€L
 p	T;'       d    T	V n        V P$                  '       d$   RV n
        V P'                  V P                  R
7       R# VP(                  '       d   RV n        RV n        R#  ELK Lq5i)zÕNo message to edit yet and the buffer overflows: seal only the head chunks; the
tail stays in _accumulated as the active preview later deltas edit in place.
True when the turn finished here (the run loop returns).N)rÃ   Fz (Ú/Ú)Tr    rs  rå   éÿÿÿÿ)Ú_truncate_for_streamrŽ   rŠ  r‰  rè   Ú_split_text_chunksr_   Ú_send_new_chunkr1   Úremovesuffixrž   rŒ   r�   r�   rÅ  rÆ  ro   Ú_send_or_editr›   ré   r2   r‘   r’   )
rD   rž  ÚchunksÚreply_toÚheads_deliveredÚchunkÚnew_idÚtailÚ	indicatorÚtail_delivereds
   &&        r.   r–  Ú'GatewayStreamConsumer._split_first_sendó  sÝ  é € ð ×*Ñ*¨4×+<Ñ+<¸d×>NÑ>NÐPT×P\ÑP\Ó]ˆÜˆv‹;˜!Ôà×,Ñ,¨T×->Ñ->À×@PÑ@PÐRV×R^ÑR^Ó_ˆFØ×,Ñ,ˆÜ˜f›+¨™/ˆØ˜C˜R“[ˆEØ×/Ñ/°ÀtÇ}Á}Ð/ÓU×UˆFØŠ~ Ô!3Ø"'�ÙØŠHñ !÷ ð ˜"•:ˆDØœS ›[˜M¨¬3¨v«;¨-°qÐ9ˆIØ $× 1Ñ 1°)Ó <ˆDÔð )-ˆDÔ%ð  ˆÔØ#'ˆÔ Ø!ˆÔÜ#Ÿ~š~Ó/ˆÔØ�=�=ˆ=Ø"&×"3Ñ"3Ô3÷ \ð \Ø'+×'9Ñ'9¸$×:KÑ:KÐVZÐ'9Ó'[×![ð ð )8×(JÐ(J¸NˆDÔ%Ø×(×(Ð(Ø,0�Ô)Ø×*Ñ*°$×2CÑ2CÐ*ÔDÙØ×!×!Ð!Ø(-ˆDÔ%Ø$&ˆDÔ!ÙòE Vñ0 "\ùsI   ‚B5HÂ7HÂ8HÃBHÅHÅ2!HÆHÆHÆ!HÆ;6HÇ2HÈHc               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   "  s   € ÷ Bñ B˜Dñ Br-   c                	óR   € V P                  V P                  4      V P                  8„  # rº   )r‰  rŽ   rŠ  rC   s   &r.   Ú
_overflowsÚ GatewayStreamConsumer._overflows"  s"   € Ø�|‰|˜D×-Ñ-Ó.°×1AÑ1AÑAÐAr-   c               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   %  s   € ÷ >ñ > tñ >r-   c                	óN   € V P                   R J ;'       d    V P                  4       # rº   )rŒ   rà  rC   s   &r.   r•  Ú+GatewayStreamConsumer._first_send_overflows%  s"   € Ø×Ñ 4Ð'×=Ð=¨D¯O©OÓ,=Ð=r-   c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   (  s   € ÷ -ñ -¨Dñ -r-   c              ƒ  ó8  "  € V P                  4       '       dþ   V P                  eî   V P                  '       dÚ   \        V P                  V P
                  V P                  4      pV P                  P                  R^ V4      pW!^,          8  d   TpV P                  RV pV P                  VRRR7      G Rj  x€L
 pV P                  '       g	   V'       g   R# V P                  VR P                  R4      V n        RV n        RV n        RV n        EK  R# R# R#  La5i)zVExisting message overflowing: seal it with the head, start a new message for the rest.Nr¸   TF©rt  Úis_turn_finalr    )rà  rŒ   rn   r   rŽ   rŠ  r‰  ÚrfindrÔ  r‘   Úlstripr�   rž   )rD   Ú	cp_budgetÚsplit_atrØ  Úoks   &    r.   r”  Ú*GatewayStreamConsumer._seal_overflow_heads(  sü   é € à�o‰o×Ò D×$4Ñ$4Ò$@ÀT×EY×EYÐEYÜ*¨4×+<Ñ+<¸d×>NÑ>NÐPT×P\ÑP\Ó]ˆIØ×(Ñ(×.Ñ.¨t°Q¸	ÓBˆHØ q�.Ô(Ø$�Ø×%Ñ% i xÐ0ˆEð ×)Ñ)¨%¸$ÈeÐ)ÓT×TˆBØ×(×(Ð(·ÙØ $× 1Ñ 1°(°)Ð <× CÑ CÀDÓ IˆDÔØ#ˆDÔØ#%ˆDÔ Ø(,ˆD×%ñ FZÑ$@Ññ Uùs)   ‚D™D¹A=DÂ6DÂ7DÃDÃADc               ó    € V ^8„  d   QhRRRR/# ©r=   rž  r0   r>   rŠ   r"   )r?   s   "r.   r@   rT   ;  s   € ÷ +ñ + uð +°ñ +r-   c              ƒ  ó”  "  € V P                   pVP                  '       d€   V P                  '       dR   V P                  4       pV'       d9   V P                  P
                  '       d   W P                  P
                  ,          pMW P                  P
                  ,          pVP                  ;'       d#    V P                  ;'       d    V P                  RJ Vn	        T P                  Y!P                  ;'       g    VP                  VP                  R7      G Rj  x€L
 Vn        \        P                  ! 4       V n        RV n        R#  L,5i)zGSend/edit this tick's visible text (cursor-suffixed unless finalizing).Nrç  F)rŽ   rE   r}   rÁ   r\   r   r1   ry   rŒ   r:   rÔ  r2   r9   rÅ  rÆ  ro   r–   )rD   rž  Údisplay_texts   && r.   r˜  Ú"GatewayStreamConsumer._push_update;  sû   é € à×(Ñ(ˆØ�?�?ˆ?Ø×)×)Ð)Ø#×:Ñ:Ó<�ß D§H¡H§O§O OØ §H¡H§O¡OÕ3�Løà§¡§¡Õ/�ð (,§}¡}÷ (Dð (D¸×9RÑ9R÷ (Dð (DØ+/×+;Ñ+;¸tÐ+Cð 	Ô#ð
 %)×$6Ñ$6Ø§=¡=×#JÐ#J°D×4JÑ4JØŸ-™-ð %7ó %)÷ )ˆÔô  $Ÿ~š~Ó/ˆÔà%*ˆÖ"ñ)ùs5   ‚0E³EÁEÁ'AEÂ3EÃ1EÃ9 EÄEÄ-Ec               ó    € V ^8„  d   QhRRRR/# rð  r"   )r?   s   "r.   r@   rT   T  s   € ÷ 1ñ 1¨ð 1°4ñ 1r-   c              ƒ  óv  "  € V P                   '       g!   V P                  f   V P                  '       d   V P                  4       G Rj  x€L
  V P	                  4       '       d5   V P                   '       g#   \
        P                  RV P                  4       R# V P                  '       dr   V P                  '       d`   V P                   '       gN   VP                  '       g<   V P                  R4      G Rj  x€L
  \
        P                  RV P                  4       R# V P                  '       dV   VP                  '       g2   T P                  V P                   ;'       g    RRR7      G Rj  x€L
  R# V P                  4        R# V P                   '       d   V P                  V4      G Rj  x€L
  R# R#  ELh L¿ LL L5i)zNgot_done: final edit without cursor, or one continuation send if edits failed.Nud   Clarify reopen boundary with no post-prompt content â€” skipping lone-placeholder finalize (turn=%s)z$Eager-seed empty finalize failed: %suU   Eager reopen seed but no post-answer content â€” closed empty typing bubble (turn=%s)u   âœ…Frå   )rŽ   rŒ   rm   rÙ   rC  rN  rO  rb   r…   r~   r9   Ú_close_empty_native_bubbler}   Ú_finalize_editré   Ú_finalize_edit_path©rD   rž  s   &&r.   r™  Ú$GatewayStreamConsumer._finalize_turnT  sV  é € à××Ð × 0Ñ 0Ò <À×@R×@RÐ@RØ×.Ñ.Ó0×0Ð0Ø×$Ñ$×&Ò&¨t×/@×/@Ð/@ô �L‰Lð LØMQÏ]É]ö\à×)×)Ð)¨d×.H×.HÐ.HØ×'×'Ð'°×0C×0CÐ0Cð ×1Ñ1Ð2XÓY×YÐYÜ�L‰Lð @ØAEÇÁöPà×'×'Ð'ð ×&×&Ð&Ø×)Ñ)¨$×*;Ñ*;×*DÐ*D¸uÈUÐ)ÓS×SÒSà×*Ñ*Ö,Ø××ÐØ×*Ñ*¨4Ó0×0Ò0ñ ò) 1ñ Zñ Tñ 1ùsˆ   ‚2F9µF9ÁF0Á	F9Á#F9Á53F9Â)F9Â;F9ÃF9ÃF9Ã3F3Ã47F9Ä,F9Ä>F9ÅF9Å(F5Å))F9ÆF9Æ'F7Æ(	F9Æ3F9Æ5F9Æ7F9c               ó    € V ^8„  d   QhRRRR/# rð  r"   )r?   s   "r.   r@   rT   n  s   € ÷ 9ñ 9¨eð 9¸ñ 9r-   c              ƒ  óü  "  € V P                   '       d&   V P                  V P                  4      G Rj  x€L
  R# V P                  '       d   V P	                  V P                  R7       R# VP
                  '       dI   V P                  '       d%   V P                  '       g   VP                  '       d   V P                  4        R# V P                  '       de   V P                  V P                  4      G Rj  x€L
 '       g:   V P                   '       d&   V P                  V P                  4      G Rj  x€L
  R# R# R# V P                  '       g&   V P                  V P                  4      G Rj  x€L
  R# R#  EL@ L� LH L5i)zNEdit-transport finalize (the non-native got_done branches, in priority order).Nrå   )r‘   Ú_send_fallback_finalrŽ   r›   ré   r9   rf   rp   r:   rë   rŒ   r÷  rm   rù  s   &&r.   rø  Ú)GatewayStreamConsumer._finalize_edit_pathn  s!  é € à×$×$Ð$Ø×+Ñ+¨D×,=Ñ,=Ó>×>Ò>Ø×&×&Ð&à×&Ñ&¨d×.?Ñ.?Ð&Ö@Ø× × Ð ¨$×*I×*IÐ*IØ)-×)C×)CÐ)CÀt×Gb×GbÐGbð ×.Ñ.Ö0Ø××Ðð ×,Ñ,¨T×->Ñ->Ó?×?Ö?ÀD×D]×D]ÐD]Ø×/Ñ/°×0AÑ0AÓB×BÒBñ E^Ñ?à×#×#Ð#ð ×%Ñ% d×&7Ñ&7Ó8×8Ò8ñ	 $ò ?ñ @ÙBñ
 9ùs{   ‚1E<³E3´E<Á/E<Á<E<ÂE<Â E<Â2#E<ÃE<Ã4E6Ã5	E<Ã?E<ÄE<Ä/E8Ä0E<ÅE<Å*E:Å+	E<Å6E<Å8E<Å:E<ræ   Tc               ó$   € V ^8„  d   QhRRRRRR/# )r=   rÝ   r   ræ   r   r>   r"   )r?   s   "r.   r@   rT   †  s!   € ÷ )ñ )¨ð )¸ð )Èñ )r-   c             ƒ  óÂ   "  € V P                  VRR7      G Rj  x€L
 V n        V P                  '       d   T P                  V'       d   TMRR7       V P                  #  LC5i)zRfinalize=True send_or_edit; on success mark the turn delivered (+ record payload).Trs  Nrå   )rÔ  r›   ré   )rD   rÝ   ræ   s   &&$r.   r÷  Ú$GatewayStreamConsumer._finalize_edit†  sS   é € à*.×*<Ñ*<¸TÈDÐ*<Ó*Q×$QˆÔ!Ø×$×$Ð$Ø×&Ñ&·f©dÀ$Ð&ÔGØ×(Ñ(Ð(ñ %Rùs   ‚A™AšAµAÁAc               ó   € V ^8„  d   QhRR/# r<   r"   )r?   s   "r.   r@   rT   �  s   € ÷ :ñ : tñ :r-   c                óv   € V P                  4       ;'       d    V P                  pT;'       g    V P                  # )zOStream-is-the-message drafts and WeCom native: one append-only stream per turn.)r©   ry   r}   )rD   Ústream_drafts   & r.   Ú_cumulative_transportÚ+GatewayStreamConsumer._cumulative_transport�  s2   € à×.Ñ.Ó0×NÐN°T×5NÑ5NˆØ×9Ð9˜t×9Ñ9Ð9r-   c               ó    € V ^8„  d   QhRRRR/# )r=   r8   r   r>   rŠ   r"   )r?   s   "r.   r@   rT   ’  s   € ÷ 	(ñ 	(¸ð 	(Àñ 	(r-   c              ƒ  óü   "  € V P                  4       pV'       g   V P                  4        V P                  V4      G Rj  x€L
  \        P                  ! 4       V n        V'       g   V P                  4        R# R#  L:5i)už   Post commentary as its own message.  Cumulative transports keep the stream going â€”
resetting _accumulated would break the append-only invariant / lose text.N)r  r\  Ú_send_commentaryrÅ  rÆ  ro   )rD   r8   Ú
cumulatives   && r.   rš  Ú)GatewayStreamConsumer._deliver_commentary’  s`   é € ð ×/Ñ/Ó1ˆ
ßØ×%Ñ%Ô'Ø×#Ñ# OÓ4×4Ð4Ü#Ÿ~š~Ó/ˆÔßØ×%Ñ%Ö'ñ ñ 	5ùs   ‚=A<¿A:Á %A<Á&A<c               ó    € V ^8„  d   QhRRRR/# rð  r"   )r?   s   "r.   r@   rT   �  s   € ÷ 9ñ 9 uð 9°ñ 9r-   c              ƒ  ó   "  € V P                  4       '       d   R# V P                  '       d<   VP                  '       g*   V P                  R8w  d   V P	                  4       G Rj  x€L
  V P                  RR7       R#  L5i)uÍ  Tool boundary: edit-based transports reset so the next chunk is a fresh message.
Cumulative transports must NOT reset â€” clearing _accumulated makes the next frame a
non-prefix snapshot and the connector re-appends the whole answer.  preserve_no_edit:
"__no_edit__" (platform never returned a real id â€” Signal, github_comment webhook)
must keep its sentinel or every tool boundary posts a new message; the
continuation goes out once via _send_fallback_final.NrY  T)rV  )r  rŽ   r9   rŒ   Ú#_flush_segment_tail_on_edit_failurer\  rù  s   &&r.   r›  Ú"GatewayStreamConsumer._end_segment�  sh   é € ð ×%Ñ%×'Ò'Ùð ××Ð d×&9×&9Ð&9Ø×$Ñ$¨Ô5Ø×:Ñ:Ó<×<Ð<Ø×!Ñ!°4Ð!Ö8ñ =ùs   ‚*A>­A>¿$A>Á#A<Á$A>c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   ®  s   € ÷ Añ A Tñ Ar-   c           
   ƒ  óþ  "  € RpV P                   '       dn   V P                  '       d\   \        P                  ! \        4      ;_uu_ 4        \        V P                  V P                   RRR7      G Rj  x€L
 4      pRRR4       M&V P                  f   V P                  4       G Rj  x€L
  V'       d3   V P                  '       g   V P                  V P                   R7       R# R# R#  Ls  + '       g   i     LN; i LU5i)u  Best-effort final edit on task cancel: finalize=True so REQUIRES_EDIT_FINALIZE
platforms apply formatting; is_turn_final=False because this handler owns the flags.
Only a successful edit confirms delivery â€” a partial send may be just "Let me
searchâ€¦", not the answer.FTrç  Nrå   )
rŽ   rŒ   rÔ   rÕ   r§   r   rÔ  rŒ  r›   ré   )rD   Úbest_effort_oks   & r.   r�  Ú#GatewayStreamConsumer._on_cancelled®  sÏ   é € ð
 ˆØ××Ð ×!1×!1Ð!1Ü×$Ò$¤Y×/Õ/Ü!%¨D×,>Ñ,>Ø×%Ñ%°ÀEð -?ó -K÷ 'Kó "L�÷ 0Ð/ð ×ÑÒ%ð ×-Ñ-Ó/×/Ð/ß $×";×";Ð";Ø×&Ñ&¨d×.?Ñ.?Ð&Ö@ñ #<‰>ñ'K÷ 0×/úñ 0ùsL   ‚&C=©"C=Á'C(Á2C&Á3C(Á;*C=Â%C;Â&C=Â2C=Ã"C=Ã&C(Ã(C8	Ã3	C=c               ó   € V ^8„  d   QhRR/# r‰   r"   )r?   s   "r.   r@   rT   ¿  s   € ÷ 0ñ 0 Tñ 0r-   c                óT  € \         P                  ! \        4      ;_uu_ 4         V P                  P	                  4       p\        V\        4      '       g   K3  \        V4      ^8X  g   KE  V^ ,          \        J g   KX  V P                  V^,          4       Kr    + '       g   i     R# ; i)zwWake still-queued _FLUSH waiters so a consumer dying mid-flush
doesn't stall flush_pending_sync() for its full timeout.N)
rÔ   rÕ   r§   rj   r°  ri  r²  rè   r;  rT  )rD   rµ  s   & r.   r�  Ú)GatewayStreamConsumer._wake_flush_waiters¿  sj   € ô × Ò ¤×+Õ+ØØ—{‘{×-Ñ-Ó/�Ü˜d¤E×*Ô*¬s°4«y¸A®~À$ÀqÅ'ÌVÕBSØ×&Ñ& t¨A¥wÖ/÷	 ,×+Ð+ús   £/BÁBÁ)BÁ<BÂB'	c               ó    € V ^8„  d   QhRRRR/# rò   r"   )r?   s   "r.   r@   rT   Î  s   € ÷ Mñ M ð M¨ñ Mr-   c                ó.   € \         P                  ! V 4      # )zRHide MEDIA:<path> / [[audio_as_voice]] directives; media is delivered post-stream.)Ú_BasePlatformAdapterÚ"strip_media_directives_for_display)rÝ   s   &r.   rô   Ú(GatewayStreamConsumer._clean_for_displayÈ  s   € ô $×FÒFÀtÓLÐLr-   )7rŽ   rf   rm   r„   rw   r�   r‚   rƒ   rr   rs   r�   rt   rŸ   r{   rz   rn   r|   r‘   r’   r“   rœ   r›   rq   ru   r_   rp   ro   r�   r‰  rg   r�   rŒ   r   r~   r^   r]   rl   rj   r…   rc   rŠ  r”   r�   rv   r–   r•   rb   rž   ry   r}   rL   r\   rM   rO   rd   )NNNNNNrº   )Nr[   F)rZ   )Er#   r$   r%   r&   r'   Ú_MAX_FLOOD_STRIKESÚsecretsÚrandbitsrJ   r)   r†   rx   r—   r©   rG   r­   r´   rÁ   rË   Úalready_sentÚfinal_response_sentÚ
message_idÚfinal_content_deliveredrÙ   rá   rë   ré   rö   rï   r   rþ   r  r  r/  r4  r?  rC  rH  rP  ÚstaticmethodrT  r\  rZ  ro  rd  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.   rI   rI   c   s¶  ‡ ñ^ð Ðð %×-Ò-¨bÓ1Ð�sÓ1÷M,õ^'õ$)õ(
ð ô*ó ð*õ4õ
Oð
°%ð Èe÷ ñ Ñ;Ó<€LÙ"Ñ#IÓJÐÙÑ7Ó8€JÙ&Ñ'QÓRÐõ	!õ$õ1÷4õVõAõ;õ<Mõ	Mõ&÷/õ21÷
	:õ4õ
*õIð ô"ó ð"ð"¸u÷ "õ 6÷<õ>õ2$÷õL'õ`[õ7õ.&2õP,õ&4õ"8õ.-õ^Bõ>õ-õ&+õ21õ49ð0)À÷ )õ:õ
	(õ9õ"Aõ"0ð ôMó ôMr-   rI   )>r'   Ú
__future__r   r$  Úconcurrent.futuresr'  rÔ   rÖ   Úloggingrh   r  r9  rÅ  r`   Údataclassesr   Útypingr   r   r   Úgateway.platforms.baser   r  r   Úgateway.configr	   r(   r
   r*   r   r+   Úgateway.response_filtersr   r‘  r   rÇ  Úgateway.stream_consumer_fencesr   Ú!gateway.stream_consumer_transportr   Ú gateway.stream_consumer_fallbackr   Úgateway.stream_consumer_thinkr   Ú	getLoggerrN  Úobjectrƒ  r  r3  r³   r‚  r;  r+  rG  r)  r(  rj  r€   r   r0   rI   r"   r-   r.   Ú<module>r2     s  ðñõ #ã Û Û Û Û Û Û Û Û Û Ý !ß *Ñ *å NÝ 5÷;ñ ;÷=õ EÝ BÝ @Ý @à	×	Ò	Ð4Ó	5€ñ 	‹€Ù‹x€Ù‹h€Ù“€Ù‹h€Ù	‹€Ù“XÐ Ù‹x€Ø—‘ ×!3Ñ!3×!:Ñ!:Ð;€ð !9Ð ð ÷ð ó ðð$ ÷að aó ðaô&mMÐ0Ð2EÐG]ö mMr-   