Ë
    uPêj!  ã                   ó’   — d Z ddlmZ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e«      Z G d	„ d
ed¬«      Z G d„ de	«      Zy)zz
Calls SearXNG's /search endpoint to search the web.

SearXNG API Reference: https://docs.searxng.org/dev/search_api.html
é    )ÚFinalÚ	TypedDictN)ÚLogging)ÚBaseSearchConfigÚSearchResponseÚSearchResult)Úget_secret_strc                   ó   — e Zd ZU dZeed<   y)Ú_SearXNGSearchRequestRequiredz/Required fields for SearXNG Search API request.ÚqN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__© ó    úo/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/searxng/search/transformation.pyr   r      s
   … Ù9à
„Fr   r   c                   óN   — e Zd ZU dZeed<   eed<   eed<   eed<   eed<   eed<   y)	ÚSearXNGSearchRequestzg
    SearXNG Search API request format.
    Based on: https://docs.searxng.org/dev/search_api.html
    Ú
categoriesÚenginesÚlanguageÚpagenoÚ
time_rangeÚformatN)r   r   r   r   r   r   Úintr   r   r   r   r      s'   … ñð
 ƒOØƒLØƒMØƒKØƒOØ„Kr   r   F)Útotalc            	       óÎ   — e Zd Zedefd„«       Zd„ Z	 	 ddededz  dedz  defd„Z	 ddedz  d	ed
ee	e   z  dz  defd„Z
dee	e   z  d	edefd„Zdej                  dedefd„Zy)ÚSearXNGSearchConfigÚreturnc                   ó   — y)NÚSearXNGr   r   r   r   Úui_friendly_namez$SearXNGSearchConfig.ui_friendly_name)   s   € àr   c                  ó   — y)zW
        SearXNG supports both GET and POST, but we'll use GET for simplicity.
        ÚGETr   )Úselfs    r   Úget_http_methodz#SearXNGSearchConfig.get_http_method-   s   € ð r   NÚheadersÚapi_keyÚapi_basec                 óP   — | j                  ||ddd¬«      }|rd|› �|d<   d|d<   |S )	zÃ
        Validate environment and return headers.
        SearXNG is open-source and doesn't require an API key by default.
        Some instances may require authentication via headers.
        )ÚSEARXNG_API_KEYÚSEARXNG_API_BASEN)Úcaller_api_keyÚcaller_api_baseÚkey_env_varsÚbase_env_varÚdefault_api_basezBearer ÚAuthorizationzapplication/jsonzContent-Type)Úresolve_server_api_key)r(   r*   r+   r,   Úkwargss        r   Úvalidate_environmentz(SearXNGSearchConfig.validate_environment3   sM   € ð ×-Ñ-Ø"Ø$Ø-Ø+Ø!ð .ó 
ˆñ Ø)0°°	Ð':ˆG�OÑ$Ø"4ˆ�ÑØˆr   Úoptional_paramsÚdatac                 óø   — ddl m} |xs t        d«      }|st        d«      ‚|j	                  d«      s|j	                  d«      r|› d�}n|› d�}|r(t        |t        «      rd|v r|d   } ||«      }|› d	|› �S |S )
zú
        Get complete URL for Search endpoint with query parameters.

        SearXNG uses GET requests, so we build the full URL with query params here.
        The transformed request body (data) contains the parameters needed for the URL.
        r   )Ú	urlencoder/   z¿SEARXNG_API_BASE is not set. Please set the `SEARXNG_API_BASE` environment variable or pass `api_base` parameter. Example: os.environ['SEARXNG_API_BASE'] = 'https://your-searxng-instance.com'z/searchú/ÚsearchÚ_searxng_paramsú?)Úurllib.parser<   r	   Ú
