+
    kHàjn  ã                  ó   € R t ^ RIHt ^ RIt^ RIHtHtHtHt ^ RI	t	^ RI
HtHtHtHtHtHtHtHtHtHtHtHtHt ]P0                  ! ]4      tRtRRRR/tR	 R
 ltRR/R 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]4      t$R# )u“  Tavily web search + content extraction (``/search``, ``/extract``; sync httpx).

Env: ``TAVILY_API_KEY`` (https://app.tavily.com/home, optional), ``TAVILY_BASE_URL``.
Keyed requests use ``Authorization: Bearer``; without a key the request is
keyless (``X-Tavily-Access-Mode: keyless``). Tavily is NOT in the zero-config
keyless ring â€” keyless access is opt-in by selecting Tavily in ``hermes tools``.
)ÚannotationsN)ÚAnyÚDictÚListÚOptional)ÚSEARCH_LIMIT_CAPÚBaseWebSearchProviderÚdocumentÚextract_failÚhttp_status_detailÚprovider_envÚrun_extractÚ
run_searchÚsearch_failÚ	search_okÚsetup_schemaÚ	title_hitÚuse_keylesszhermes-agentÚinclude_raw_contentFÚinclude_imagesc               ó    € V ^8„  d   QhRRRR/# )é   Úapi_keyÚstrÚreturnzdict[str, str]© )Úformats   "Ú@/home/ubuntu/.hermes/hermes-agent/plugins/web/tavily/provider.pyÚ__annotate__r      s   € ÷ ñ ˜Sð  ^ñ ó    c                óD   € R \         /pV '       d   RV  2VR&   V# RVR&   V# )zX-Client-NamezBearer ÚAuthorizationÚkeylesszX-Tavily-Access-Mode)Ú_CLIENT_NAME)r   Úheaderss   & r   Ú_tavily_headersr%      s9   € Ø¤Ð-€GßØ%,¨W¨IÐ#6ˆ�Ñ ð €Nð +4ˆÐ&Ñ'Ø€Nr   r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úendpointr   Úpayloadúdict[str, Any]r   zOptional[str]r   r   )r   s   "r   r   r   %   s)   € ÷ ñ ˜cð ¨Nð Èð Ðaoñ r   c               óP  € Vf   \        R4      p\        R4      ;'       g    RpV RV P                  R4       2p\        P                  RW4       \        P
                  ! WA^<\        V4      R7      pVP                  R8¼  d   \        \        V4      4      hVP                  4       # )a  POST to Tavily and return parsed JSON. ``api_key=None`` reads ``TAVILY_API_KEY``;
pass ``""`` to force the keyless header even when a key exists
(``web.provider_tier.tavily: free``). Non-2xx raises ValueError with the body so
Tavily's rate-limit/upgrade text reaches the model.ÚTAVILY_API_KEYÚTAVILY_BASE_URLzhttps://api.tavily.comÚ/zTavily %s request to %s)ÚjsonÚtimeoutr$   i�  )r   ÚlstripÚloggerÚinfoÚhttpxÚpostr%   Ústatus_codeÚ
ValueErrorr   r.   )r'   r(   r   Úbase_urlÚurlÚresponses   &&$   r   Ú_tavily_requestr:   %   s”   € ð
 ‚ÜÐ/Ó0ˆÜÐ-Ó.×JÐJÐ2J€HØˆJ�a˜Ÿ™¨Ó,Ð-Ð
