+
    lHàj)y  ã                  óê  € 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	H
t
Ht ^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHtHtHtHt ^ RIHt ]P6                  ! R	4      tR
tRtRtRt Rt!Rt"Rt#Rt$Rt%Rt&Rt'Rt(Rt)Rt*Rt+Rt,Rt-Rt.Rt/^ t0Rt1Rt2Rt3Rt4Rt5R t6Rkt7Rlt80 Rmmt90 Rnmt:RoR! R" llt;R# R$ lt<R% R& lt=R' R( lt>R) R* lt?R+R/R, R- llt@R. R/ ltAR+R/R0 R1 lltBR2 R3 ltCR4 R5 ltDR6 R7 ltER8tFR9tGR: R; ltHR< R= ltIR> R? ltJR@ RA ltKRptLRqtM]Pœ                  ! RBRCPŸ                  ]L4       RDRCPŸ                  ]M4       RE2]P                   RF7      tQ]Pœ                  ! RG]P¤                  RF7      tSRH RI ltTRJ RK ltURL RM ltV]
! RNRO7       ! RP RQ4      4       tWRR]#RS]$/tXRR]Y! RTRU04      RS]Y! RV04      /tZRW RX lt[RY RZ lt\R[ R\ lt]R] R^ lt^R_ R` lt_Ra Rb lt`RrRc Rd lltaRsRe Rf lltbRg Rh ltcRi Rj ltdR# )taô  Cloud TTS backends for ``tools.tts_tool``: Edge, ElevenLabs, xAI, MiniMax, Mistral, Gemini.

Each ``_generate_<provider>(text, output_path, tts_config) -> path`` writes one final-encoded
file. Shared here: bounded upstream response reading (16 MiB cap so a hostile endpoint can't
feed unbounded audio) and the auxiliary-model speech-tag rewrites. OpenAI/DeepInfra live in
``tts_tool_openai``. Origin seams (``_resolve_provider_key``, ``_import_*``)
are resolved through :func:`_origin` at call time.
)ÚannotationsN)Ú	dataclassÚfield)ÚPath)ÚAnyÚDictÚOptional)Úurlparse)Ú_originÚ_sectionÚ_wrap_pcm_as_wavÚ_write_wav_bytes_as)Úhermes_xai_user_agentztools.tts_toolzen-US-AriaNeuralÚpNInz6obpgDQGcFmaJgBÚeleven_multilingual_v2Úeleven_flash_v2_5zspeech-02-hdÚEnglish_expressive_narratorz https://api.minimax.io/v1/t2a_v2z"https://api.minimaxi.com/v1/t2a_v2zvoxtral-mini-tts-2603z$c69964a6-ab8b-4f8a-9465-ec0925096ec8ÚeveÚeniÀ]  é ô Fzhttps://api.x.ai/v1çffffffæ?g      ø?ç      ð?zgemini-2.5-flash-preview-ttsÚKorez0https://generativelanguage.googleapis.com/v1betaÚtts_audio_tagsc               ó$   € V ^8„  d   QhRRRRRR/# )é   Úvaluer   ÚdefaultÚboolÚreturn© )Úformats   "Ú=/home/ubuntu/.hermes/hermes-agent/tools/tts_tool_providers.pyÚ__annotate__r#   @   s&   € ÷ ^ñ ^˜ð ^ dð ^°tñ ^ó    c                ó  € \        V \        \        \        34      '       d   \        V 4      # \        V \        4      '       d   V P                  4       P                  4       MRpV\        \        ,          9   d
   V\        9   # T# )zNCoerce common YAML/env bool spellings without treating random strings as true.N)	Ú
isinstancer   ÚintÚfloatÚstrÚstripÚlowerÚ_TRUE_WORDSÚ_FALSE_WORDS)r   r   Ú
normalizeds   && r"   Ú_config_boolr/   @   s_   € ä�%œ$¤¤UÐ+×,Ò,Ü�E‹{ÐÜ*4°U¼C×*@Ò*@�—‘“×$Ñ$Ô&Àd€JØ(2´kÄLÕ6PÔ(Pˆ:œÑ$Ð]ÐV]Ð]r$   c               ó    € V ^8„  d   QhRRRR/# )r   Úoutput_pathr)   r   r    )r!   s   "r"   r#   r#   H   s   € ÷ Sñ S°ð S¸ñ Sr$   c                ó4   a € Rp\        V 3R lV 4       R4      # )zSPick an OpenAI-style response format (opus/wav/flac/mp3) from the output extension.c              3  ó^   <"  € T F"  w  rSP                  V4      '       g   K  Vx € K$  	  R # 5i©N)Úendswith)Ú.0ÚextÚfmtr1   s   &  €r"   Ú	<genexpr>Ú1_tts_response_format_from_path.<locals>.<genexpr>K   s"   øé € ÐJ¡W™˜°×0DÑ0DÀS×0I—’£Wùs   ƒ-£
-Úmp3))ú.oggÚopus)ú.wavÚwav)z.flacÚflac)Únext)r1   Úformatss   f r"   Ú_tts_response_format_from_pathrC   H   s   ø€ àD€GÜÔJ¡WÓJÈEÓRÐRr$   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úenv_varr)   Úprovider_idÚhintr   r    )r!   s   "r"   r#   r#   N   s(   € ÷ ñ ˜#ð ¨Cð °sð ¸sñ r$   c                ó|   € \        4       P                  W4      ;'       g    RpV'       g   \        V  RV 24      hV# )zbResolve *env_var* via the origin key resolver; ValueError ``"<ENV> not set. <hint>"`` when absent.Ú z
 not set. )r
   Ú_resolve_provider_keyÚ
