gpt4free/g4f/Provider/search/SearXNG.py
kqlio67 9bac34fc88 refactor: reorganize providers and update model configurations
- Rename DeepInfraChat to DeepInfra across all files
- Move DeepInfra from needs_auth to main Provider directory
- Rename LMArenaBeta to LMArena throughout codebase
- Move search-related providers to new search subdirectory (GoogleSearch, SearXNG, YouTube)
- Move deprecated providers to not_working directory (Free2GPT, LegacyLMArena, PenguinAI, ImageLabs, har)
- Add new Mintlify provider with custom AI assistant implementation
- Update Anthropic provider with Claude 4 models and Opus 4.1 parameter handling
- Update Grok provider with Grok 4 models and improved streaming support
- Update GithubCopilot with expanded model list including o3-mini, o4-mini, gpt-5 previews
- Update LambdaChat default model from deepseek-r1 to deepseek-llama3.3-70b
- Update TeachAnything default model from gemini-1.5-pro to gemma
- Remove DeepInfra from needs_auth directory
- Update all model_map references from DeepInfraChat to DeepInfra
- Update all model_map references from LMArenaBeta to LMArena
- Add beta_headers support to Anthropic for special features
- Improve Mintlify provider with system prompt handling and streaming
- Update model configurations in models.py to reflect provider changes
2025-08-25 23:50:53 +03:00

66 lines
2.4 KiB
Python

import os
import aiohttp
import asyncio
from ...typing import Messages, AsyncResult
from ...providers.base_provider import AsyncGeneratorProvider
from ...providers.response import FinishReason
from ...tools.web_search import fetch_and_scrape
from ..helper import format_media_prompt
from ... import debug
class SearXNG(AsyncGeneratorProvider):
url = os.environ.get("SEARXNG_URL", "http://searxng:8080")
label = "SearXNG"
@classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
prompt: str = None,
proxy: str = None,
timeout: int = 30,
language: str = "it",
max_results: int = 5,
max_words: int = 2500,
add_text: bool = True,
**kwargs
) -> AsyncResult:
prompt = format_media_prompt(messages, prompt)
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=timeout)) as session:
params = {
"q": prompt,
"format": "json",
"language": language,
"safesearch": 0,
"categories": "general",
}
async with session.get(f"{cls.url}/search", params=params, proxy=proxy) as resp:
debug.log(f"Request URL on SearXNG: {resp.url}")
data = await resp.json()
results = data.get("results", [])
if not results:
return
if add_text:
requests = []
for r in results[:max_results]:
requests.append(fetch_and_scrape(session, r["url"], int(max_words / max_results), False))
texts = await asyncio.gather(*requests)
for i, r in enumerate(results[:max_results]):
r["text"] = texts[i]
formatted = ""
used_words = 0
for i, r in enumerate(results[:max_results]):
title = r.get("title")
url = r.get("url", "#")
content = r.get("text") or r.get("snippet") or ""
formatted += f"Title: {title}\n\n{content}\n\nSource: [[{i}]]({url})\n\n"
used_words += content.count(" ")
if max_words and used_words >= max_words:
break
yield formatted.strip()
yield FinishReason("stop")