+
    jHàj×(  ã                  ó~   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ]P                  ! R4      t ! R R4      tR# )zXVoice-clip transcription for inbound messages (moved out of ``gateway/run_inbound.py``).)ÚannotationsN)ÚOptional)Ú_UNSETzgateway.runc                  ó®   € ] tR t^tRtRR R lltR R ltRR R lltR	RR
R/R R lltR	]	/R R llt
Rt]R R l4       t]R R l4       tR R ltRtR# )Ú GatewayInboundTranscriptionMixinzCSTT enrichment and the once-only echo of pending voice transcripts.Nc               ó(   € V ^8„  d   QhRRRRRRRR/# )	é   Ú	user_textÚstrÚaudio_pathsú	list[str]Ú	clip_memozOptional[dict]Úreturnútuple[str, list[str]]© )Úformats   "ÚF/home/ubuntu/.hermes/hermes-agent/gateway/run_inbound_transcription.pyÚ__annotate__Ú-GatewayInboundTranscriptionMixin.__annotate__   s,   € ÷ 01ñ 01Øð01Ø+4ð01ØAOð01à	ñ01ó    c              ƒ  óR  "  € ^ RI Hp \        \        P	                  V4      4      p\        V P                  RR4      '       g‘   . pV FY  p\        P                  P                  V4      pV! V4      G Rj  x€L
 pV'       d   RV R2MRp	VP                  RV V	 R	24       K[  	  V'       d$   V P                  R
P                  V4      V4      . 3# T. 3#  ^ RIHp
Hp . p. pT F}  p Te   Yc9   d   Y6,          w  ppM=\"        P'                  RT4       T P)                  YjT4      G Rj  x€L
 w  ppTe   TT3Y6&   Te   TP                  T4       TP                  T4       K  	  T'       d"   T P                  R
