+
    lHàj!  ã                  ó8  € R t ^ RIHt ^ RIt^ RI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HtHtHt ^ RIHtHt ^ RIHt ]P2                  ! R	4      tR
t]! R
04      tRtRtRt R R lt!R R lt"R R lt#R R lt$RRRRRRRRRRRR/R R llt%R R lt&R# ) a‹  OpenAI-compatible TTS backends for ``tools.tts_tool``: OpenAI and DeepInfra.

Also owns the managed-gateway (Nous portal ``openai-audio`` proxy) route selection that
decides where the OpenAI client points. Seams defined on the origin module (``_load_tts_config``,
``_import_openai_client``, ``_resolve_provider_key``, ``_generate_openai_tts``) are resolved
through :func:`_origin` at call time.
)ÚannotationsN)ÚAnyÚDictÚOptional)Úurljoin)Úresolve_managed_tool_gateway)ÚNOUS_MANAGED_PROVIDERÚmanaged_nous_tools_enabledÚ%nous_tool_gateway_unavailable_messageÚread_selectionÚresolve_openai_audio_api_keyÚselection_error)Ú_originÚ_section)Ú_tts_response_format_from_pathztools.tts_toolzgpt-4o-mini-ttsÚalloyzhttps://api.openai.com/v1Údefaultc               ó   € V ^8„  d   QhRR/# )é   ÚreturnzOptional[tuple]© )Úformats   "Ú:/home/ubuntu/.hermes/hermes-agent/tools/tts_tool_openai.pyÚ__annotate__r   "   s   € ÷ bñ b _ñ bó    c                 óŽ   € \        R 4      p V f   R# V P                  \        V P                  P	                  R4       R2R4      R3# )zopenai-audioNÚ/Úv1T)r   Únous_user_tokenr   Úgateway_originÚrstrip)Úgateways    r   Ú_managed_openai_audio_router"   "   sJ   € Ü*¨>Ó:€GØ‚ÙØ×"Ñ"¤G¨w×/EÑ/E×/LÑ/LÈSÓ/QÐ.RÐRSÐ,TÐVZÓ$[Ð]aÐaÐar   c               ó   € V ^8„  d   QhRR/# )r   r   ztuple[str, str, bool]r   )r   s   "r   r   r   )   s   € ÷ ñ Ð-Bñ r   c                 ó"  € \        4       p \        V P                  4       R4      p\        R4      pV\        8X  d+   \        4       pVf   \        \        R\        R4      4      hV# VP                  R4      ;'       g    \        4       pV'       d"   YAP                  R4      ;'       g    \        R3# Ve   \        \        RVR4      4      h\        4       pVf7   Rp\        4       '       d   VR	\        R
4      ,           ,          p\        V4      hV# )u‰  ``(api_key, base_url, is_managed)`` for the OpenAI audio client (``is_managed`` = the restricted
Nous proxy, so callers coerce the request). Strict on the stored ``tts`` selection: ``"nous"``
â†’ managed ONLY (error if unavailable); any other â†’ direct credentials ONLY (``tts.openai.api_key``
then ``VOICE_TOOLS_OPENAI_KEY``/``OPENAI_API_KEY``); unset â†’ config key â†’ env key â†’ managed.ÚopenaiÚttszDthe Nous Tool Gateway is not available (not entitled or unreachable)Úapi_keyÚbase_urlFzUneither tts.openai.api_key in config nor VOICE_TOOLS_OPENAI_KEY/OPENAI_API_KEY is setzUNeither tts.openai.api_key in config nor VOICE_TOOLS_OPENAI_KEY/OPENAI_API_KEY is setz. zmanaged OpenAI audio for TTS)r   r   Ú_load_tts_configr   r   r"   Ú
ValueErrorr   Úgetr   ÚDEFAULT_OPENAI_BASE_URLr	   r
   )ÚoriginÚ