ValueError)rE   rF   rG   Úapi_keys   &&& r"   Ú_require_keyrM   N   s:   € ä‹i×-Ñ-¨gÓC×IÐIÀr€GßÜ˜G˜9 J¨t¨fÐ5Ó6Ð6Ø€Nr$   c               ó    € V ^8„  d   QhRRRR/# )r   Úresponser   r   r   r    )r!   s   "r"   r#   r#   W   s   € ÷ eñ e¨Cð e°Dñ er$   c                ó¶   € \        \        V RR4      4      '       g   R# \        V 4      pVP                  P	                  R4      ;'       g    R\        V4      9   # )zWTrue for real ``requests`` responses (or doubles defining ``iter_content`` themselves).Úiter_contentNFz	requests.)ÚcallableÚgetattrÚtypeÚ
__module__Ú
startswithÚvars)rO   Úresponse_types   & r"   Ú_response_has_explicit_streamrY   W   sM   € ä”G˜H n°dÓ;×<Ò<ÙÜ˜“N€MØ×#Ñ#×.Ñ.¨{Ó;×dÐd¸~ÔQUÐVcÓQdÑ?dÐdr$   c               ó    € V ^8„  d   QhRRRR/# )r   rO   r   r   ÚNoner    )r!   s   "r"   r#   r#   _   s   € ÷ ñ ˜cð  dñ r$   c                óÒ   € \        V R R4      p\        V4      '       d5   \        P                  ! \        4      ;_uu_ 4        V! 4        RRR4       R# R#   + '       g   i     R# ; i)ÚcloseN)rS   rR   Ú
contextlibÚsuppressÚ	Exception)rO   r]   s   & r"   Ú_close_responsera   _   sF   € Ü�H˜g tÓ,€EÜ�‡‚Ü× Ò ¤×+Õ+ÙŒG÷ ,Ñ+ñ ß+×+Ð+ús   ÁAÁA&	Úlimitc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rO   r   Úlabelr)   rb   úOptional[int]r   Úbytesr    )r!   s   "r"   r#   r#   f   s)   € ÷ "ñ " sð "°cð "À-ð "Ð[`ñ "r$   c               óŽ  € Vf   \         MTp. p^ p \        V 4      '       d   V P                  \        R7      pMU\	        V 4      P                  R\        \        V 4      RR4      4      p\        V\        \        \        34      '       d   V3MR	pV F†  pV'       g   K  \        V\        4      '       d   VP                  RRR7      p\        V4      pV\        V4      ,          pWB8”  d   \        V 4       \        V RV R24      hVP!                  V4       Kˆ  	  RP#                  V4      \        V 4       #   \        T 4       i ; i)
z3Read an upstream TTS response with a hard byte cap.)Ú
chunk_sizeÚcontentr$   úutf-8Úreplace©Úerrorsz response exceeds z bytesr    )ÚTTS_RESPONSE_BODY_LIMIT_BYTESrY   rQ   ÚTTS_RESPONSE_BODY_CHUNK_BYTESrW   ÚgetrS   rT   r&   r)   rf   Ú	bytearrayÚencodeÚlenra   ÚRuntimeErrorÚappendÚjoin)rO   rd   rb   ÚchunksÚtotalÚiteratorri   Úchunks   &$$     r"   Ú_read_tts_response_bytesr{   f   s  € à-2ª]Õ)À€EØ€FØ€Eð"Ü(¨×2Ò2Ø×,Ñ,Ô8UÐ,ÓV‰Hä˜8“n×(Ñ(¨´G¼DÀ»NÈIÐWZÓ4[Ó\ˆGÜ%/°¼#¼uÄiÐ9P×%QÒ%Q˜‘zÐWYˆHÛˆEßÙÜ˜%¤×%Ò%ØŸ™ W°Y˜Ó?�Ü˜%“LˆEØ”S˜“ZÕˆEØŒ}Ü Ô)Ü" e WÐ,>¸u¸gÀVÐ#LÓMÐMØ�M‰M˜%Ö ñ ð �x‰x˜Óä˜Õ!øŒ˜Õ!ús   ’DD7 Ä7Ec               ó$   € V ^8„  d   QhRRRRRR/# )r   rO   r   Úrawrf   r   údict[str, Any]r    )r!   s   "r"   r#   r#   �   s!   € ÷ 
ñ 
˜sð 
¨ð 
°>ñ 
r$   c                ó   € V'       d&   \         P                  ! VP                  R4      4      # \        V 4      '       g@   \	        V RR4      p\        V4      '       d"   V! 4       p\        V\        4      '       d   V# / # / # )z²JSON from the already-read *raw* body. Unit-test doubles often only provide ``.json()``;
real ``requests`` responses took the streaming path, so production never buffers eagerly.rj   ÚjsonN)r€   ÚloadsÚdecoderY   rS   rR   r&   Údict)rO   r}   Újson_readerÚparseds   &&  r"   Ú_parse_json_bodyr†   �   sf   € ÷ Ü�zŠz˜#Ÿ*™* WÓ-Ó.Ð.Ü(¨×2Ò2Ü˜h¨°Ó5ˆÜ�K× Ò Ù “]ˆFÜ'¨´×5Ò5�6Ð=¸2Ð=Ø€Ir$   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rO   r   rd   r)   rb   re   r   r~   r    )r!   s   "r"   r#   r#   Ž   s/   € ÷ dñ d cð d°Sð dÀð dÐZhñ dr$   c          	     ó0   € \        V \        WVR 7      4      # ))rd   rb   )r†   r{   )rO   rd   rb   s   &$$r"   Ú_read_tts_response_jsonr‰   Ž   s   € Ü˜HÔ&>¸xÐ\aÔ&bÓcÐcr$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r1   r)   Úaudio_bytesrf   r   r    )r!   s   "r"   r#   r#   ’   s!   € ÷ ñ ˜cð °ð ¸#ñ r$   c                óŠ   € \        V R 4      ;_uu_ 4       pVP                  V4       RRR4       V #   + '       g   i     T # ; i)ÚwbN)ÚopenÚwrite)r1   r‹   Úfs   && r"   Ú_write_bytesr‘   ’   s7   € Ü	ˆk˜4×	 Ô	  AØ	�‰�Ô÷ 
!àÐ÷ 
!Ö	 àÐús	   •1±A	c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úurlr)   Úpayloadr~   Úheaderszdict[str, str]Úextrar   r    )r!   s   "r"   r#   r#   ˜   s/   € ÷ _ñ _�Cð _ .ð _¸>ð _ÐTWñ _r$   c                ó@   € ^ RI pVP                  ! V 3RVRVR^<RR/VB # )z\Streaming ``requests.post`` with the shared 60s timeout (body read via the bounded readers).Nr•   r€   ÚtimeoutÚstreamT)ÚrequestsÚpost)r“   r”   r•   r–   rš   s   &&&, r"   Ú
_post_jsonrœ   ˜   s/   € ãØ�=Š=˜Ñ^ gÐ^°GÐ^ÀRÐ^ÐPTÐ^ÐX]Ñ^Ð^r$   c               ó    € V ^8„  d   QhRRRR/# ©r   rO   r   r   r)   r    )r!   s   "r"   r#   r#   Ÿ   s   € ÷ 	6ñ 	6 Cð 	6¨Cñ 	6r$   c                ó²  €  \        V P                  ^ ,          RR4      p\        V\        4      '       d   VP	                  R4      M\        VRR4      p\        T;'       g    R4      P                  4       p\        P                  ! RT\        P                  R7      pT'       d    TP                  ^4      P                  4       # T#   \
         d     R# i ; i)zWThe first choice's message content with any ```fence``` unwrapped ("" when unreadable).ÚmessageNri   rI   z$```(?:[A-Za-z0-9_-]+)?\s*(.*?)\s*```©Úflags)rS   Úchoicesr&   rƒ   rp   r`   r)   r*   ÚreÚ	fullmatchÚDOTALLÚgroup)rO   r    ri   ÚcleanÚfences   &    r"   Ú_auxiliary_reply_textrª   Ÿ   s¬   € ðÜ˜(×*Ñ*¨1Õ-¨y¸$Ó?ˆÜ,6°wÄ×,EÒ,E�'—+‘+˜iÔ(Ì7ÐSZÐ\eÐgiÓKjˆô �—�˜2Ó×$Ñ$Ó&€EÜ�LŠLÐ@À%ÌrÏyÉyÔY€Eß%*ˆ5�;‰;�q‹>×ÑÓ!Ð5°Ð5øô	 ô Úðús   ‚AC ÃCÃCz{Rules:
- Preserve the spoken words, order, and meaning.
- Do not add new spoken sentences or remove existing spoken words.
zA- Do not explain or comment.
- Return only the tagged TTS script.c               ó4   € V ^8„  d   QhRRRRRRRRRRRRR	R/# )
r   Úsystem_promptr)   Úuser_promptÚfallbackrd   Úfallback_labelÚlevelr'   r   r    )r!   s   "r"   r#   r#   ³   sD   € ÷ ñ ØðØ%(ðØ47ðØCFðØX[ðØdgðàñr$   c          	     óÐ   €  ^ RI Hp V! \        RRRRV /RRRV/.R7      p\        V4      ;'       g    T#   \         d%   p\
        P                  TRY4T4       Tu R	p?# R	p?ii ; i)
