§
    øžyjè  ã                  ó†   — d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	  ej
        e¦  «        Zdd„Z G d	„ d
e	¦  «        ZdS )uÈ  SearXNG search â€” plugin form.

Subclasses :class:`agent.web_search_provider.WebSearchProvider`. Same JSON
API call (``/search?format=json``), same result normalization. The legacy
in-tree module ``tools.web_providers.searxng`` was removed in the same
commit that moved this code under ``plugins/``; this file is now the
canonical implementation.

Search-only â€” SearXNG aggregates results from upstream engines but does not
fetch/extract arbitrary URLs. ``supports_extract()`` returns False.

Config keys this provider responds to::

    web:
      search_backend: "searxng"     # explicit per-capability
      backend: "searxng"            # shared fallback

Env var::

    SEARXNG_URL=http://localhost:8080
é    )ÚannotationsN)ÚAnyÚDict)ÚWebSearchProviderÚreturnÚstrc                 ó¦   — 	 ddl m}   | d¦  «        }n# t          $ r d}Y nw xY w|€t          j        dd¦  «        }|pd                     ¦   «         S )zMReturn SEARXNG_URL from Hermes config-aware env, falling back to process env.r   )Úget_env_valueÚSEARXNG_URLNÚ )Úhermes_cli.configr
   Ú	ExceptionÚosÚgetenvÚstrip)r
   Úvals     úB/home/ragecks/.hermes/hermes-agent/plugins/web/searxng/provider.pyÚ_searxng_urlr   "   sz   € ðØ3Ð3Ð3Ð3Ð3Ð3àˆm˜MÑ*Ô*ˆˆøÝð ð ð Øˆˆˆðøøøà
€{ÝŒi˜ rÑ*Ô*ˆØˆI�2×ÒÑÔÐs   ‚ ”#¢#c                  ól   — e Zd ZdZedd„¦   «         Zedd„¦   «         Zdd„Zdd„Zdd	„Z	ddd„Z
dd„ZdS )ÚSearXNGWebSearchProviderz*Search via a user-hosted SearXNG instance.r   r   c                ó   — dS )NÚsearxng© ©Úselfs    r   ÚnamezSearXNGWebSearchProvider.name2   ó   € àˆyó    c                ó   — dS )NÚSearXNGr   r   s    r   Údisplay_namez%SearXNGWebSearchProvider.display_name6   r   r   Úboolc                ó8   — t          t          ¦   «         ¦  «        S )z(Return True when ``SEARXNG_URL`` is set.)r"   r   r   s    r   Úis_availablez%SearXNGWebSearchProvider.is_available:   s   € å•L‘N”NÑ#Ô#Ð#r   c                ó   — dS )NTr   r   s    r   Úsupports_searchz(SearXNGWebSearchProvider.supports_search>   s   € Øˆtr   c                ó   — dS )NFr   r   s    r   Úsupports_extractz)SearXNGWebSearchProvider.supports_extractA   s   € Øˆur   é   ÚqueryÚlimitÚintúDict[str, Any]c                ór  — ddl }t          ¦   «                              d¦  «        }|sdddœS |ddd	œ}	 |                     |› d
�|dddi¬¦  «        }|                     ¦   «          n|# |j        $ r7}t                               d|¦  «         dd|j        j	        › �dœcY d}~S d}~w|j
        $ r0}t                               d|¦  «         dd|› d|› �dœcY d}~S d}~ww xY w	 |                     ¦   «         }n7# t          $ r*}t                               d|¦  «         dddœcY d}~S d}~ww xY w|                     dg ¦  «        }	t          |	d„ d¬¦  «        d|…         }
d„ t          |
¦  «        D ¦   «         }t                               d|t!          |¦  «        t!          |	¦  «        |¦  «         dd|idœS )z9Execute a search against the configured SearXNG instance.r   Nú/FzSEARXNG_URL is not set)ÚsuccessÚerrorÚjsoné   )ÚqÚformatÚpagenoz/searché   ÚAcceptzapplication/json)ÚparamsÚtimeoutÚheaderszSearXNG HTTP error: %szSearXNG returned HTTP zSearXNG request error: %szCould not reach SearXNG at z: z SearXNG response parse error: %sz(Could not parse SearXNG response as JSONÚresultsc                óH   — t          |                      dd¦  «        ¦  «        S )NÚscorer   )ÚfloatÚget)Úrs    r   ú<lambda>z1SearXNGWebSearchProvider.search.<locals>.<lambda>u   s   € �% §¢ g¨qÑ 1Ô 1Ñ2Ô2€ r   T)ÚkeyÚreversec           
     óî   — g | ]r\  }}t          |                     d d¦  «        ¦  «        t          |                     dd¦  «        ¦  «        t          |                     dd¦  «        ¦  «        |dz   dœ‘ŒsS )Útitler   ÚurlÚcontentr3   )rF   rG   ÚdescriptionÚposition)r   r@   )Ú.0ÚirA   s      r   ú
