
    nSjH                        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Z G d de	          ZdS )	uB  Brave Search (free tier) — plugin form.

Subclasses :class:`agent.web_search_provider.WebSearchProvider` (the
plugin-facing ABC). The legacy in-tree module
``tools.web_providers.brave_free`` was removed in the same commit that
moved this code under ``plugins/``; this file is now the canonical
implementation.

Config keys this provider responds to::

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

Auth env var::

    BRAVE_SEARCH_API_KEY=...    # https://brave.com/search/api/ (free tier)
    )annotationsN)AnyDict)WebSearchProviderz.https://api.search.brave.com/res/v1/web/searchc                  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 )BraveFreeWebSearchProvideru   Search-only Brave provider using the free-tier Data-for-Search API.

    Free tier is 2,000 queries/month (1 qps). No content-extraction capability —
    users pair this with Firecrawl/Tavily/Exa for ``web_extract``.
    returnstrc                    dS )Nz
brave-free selfs    A/home/ice/.hermes/hermes-agent/plugins/web/brave_free/provider.pynamezBraveFreeWebSearchProvider.name(   s	     |    c                    dS )NBrave Search (Free)r   r   s    r   display_namez'BraveFreeWebSearchProvider.display_name.   s    $$r   boolc                >    ddl m} t           |d                    S )zFReturn True when ``BRAVE_SEARCH_API_KEY`` is set to a non-empty value.r   get_provider_envBRAVE_SEARCH_API_KEY)agent.web_search_providerr   r   )r   r   s     r   is_availablez'BraveFreeWebSearchProvider.is_available2   s/    >>>>>>$$%;<<===r   c                    dS )NTr   r   s    r   supports_searchz*BraveFreeWebSearchProvider.supports_search8   s    tr   c                    dS )NFr   r   s    r   supports_extractz+BraveFreeWebSearchProvider.supports_extract;   s    ur      querylimitintDict[str, Any]c                   ddl }ddlm}  |d          }|sdddS t          dt	          t          |          d	                    }	 |                    t          ||d
|ddd          }|                                 ny# |j	        $ r7}t                              d|           dd|j        j         dcY d}~S d}~w|j        $ r-}t                              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          pi                     dg           pg }
|
d|         }d t#          |          D             }t                              d|t'          |          t'          |
          |           dd|idS )zExecute a search against the Brave Search API.

        Returns ``{"success": True, "data": {"web": [{"title", "url", "description", "position"}]}}``
        on success, or ``{"success": False, "error": str}`` on failure.
        r   Nr   r   FzBRAVE_SEARCH_API_KEY is not set)successerror      )qcountzapplication/json)zX-Subscription-TokenAccept   )paramsheaderstimeoutzBrave Search HTTP error: %szBrave Search returned HTTP zBrave Search request error: %szCould not reach Brave Search: z%Brave Search response parse error: %sz-Could not parse Brave Search response as JSONwebresultsc           
         g | ]r\  }}t          |                    d d                    t          |                    dd                    t          |                    dd                    |dz   dsS )title urldescriptionr(   )r4   r6   r7   position)r
   get).0irs      r   
<listcomp>z5BraveFreeWebSearchProvider.search.<locals>.<listcomp>m   s     
 
 
 1 QUU7B//00155++,,"155#;#;<<E	 
 
 
r   z5Brave Search '%s': %d results (from %d raw, limit %d)T)r&   data)httpxr   r   maxminr#   r9   _BRAVE_ENDPOINTraise_for_statusHTTPStatusErrorloggerwarningresponsestatus_codeRequestErrorjson	Exception	enumerateinfolen)r   r!   r"   r?   r   api_keyr+   respexcr>   raw_results	truncatedweb_resultss                r   searchz!BraveFreeWebSearchProvider.search>   s    	>>>>>>""#9:: 	R$/PQQQ As3u::r**++	W99"U33,30     D !!####$ 	 	 	NN8#>>> Qs|7OQQ        ! 	W 	W 	WNN;SAAA$/UPS/U/UVVVVVVVV	W	`99;;DD 	` 	` 	`NNBCHHH$/^________	` xx,"11)R@@FB'	
 
 "),,
 
 
 	C	
 	
 	
  %)=>>>sN   	8B 
C8,B>8C8>C8"C3-C83C8<D 
EE :E Ec                    dddddddgdS )	Nr   freeu1   Free-tier API key — 2k queries/mo, search only.r   z Brave Search API key (free tier)zhttps://brave.com/search/api/)keypromptr6   )r   badgetagenv_varsr   r   s    r   get_setup_schemaz+BraveFreeWebSearchProvider.get_setup_schema   s4    )F 2@: 	
 
 	
r   N)r	   r
   )r	   r   )r    )r!   r
   r"   r#   r	   r$   )r	   r$   )__name__
__module____qualname____doc__propertyr   r   r   r   r   rU   r]   r   r   r   r   r   !   s             X
 % % % X%> > > >      A? A? A? A? A?F
 
 
 
 
 
r   r   )ra   
__future__r   loggingostypingr   r   r   r   	getLoggerr^   rE   rB   r   r   r   r   <module>rh      s    & # " " " " "  				         7 7 7 7 7 7		8	$	$Bl
 l
 l
 l
 l
!2 l
 l
 l
 l
 l
r   