zmAsk the auxiliary model (task ``tts_audio_tags``) to rewrite a script; *fallback* on any failure/empty reply.)Úcall_llmr   ÚroleÚsystemri   Úuser)ÚtaskÚtemperatureÚmessagesz)%s audio tag rewrite failed; using %s: %sN)Úagent.auxiliary_clientr²   ÚGEMINI_AUDIO_TAG_REWRITE_TASKrª   r`   ÚloggerÚlog)	r¬   r­   r®   rd   r¯   r°   r²   rO   Úexcs	   &&&$$$   r"   Ú_rewrite_with_auxiliary_modelr¾   ³   sv   € ð	Ý3ÙÜ.¸CØ˜x¨°MÐBØ˜v y°+Ð>ð@ôAˆô % XÓ.×:Ð:°(Ð:øÜô Ü�
‰
�5ÐEÀuÐ^aÔbØ�ûðús   ‚06 ³6 ¶A%ÁA ÁA%Á A%c               ó(   € V ^8„  d   QhRRRRRRRR/# ©r   Útextr)   r1   Ú
tts_configr~   r   r    )r!   s   "r"   r#   r#   Ä   s)   € ÷ ñ  3ð °Sð Ànð ÐY\ñ r$   c           	   ƒ  ó   "  € \        4       P                  4       pVP                  R 4      ;'       g    / p\        VP                  RVP                  RR4      4      4      pRVP                  R\        4      /pVR8w  d!   \        VR,
          ^d,          4      R R2VR&   VP                  ! V 3/ VB P                  V4      G Rj  x€L
  V#  L5i)ÚedgeÚspeedr   Úvoicez+dÚ%ÚrateN)r
   Ú_import_edge_ttsrp   r(   ÚDEFAULT_EDGE_VOICEÚroundÚCommunicateÚsave)rÁ   r1   rÂ   Úedge_ttsÚedge_configrÅ   Úkwargss   &&&    r"   Ú_generate_edge_ttsrÑ   Ä   s¹   é € Ü‹y×)Ñ)Ó+€HØ—.‘. Ó(×.Ð.¨B€KÜ�+—/‘/ '¨:¯>©>¸'À3Ó+GÓHÓI€EØ�{—‘ wÔ0BÓCÐD€FØ�„|Ü! 5¨3¥;°#Õ"5Ó6°rÐ:¸!Ð<ˆˆv‰Ø
×
Ò
˜tÑ
. vÑ
.×
3Ñ
3°KÓ
@×@Ð@ØÐñ Aùs   ‚CCÃCÃCc               ó    € V ^8„  d   QhRRRR/# )r   Ú	el_configr~   r   r    )r!   s   "r"   r#   r#   Ð   s   € ÷ Nñ N¨nð NÀñ Nr$   c                ó   € V P                  R4      ;'       g    RP                  R4      pV'       g   / # ^ RIHp V P                  R4      ;'       g    RP                  R4      ;'       g    \        P
                  ! RRV4      pRV! WR	7      /# )
z¬SDK client kwargs for ``tts.elevenlabs.base_url``/``wss_url``; empty (SDK default) without a
base_url. ``wss_url`` defaults to the base_url host with a ``ws(s)://`` scheme.Úbase_urlrI   Ú/)ÚElevenLabsEnvironmentÚwss_urlz^httpÚwsÚenvironment)ÚbaseÚwss)rp   ÚrstripÚelevenlabs.environmentr×   r¤   Úsub)rÓ   rÕ   r×   rØ   s   &   r"   Ú_elevenlabs_environment_kwargsrà   Ð   sx   € ð —‘˜jÓ)×/Ð/¨R×7Ñ7¸Ó<€HßØˆ	Ý<Ø�}‰}˜YÓ'×-Ð-¨2×5Ñ5°cÓ:×^Ð^¼b¿fºfÀXÈtÐU]Ó>^€GØÑ0°hÔLÐMÐMr$   c               ó(   € V ^8„  d   QhRRRRRRRR/# rÀ   r    )r!   s   "r"   r#   r#   Û   s)   € ÷ 
ñ 
˜sð 
°ð 
À.ð 
ÐUXñ 
r$   c                óê  € \        R RR4      pVP                  R4      ;'       g    / p\        4       P                  4       ! RRV/\	        V4      B pVP
                  P                  YP                  R\        4      VP                  R\        4      VP                  R4      '       d   RMRR	7      p\        VR
4      ;_uu_ 4       pVP                  V4       RRR4       V#   + '       g   i     T# ; i)ÚELEVENLABS_API_KEYÚ
elevenlabsz!Get one at https://elevenlabs.io/rL   Úvoice_idÚmodel_idr<   Úopus_48000_64Úmp3_44100_128)rÁ   rå   ræ   Úoutput_formatr�   Nr    )rM   rp   r
   Ú_import_elevenlabsrà   Útext_to_speechÚconvertÚDEFAULT_ELEVENLABS_VOICE_IDÚDEFAULT_ELEVENLABS_MODEL_IDr5   rŽ   Ú
writelines)rÁ   r1   rÂ   rL   rÓ   ÚclientÚaudio_generatorr�   s   &&&     r"   Ú_generate_elevenlabsrò   Û   sÒ   € ÜÐ/°Ð?bÓc€GØ—‘˜|Ó,×2Ð2°€IÜ‹Y×)Ñ)Ô+Ñi°GÐiÔ?]Ð^gÓ?hÑi€FØ×+Ñ+×3Ñ3ØŸM™M¨*Ô6QÓRØ—‘˜zÔ+FÓGØ)4×)=Ñ)=¸f×)EÒ)E‘oÈ?ð 4ó \€Oô 
ˆk˜4×	 Ô	  AØ	�‰�_Ô%÷ 
!àÐ÷ 
!Ö	 àÐús   ÃC!Ã!C2	z(\[(?:Ú|z
)\]|</?(?:z)>)r¡   u   ^(.{12,120}?[.!?â€¦])\s+(?=\S)c               ó    € V ^8„  d   QhRRRR/# )r   rÁ   r)   r   r    )r!   s   "r"   r#   r#   õ   s   € ÷ ñ  cð ¨cñ r$   c           	     ó„  € V P                  4       pV'       g   V # \        P                  ! RR\        P                  ! RRV4      4      p\        P	                  V4      '       g   \
        P                  RV^R7      p\        P                  ! RRV4      P                  4       p\        P	                  V4      '       d   V# RR	P                  \        4      ,           R
,           R	P                  \        4      ,           R,           \        ,           R,           \        ,           p\        VRV 2VRR\        P                  R7      # )u  Add xAI speech tags: a conservative local pass ([pause] between paragraphs / after the first
sentence), then â€” only when the text carried no explicit tags â€” an auxiliary-model rewrite
with the richer xAI tag set, falling back to the locally tagged text on any failure.z\s*\n\s*Ú z\n\s*\n+z	 [pause] z\1 [pause] )Úcountz\s{2,}zYou rewrite transcripts for the xAI /v1/tts endpoint by inserting expressive speech tags.

Valid inline tags (use as `[tag]`): z, z1.
Valid wrapping tags (use as `[tag]...[/tag]`): z.

u%  - Use inline `[tag]` for short modifiers (laughs, sighs, pause, etc.).
- Use wrapping `[tag]...[/tag]` for sustained effects (whisper, soft, slow, fast, loud, etc.).
- Do not use angle-bracket tags like `<tag>...</tag>` â€” xAI uses BBCode-style closing tags with `[/tag]`.
- Do not use SSML.
zTRANSCRIPT TO TAG:
úxAI TTSzlocally-tagged text©rd   r¯   r°   )r*   r¤   rß   Ú_XAI_SPEECH_TAG_REÚsearchÚ_XAI_FIRST_SENTENCE_RErv   Ú_XAI_INLINE_SPEECH_TAGSÚ_XAI_WRAPPING_SPEECH_TAGSÚ_TAG_REWRITE_RULESÚ_TAG_REWRITE_TAILr¾   ÚloggingÚDEBUG)rÁ   r¨   Úlocalr¬   s   &   r"   Ú_apply_xai_auto_speech_tagsr  õ   s0  € ð �J‰J‹L€EßØˆÜ�FŠF�; ¤R§V¢V¨K¸ÀeÓ%LÓM€EÜ×$Ñ$ U×+Ò+Ü&×*Ñ*¨>¸5ÈÐ*ÓJˆÜ�FŠF�9˜c 5Ó)×/Ñ/Ó1€EÜ× Ñ  ×'Ò'Øˆð	/à15·±Ô;RÓ1Sõ	TðW:õ	:ð =A¿I¹IÔF_Ó<`õ	að dkõ	kô õ		ð
	õ	ô õ		ð ô )ØÐ-¨e¨WÐ5°uÀIÐ^sô  |C÷  |Iñ  |Iôð r$   c               ó   € V ^8„  d   QhRR/# )r   r}   r   r    )r!   s   "r"   r#   r#     s   € ÷ 