<listcomp>z3SearXNGWebSearchProvider.search.<locals>.<listcomp>y   s‡   € ð 
ð 
ð 
ñ ��1õ ˜QŸUšU 7¨BÑ/Ô/Ñ0Ô0Ý˜1Ÿ5š5 ¨Ñ+Ô+Ñ,Ô,Ý" 1§5¢5¨°BÑ#7Ô#7Ñ8Ô8Ø ™Eð	ð ð
ð 
ð 
r   z7SearXNG search '%s': %d results (from %d raw, limit %d)Úweb)r0   Údata)Úhttpxr   Úrstripr@   Úraise_for_statusÚHTTPStatusErrorÚloggerÚwarningÚresponseÚstatus_codeÚRequestErrorr2   r   ÚsortedÚ	enumerateÚinfoÚlen)r   r*   r+   rP   Úbase_urlr9   ÚrespÚexcrO   Úraw_resultsÚsorted_resultsÚweb_resultss               r   ÚsearchzSearXNGWebSearchProvider.searchD   s¯  € àˆˆˆå‘>”>×(Ò(¨Ñ-Ô-ˆØð 	IØ$Ð/GÐHÐHÐHð ØØð"
ð "
ˆð	Ø—9’9ØÐ$Ð$Ð$ØØØ!Ð#5Ð6ð	 ñ ô ˆDð ×!Ò!Ñ#Ô#Ð#Ð#øØÔ$ð 	ð 	ð 	Ý�NŠNÐ3°SÑ9Ô9Ð9à ØL°#´,Ô2JÐLÐLðð ð ð ð ð ð ð øøøøð Ô!ð 	ð 	ð 	Ý�NŠNÐ6¸Ñ<Ô<Ð<à ØH°xÐHÐHÀ3ÐHÐHðð ð ð ð ð ð ð øøøøð	øøøð	Ø—9’9‘;”;ˆDˆDøÝð 	ð 	ð 	Ý�NŠNÐ=¸sÑCÔCÐCà ØCðð ð ð ð ð ð ð øøøøð	øøøð —h’h˜y¨"Ñ-Ô-ˆõ  ØØ2Ð2Øð
ñ 
ô 
ð ˆ5ˆ&ô	ˆð
ð 
õ " .Ñ1Ô1ð
ñ 
ô 
ˆõ 	�ŠØEØÝ�ÑÔÝ�ÑÔØñ	
ô 	
ð 	
ð  ¨%°Ð)=Ð>Ð>Ð>sM   ´2A' Á'
C Á1,B#ÂC Â#C Â0%CÃC ÃC Ã$C9 Ã9
D-ÄD(Ä"D-Ä(D-c                ó   — dddddddœgdœS )	Nr    u   free Â· self-hostedzHFree, privacy-respecting metasearch. Point SEARXNG_URL at your instance.r   z1SearXNG instance URL (e.g. http://localhost:8080)zhttps://searx.space/)rC   ÚpromptrG   )r   ÚbadgeÚtagÚenv_varsr   r   s    r   Úget_setup_schemaz)SearXNGWebSearchProvider.get_setup_schema�   s4   € àØ*Ø]ð )ØQØ1ðð ðð	
ð 
ð 	
r   N©r   r   )r   r"   )r)   )r*   r   r+   r,   r   r-   )r   r-   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úpropertyr   r!   r$   r&   r(   rc   ri   r   r   r   r   r   /   sÇ   € € € € € Ø4Ð4àðð ð ñ „Xðð ðð ð ñ „Xðð$ð $ð $ð $ðð ð ð ðð ð ð ðG?ð G?ð G?ð G?ð G?ðR
ð 
ð 
ð 
ð 
ð 
r   r   rj   )rn   Ú
__future__r   Úloggingr   Útypingr   r   Úagent.web_search_providerr   Ú	getLoggerrk   rT   r   r   r   r   r   ú<module>ru      sÄ   ððð ð, #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø Ð Ð Ð Ð Ð Ð Ð à 7Ð 7Ð 7Ð 7Ð 7Ð 7à	ˆÔ	˜8Ñ	$Ô	$€ð
ð 
ð 
ð 
ðj
ð j
ð j
ð j
ð j
Ð0ñ j
ô j
ð j
ð j
ð j
r   