.€CÜ
‡K�KÐ)¨8Ô9Ü�zŠz˜#°RÄÐQXÓAYÔZ€HØ×Ñ˜sÔ"ÜÔ+¨HÓ5Ó6Ð6Ø�=‰=‹?Ðr   c               ó    € V ^8„  d   QhRRRR/# )r   r9   r)   r   r   )r   s   "r   r   r   5   s   € ÷ ñ ¨~ð À.ñ r   c                ó  € \        \        V P                  R . 4      4       UUu. uFJ  w  r\        VP                  RR4      VP                  RR4      VP                  RR4      V^,           4      NKL  	  upp4      # u uppi )ÚresultsÚtitleÚ r8   Úcontent)r   Ú	enumerateÚgetr   )r9   ÚiÚrs   &  r   Ú _normalize_tavily_search_resultsrE   5   sr   € Üä˜hŸl™l¨9°bÓ9Ô:ôá:‰DˆAô 	�!—%‘%˜ Ó$ a§e¡e¨E°2Ó&6¸¿¹¸iÈÓ8LÈaÐRSÍeÖTÙ:òó ð ùó s   ¤AA<
c               ó    € V ^8„  d   QhRRRR/# )r   r9   r)   r   úlist[dict[str, Any]]r   )r   s   "r   r   r   <   s   € ÷ ñ ¨.ð Ð=Qñ r   c                ó*  € V P                  R. 4       Uu. uFZ  p\        VP                  RR4      VP                  RR4      VP                  RR4      ;'       g    VP                  RR4      4      NK\  	  ppY P                  R. 4       Uu. uF/  p\        VP                  RR4      VP                  RR	4      4      NK1  	  up,          pY P                  R
. 4       Uu. uF  p\        \        V4      R	4      NK  	  up,          pV# u upi u upi u upi )zLMap ``/extract`` to documents without attributing missing URLs to a request.r=   r8   r?   r>   Úraw_contentr@   Úfailed_resultsÚerrorzextraction failedÚfailed_urls)rB   r	   Ú_failed_documentr   )r9   rD   Ú	documentsÚfÚus   &    r   Ú_normalize_tavily_documentsrQ   <   s  € ð —‘˜i¨Ô,óá,ˆAô 	�—‘�u˜bÓ! 1§5¡5¨°"Ó#5°q·u±u¸]ÈBÓ7O×7gÐ7gÐST×SXÑSXÐYbÐdfÓSgÖhÙ,ð ð ð ×coÑcoð  qAð  CEô  dFó  Gñ  dFÐ^_Ô" 1§5¡5¨°Ó#3°Q·U±U¸7ÐDWÓ5XÖYñ  dFñ  Gõ  G€IØÏÉÐVcÐegÔIhÓiÑIhÀAÔ"¤3 q£6Ð+>Ö?ÑIhÑiÕi€IØÐùòùò GùÚis   •ADÁDÂ5DÃDc               ó$   € V ^8„  d   QhRRRRRR/# )r   r8   r   rK   r   r)   r   )r   s   "r   r   r   G   s&   € ÷ wñ w˜#ð w cð w¨nñ wr   c                ó"   € R V RRRRRRRVRRV //# )r8   r>   r?   r@   rI   rK   ÚmetadataÚ	sourceURLr   )r8   rK   s   &&r   rM   rM   G   s*   € Ø�3˜  Y°°MÀ2ÀwÐPUÐWaÐdoÐqtÐcuÐvÐvr   c               ó    € V ^8„  d   QhRRRR/# )r   Úactionr   r   r   )r   s   "r   r   r   K   s   € ÷ Rñ R˜sð R sñ Rr   c                ó   € R V  R2# )zzTAVILY_API_KEY is not set. Get a key at https://app.tavily.com/home or select Tavily in `hermes tools` for opt-in keyless Ú.r   )rW   s   &r   Ú_missing_key_errorrZ   K   s)   € ð Hð  IOð  HPð  PQð  Rð  Rr   c               ó    € V ^8„  d   QhRRRR/# )r   rW   r   r   z(tuple[Optional[str], Optional[str], str]r   )r   s   "r   r   r   O   s   € ÷ Wñ W�#ð WÐBñ Wr   c                ó    € \        R4      p\        RV4      pV'       g   V'       g   R\        V 4      R3# V'       d   RMTRV'       d   R3# R3# )z¨``(request_key, missing_key_error, log_prefix)``: request key is ``""`` when forcing
keyless, ``None`` when neither key nor keyless applies (``missing_key_error`` set).r+   ÚtavilyNr?   zkeyless )r   r   rZ   )rW   r   Úforce_keylesss   &  r   Ú_authr_   O   sO   € ô Ð+Ó,€GÜ ¨'Ó2€Mß§ØÔ'¨Ó/°Ð3Ð3ß‰2 G¨TÇ°:ÐVÐVÐTVÐVÐVr   c                  óV   € ] tR t^YtRtRtRtRtRtRt	RR R llt
R R	 ltR
 R ltRtR# )ÚTavilyWebSearchProviderz<Tavily search + extract provider (keyed, or opt-in keyless).r]   ÚTavilyr+   Tc               ó$   € V ^8„  d   QhRRRRRR/# )r   Úqueryr   ÚlimitÚintr   r)   r   )r   s   "r   r   Ú$TavilyWebSearchProvider.__annotate__b   s!   € ÷ 	3ñ 	3˜Cð 	3¨ð 	3°Nñ 	3r   c                	ó<   aa€ R  VV3R llp\        R\        V4      # )c               ó   € V ^8„  d   QhRR/# ©r   r   r)   r   )r   s   "r   r   Ú4TavilyWebSearchProvider.search.<locals>.__annotate__c   s   € ÷ 	eñ 	e�~ñ 	er   c                 óÖ   <€ \        R 4      w  rpV'       d   \        V4      # \        P                  RVSS4       RSR\	        S\
        4      /\        Cp\        \        R W0R7      4      # )Úsearchz Tavily %ssearch: '%s' (limit=%d)rd   Úmax_results©r   )	r_   r   r1   r2   Úminr   Ú_SEARCH_PAYLOADrE   r:   )ÚkeyÚmissingÚprefixr(   re   rd   s       €€r   Ú_bodyÚ-TavilyWebSearchProvider.search.<locals>._bodyc   s`   ø€ Ü#(¨£?Ñ ˆC˜&ßÜ" 7Ó+Ð+Ü�K‰KÐ:¸FÀEÈ5ÔQØ  }´c¸%ÔAQÓ6RÐfÔVeÐfˆGÜ3´OÀHÈgÔ4cÓdÐdr   rb   )r   r1   )Úselfrd   re   ru   s   &ff r   rm   ÚTavilyWebSearchProvider.searchb   s    ù€ ÷	eñ 	eô ˜(¤F¨EÓ2Ð2r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úurlsz	list[str]Úkwargsr   r   rG   r   )r   s   "r   r   rg   m   s"   € ÷ 	:ñ 	:˜Ið 	:°ð 	:Ð9Mñ 	:r   c                	ó:   a€ R  V3R llp\        R\        SV4      # )c               ó   € V ^8„  d   QhRR/# )r   r   rG   r   )r   s   "r   r   Ú5TavilyWebSearchProvider.extract.<locals>.__annotate__n   s   € ÷ 	4ñ 	4Ð+ñ 	4r   c                 óÂ   <€ \        R 4      w  rpV'       d   \        SV4      # \        P                  RV\	        S4      4       \        R RSRR/V R7      p\        V4      # )ÚextractzTavily %sextract: %d URL(s)rz   r   Fro   )r_   r
   r1   r2   Úlenr:   rQ   )rr   rs   rt   Úrawrz   s       €r   ru   Ú.TavilyWebSearchProvider.extract.<locals>._bodyn   s[   ø€ Ü#(¨Ó#3Ñ ˆC˜&ßÜ# D¨'Ó2Ð2Ü�K‰KÐ5°v¼sÀ4»yÔIÜ! )¨f°dÐ<LÈeÐ-TÐ^aÔbˆCÜ.¨sÓ3Ð3r   rb   )r   r1   )rw   rz   r{   ru   s   &f, r   r€   ÚTavilyWebSearchProvider.extractm   s    ø€ ÷	4ð 	4ô ˜8¤V¨T°5Ó9Ð9r   c               ó   € V ^8„  d   QhRR/# rj   r   )r   s   "r   r   rg   x   s   € ÷ 
ñ 
 .ñ 
r   c                	ó"   € \        R RRRRR4      # )rb   u   free Â· key optionalzGSearch + extract. Opt-in keyless; set TAVILY_API_KEY for higher limits.r+   uC   Tavily API key (optional â€” keyless works when Tavily is selected)zhttps://app.tavily.com/home)r   )rw   s   &r   Úget_setup_schemaÚ(TavilyWebSearchProvider.get_setup_schemax   s%   € ÜØÐ,Ð.wØÐcð  fCó
ð 	
r   r   N)é   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚNAMEÚDISPLAY_NAMEÚKEY_ENVÚEXTRACTÚKEYLESSrm   r€   r‡   Ú__static_attributes__r   r   r   ra   ra   Y   s2   † ÙFà€DØ€LØ€GØ€GØ€G÷	3õ	:÷
ñ 
r   ra   )%rŽ   Ú
__future__r   ÚloggingÚtypingr   r   r   r   r3   Úplugins.web._commonr   r   r	   r
   r   r   r   r   r   r   r   r   r   Ú	getLoggerrŠ   r1   r#   rq   r%   r:   rE   rQ   rM   rZ   r_   ra   r   r   r   Ú<module>rš      s�   ðñõ #ã ß ,Ó ,ã ÷÷ ÷ õ ð
 
×	Ò	˜8Ó	$€à€à(¨%Ð1AÀ5ÐI€õðÐX\÷ õ õõwõRõWô#
Ð3ö #
r   