!ñ 
!˜ñ 
!r$   c                óˆ   € V f   R# V R8w  d
    V! V 4      p \        V\        W04      4      #   \         \        3 d     R# i ; i)z¼Parse an optional numeric knob and clamp into [lo, hi]; ``None``/unparseable -> None. An empty
string is deliberately clamped unconverted (its TypeError surfaces as a generic TTS failure).NrI   )Ú	TypeErrorrK   ÚmaxÚmin)r}   ÚcastÚloÚhis   &&&&r"   Ú_clamped_numberr    sM   € ð ‚{ÙØ
ˆb„yð	Ù�s“)ˆCô ˆr”3�r“<Ó Ð øô œ:Ð&ô 	Úð	ús   �, ¬AÁ Ac               ó(   € V ^8„  d   QhRRRRRRRR/# rÀ   r    )r!   s   "r"   r#   r#     s/   € ÷ 6Zñ 6Z˜Cð 6Z¨cð 6Z¸~ð 6ZÐRUñ 6Zr$   c                óâ  € ^ RI Hp V! RR7      p\        VP                  R4      ;'       g    R4      P	                  4       pV'       g   \        R4      hVP                  R4      ;'       g    / p\        VP                  R\        4      4      P	                  4       ;'       g    \        p\        VP                  R	\        4      4      P	                  4       ;'       g    \        p\        VP                  R
\        4      4      \        VP                  R\        4      4      r©VP                  RVP                  R4      4      p\        V\        4      '       d   \        V 4      p \        VP                  RVP                  R4      4      \        \         \"        4      p\        VP                  RVP                  R4      4      \        ^ ^4      p\        VP                  R4      \$        4      pVP                  R4      R8X  d   VP                  R4      pM@^ RIHp VP                  R4      ;'       g"    VP                  R4      ;'       g	    V! R4      p\        T;'       g    \*        4      P	                  4       P-                  R4      pVP/                  R4      '       d   RMRpRV RVR	V/pVR8w  g   V	\        8w  g   V
\        8w  d+   RV/pV	'       d   V	VR
&   VR8X  d   V
'       d   V
VR&   VVR&   Ve   V\0        8w  d   VVR&   VR\2        39  d   VVR&   V'       d   RVR&   \5        V R2VRR V 2R!R"R#\7        4       /4      pVP9                  4        \;        V\=        VR$R%7      4      # )&é    )Úresolve_xai_http_credentialsT)Úprefer_api_keyrL   rI   zSNo xAI credentials found. Configure xAI OAuth in `hermes model` or set XAI_API_KEY.Úxairå   ÚlanguageÚsample_rateÚbit_rateÚauto_speech_tagsÚspeech_tagsrÅ   Úoptimize_streaming_latencyÚtext_normalizationÚproviderz	xai-oauthrÕ   ©Úget_env_valueÚXAI_BASE_URLrÖ   r>   r?   r;   rÁ   Úcodecré   Nz/ttsÚAuthorizationúBearer úContent-Typeúapplication/jsonz
User-Agentrø   ©rd   )Útools.xai_httpr  r)   rp   r*   rK   ÚDEFAULT_XAI_VOICE_IDÚDEFAULT_XAI_LANGUAGEr'   ÚDEFAULT_XAI_SAMPLE_RATEÚDEFAULT_XAI_BIT_RATEr/   ÚDEFAULT_XAI_AUTO_SPEECH_TAGSr  r  r(   ÚDEFAULT_XAI_SPEED_MINÚDEFAULT_XAI_SPEED_MAXÚ&DEFAULT_XAI_TEXT_NORMALIZATION_DEFAULTÚhermes_cli.configr  ÚDEFAULT_XAI_BASE_URLrÝ   r5   ÚDEFAULT_XAI_SPEED_DEFAULTÚ.DEFAULT_XAI_OPTIMIZE_STREAMING_LATENCY_DEFAULTrœ   r   Úraise_for_statusr‘   r{   )rÁ   r1   rÂ   r  ÚcredsrL   Ú
xai_configrå   r  r  r  r  rÅ   r  r  rÕ   r  r  r”   ré   rO   s   &&&                  r"   Ú_generate_xai_ttsr5    s  € Ý;ñ
 )¸Ô=€EÜ�%—)‘)˜IÓ&×,Ð,¨"Ó-×3Ñ3Ó5€GßÜÐnÓoÐoØ—‘ Ó&×,Ð,¨"€JÜ�:—>‘> *Ô.BÓCÓD×JÑJÓL×dÐdÔPd€HÜ�:—>‘> *Ô.BÓCÓD×JÑJÓL×dÐdÔPd€HÜ  §¡°Ô?VÓ!WÓXÜ  §¡°
