
    ,Vj                    v    d Z ddlmZ ddlZddlmZmZ ddlmZ  ej	        e
          Z G d de          ZdS )u  DuckDuckGo web search provider via the ``ddgs`` Python package.

DuckDuckGo does not provide an official programmatic search API.  The
community-maintained `ddgs <https://pypi.org/project/ddgs/>`_ package (the
renamed successor of ``duckduckgo-search``) scrapes DuckDuckGo's HTML results
page and normalizes them.  It implements ``WebSearchProvider`` only — there is
no extract capability.

Configuration::

    # No API key required. Enable by installing the package and pointing the
    # web backend at ddgs:
    pip install ddgs

    # ~/.hermes/config.yaml
    web:
      search_backend: "ddgs"
      extract_backend: "firecrawl"    # pair with an extract provider if needed

Rate limits are enforced server-side by DuckDuckGo.  Expect intermittent
``DuckDuckGoSearchException`` / 202 responses under heavy use; this provider
surfaces them as ``{"success": False, "error": ...}`` rather than crashing
the tool call.

See https://duckduckgo.com/?q=duckduckgo+tos for terms of use.
    )annotationsN)AnyDict)WebSearchProviderc                  ,    e Zd ZdZddZddZdddZdS )DDGSSearchProvideru   Search via the ``ddgs`` package (DuckDuckGo HTML scrape).

    No API key required.  The provider is considered "configured" when the
    ``ddgs`` package is importable — there is nothing else to set up.
    returnstrc                    dS )Nddgs )selfs    6/root/.hermes/hermes-agent/tools/web_providers/ddgs.pyprovider_namez DDGSSearchProvider.provider_name-   s    v    boolc                2    	 ddl }dS # t          $ r Y dS w xY w)zReturn True when the ``ddgs`` package is importable.

        Called at tool-registration time; must not perform network I/O.
        r   NTF)r   ImportError)r   r   s     r   is_configuredz DDGSSearchProvider.is_configured0   s7    
	KKK4 	 	 	55	s    
   querylimitintDict[str, Any]c                ,   	 ddl m} n# t          $ r dddcY S w xY wt          dt	          |                    }	 g } |            5 }t          |                    ||                    D ]\  }}||k    r nt          |                    d          p|                    d	          pd
          }	|	                    t          |                    dd
                    |	t          |                    dd
                    |dz   d           ddd           n# 1 swxY w Y   n:# t          $ r-}
t                              d|
           dd|
 dcY d}
~
S d}
~
ww xY wt                              d|t          |          |           dd|idS )a  Execute a DuckDuckGo search and return normalized results.

        Returns ``{"success": True, "data": {"web": [...]}}`` on success or
        ``{"success": False, "error": str}`` on failure (missing package,
        rate-limited, network error, etc.).
        r   )DDGSFu8   ddgs package is not installed — run `pip install ddgs`)successerror   )max_resultshrefurl titlebody)r$   r"   descriptionpositionNzDDGS search error: %szDuckDuckGo search failed: z'DDGS search '%s': %d results (limit %d)Tweb)r   data)r   r   r   maxr   	enumeratetextr
   getappend	Exceptionloggerwarninginfolen)r   r   r   r   
safe_limitweb_resultsclientihitr"   excs              r   searchzDDGSSearchProvider.search;   s5   	!!!!!!! 	 	 	 S    	 CJJ''
	SK 6'Ez(R(RSS  FAsJcggfooEE2FFC&&%(")=)=%>%>#&+.swwvr/B/B+C+C()A	                    	S 	S 	SNN2C888$/QC/Q/QRRRRRRRR	S 	=uc+FVFVX]^^^%)=>>>sN   	 D+ CDD+ D##D+ &D#'D+ +
E"5"EE"E"N)r	   r
   )r	   r   )r   )r   r
   r   r   r	   r   )__name__
__module____qualname____doc__r   r   r:   r   r   r   r   r   &   s_            	 	 	 	'? '? '? '? '? '? '?r   r   )r>   
__future__r   loggingtypingr   r   tools.web_providers.baser   	getLoggerr;   r0   r   r   r   r   <module>rD      s    6 # " " " " "          6 6 6 6 6 6		8	$	$<? <? <? <? <?* <? <? <? <? <?r   