P                  T4      T4      pY3#  EL  \          d5   p\"        P%                  RT4       T P                  RT4      . 3u Rp?# Rp?ii ; i L¬  \*         dC   p\"        P%                  RT4       TP                  T P-                  T4      4        Rp?EK<  Rp?ii ; i5i)um  Transcribe voice clips with the configured STT provider and prepend the transcripts â†’
``(enriched_text, successful_transcripts)``; the transcripts (input order; empty if every clip
failed or STT is disabled) let callers echo them back before the agent loop. ``clip_memo``
(path â†’ ``_transcribe_one_clip`` result) skips clips an earlier pass already transcribed.)Ú_probe_audio_durationÚstt_enabledTNz (duration: Ú)Ú z [The user sent a voice message: Ú]ú

)Útranscribe_audioÚtranscribe_audio_local_fallbackz$Transcription module unavailable: %sz([voice message could not be transcribed]zTranscribing user voice: %szTranscription error: %s)Úgateway.runr   ÚlistÚdictÚfromkeysÚgetattrÚconfigÚosÚpathÚabspathÚappendÚ_prepend_media_prefixÚjoinÚtools.transcription_toolsr   r   ÚModuleNotFoundErrorÚloggerÚerrorÚdebugÚ_transcribe_one_clipÚ	ExceptionÚ_untranscribed_audio_note)Úselfr	   r   r   r   Únotesr&   Úabs_pathÚduration_strÚsuffixr   r   ÚeÚenriched_partsÚsuccessful_transcriptsÚ
transcriptÚnotes   &&&&             r   Ú"_enrich_message_with_transcriptionÚCGatewayInboundTranscriptionMixin._enrich_message_with_transcription   s  é € õ 	6Üœ4Ÿ=™=¨Ó5Ó6ˆÜ�t—{‘{ M°4×8Ò8ØˆEÛ#�ÜŸ7™7Ÿ?™?¨4Ó0�Ù%:¸8Ó%D×D�ß;G˜<¨ ~°QÑ7ÈR�Ø—‘Ð?À¸zÈ&ÈÐQRÐSÖTñ	 $÷
 RW�D×.Ñ.¨v¯{©{¸5Ó/AÀ9ÓMÐhjÐjÐjÐ\eÐhjÐjÐjð	i÷ð ˆØ,.ÐÛˆDðLØÒ(¨TÔ->Ø'0¥Ñ$�J¡ä—L‘LÐ!>ÀÔEØ-1×-FÑ-FØÐ0Oó.÷ (Ñ$�J ð !Ò,Ø+5°tÐ*<˜	™ØÒ)Ø*×1Ñ1°*Ô=Ø×%Ñ% dÖ+ñ  ÷$ Ø×2Ñ2°6·;±;¸~Ó3NÐPYÓZˆIØÐ0Ð0òG  Eøô #ô 	iÜ�L‰LÐ?ÀÔCØ×-Ñ-Ð.XÐZcÓdÐfhÐhÕhûð	iúñ(øô ô LÜ—‘Ð6¸Ô:Ø×%Ñ% d×&DÑ&DÀTÓ&J×KÓKûðLüs‘   ‚A3H'Á5FÁ6H'Â*H'Â-'H'ÃF Ã	H'Ã'AGÄ(GÄ)7GÅ H'Å,%H'ÆGÆ)GÇGÇH'ÇGÇH'ÇGÇH$Ç"6HÈH'ÈH$È$H'c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   E   s   € ÷ 
ñ 
°9ñ 
r   c                ó¢   € ^ RI Hp \        \        VRR4      ;'       g    . 4       UUu. uF  w  r4V! W4      '       g   K  VNK  	  upp# u uppi )z7Return STT-eligible paths from a pending voice message.)Ú_event_media_is_stt_inputÚ
media_urlsN)r   rA   Ú	enumerater#   )r3   ÚeventrA   Úir&   s   &&   r   Ú_pending_event_audio_pathsÚ;GatewayInboundTranscriptionMixin._pending_event_audio_pathsE   sM   € å9ä )¬'°%¸ÀtÓ*L×*RÐ*RÐPRÔ Sô
Ù S‘W�QÙ(¨×2÷ ˆDÑ Sò
ð 	
ùó 
s   ªAÁAc               ó    € V ^8„  d   QhRRRR/# )r   r	   zOptional[str]r   ztuple[str | None, list[str]]r   )r   s   "r   r   r   M   s   € ÷ 5ñ 5Ø -ð5à	%ñ5r   c              ƒ  óœ  "  € \        VR4      '       d-   VP                  \        \        VR. 4      ;'       g    . 4      3# V P	                  V4      pV'       g"   Ve   V. 3# \        VRR4      ;'       g    R. 3# Ve   TM\        VRR4      ;'       g    Rp\        VRR4      pVf	   / pWQn        V P                  WCV4      G Rj  x€L
 w  rgV P	                  V4      V8w  dM   V P	                  V4      pVe   TM\        VRR4      ;'       g    RpV P                  WCV4      G Rj  x€L
 w  rgKb  Wan        \        V4      Vn        Wg3#  L� L#5i)u  Transcribe a pending audio event once and cache the result on the event: the interrupt
monitor and the pending-drain path both need it â€” one STT call and one echo per message.
``user_text`` is a deliberate override of the caption; ``None`` reads ``event.text`` live.Ú_gateway_pending_stt_textÚ _gateway_pending_stt_transcriptsNÚtextr   Ú_gateway_pending_stt_clips)ÚhasattrrJ   r    r#   rF   rM   r=   rK   )r3   rD   r	   r   rL   r   Úenriched_textr:   s   &&&     r   Ú$_transcribe_pending_audio_event_onceÚEGatewayInboundTranscriptionMixin._transcribe_pending_audio_event_onceM   si  é € ô �5Ð5×6Ò6Ø×2Ñ2´D¼ÀÐHjÐlnÓ9o×9uÐ9uÐsuÓ4vÐvÐvØ×5Ñ5°eÓ<ˆßØ )Ò 5�9ÐceÐeÐe¼GÀEÈ6ÐSWÓ<X×<`Ð<`Ð\`ÐceÐeÐeØ%Ò1‰y¼ÀÀvÈrÓ8R×8XÐ8XÐVXˆô ˜EÐ#?ÀÓFˆ	ØÒØˆIØ/8Ô,Ø6:×6]Ñ6]Ð^bÐqzÓ6{×0{Ñ-ˆð ×-Ñ-¨eÓ4¸ÔCØ×9Ñ9¸%Ó@ˆKØ )Ò 5‘9¼GÀEÈ6ÐSUÓ<V×<\Ð<\ÐZ\ˆDØ:>×:aÑ:aØ 9ó;÷ 5Ñ1ˆMÑ1ð +8Ô'Ü15Ð6LÓ1MˆÔ.ØÐ4Ð4ñ 1|ñ5ùsA   ‚6E¹ EÁEÁ6EÂ1EÃEÃAEÄEÄ&E
Ä'"EÅ
EÚmetadataÚlog_contextÚ
Transcriptc               ó$   € V ^8„  d   QhRRRRRR/# )r   Útranscriptsr   rS   r
   r   ÚNoner   )r   s   "r   r   r   l   s&   € ÷ 