Ô<PÓ!QÓRð à!—~‘~Ð&8¸*¿.¹.ÈÓ:WÓXÐÜÐ$Ô&B×CÒCÜ*¨4Ó0ˆô ˜JŸN™N¨7°J·N±NÀ7Ó4KÓLÌeÜ1Ô3HóJ€Eä!0Ø�‰Ð3°Z·^±^ÐD`Ó5aÓbÜˆQ�ó"Ðô &Ø�‰Ð+Ó,Ô.TóVÐà‡y�y�Ó Ô+Ø—9‘9˜ZÓ(‰å3Ø—>‘> *Ó-×gÐg°·±¸:Ó1F×gÐgÉ-ÐXfÓJgˆÜ�8×3Ð3Ô3Ó4×:Ñ:Ó<×CÑCÀCÓH€Hð !×)Ñ)¨&×1Ò1‰E°u€EØ% t¨Z¸À:ÈxÐX€GØ�„~˜Ô(?Ô?À8ÔOcÔCcØ)0°%Ð(8ˆßØ+6ˆM˜-Ñ(Ø�EŒ>ŸhØ(0ˆM˜*Ñ%Ø#0ˆ�Ñ ØÒ˜UÔ&?Ô?Ø ˆ�ÑØ!¨$Ô0^Ð)_Ô_Ø0JˆÐ,Ñ-ßØ(,ˆÐ$Ñ%Ü˜X˜J dÐ+¨WØ˜7 7 )Ð,¨nÐ>PØÔ+Ó-ð7/ó 0€Hð ×ÑÔÜ˜Ô%=¸hÈiÔ%XÓYÐYr$   T)Úfrozenc                  óV   € ] tR tRt$ RtR]R&   R]R&   R]R&   ]! RR7      tR]R	&   R
tR# )Ú_MiniMaxTTSRuntimeiY  zLA region-bound MiniMax endpoint and credential (key excluded from ``repr``).r)   ÚregionÚendpointÚcredential_sourceF)ÚreprrL   r    N)	Ú__name__rU   Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   rL   Ú__static_attributes__r    r$   r"   r8  r8  Y  s$   ‡ áVàƒKØƒMØÓÙ˜eÔ$€GˆS×$r$   r8  ÚglobalÚcnzapi.minimax.iozapi.minimax.chatzapi.minimaxi.comc               ó    € V ^8„  d   QhRRRR/# )r   rÂ   r~   r   r8  r    )r!   s   "r"   r#   r#   i  s   € ÷ vñ v¨^ð vÐ@Rñ vr$   c                óˆ  € \        V R4      p\        4       P                  pR UUu/ uF1  w  r4Y4\        V! VR4      ;'       g    R4      P	                  4       3bK3  	  ppp\        VP                  R4      ;'       g    R4      P	                  4       P                  4       pV'       d   V\        9  d   \        R4      hV'       g1   VR,          ^,          '       d   VR,          ^,          '       g   RMRpWS,          w  rgV'       g   \        V RV: 24      h\        VP                  R4      ;'       g    \        V,          4      P	                  4       pVR8X  d   RMRp	\        V4      P                  ;'       g    RP                  4       \        V	,          9   d   \        R	V	: R
V: 24      h\        W8WgR7      # u uppi )zºSelect MiniMax region, endpoint and credential atomically: explicit ``tts.minimax.region`` wins,
else the legacy global credential; ``cn`` only when it is the sole configured credential.ÚminimaxrC  rD  rI   r9  z+tts.minimax.region must be 'global' or 'cn'z  not set for MiniMax TTS region rÕ   z#tts.minimax.base_url points to the z  MiniMax endpoint but region is )r9  r:  r;  rL   ))rC  ÚMINIMAX_API_KEY)rD  ÚMINIMAX_CN_API_KEY)r   r
   rJ   r)   r*   rp   r+   Ú_MINIMAX_ENDPOINTSrK   r	   ÚhostnameÚ_MINIMAX_OFFICIAL_HOSTSr8  )
rÂ   Ú	mm_configÚresolve_keyr9  rE   Úcredentialsr;  rL   r:  Úother_regions
   &         r"   Ú_resolve_minimax_tts_runtimerQ  i  s™  € ô ˜ YÓ/€IÜ“)×1Ñ1€Kñ  ]ô^á\‰OˆFð 	œ#™k¨'°9Ó=×CÐCÀÓD×JÑJÓLÐMÒMÙ\ð ñ ^ô �—‘˜xÓ(×.Ð.¨BÓ/×5Ñ5Ó7×=Ñ=Ó?€Fß�&Ô 2Ô2ÜÐFÓGÐGßØ$ TÕ*¨1×-Ô-°kÀ(Õ6KÈA×6NÔ6N‘ÐT\ˆØ!,Õ!4ÑÐßÜÐ-Ð.Ð.NÈvÉjÐYÓZÐZÜ�9—=‘= Ó,×JÐJÔ0BÀ6Õ0JÓK×QÑQÓS€HØ! XÔ-‘4°8€LÜ�Ó×#Ñ#×)Ð) r×0Ñ0Ó2Ô6MÈlÕ6[Ô[ÜØ1°,Ñ1AÐAaÐbhÑakÐlónð 	nä VÐRcÔuÐuùó!^s   ¦7F>c               ó    € V ^8„  d   QhRRRR/# )r   Úresultr~   r   r[   r    )r!   s   "r"   r#   r#   �  s   € ÷ kñ k ^ð k¸ñ kr$   c           	     óž   € V P                  R / 4      pVP                  RR4      pV^ 8w  d"   \        RV RVP                  RR4       24      hR# )Ú	base_respÚstatus_codezMiniMax TTS API error (code ú): Ú
status_msgzunknown errorNéÿÿÿÿ)rp   rt   )rS  rU  rV  s   &  r"   Ú_raise_minimax_api_errorrZ  �  s[   € Ø—
‘
˜;¨Ó+€IØ—-‘- ¨rÓ2€KØ�aÔÜØ*¨;¨-°s¸9¿=¹=ÈÐWfÓ;gÐ:hÐiókð 	kñ r$   c               ó(   € V ^8„  d   QhRRRRRRRR/# rÀ   r    )r!   s   "r"   r#   r#   ‰  s)   € ÷ 4=ñ 4= ð 4=°#ð 4=À>ð 4=ÐVYñ 4=r$   c                óÀ  € \        V4      p\        VR4      pVP                  R\        4      pVP                  R\        4      pVP
                  p^ RIHp \        VP                  R4      ;'       g    R4      P                  4       ;'       g!    V! R4      ;'       g    RP                  4       p	V	'       d   RV9  d   T R	V9   d   R
MR	 RV	 2pRV9   p
V
'       d~   RVRV RRVRVP                  RR4      RVP                  RR4      RVP                  R^ 4      RVP                  RR4      /RRVP                  RR4      RVP                  RR4      RRR^//pMRVRV RV/p\        W{RRRRVP                   2/4      pV
'       d}   VP                  4        \        VR R!7      p\        V4       VP                  R"/ 4      P                  R#R4      pV'       g   \        R$4      h\!        V\"        P%                  V4      4      # VP&                  P                  RR4      pR%V9   d   \!        V\)        VR R!7      4      # R&p \)        VR R!7      p\        V'       d&   \*        P,                  ! VP/                  R'4      4      M/ 4       \        R+4      h  \*        P0                  \2        \4        3 d-    TP                  4        \        R(T R)\7        T4       R*24      hi ; i),z¹Generate audio via MiniMax: ``t2a_v2`` (nested payload, JSON reply with hex audio) or the legacy
``text_to_speech`` endpoint (flat payload, raw ``audio/*`` body), detected from the URL.rG  Úmodelrå   r  Úgroup_idrI   ÚMINIMAX_GROUP_IDzGroupId=Ú?Ú&Út2a_v2rÁ   Úvoice_settingrÅ   r   ÚvolÚpitchÚemotionÚneutralÚaudio_settingr  i }  Úbitrater   r!   r;   Úchannelr"  r#  r   r!  zMiniMax TTSr$  ÚdataÚaudioz%MiniMax TTS returned empty audio datazaudio/r$   rj   z.MiniMax TTS returned unexpected Content-Type 'z' (z bytes)z"MiniMax TTS returned no audio data)rQ  r   rp   ÚDEFAULT_MINIMAX_MODELÚDEFAULT_MINIMAX_VOICE_IDr:  r.  r  r)   r*   rœ   rL   r2  r‰   rZ  rt   r‘   rf   Úfromhexr•   r{   r€   r�   r‚   ÚJSONDecodeErrorÚUnicodeDecodeErrorr  rs   )rÁ   r1   rÂ   ÚruntimerM  r]  rå   rÕ   r  r^  Ú	is_t2a_v2r”   rO   rS  Ú	hex_audioÚcontent_typeÚraw_bodys   &&&              r"   Ú_generate_minimax_ttsrw  ‰  sÑ  € ô +¨:Ó6€GÜ˜ YÓ/€IØ�M‰M˜'Ô#8Ó9€EØ�}‰}˜ZÔ)AÓB€HØ×Ñ€Hõ 0Ü�I—M‘M *Ó-×3Ð3°Ó4×:Ñ:Ó<÷ Eð EÙ!Ð"4Ó5×;Ð;¸×BÑBÓDð ç�J hÔ.Ø�Z s¨h¤¡¸CÐ@ÀÈÈ
ÐSˆØ˜HÑ$€Ißà�U˜F DØØ˜H g¨y¯}©}¸WÀcÓ/JÈEÐS\×S`ÑS`ÐafÐhkÓSlØ˜Ÿ™ w°Ó2°I¸y¿}¹}ÈYÐXaÓ?bðð Ø˜yŸ}™}¨]¸EÓBÀIÈyÏ}É}Ð]fÐhnÓOoØ˜% ¨Aðð

‰ð ˜E 6¨4°¸XÐFˆÜ˜(ØÐ*¨O¸wÀwÇÁÐFWÐ=Xð.Zó [€HçØ×!Ñ!Ô#Ü(¨¸ÔGˆÜ  Ô(Ø—J‘J˜v rÓ*×.Ñ.¨w¸Ó;ˆ	ßÜÐFÓGÐGÜ˜K¬¯©°yÓ)AÓBÐBØ×#Ñ#×'Ñ'¨¸Ó;€LØ�<ÔÜ˜KÔ)AÀ(ÐR_Ô)`ÓaÐaà€HðfÜ+¨H¸MÔJˆÜ Ï¤§¢¨H¯O©O¸GÓ,DÔ!EÐWYÔZô
 Ð;Ó
