Ë
    âß²j¢  ã                  óÄ   — d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZ  ej*                  e«      ZdZdd„Z G d„ d	e	«      ZddlZd
diZd„ Zy)uà   Exa web search + content extraction via the ``exa-py`` SDK (lazy-installed).

Env: ``EXA_API_KEY`` (https://exa.ai). Both methods are sync â€” Exa's SDK is
sync-only; the dispatcher threads extract when the caller is async.
é    )ÚannotationsN)ÚAnyÚDictÚList)ÚBaseWebSearchProviderÚcached_sdk_clientÚdocumentÚkeyless_extractÚkeyless_searchÚkeyless_variant_schemaÚprovider_envÚrun_extractÚ
run_searchÚ	search_okÚuse_keylessÚweb_hitzLEXA_API_KEY environment variable not set. Get your API key at https://exa.aic                 ó0   — dd„} t        ddt        d| «      S )Nc                óB   — ddl m}  || ¬«      }d|j                  d<   |S )Nr   )ÚExa)Úapi_keyzhermes-agentzx-exa-integration)Úexa_pyr   Úheaders)r   r   Úclients      ú=/home/ubuntu/.hermes/hermes-agent/plugins/web/exa/provider.pyÚ_factoryz!_get_exa_client.<locals>._factory   s#   € ÝÙ˜WÔ%ˆØ.<ˆ�‰Ð*Ñ+Øˆó    Ú_exa_clientÚEXA_API_KEYz
search.exa)r   ÚstrÚreturnr   )r   Ú_MISSING_KEY)r   s    r   Ú_get_exa_clientr"      s   € óô ˜]¨M¼<ÈÐW_Ó`Ð`r   c                  ó>   — e Zd ZdZdZdZdZdZdZd
dd„Z	dd„Z
dd„Zy	)ÚExaWebSearchProviderzExa search + extract provider.Úexar   r   Tc                ó:   ‡‡— dˆˆfd„}t        dt        |d¬«      S )Nc                 óÄ  •— t        dt        d«      «      rt        dd‰‰t        «      S t        j	                  d‰‰«       t        «       j                  ‰‰ddi¬«      } t        t        | j                  xs g «      D ��cg c]O  \  }}t        |j                  xs d|j                  xs dd	j                  |j                  xs g «      |d
z   «      ‘ŒQ c}}«      S c c}}w )Nr%   r   r   zExa search: '%s' (limit=%d)Ú
highlightsT)Únum_resultsÚcontentsÚ Ú é   )r   r   r   ÚloggerÚinfor"   Úsearchr   Ú	enumerateÚresultsr   ÚurlÚtitleÚjoinr(   )ÚresponseÚiÚrÚlimitÚquerys      €€r   Ú_bodyz*ExaWebSearchProvider.search.<locals>._body*   sÇ   ø€ Ü˜5¤,¨}Ó"=Ô>Ü% e¨U°E¸5Ä&ÓIÐIÜ�K‰KÐ5°u¸eÔDÜ&Ó(×/Ñ/°À5ÐT`ÐbfÐSgÐ/ÓhˆHÜä% h×&6Ñ&6Ò&<¸"Ó=÷á�A�qô ˜Ÿ™š  Q§W¡W¢]°°C·H±H¸Q¿\¹\Ò=OÈRÓ4PÐRSÐVWÑRWÕXóó ð ùó s   Â AC
r   T©Úsdk©r    úDict[str, Any])r   r.   )Úselfr:   r9   r;   s    `` r   r0   zExaWebSearchProvider.search)   s   ù€ ö	ô ˜%¤¨°DÔ9Ð9r   c                ó8   ‡— dˆfd„}t        dt        ‰|d¬«      S )Nc            	     óv  •— t        dt        d«      «      rt        dd‰t        «      S t        j	                  dt        ‰«      «       t        «       j                  ‰d¬«      } | j                  xs g D �cg c]9  }t        |j                  xs d|j                  xs d|j                  xs d«      ‘Œ; c}S c c}w )Nr%   r   r   zExa extract: %d URL(s)T)Útextr+   )r   r   r
   r.   r/   Úlenr"   Úget_contentsr2   r	   r3   r4   rC   )r6   r8   Úurlss     €r   r;   z+ExaWebSearchProvider.extract.<locals>._body7   s�   ø€ Ü˜5¤,¨}Ó"=Ô>Ü& u¨e°T¼6ÓBÐBÜ�K‰KÐ0´#°d³)Ô<Ü&Ó(×5Ñ5°dÀÐ5ÓFˆHØPX×P`ÑP`ÒPfÐdfÖgÈ1”H˜QŸU™Uš[ b¨!¯'©'ª-°R¸¿¹ºÀ2ÕFÒgÐgùÒgs   Á5>B6r   Tr<   )r    úList[Dict[str, Any]])r   r.   )r@   rF   Úkwargsr;   s    `  r   ÚextractzExaWebSearchProvider.extract6   s   ø€ õ	hô ˜5¤&¨$°¸4Ô@Ð@r   c                ó"   — t        ddddd¬«      S )Nr   r   zhttps://exa.aizqSemantic + neural web search with content extraction on Exa's anonymous free tier. Rate-limited under burst load.zfSemantic + neural web search with content extraction via the Exa SDK. Unthrottled, guaranteed service.)Úfree_tagÚpaid_tag)r   )r@   s    r   Úget_setup_schemaz%ExaWebSearchProvider.get_setup_schema@   s    € Ü%Ø�=Ð"2ð IØ}ô
ð 	
r   N)é   )r:   r   r9   Úintr    r?   )rF   z	List[str]rH   r   r    rG   r>   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚNAMEÚDISPLAY_NAMEÚKEY_ENVÚEXTRACTÚKEYLESSr0   rI   rM   © r   r   r$   r$       s.   „ Ù(à€DØ€LØ€GØ€GØ€Gô:óAô
r   r$   ÚWebSearchProvider)zagent.web_search_providerrZ   c                óÌ   — t         j                  | «      }|€t        dt        ›d| ›�«      ‚dd l}ddlm}  |t        | g|¢­Ž  t        |j                  |d   «      |d   «      S )Nzmodule z has no attribute r   )Ú	warn_oncer-   )	Ú_PLUGIN_COMPAT_LAZYÚgetÚAttributeErrorrP   Ú	importlibÚhermes_cli.plugin_compatr\   ÚgetattrÚimport_module)ÚnameÚtargetr`   r\   s       r   Ú__getattr__rf   T   se   € Ü ×$Ñ$ TÓ*€FØ€~Ü˜w¤x lÐ2DÀTÀHÐMÓNÐNÛÝ2ÙŒh˜Ð&˜vÓ&Ü�9×*Ñ*¨6°!©9Ó5°v¸a±yÓAÐAr   )r    r   )rS   Ú
__future__r   ÚloggingÚtypingr   r   r   Úplugins.web._commonr   r   r	   r
   r   r   r   r   r   r   r   r   Ú	getLoggerrP   r.   r!   r"   r$   Úosr]   rf   rY   r   r   ú<module>rm      st   ðñõ #ã ß "Ñ "÷÷ ÷ ó ð
 
ˆ×	Ñ	˜8Ó	$€à]€óaô%
Ð0ô %
óX 
ð ÐKðÐ ó
Br   