ñ 
Ø3<ð
àð
ð 
ñ
r   c             ƒ  ó
  "  € V'       d   V P                  4       '       d   Vf   R# \        \        VR^ 4      ;'       g    ^ 4      p\        V\	        V4      4      Vn        V P                  W#WGR WVR7      G Rj  x€L
  R#  L5i)u>  Echo pending-event STT transcripts to the chat at most once. Tracked as a COUNT (not a
set â€” identical transcripts are distinct deliveries): ``merge_pending_message_event`` can
append a second voice note and invalidate the cache; the re-run returns earlier transcripts
as a prefix, so only the unsent tail is echoed.NÚ_gateway_pending_stt_echoed©rR   rS   )Ú_should_echo_stt_transcriptsÚintr#   ÚmaxÚlenrY   Ú_echo_stt_transcripts)r3   rD   ÚadapterÚsourcerV   rR   rS   Úalready_echoeds   &&&&&$$ r   Ú"_echo_pending_stt_transcripts_onceÚCGatewayInboundTranscriptionMixin._echo_pending_stt_transcripts_oncel   sy   é € ÷  $×"CÑ"C×"EÒ"EÈÊÙÜœW UÐ,IÈ1ÓM×RÐRÐQRÓSˆÜ,/°ÄÀKÓ@PÓ,QˆÔ)Ø×(Ñ(Ø˜[¨Ð9ÀHð )ó 
÷ 	
ô 	
ùs   ‚B¡BÁ :BÁ:BÁ;Bc               ó$   € V ^8„  d   QhRRRRRR/# )r   rL   r
   rS   r   r   r   )r   s   "r   r   r   |   s$   € ÷ ñ Ø,/ðØADðà	ñr   c          	   ƒ  óŒ  "  € V P                  V4      '       g   V. 3#  V P                  V4      G Rj  x€L
 w  rxV\        J d!   V P                  W0P	                  V4      4      pV P                  WW8WeR7      G Rj  x€L
  T;'       g    TV3#  LZ L  \         d%   p	\        P                  RYY4       T. 3u Rp	?	# Rp	?	ii ; i5i)u|  Transcribe a pending voice event and echo transcripts once â†’ ``(enriched_text,
transcripts)`` for ``agent.interrupt()`` or the pending-drain flow; ``(text, [])`` when there
is no STT-eligible media (caller owns the ``_build_media_placeholder`` fallback). ``text`` is
only that fallback: the caption is read live from ``event.text`` so one merged in during
the STT await is kept.NrZ   z%s transcription failed: %s)	rF   rP   r   Ú_thread_metadata_for_sourceÚ_reply_anchor_for_eventrc   r1   r-   Úwarning)
r3   rD   r`   ra   rL   rS   rR   rO   rV   Ú	trans_excs
   &&&&&$$   r   Ú"_transcribe_and_echo_pending_voiceÚCGatewayInboundTranscriptionMixin._transcribe_and_echo_pending_voice|   sÎ   é € ð ×.Ñ.¨u×5Ò5Ø˜�8ˆOð
	Ø/3×/XÑ/XÐY^Ó/_×)_Ñ&ˆMØœ6Ó!Ø×;Ñ;¸F×D`ÑD`ÐafÓDgÓh�Ø×9Ñ9Ø ¸hð :ó ÷ ð ð !×(Ð( D¨+Ð5Ð5ñ *`ñøô ô 	Ü�N‰NÐ8¸+ÔQØ˜�8�Oûð	üs]   ‚CŸB ³B´AB Á;BÁ<B Â	B ÂCÂB ÂB ÂCÂB<Â6CÂ7CÂ<CÃCz.(The user sent a message with no text content)c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úprefixr
   r	   r   r   )r   s   "r   r   r   •   s!   € ÷ ñ ¨3ð ¸3ð À3ñ r   c                ób   € V'       d'   VP                  4       V P                  8w  d   V RV 2# V# )z\``prefix`` + the user's text; the Discord empty-content placeholder is dropped as redundant.r   )ÚstripÚ_EMPTY_TEXT_PLACEHOLDER)Úclsrn   r	   s   &&&r   r)   Ú6GatewayInboundTranscriptionMixin._prepend_media_prefix”   s1   € ÷ ˜Ÿ™Ó*¨c×.IÑ.IÔIØ�X˜T ) Ð-Ð-Øˆr   c               ó    € V ^8„  d   QhRRRR/# )r   r&   r
   r   r   )r   s   "r   r   r   œ   s   € ÷ rñ r¨ð r°ñ rr   c                ód   € ^ RI Hp V! \        P                  P	                  V 4      4      pRV R2# )u±   One minimal neutral marker for every STT failure. Never mention "no STT provider" or setup