<Ð<øô	 × Ñ Ô"4´iÐ@ô fØ×!Ñ!Ô#ÜØ<¸\¸NÈ#ÌcÐRZËmÈ_Ð\cÐdófð 	fðfús   ÉAJ ÊAKc               ó(   € V ^8„  d   QhRRRRRRRR/# rÀ   r    )r!   s   "r"   r#   r#   Á  s)   € ÷ 2ñ 2 ð 2°#ð 2À>ð 2ÐVYñ 2r$   c           
     óø  € \        R RR4      pVP                  R4      ;'       g    / pRV/pVP                  R4      '       d   VR,          VR&   \        4       P                  4       p V! R/ VB ;_uu_ 4       pVP                  P
                  P                  VP                  R\        4      T VP                  R4      ;'       g    \        \        V4      R7      p\        P                  ! VP                  4      p	R	R	R	4       \)        TX	4      #   + '       g   i     L; i  \         d    h \         d@   p
\        P!                  R
T
RR7       \#        R\%        T
4      P&                   24      T
hR	p
?
ii ; i)ÚMISTRAL_API_KEYÚmistralz&Get one at https://console.mistral.ai/rL   rÕ   Ú
server_urlr]  rå   )r]  Úinputrå   Úresponse_formatNzMistral TTS failed: %sT)Úexc_infozMistral TTS failed: r    )rM   rp   r
   Ú_import_mistral_clientrl  ÚspeechÚcompleteÚDEFAULT_MISTRAL_TTS_MODELÚDEFAULT_MISTRAL_TTS_VOICE_IDrC   Úbase64Ú	b64decodeÚ
audio_datarK   r`   r»   Úerrorrt   rT   r=  r‘   )rÁ   r1   rÂ   rL   Ú	mi_configÚclient_kwargsÚMistralrð   rO   r‹   Úes   &&&        r"   Ú_generate_mistral_ttsr�  Á  sJ  € ÜÐ,¨iÐ9aÓb€GØ—‘˜yÓ)×/Ð/¨R€IØ%.°Ð$8€MØ‡}�}�Z× Ò Ø&/°
Õ&;ˆ�lÑ#Ü‹i×.Ñ.Ó0€GðMÙÑ%�}×%Ò%¨Ø—|‘|×*Ñ*×3Ñ3Ø—m‘m GÔ-FÓGÈtØ"Ÿ™ zÓ2×RÐRÔ6RÜ >¸{Ó Kð 4ó MˆHô !×*Ò*¨8×+>Ñ+>Ó?ˆK÷ &ô ˜ [Ó1Ð1÷ &×%ûô ô ØÜô MÜ�‰Ð-¨q¸4ˆÔ@ÜÐ1´$°q³'×2BÑ2BÐ1CÐDÓEÈ1ÐLûðMús=   Á)D$ Á9BDÃ=D$ ÄD!	ÄD$ Ä!D$ Ä$E9Ä9E9Ä::E4Å4E9c               ó    € V ^8„  d   QhRRRR/# )r   Úgemini_configr~   r   r)   r    )r!   s   "r"   r#   r#   Ø  s   € ÷ ñ ¨~ð À#ñ r$   c                ód  € V P                  R4      p\        V\        4      '       d   VP                  4       '       g   R# \	        \
        P                  P                  VP                  4       4      4      P                  4       pVP                  4       '       g    ^ RI
Hp V! 4       V,          p VP                  RR7      P                  4       #   \         d     \        P                  ! 4       T,          p LJi ; i  \        \         3 d"   p\"        P%                  RY$4        Rp?R# Rp?ii ; i)zVRead ``tts.gemini.persona_prompt_file`` (relative -> under HERMES_HOME), failing soft.Úpersona_prompt_filerI   )Úget_hermes_homez	utf-8-sig)Úencodingz4Gemini TTS persona prompt file unavailable at %s: %sN)rp   r&   r)   r*   r   ÚosÚpathÚ
expandvarsÚ
expanduserÚis_absoluteÚhermes_constantsr’  r`   ÚcwdÚ	read_textÚOSErrorrq  r»   Úwarning)r�  r}   r•  r’  r½   s   &    r"   Ú_read_gemini_persona_promptrž  Ø  sâ   € à
×
Ñ
Ð1Ó
2€CÜ�cœ3×Ò s§y¡y§{¢{ÙÜ”—‘×"Ñ" 3§9¡9£;Ó/Ó0×;Ñ;Ó=€DØ×Ñ×Òð	%Ý8Ù"Ó$ tÕ+ˆDðØ�~‰~ {ˆ~Ó3×9Ñ9Ó;Ð;øô ô 	%Ü—8’8“: Õ$ŠDð	%ûô Ô'Ð(ô Ü�‰ÐMÈtÔYÝûðús*   ÂC Â0C= Ã'C:Ã9C:Ã=D/ÄD*Ä*D/c               ó$   € V ^8„  d   QhRRRRRR/# )r   r�  r~   r]  r)   r   r   r    )r!   s   "r"   r#   r#   ë  s!   € ÷ ñ ¨nð ÀSð ÈTñ r$   c                ór  € V P                  R4      p\        V\        4      '       d   VP                  R4      p\        V\        R7      '       g   R# T;'       g    RP                  4       P                  4       P                  R^4      R,          pRV9   d
   RV9   d   R	# \        P                  R
V4       R# )zMAudio tags are opt-in and only Gemini 3.1 TTS models are known to honor them.Ú
audio_tagsÚenabled)r   FrI   rÖ   z
gemini-3.1ÚttsTzrGemini TTS audio_tags enabled, but model %s is not known to support Gemini audio tags; skipping hidden tag rewriterY  )
rp   r&   rƒ   r/   ÚDEFAULT_GEMINI_AUDIO_TAGSr*   r+   Úrsplitr»   r�  )r�  r]  r}   r.   s   &&  r"   Ú_gemini_audio_tags_enabledr¦  ë  s˜   € à
×
Ñ
˜LÓ
)€CÜ�#”t×ÒØ�g‰g�iÓ ˆÜ˜Ô%>×?Ó?ÙØ—+�+˜2×$Ñ$Ó&×,Ñ,Ó.×5Ñ5°c¸1Ó=¸bÕA€JØ�zÔ! e¨zÔ&9ÙÜ
‡N�Nð DØEJôLár$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rÁ   r)   Úpersona_promptr   r    )r!   s   "r"   r#   r#   ú  s&   € ÷ `ñ `¨ð `¸cð `È3ñ `r$   c           	     óð   € V P                  4       pV'       g   V # R\        ,           R,           \        ,           pRVP                  4       ;'       g    R RV 2p\        W4V RR\        P
                  R7      # )	zVUse the configured auxiliary model to insert Gemini audio tags (falls back to *text*).aÛ  You rewrite transcripts for Gemini 3.1 Flash TTS by inserting expressive audio tags.

