
    L0&j                        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     A/home/ubuntu/.hermes/hermes-agent/plugins/web/searxng/provider.py_searxng_urlr   "   sz    333333mM**   
{ir**I2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    LNN###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    %gq 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 QUU7B//00155++,,"155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 "
 "
	99$$$!#56	   D !!####$ 	 	 	NN3S999 L#,2JLL        ! 	 	 	NN6<<< HxHH3HH       		99;;DD 	 	 	NN=sCCC C       	 hhy"--  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   