steps â€” persisted in history they make the model keep volunteering STT-setup advice.)Úto_agent_visible_cache_pathzR[voice message could not be transcribed automatically; the audio is available at: r   )Útools.credential_filesrv   r%   r&   r'   )r&   rv   Ú
agent_paths   &  r   r2   Ú:GatewayInboundTranscriptionMixin._untranscribed_audio_note›   s1   € õ 	GÙ0´·±·±ÀÓ1FÓGˆ
ØcÐdnÐcoÐopÐqÐqr   c               ó    € V ^8„  d   QhRRRR/# )r   r&   r
   r   ztuple[Optional[str], str]r   )r   s   "r   r   r   £   s   € ÷ -ñ -¨sð -ð  kDñ -r   c              ƒ  ó  "  € \         P                  ! W!RR4      G Rj  x€L
 pVP                  R4      '       gN   \         P                  ! W14      G Rj  x€L
 pVP                  R4      '       d   \        P	                  RV4       TpVR,          '       g:   \        P	                  RWP                  RR4      4       RV P                  V4      3# VR,          pT;'       g    R	P                  4       '       g   R# VR
V R
23#  Lã L°5i)zS``(transcript_or_None, note)`` for one clip via configured STT with local fallback.NÚgatewayÚsuccessz6Configured STT failed for %s; recovered with local STTz%Voice transcription failed for %s: %sr.   zunknown errorr;   r   Ú")Nu°   [The user sent a voice message but it came through empty or inaudible â€” speech-to-text returned no words. Do not guess at the content; ask the user to resend or type it out.])ÚasyncioÚ	to_threadÚgetr-   Úinfor2   rp   )r3   r&   r   r   ÚresultÚfallbackr;   s   &&&&   r   r0   Ú5GatewayInboundTranscriptionMixin._transcribe_one_clip£   sí   é € ä×(Ò(Ð)9ÀÀyÓQ×QˆØ�z‰z˜)×$Ò$Ü$×.Ò.Ð/NÓU×UˆHØ�|‰|˜I×&Ò&Ü—‘ÐTÐVZÔ[Ø!�Ø�i× Ô Ü�K‰KÐ?ÀÇzÁzÐRYÐ[jÓGkÔlØ˜×7Ñ7¸Ó=Ð=Ð=Ø˜LÕ)ˆ
ð × Ð ˜b×'Ñ'×)Ò)ðð ð ˜Q˜z˜l¨!Ð,Ð,Ð,ñ- RáUùs?   ‚DžDŸDºDÁDÁDÁ/&DÂA
DÃ!DÃ8DÄDr   )N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r=   rF   rP   rc   r   rk   rq   Úclassmethodr)   Ústaticmethodr2   r0   Ú__static_attributes__r   r   r   r   r      sr   † ÙM÷01õd
÷5ð>
ØJNð
à'÷
ð ØOU÷ð, OÐàôó ðð ôró ðr÷-ñ -r   r   )rŠ   Ú
__future__r   r   Úloggingr%   Útypingr   Úgateway.run_commonr   Ú	getLoggerr-   r   r   r   r   Ú<module>r“      s8   ðÙ ^å "ã Û Û 	Ý å %ð 
×	Ò	˜=Ó	)€÷k-ó k-r   