o
    ưit%                     @   s   d Z ddlmZmZmZmZmZmZ ddlm	Z	 ddl
Z
ddlmZ ddlmZmZmZ ddlmZ G dd	 d	eZG d
d deddZG dd deZdS )zp
Calls DuckDuckGo's Instant Answer API to search the web.

DuckDuckGo API Reference: https://duckduckgo.com/api
    )DictListLiteralOptional	TypedDictUnion)	urlencodeN)Logging)BaseSearchConfigSearchResponseSearchResult)get_secret_strc                   @   s   e Zd ZU dZeed< dS ) _DuckDuckGoSearchRequestRequiredz2Required fields for DuckDuckGo Search API request.qN)__name__
__module____qualname____doc__str__annotations__ r   r   d/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/duckduckgo/search/transformation.pyr      s   
 r   c                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )DuckDuckGoSearchRequestz`
    DuckDuckGo Instant Answer API request format.
    Based on: https://duckduckgo.com/api
    formatprettyno_redirectno_htmlskip_disambigN)r   r   r   r   r   r   intr   r   r   r   r      s   
 r   F)totalc                   @   s   e Zd ZdZedefddZded fddZ		dd	e	d
e
e de
e de	fddZ	dde
e dede
ee	ee	 f  defddZdeeee f dede	fddZdejdedefddZdS )DuckDuckGoSearchConfigzhttps://api.duckduckgo.comreturnc                   C      dS )NZ
DuckDuckGor   r   r   r   r   ui_friendly_name(   s   z'DuckDuckGoSearchConfig.ui_friendly_name)GETPOSTc                 C   r"   )z
        Get HTTP method for search requests.
        DuckDuckGo Instant Answer API uses GET requests.
        
        Returns:
            HTTP method 'GET'
        r$   r   )selfr   r   r   get_http_method,   s   z&DuckDuckGoSearchConfig.get_http_methodNheadersapi_keyapi_basec                 K   s   d|d< |S )z
        Validate environment and return headers.
        DuckDuckGo Instant Answer API does not require authentication.
        zapplication/jsonzContent-Typer   )r&   r(   r)   r*   kwargsr   r   r   validate_environment6   s   z+DuckDuckGoSearchConfig.validate_environmentoptional_paramsdatac                 K   sN   |pt dp| j}|r%t|tr%d|v r%|d }t|dd}| d| S |S )z
        Get complete URL for Search endpoint.
        DuckDuckGo uses query parameters, so we construct the URL with the query.
        DUCKDUCKGO_API_BASE_duckduckgo_paramsT)doseqz/?)r   r/   
isinstancedictr   )r&   r*   r-   r.   r+   paramsZquery_stringr   r   r   get_complete_urlE   s   z'DuckDuckGoSearchConfig.get_complete_urlqueryc                 K   sh   t |tr
d|}|dd}t|}d|v r|d |d< g d}|D ]}||v r/|| ||< q#d|iS )a  
        Transform Search request to DuckDuckGo API format.
        
        Args:
            query: Search query (string or list of strings). DuckDuckGo only supports single string queries.
            optional_params: Optional parameters for the request
                - max_results: Maximum number of search results (DuckDuckGo API doesn't directly support this, used for filtering)
                - format: Output format ('json', 'xml')
                - pretty: Pretty print (0 or 1)
                - no_redirect: Skip HTTP redirects (0 or 1)
                - no_html: Remove HTML from text (0 or 1)
                - skip_disambig: Skip disambiguation results (0 or 1)
            
        Returns:
            Dict with typed request data following DuckDuckGoSearchRequest spec
         json)r   r   max_results_max_results)r   r   r   r   r0   )r2   listjoinr3   )r&   r6   r-   r+   Zrequest_dataZresult_dataZ
ddg_paramsparamr   r   r   transform_search_request[   s   

z/DuckDuckGoSearchConfig.transform_search_requestraw_responselogging_objc              	   K   sb  |  }|jr|jjjni }d}d|v r(zt|d }W n ttfy'   Y nw g }|drN|drNt|dd|dd|ddddd}|	| |dg }	|	D ]}
|durdt
||krd nt|
tr*d	|
v rd
|
v r|
d
d}|
d	d}d|v r|dd}|d }t
|dkr|d n|}nt
|dkr|dd d n|}|}t|||ddd}|	| qVd|
v r*|
dg }|D ]b}|durt
||kr nUd	|v r)d
|v r)|d
d}|d	d}d|v r|dd}|d }t
|dkr|d n|}nt
|dkr|dd d n|}|}t|||ddd}|	| qqVt|ddS )ui  
        Transform DuckDuckGo API response to LiteLLM unified SearchResponse format.
        
        DuckDuckGo → LiteLLM mappings:
        - RelatedTopics[].Text → SearchResult.title + snippet
        - RelatedTopics[].FirstURL → SearchResult.url
        - RelatedTopics[].Text → SearchResult.snippet
        - No date/last_updated fields in DuckDuckGo response (set to None)
        
        Args:
            raw_response: Raw httpx response from DuckDuckGo API
            logging_obj: Logging object for tracking
            
        Returns:
            SearchResponse with standardized format
        Nr:   ZAbstractURLZAbstractTextHeading )titleurlsnippetdateZlast_updatedZRelatedTopicsZFirstURLTextz -    r   2   z...ZTopicssearch)resultsobject)r8   requestrD   r4   r   
ValueError	TypeErrorgetr   appendlenr2   r3   splitr   )r&   r?   r@   r+   Zresponse_jsonZquery_paramsr9   rK   Zabstract_resultZrelated_topicsZtopictextrD   partsrC   rE   Zsearch_resultZnested_topicsZnested_topicr   r   r   transform_search_response   s   



 

"
z0DuckDuckGoSearchConfig.transform_search_response)NN)N)r   r   r   r/   staticmethodr   r#   r   r'   r   r   r,   r3   r   r   r5   r>   httpxResponseLiteLLMLoggingObjr   rV   r   r   r   r   r    %   sP    


/r    )r   typingr   r   r   r   r   r   urllib.parser   rX   Z*litellm.litellm_core_utils.litellm_loggingr	   rZ   Z+litellm.llms.base_llm.search.transformationr
   r   r   Zlitellm.secret_managers.mainr   r   r   r    r   r   r   r   <module>   s     