ValueErrorÚendswithÚ
isinstanceÚdict)r(   r,   r9   r:   r7   r<   ÚparamsÚquery_strings           r   Úget_complete_urlz$SearXNGSearchConfig.get_complete_urlL   s¤   € õ 	+àÒAœ~Ð.@ÓAˆáÜð~óð ð × Ñ  Ô+Ø× Ñ  Ô%Ø&˜Z vÐ.‘à&˜Z wÐ/�ñ ”J˜t¤TÔ*Ð/@ÀDÑ/HØ Ð!2Ñ3ˆFÙ"+¨FÓ"3ˆLØ�Z˜q  Ð/Ð/àˆr   Úqueryc                 ó�  — t        |t        «      rdj                  |«      }|ddœ}d|v rT|d   j                  «       }|dk(  s|dk(  rd|d<   n1|d	k(  rd	|d<   n&|d
k(  rd
|d<   n|dk(  rd|d<   n|dk(  rd|d<   n||d<   d|v r	 t	        |«      }|j                  «       D ]"  \  }}|| j                  «       vsŒ||vsŒ|||<   Œ$ d|iS )uó  
        Transform Search request to SearXNG API format.

        Transforms Perplexity unified spec parameters:
        - query â†’ q
        - max_results â†’ (handled via pageno, SearXNG returns ~20 results per page)
        - search_domain_filter â†’ (not directly supported)
        - country â†’ language (approximate mapping)
        - max_tokens_per_page â†’ (not applicable, ignored)

        All other SearXNG-specific parameters are passed through as-is.

        Args:
            query: Search query (string or list of strings). SearXNG only supports single string queries.
            optional_params: Optional parameters for the request

        Returns:
            Dict with typed request data following SearXNGSearchRequest spec
        ú Újson)r   r   ÚcountryÚusÚukÚenr   ÚdeÚfrÚesÚjpÚjaÚmax_resultsr?   )rD   ÚlistÚjoinÚlowerrE   ÚitemsÚ(get_supported_perplexity_optional_params)	r(   rI   r9   r7   Úrequest_datarM   Úresult_dataÚparamÚvalues	            r   Útransform_search_requestz,SearXNGSearchConfig.transform_search_requestr   s  € ô2 �eœTÔ"à—H‘H˜U“OˆEð Øñ5
ˆð ˜Ñ'à,¨YÑ7×=Ñ=Ó?ˆGØ˜$Š '¨T¢/Ø+/�˜ZÒ(Ø˜D’Ø+/�˜ZÒ(Ø˜D’Ø+/�˜ZÒ(Ø˜D’Ø+/�˜ZÒ(Ø˜D’Ø+/�˜ZÒ(à+2�˜ZÑ(ð ˜OÑ+ð ô " ,Ó/ˆð ,×1Ñ1Ó3ò 	+‰LˆE�5Ø˜D×IÑIÓKÒKÐPUÐ]hÒPhØ%*�˜EÒ"ð	+ð " ;Ð/Ð/r   Úraw_responseÚlogging_objc           	      óX  — |j                  «       }g }|j                  dg «      D ]w  }|j                  d«      xs |j                  d«      }t        |j                  dd«      |j                  dd«      |j                  dd«      |d¬	«      }|j                  |«       Œy t	        |d
¬«      S )uk  
        Transform SearXNG API response to LiteLLM unified SearchResponse format.

        SearXNG â†’ LiteLLM mappings:
        - results[].title â†’ SearchResult.title
        - results[].url â†’ SearchResult.url
        - results[].content â†’ SearchResult.snippet
        - results[].publishedDate OR results[].pubdate â†’ SearchResult.date
        - No last_updated field in SearXNG response (set to None)

        Args:
            raw_response: Raw httpx response from SearXNG API
            logging_obj: Logging object for tracking

        Returns:
            SearchResponse with standardized format
        ÚresultsÚpublishedDateÚpubdateÚtitleÚ ÚurlÚcontentN)rg   ri   ÚsnippetÚdateÚlast_updatedr>   )rd   Úobject)rL   Úgetr   Úappendr   )	r(   ra   rb   r7   Úresponse_jsonrd   Úresultrl   Úsearch_results	            r   Útransform_search_responsez-SearXNGSearchConfig.transform_search_response¸   s®   € ð.  ,×0Ñ0Ó2ˆð
 ˆØ#×'Ñ'¨	°2Ó6ò 	*ˆFà—:‘:˜oÓ.ÒG°&·*±*¸YÓ2GˆDä(Ø—j‘j ¨"Ó-Ø—J‘J˜u bÓ)ØŸ
™
 9¨bÓ1ØØ!ôˆMð �N‰N˜=Õ)ð	*ô ØØô
ð 	
r   )NN)N)r   r   r   Ústaticmethodr   r%   r)   rE   r8   rW   rH   r`   ÚhttpxÚResponseÚLiteLLMLoggingObjr   rt   r   r   r   r!   r!   (   sñ   „ Øð˜cò ó ðòð #Ø#ñ	àðð �t‘ðð ˜‘*ð	ð 
óð: *.ñ	$à˜‘*ð$ð ð$ð �T˜$‘ZÑ $Ñ&ð	$ð 
ó$ðLD0à�T˜#‘Y‰ðD0ð ðD0ð
 
óD0ðL-
à—n‘nð-
ð 'ð-
ð
 
ô-
r   r!   )r   Útypingr   r   rv   Ú*litellm.litellm_core_utils.litellm_loggingr   rx   Ú+litellm.llms.base_llm.search.transformationr   r   r   Úlitellm.secret_managers.mainr	   r   r   r!   r   r   r   ú<module>r}      sN   ðñ÷ $ã å S÷ñ õ
 8ô Iô ôÐ8Àõ ô}
Ð*õ }
r   