Audio tags are inline square-bracket modifiers such as [whispers], [excitedly], [very slow], [sarcastically], [laughs], [sighs], or [gasp]. There is no fixed allowlist. Use creative freeform tags generously but naturally to control tone, pace, emotional vibe, emphasis, section-level delivery, and non-verbal sounds. Use English audio tags even when the spoken transcript is not English.

zJ- Use square brackets for every audio tag.
- Do not use SSML or XML tags.
zPERSONA AND DIRECTOR CONTEXT:
z(none)z

TRANSCRIPT TO TAG:
ú
Gemini TTSzuntagged textrù   )r*   rÿ   r   r¾   r  ÚWARNING)rÁ   r¨  Ú
transcriptr¬   r­   s   &&   r"   Ú_rewrite_gemini_tts_audio_tagsr­  ú  s‰   € à—‘“€JßØˆð	0ô õ	ð	+õ
	+ô õ	ð ð 5°^×5IÑ5IÓ5K×5WÐ5WÈxÐ4Xð Y*Ø*4¨ð7€Kä(¨ÀTÐQ]Ø8GÌwÏÉô`ð `r$   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rÁ   r)   r�  r~   r¨  zOptional[str]r   r    )r!   s   "r"   r#   r#     s0   € ÷ Vñ V Sð V¸ð VÐYfð VÐruñ Vr$   c                ó`  € V P                  4       pVf   \        V4      pV'       g   V# RpR Ff  p\        P                  ! V\        P                  R7      pVP                  V4      '       g   KB  V RVP                  W24       2P                  4       u # 	  V RV RV 2P                  4       # )z²Gemini prompt = persona direction + transcript; a ``{transcript}`` / ``{{transcript}}``
placeholder is substituted in place, otherwise the transcript is appended under a heading.z©Synthesize speech from the TRANSCRIPT only. Treat AUDIO PROFILE, SCENE, DIRECTOR'S NOTES, and SAMPLE CONTEXT as performance direction; do not speak those sections aloud.r¡   z

z

#### TRANSCRIPT
)z\{\{\s*transcript\s*\}\}z\{\s*transcript\s*\})r*   rž  r¤   ÚcompileÚ
IGNORECASErû   rß   )rÁ   r�  r¨  r¬  ÚpreambleÚpatternÚcompileds   &&&    r"   Ú_compose_gemini_tts_promptrµ    s«   € ð —‘“€JØÒÜ4°]ÓCˆßØÐð	-ð ó JˆÜ—:’:˜g¬R¯]©]Ô;ˆØ�?‰?˜>×*Ô*Ø�Z˜t H§L¡L°Ó$LÐ#MÐN×TÑTÓVÒVñ Jð ˆZ�t˜NÐ+Ð+@ÀÀÐM×SÑSÓUÐUr$   c               ó    € V ^8„  d   QhRRRR/# rž   r    )r!   s   "r"   r#   r#   %  s   € ÷ Gñ G 3ð G¨3ñ Gr$   c                óà   € \        V RR7      p \        W4      P                  R/ 4      P                  R4      pT;'       g    VP	                  RRR7      R	,          #   \         d    Rp L3i ; i)
zYBest-effort ``error.message`` from a non-200 Gemini reply, else the first 300 body chars.rª  r$  rˆ  r    Nrj   rk   rl   :Ni,  N)r{   r†   rp   r`   r‚   )rO   rv  r    s   &  r"   Ú_gemini_error_detailr¸  %  sm   € ä'¨¸ÔE€HðÜ" 8Ó6×:Ñ:¸7ÀBÓG×KÑKÈIÓVˆð ×FÐF�h—o‘o g°i�oÓ@ÀÕFÐFøô ô ØŠðús   �*A ÁA-Á,A-c               ó(   € V ^8„  d   QhRRRRRRRR/# rÀ   r    )r!   s   "r"   r#   r#   /  s/   € ÷ :[ñ :[˜sð :[°ð :[À.ð :[ÐUXñ :[r$   c           
     ó`  € \        4       pVP                  RR4      ;'       g    VP                  RR4      pV'       g   \        R4      h\        VR4      p\	        VP                  R\        4      4      P                  4       ;'       g    \        p\	        VP                  R\        4      4      P                  4       ;'       g    \        p^ RI	H
p ^ RIHp	 T	! VP                  R	4      ;'       g    V! R
4      ;'       g    \        4      p
\        V4      pT p\        WV4      '       d   \!        WR7      p\#        WÅVR7      pVP%                  RV4      p\'        V4      V8”  d   \        R\'        V4       RV R24      hRRRV/./.RRR.RRRRV/////pRRRV/p\)        V
4      P*                  R8X  d    ^ RIHp RV! 4       P0                   2VR&   \5        V
 R!V R"2VV4      pVP6                  ^È8w  d%   \9        R#VP6                   R$\;        V4       24      h \=        VR%R&7      pVR',          ^ ,          R(,          R,          p\?        R) V 4       R*4      pVf   \9        R+4      hVP                  R,4      ;'       g    VP                  R-4      ;'       g    / P                  R.R/4      pT'       g   \9        R14      h\G        \I        \J        PL                  ! T4      4      T4      #   \2         d
    R TR&    EL)i ; i  \@        \B        \D        3 d   p\9        R0T 24      ThR*p?ii ; i)2z¼Generate audio via Gemini ``generateContent`` (``responseModalities=["AUDIO"]``). The reply is