openai_cfgÚselectedÚrouteÚdirect_api_keyÚmessages         r   Ú#_resolve_openai_audio_client_configr3   )   s  € ô
 ‹Y€FÜ˜&×1Ñ1Ó3°XÓ>€JÜ˜eÓ$€HØÔ(Ô(Ü+Ó-ˆØŠ=Üœ_ØÔ,ØVóXó Yð Yð ˆØ—^‘^ IÓ.×PÐPÔ2NÓ2P€NßØŸ~™~¨jÓ9×TÐTÔ=TÐV[Ð[Ð[ØÒÜœØ�8Øcó
ó ð 	ô (Ó)€EØ‚}ØiˆÜ%×'Ò'Ø�tÔCÐDbÓcÕcÕcˆGÜ˜Ó!Ð!Ø€Lr   c               ó   € V ^8„  d   QhRR/# )r   r   Úboolr   )r   s   "r   r   r   I   s   € ÷ ñ  4ñ r   c                 ó@   €  \        4        R#   \         d     R# i ; i)z;Return True when the selected OpenAI audio route is usable.TF)r3   r*   r   r   r   Ú_has_openai_audio_backendr7   I   s"   € ðÜ+Ô-ÙøÜô Úðús   ‚
 Žœc               ó    € V ^8„  d   QhRRRR/# )r   Ú
oai_configúdict[str, Any]r   r   )r   s   "r   r   r   R   s   € ÷ 	ñ 	 >ð 	°nñ 	r   c                ó–   € / pV P                  R4      '       d   V R,          VR&   V P                  R4      '       d   V R,          VR&   V# )zûOptional ``tts.openai`` fields OpenAI-compatible servers read from the JSON body: ``language``
(sent as ``lang_code``) and ``consent_attestation`` (cloned voices). Unset keys are omitted so
the official API and strict servers never see unknown fields.ÚlanguageÚ	lang_codeÚconsent_attestation)r+   )r9   Ú
extra_bodys   & r   Ú_openai_extra_bodyr@   R   sN   € ð "$€JØ‡~�~�j×!Ò!Ø",¨ZÕ"8ˆ
�;ÑØ‡~�~Ð+×,Ò,Ø,6Ð7LÕ,Mˆ
Ð(Ñ)ØÐr   r'   r(   ÚmodelÚvoiceÚspeedÚinstructionsc               ó@   € V ^8„  d   QhRRRRRRRRRRR	RR
RRRRRRR/
# )r   ÚtextÚstrÚoutput_pathÚ
tts_configr:   r'   zOptional[str]r(   rA   rB   rC   zOptional[float]rD   r   r   )r   s   "r   r   r   ^   sd   € ÷ 4ñ 4Ø
ð4Øð4Ø-;ð4ØIVð4àð4à+8ð4àHUð4ð ð4ð 2?ð4ð KNñ4r   c               ól  € Rp	Rp
VRJpVf   \        4       w  r9p
\        VR4      pVf   VP                  R\        4      pVf   VP                  R\        4      pVP                  R4      pVf   T;'       g    T	;'       g    \
        pVfF   \        V\        4      '       d   VP                  RR4      MRp\        VP                  RV4      4      pV
'       d>   V'       g6   V'       g.   V\        9  d#   \        P                  R	V\        V4       \        pRVRVR
V R\        V4      RR\        \        P                  ! 4       4      //pVR8w  d   \!        R\#        RV4      4      VR&   V'       d   W�R&   \%        V4      ;p'       d   VVR&   \'        4       P)                  4       ! W4R7      p VP*                  P,                  P.                  ! R/ VB P1                  V4       T\3        VRR4      p\5        V4      '       d	   V! 4        # #   \3        TRR4      p\5        T4      '       d	   T! 4        i i ; i)a°  Generate audio via the OpenAI ``audio.speech.create`` SDK shape.

Explicit kwargs let OpenAI-compatible backends (DeepInfra) supply credentials/model/voice
and skip the managed-gateway resolution; otherwise the OpenAI auth chain and ``tts.openai``
(speed falling back to ``tts.speed``) apply. ``instructions`` is forwarded only when truthy
so ``tts-1`` and strict OpenAI-compatible servers that reject unknown kwargs are unaffected.NFr%   rA   rB   r(   rC   ç      ð?z‘TTS: managed OpenAI audio gateway does not support model %r; falling back to %s. Set VOICE_TOOLS_OPENAI_KEY or OPENAI_API_KEY to use %r directly.ÚinputÚresponse_formatÚextra_headerszx-idempotency-keyg      Ð?g      @rD   r?   )r'   r(   Úcloser   )r3   r   r+   ÚDEFAULT_OPENAI_MODELÚDEFAULT_OPENAI_VOICEr,   Ú
isinstanceÚdictÚfloatÚMANAGED_OPENAI_TTS_MODELSÚloggerÚwarningr   rG   ÚuuidÚuuid4ÚmaxÚminr@   r   Ú_import_openai_clientÚaudioÚspeechÚcreateÚstream_to_fileÚgetattrÚcallable)rF   rH   rI   r'   r(   rA   rB   rC   rD   Úfallback_baseÚ
is_managedÚexplicit_base_urlr9   Úconfig_base_urlÚspeed_defaultÚcreate_kwargsr?   ÚclientrO   s   &&&$$$$$$          r   Ú_generate_openai_ttsrj   ^   sþ  € ð $(€MØ€JØ ¨Ð,ÐØ‚Ü-PÓ-RÑ*ˆ 
Ü˜* hÓ/€JØ‚}Ø—‘˜wÔ(<Ó=ˆØ‚}Ø—‘˜wÔ(<Ó=ˆØ —n‘n ZÓ0€OØÒØ"×NÐN m×NÐNÔ7NˆØ‚}Ü8BÀ:Ìt×8TÒ8T˜
Ÿ™ w°Ô4ÐZ]ˆÜ�j—n‘n W¨mÓ<Ó=ˆ÷ ×+·OÈÔUnÔHnÜ�‰ð"ð Ô'¨ô		0ô
 %ˆà�˜ ¨°ØÔ9¸+ÓFØÐ-¬s´4·:²:³<Ó/@ÐAð%C€Mð �„|Ü!$ T¬3¨s°E«?Ó!;ˆ�gÑßØ(4�nÑ%Ü'¨
Ó3Ð3€zÖ3Ø&0ˆ�lÑ#Ü‹Y×,Ñ,Ô.°wÔR€FðØ�‰×Ñ×"Ò"Ñ3 ]Ñ3×BÑBÀ;ÔOØä˜ ¨Ó.ˆÜ�E�?Š?Ù�Gð øô ˜ ¨Ó.ˆÜ�E�?Š?Ù�Gð ús   Æ.6H È(H3c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rF   rG   rH   rI   r:   r   r   )r   s   "r   r   r   •   s/   € ÷ Kñ K #ð K°Cð KÀ^ð KÐX[ñ Kr   c                ó  € \        4       P                  RR4      pV'       g   \        R4      h\        VR4      p^ RIHpHp VP                  R4      p\        V\        4      '       d   VP                  4       '       g%   V! R4      pV'       g   \        R4      hV^ ,          p\        4       P                  WW#V! V4      WtP                  R\        4      \        VP                  R	VP                  R	R
4      4      4      R7      # )z‹Resolve DeepInfra credentials/model (live ``hermes_cli.models`` catalog, no hardcoded ids), then
delegate to the OpenAI-compatible handler.ÚDEEPINFRA_API_KEYÚ	deepinfrazXDEEPINFRA_API_KEY not set. Run `hermes setup` to configure, or set the env var directly.)Údeepinfra_base_urlÚdeepinfra_model_idsrA   r&   z¢No DeepInfra TTS model available. Pin one in config.yaml under tts.deepinfra.model, or check connectivity to api.deepinfra.com so the live catalog can be fetched.rB   rC   rK   )r'   r(   rA   rB   rC   )r   Ú_resolve_provider_keyr*   r   Úhermes_cli.modelsro   rp   r+   rR   rG   Ústriprj   ÚDEFAULT_DEEPINFRA_TTS_VOICErT   )	rF   rH   rI   r'   Ú	di_configro   rp   rA   Ú
candidatess	   &&&      r   Ú_generate_deepinfra_ttsrw   •   sà   € ô ‹i×-Ñ-Ð.AÀ;ÓO€GßÜÐsÓtÐtÜ˜ [Ó1€IßIØ�M‰M˜'Ó"€EÜ�eœS×!Ò!¨¯©¯ªÙ(¨Ó/ˆ
ßÜðHóIð Ið ˜1•ˆÜ‹9×)Ñ)Ø˜:ÑASÐT]ÓA^ØŸ=™=¨Ô2MÓNÜ�I—M‘M '¨:¯>©>¸'À3Ó+GÓHÓIð *ó Kð Kr   )'Ú__doc__Ú
__future__r   ÚloggingrX   Útypingr   r   r   Úurllib.parser   Útools.managed_tool_gatewayr   Útools.tool_backend_helpersr   r	   r
   r   r   r   Útools.tts_tool_deliveryr   r   Útools.tts_tool_providersr   Ú	getLoggerrV   rP   Ú	frozensetrU   rQ   r,   rt   r"   r3   r7   r@   rj   rw   r   r   r   Ú<module>rƒ      sÅ   ðñõ #ã Û ß &Ñ &Ý  å C÷C÷ C÷ 6Ý Cà	×	Ò	Ð+Ó	,€à(Ð á%Ð'8Ð&9Ó:Ð ØÐ Ø5Ð à'Ð õbõõ@õ	ð4ØY]ð4à"ð4à;?ð4àX\ð4ð "ð4ð BF÷4÷nKr   