base64 24kHz mono 16-bit PCM, wrapped as WAV and ffmpeg-converted to the requested container.ÚGEMINI_API_KEYÚgeminiÚGOOGLE_API_KEYzIGEMINI_API_KEY not set. Get one at https://aistudio.google.com/app/apikeyr]  rÆ   r  )Únormalize_gemini_base_urlrÕ   ÚGEMINI_BASE_URL)r¨  z?Gemini TTS composed prompt exceeds the provider request limit (z > zˆ chars). Reduce the persona/audio-tag prompt or lower tts.gemini.max_text_length so long-form text is split with enough prompt headroom.ÚcontentsÚpartsrÁ   ÚgenerationConfigÚresponseModalitiesÚAUDIOÚspeechConfigÚvoiceConfigÚprebuiltVoiceConfigÚ	voiceNamer"  r#  zx-goog-api-keyz!generativelanguage.googleapis.com)Úget_version_infozhermes-agent/zX-Goog-Api-Clientzhermes-agent/0.0.0z/models/z:generateContentzGemini TTS API error (HTTP rW  rª  r$  Ú
candidatesri   c              3  óF   "  € T F  pR V9   g
   RV9   g   K  Vx € K  	  R# 5i)Ú
inlineDataÚinline_dataNr    )r6   Úps   & r"   r9   Ú'_generate_gemini_tts.<locals>.<genexpr>a  s!   é € ÐW¡e ¨|¸qÔ/@ÀMÐUVÑDVŸ1š1£eùs   ‚!—
!Nz+Gemini TTS response contained no audio datarÌ  rÍ  rk  rI   z#Gemini TTS response was malformed: z$Gemini TTS returned empty audio data)'r
   rJ   rK   r   r)   rp   ÚDEFAULT_GEMINI_TTS_MODELr*   ÚDEFAULT_GEMINI_TTS_VOICEr.  r  Úagent.gemini_native_adapterr¾  ÚDEFAULT_GEMINI_TTS_BASE_URLrž  r¦  r­  rµ  Ú_resolve_max_text_lengthrs   r	   rK  Úhermes_cli.version_inforÉ  Úbase_versionr`   rœ   rV  rt   r¸  r‰   rA   ÚKeyErrorÚ
IndexErrorr  r   r   r…  r†  )rÁ   r1   rÂ   ÚoriginrL   r�  r]  rÆ   r  r¾  rÕ   r¨  Ú
tts_scriptÚprompt_textÚmax_lenr”   r•   rÉ  rO   rk  rÁ  Ú
audio_partÚ	audio_b64rŒ  s   &&&                     r"   Ú_generate_gemini_ttsrß  /  sH  € ô ‹Y€FØ×*Ñ*Ð+;¸XÓF÷ $ð $È&×JfÑJfØ˜(óK$€GçÜÐdÓeÐeÜ˜Z¨Ó2€MÜ�×!Ñ! 'Ô+CÓDÓE×KÑKÓM×iÐiÔQi€EÜ�×!Ñ! 'Ô+CÓDÓE×KÑKÓM×iÐiÔQi€EÝ/ÝEÙ(Ø×Ñ˜*Ó%×hÐh©Ð7HÓ)I×hÐhÔMhó€Hô 1°Ó?€NØ€JÜ! -×7Ò7Ü3°DÔXˆ
Ü,Ø°.ôB€Kà×-Ñ-¨h¸
ÓC€GÜ
ˆ;Ó˜'Ô!ÜðÜ�KÓ Ð!  W Ið .1ð1ó2ð 	2ð 	�g ¨Ð 5Ð6Ð7Ð8ØØ  7 )Ø˜]Ð-BÀ[ÐRWÐDXÐ,YÐZð
ð€Gð Ð1Ð3CÀWÐM€GÜ�Ó×"Ñ"Ð&IÔIð	@Ý@Ø-:Ñ;KÓ;M×;ZÑ;ZÐ:[Ð+\ˆGÐ'Ñ(ô ˜X˜J h¨u¨gÐ5EÐFÈÐQXÓY€HØ×Ñ˜sÔ"ÜÐ8¸×9MÑ9MÐ8NÈcÔRfÐgoÓRpÐQqÐrÓsÐsðMÜ& x°|ÔDˆØ�\Õ" 1Õ% iÕ0°Õ9ˆÜÑW¡eÓWÐY]Ó^ˆ
ØÒÜÐLÓMÐMØ—^‘^ LÓ1×XÐX°Z·^±^ÀMÓ5R×XÐXÐVX×]Ñ]Ð^dÐfhÓiˆ	÷ ÜÐAÓBÐBÜÔ/´×0@Ò0@ÀÓ0KÓLÈkÓZÐZøô! ô 	@Ø+?ˆGÐ'Ô(ð	@ûô ”j¤)Ð,ô MÜÐ@ÀÀÐDÓEÈ1ÐLûðMús7   Æ9K, ÈA$L ÊL ÊL Ë,L Ë?L ÌL-ÌL(Ì(L-i   i   >   Ú1ÚonÚyesÚtruer¢  >   Ú0ÚnoÚoffÚfalseÚdisabled)F)Úpausez
long-pausezhum-tuneÚlaughÚchuckleÚgiggleÚcryÚtskztongue-clickz	lip-smackÚbreathÚinhaleÚexhaleÚsigh)ÚsoftÚwhisperÚloudzbuild-intensityzdecrease-intensityzhigher-pitchzlower-pitchÚslowÚfastz	sing-songÚsingingzlaugh-speakÚemphasis)rI   r4   )er@  Ú
__future__r   r…  r^   r€   r  r”  r¤   Údataclassesr   r   Úpathlibr   Útypingr   r   r   Úurllib.parser	   Útools.tts_tool_deliveryr
   r   r   r   r%  r   Ú	getLoggerr»   rÊ   rí   rî   Ú%DEFAULT_ELEVENLABS_STREAMING_MODEL_IDrm  rn  ÚDEFAULT_MINIMAX_BASE_URLÚDEFAULT_MINIMAX_CN_BASE_URLrƒ  r„  r&  r'  r(  r)  r*  r/  r+  r,  r0  r1  r-  rÐ  rÑ  rÓ  r¤  rº   rn   ro   r,   r-   r/   rC   rM   rY   ra   r{   r†   r‰   r‘   rœ   rª   rÿ   r   r¾   rÑ   rà   rò   rý   rþ   r°  rv   r±  rú   r¦   rü   r  r  r5  r8  rJ  Ú	frozensetrL  rQ  rZ  rw  r�  rž  r¦  r­  rµ  r¸  rß  r    r$   r"   Ú<module>r     s�  ðñõ #ã Û Û Û Û 	Û 	ß (Ý ß &Ñ &Ý !ç \Ó \Ý 0à	×	Ò	Ð+Ó	,€à'Ð Ø4Ð Ø6Ð Ø(;Ð %Ø&Ð Ø8Ð Ø=Ð ØBÐ Ø3Ð ØEÐ ØÐ ØÐ ØÐ ØÐ Ø$Ð Ø,Ð ð Ð ØÐ ØÐ Ø12Ð .Ø).Ð &Ø9Ð Ø!Ð ØPÐ Ø!Ð Ø 0Ð Ø 0Ð Ø )Ð â3€Ú6€÷^õSõõeõð"ÐRV÷ "õ6
ðdÐQU÷ dõõ_õ	6ðKð ð
 YÐ õõ"õNõ
ðGÐ ðVÐ ð —Z’ZØˆc�h‰hÐ.Ó/Ð0°
¸3¿8¹8ÐD]Ó;^Ð:_Ð_bÐcØ
�-‰-ôÐ ð ŸšÐ$EÈRÏYÉYÔWÐ õõ:
!õ6Zñt �$Ô÷%ð %ó ð%ð Ð 8¸$Ð@[Ð\Ð à‰iÐ)Ð+=Ð>Ó?Ø‰)Ð'Ð(Ó
)ð+Ð õ
võ0kõ4=õp2õ.õ&÷`÷0Võ&G÷:[r$   