From 7b795f25d84989a16064b346c8d684aad9093f37 Mon Sep 17 00:00:00 2001 From: Krishnakanth Alagiri <39209037+bearlike@users.noreply.github.com> Date: Fri, 1 Aug 2025 22:14:46 -0700 Subject: [PATCH 1/2] Add AI-powered LLM answer plugin for SearXNG Introduces a new SearXNG plugin that generates contextual, AI-powered answers using LangChain and an LLM, with results formatted in Markdown and rendered via a custom HTML template. Updates the README with usage details and adds supporting documentation and image assets. --- docs/scripts.xls | Bin 17408 -> 17920 bytes docs/search_llm_assist.png | Bin 0 -> 89980 bytes python/searxng-addons/README.md | 8 +- .../search_answers_llm/llm_answer.html | 211 ++++++++++ .../plugins_langchain_llm.py | 392 ++++++++++++++++++ 5 files changed, 610 insertions(+), 1 deletion(-) create mode 100644 docs/search_llm_assist.png create mode 100644 python/searxng-addons/search_answers_llm/llm_answer.html create mode 100644 python/searxng-addons/search_answers_llm/plugins_langchain_llm.py diff --git a/docs/scripts.xls b/docs/scripts.xls index abac8930afb312d8cafbeb2fa59f28c061c21558..0941757b62a150324f4b132d2e5ebb52410592fd 100644 GIT binary patch delta 1608 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
uVC6 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 USk?4*5(5x;y85}Sb4q9e0B$AMGynhq literal 0 HcmV?d00001 diff --git a/python/searxng-addons/README.md b/python/searxng-addons/README.md index cacf051..996d20f 100644 --- a/python/searxng-addons/README.md +++ b/python/searxng-addons/README.md @@ -8,7 +8,13 @@ This repository contains custom engine implementations that extend SearXNG's cap ## 🔍 Available Engines -### 1. Homepage Dashboard Integration (`dashboard_services.py`) +### 1. AI Search Assist (`search_answers_llm\plugins_langchain_llm.py`) + +This SearXNG plugin generates contextual, AI-powered answers by hooking into the `post_search` process. It programmatically executes a secondary, targeted search against Google and DuckDuckGo using `SearchQuery` and `EngineRef` to gather real-time context for the user's query. This context is then sent to a LLM. The plugin injects this response as a custom `Answer` result type, overriding the default template to use a custom one with the `|safe` filter, ensuring the rich text is rendered correctly on the results page. + +![SearXNG LLM Assist](/docs/search_llm_assist.png) + +### 2. Homepage Dashboard Integration (`dashboard_services.py`) Integrates with [`gethomepage/homepage`](https://github.com/gethomepage/homepage), a customizable home or startpage with Docker and service API support. This enables your home lab dashboard to become fully searchable using SearXNG. diff --git a/python/searxng-addons/search_answers_llm/llm_answer.html b/python/searxng-addons/search_answers_llm/llm_answer.html new file mode 100644 index 0000000..8ce0bbf --- /dev/null +++ b/python/searxng-addons/search_answers_llm/llm_answer.html @@ -0,0 +1,211 @@ +
+
+ {{ answer.answer|safe }} +
+ + +
diff --git a/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py b/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py new file mode 100644 index 0000000..8d9ffb3 --- /dev/null +++ b/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python3 +"""This plugin uses LangChain to generate AI answers with rich formatting. + +Set LLM_MODEL_NAME, LLM_BASE_URL, LLM_API_KEY environment variables to +configure the LLM model. Bind python/searxng-addons/search_answers_llm/llm_answer.html +to your own template to customize the answer display. +""" +from __future__ import annotations +from os import environ +import traceback +import typing +import markdown + +from searx.search.models import SearchQuery, EngineRef +from searx.result_types import EngineResults, Answer +from searx.plugins import Plugin, PluginInfo +from flask_babel import gettext +from searx.search import Search +from searx import engines +from pydantic import SecretStr + +from langchain_openai import ChatOpenAI +from langchain.schema import HumanMessage, SystemMessage +from langfuse.langchain import CallbackHandler as LangfuseLangchainCallbackHandler +from langfuse import get_client + + +if typing.TYPE_CHECKING: + from searx.search import SearchWithPlugins + from searx.extended_types import SXNG_Request + from searx.plugins import PluginCfg + + +try: + langfuse = get_client() + langchain_callback_handler = LangfuseLangchainCallbackHandler() + print("Langfuse client initialized successfully.") +except Exception as exc: # pragma: no cover - fallback when Langfuse is unavailable + print("Langfuse client initialization failed: %s. Tracing disabled.", exc) + + class _DummySpan: # type: ignore + def update(self, *_, **__): + pass + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + return False + + class _DummyLangfuse: + def start_as_current_span(self, *_, **__): + return _DummySpan() + + def shutdown(self): + pass + + def flush(self): + pass + + class _DummyCallbackHandler: + def __init__(self, *_, **__): + pass + + langfuse = _DummyLangfuse() + langchain_callback_handler = _DummyCallbackHandler() + + +class SXNGPlugin(Plugin): + """LangChain LLM Answer Plugin that generates contextual answers with rich formatting.""" + + id = "langchain_llm" + + def __init__(self, plg_cfg: "PluginCfg") -> None: + super().__init__(plg_cfg) + print(f"[DEBUG] LangChain plugin initialized with active={plg_cfg.active}") + + self.info = PluginInfo( + id=self.id, + name=gettext("LangChain LLM"), + description=gettext("Generate AI answers using LLM with rich formatting"), + preference_section="general", + ) + + self.model_name = environ.get("LLM_MODEL_NAME", "gemini-2.0-flash") + # Initialize ChatOpenAI once and reuse + self.llm = ChatOpenAI( + model=self.model_name, + temperature=0.7, + base_url=environ.get( + "LLM_BASE_URL", + "https://generativelanguage.googleapis.com/v1beta/openai/", + ), + api_key=SecretStr(environ.get("LLM_API_KEY", "dummy-key")), + ) + + # Initialize markdown converter with common extensions + self.md_converter = markdown.Markdown( + extensions=["extra", "codehilite", "toc"], + extension_configs={"codehilite": {"css_class": "highlight"}}, + ) + + def post_search( + self, request: "SXNG_Request", search: "SearchWithPlugins" + ) -> EngineResults: + results = EngineResults() + + print(f"[DEBUG] post_search called for query: {search.search_query.query}") + + # Only process on first page + if search.search_query.pageno > 1: + print("[DEBUG] Skipping, not on first page.") + return results + + query = search.search_query.query + print(f"[DEBUG] Processing query: {query}") + + try: + # Get search context from Google and DuckDuckGo + search_context = self._get_search_context(query) + + if search_context: + print( + f"[DEBUG] Retrieved {len(search_context)} search results for context" + ) + + # Generate LLM response with search context + llm_answer_html = self._generate_contextual_answer_html( + query, search_context + ) + + if llm_answer_html: + print("[DEBUG] Generated contextual HTML answer") + + # Create Answer with custom template + answer = Answer( + answer=llm_answer_html, + template="answer/llm_answer.html", # Use our custom template + ) + results.add(answer) + print("[DEBUG] Added HTML Answer to results") + else: + print("[DEBUG] No contextual answer generated") + else: + print( + "[DEBUG] No search context retrieved, falling back to simple answer" + ) + # Fallback to simple answer if no search context + simple_answer_html = self._generate_simple_answer_html(query) + if simple_answer_html: + answer = Answer( + answer=simple_answer_html, template="answer/llm_answer.html" + ) + results.add(answer) + + except Exception as e: + print(f"[DEBUG] Exception in post_search: {e}") + + traceback.print_exc() + + return results + + def _get_search_context(self, query: str) -> list[dict]: + """Fetch search results from Google and DuckDuckGo for context.""" + print(f"[DEBUG] Fetching search context for: {query}") + + try: + # Create engine references for Google and DuckDuckGo + engine_refs = [] + + # Check if Google is available and enabled + if "google" in engines.engines: + engine_refs.append(EngineRef("google", "general")) + print("[DEBUG] Added Google engine") + + # Check if DuckDuckGo is available and enabled + if "duckduckgo" in engines.engines: + engine_refs.append(EngineRef("duckduckgo", "general")) + print("[DEBUG] Added DuckDuckGo engine") + + if not engine_refs: + print("[DEBUG] No suitable engines found") + return [] + + # Create a search query for just these engines + context_search_query = SearchQuery( + query=query, + engineref_list=engine_refs, + lang="en-US", + safesearch=0, + pageno=1, + timeout_limit=5.0, # 5 second timeout for context search + ) + + print(f"[DEBUG] Created SearchQuery with {len(engine_refs)} engines") + + # Execute the search + context_search = Search(context_search_query) + context_results = context_search.search() + + # Extract relevant results + ordered_results = context_results.get_ordered_results() + print(f"[DEBUG] Retrieved {len(ordered_results)} raw results") + + # Convert to simplified format for LLM context + search_context = [] + for i, result in enumerate(ordered_results[:5]): # Top 5 results + try: + context_item = { + "title": getattr(result, "title", ""), + "content": getattr(result, "content", ""), + "url": getattr(result, "url", ""), + "engine": getattr(result, "engine", ""), + } + + # Filter out empty results + if context_item["title"] or context_item["content"]: + search_context.append(context_item) + print( + f"[DEBUG] Added result {i+1}: {context_item['title'][:50]}..." + ) + + except Exception as e: + print(f"[DEBUG] Error processing result {i}: {e}") + continue + + print(f"[DEBUG] Final search context: {len(search_context)} items") + return search_context + + except Exception as e: + print(f"[DEBUG] Error in _get_search_context: {e}") + + traceback.print_exc() + return [] + + def _generate_contextual_answer_html( + self, query: str, search_context: list[dict] + ) -> str: + """Generate LLM answer with markdown formatting using search results as context.""" + print(f"[DEBUG] Generating contextual markdown answer for: {query}") + + try: + # Use the pre-initialized ChatOpenAI instance + llm = self.llm + + # Prepare context from search results + context_text = self._format_search_context(search_context) + + # Create messages with search context - Updated to request markdown + messages = [ + SystemMessage( + content="""You are a helpful Search Engine assistant that provides accurate answers and sources based on search results. + Identify the most important information and links from the search results. + Format your response using Markdown syntax for better readability. + Warn against potential malicious links when encounterd. + Keep the response concise but well-formatted in Markdown.""" + ), + HumanMessage( + content=f"""Query: {query} + +Search Results Context: +{context_text} + +Based on the search results above, provide a helpful and accurate answer to the query using Markdown formatting. If the search results don't contain relevant information, say so and provide what general knowledge you can.""" + ), + ] + + # Generate response + response = llm.invoke(messages) + answer = str(response.content).strip() + langfuse.flush() + + print(f"[DEBUG] Generated contextual response: {answer[:100]}...") + + # Create formatted HTML answer from markdown + formatted_answer = self._format_html_answer(answer, has_context=True) + return formatted_answer + + except Exception as e: + print(f"[DEBUG] Error in _generate_contextual_answer_html: {e}") + + traceback.print_exc() + return "" + + def _generate_simple_answer_html(self, query: str) -> str: + """Generate a simple LLM answer with markdown formatting (fallback).""" + print(f"[DEBUG] Generating simple markdown answer for: {query}") + + try: + # Use the pre-initialized ChatOpenAI instance + llm = self.llm + + # Create simple messages - Updated to request markdown + messages = [ + SystemMessage( + content="""You are a helpful assistant that provides concise answers using Markdown formatting. + Use Markdown syntax like **bold**, *italics*, bullet lists, and code blocks for better readability. + Keep responses brief but well-formatted.""" + ), + HumanMessage( + content=f"Question: {query}\n\nProvide a brief, helpful answer using Markdown formatting:" + ), + ] + + # Generate response + response = llm.invoke(messages) + answer = str(response.content).strip() + langfuse.flush() + + print(f"[DEBUG] Generated simple response: {answer[:100]}...") + + # Create formatted HTML answer from markdown + formatted_answer = self._format_html_answer(answer, has_context=False) + return formatted_answer + + except Exception as e: + print(f"[DEBUG] Error in _generate_simple_answer_html: {e}") + + traceback.print_exc() + return "" + + def _format_html_answer(self, markdown_answer: str, has_context: bool) -> str: + """Convert markdown answer to HTML and add header/footer with model info.""" + try: + # Convert markdown to HTML + html_content = self.md_converter.convert(markdown_answer) + + # Reset the converter for next use + self.md_converter.reset() + + context_badge = ( + "with search context" if has_context else "general knowledge" + ) + model_name = self.model_name + + # GitHub repository URL - Replace with your actual repository + github_repo_url = "https://github.com/bearlike/scripts" + + formatted_answer = f""" +
+ 🤖 AI Assistant + ({context_badge}) +
+
+ {html_content} +
+ + """ + + return formatted_answer.strip() + + except Exception as e: + print(f"[DEBUG] Error in _format_html_answer: {e}") + + traceback.print_exc() + # Fallback to original text if markdown conversion fails + return f"
{markdown_answer}
" + + def _format_search_context(self, search_context: list[dict]) -> str: + """Format search results into text context for the LLM.""" + if not search_context: + return "No search results available." + + context_parts = [] + for i, result in enumerate(search_context, 1): + context_parts.append(f"Result {i}:") + context_parts.append(f"Title: {result.get('title', 'N/A')}") + + content = result.get("content", "") + if content: + # Truncate content to avoid token limits + content = content[:300] + "..." if len(content) > 300 else content + context_parts.append(f"Content: {content}") + + source = result.get("engine", "Unknown") + context_parts.append(f"Source: {source}") + context_parts.append("") # Empty line between results + + return "\n".join(context_parts) From 48fa1e798e9aa6a0e61e59baf839b7b1511d7a78 Mon Sep 17 00:00:00 2001 From: "deepsource-autofix[bot]" <62050782+deepsource-autofix[bot]@users.noreply.github.com> Date: Sat, 2 Aug 2025 05:15:01 +0000 Subject: [PATCH 2/2] style: format code with Autopep8 This commit fixes the style issues introduced in 7b795f2 according to the output from Autopep8. Details: None --- .../plugins_langchain_llm.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py b/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py index 8d9ffb3..7a3eedc 100644 --- a/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py +++ b/python/searxng-addons/search_answers_llm/plugins_langchain_llm.py @@ -73,12 +73,14 @@ class SXNGPlugin(Plugin): def __init__(self, plg_cfg: "PluginCfg") -> None: super().__init__(plg_cfg) - print(f"[DEBUG] LangChain plugin initialized with active={plg_cfg.active}") + print( + f"[DEBUG] LangChain plugin initialized with active={plg_cfg.active}") self.info = PluginInfo( id=self.id, name=gettext("LangChain LLM"), - description=gettext("Generate AI answers using LLM with rich formatting"), + description=gettext( + "Generate AI answers using LLM with rich formatting"), preference_section="general", ) @@ -105,7 +107,8 @@ def post_search( ) -> EngineResults: results = EngineResults() - print(f"[DEBUG] post_search called for query: {search.search_query.query}") + print( + f"[DEBUG] post_search called for query: {search.search_query.query}") # Only process on first page if search.search_query.pageno > 1: @@ -192,7 +195,8 @@ def _get_search_context(self, query: str) -> list[dict]: timeout_limit=5.0, # 5 second timeout for context search ) - print(f"[DEBUG] Created SearchQuery with {len(engine_refs)} engines") + print( + f"[DEBUG] Created SearchQuery with {len(engine_refs)} engines") # Execute the search context_search = Search(context_search_query) @@ -273,7 +277,8 @@ def _generate_contextual_answer_html( print(f"[DEBUG] Generated contextual response: {answer[:100]}...") # Create formatted HTML answer from markdown - formatted_answer = self._format_html_answer(answer, has_context=True) + formatted_answer = self._format_html_answer( + answer, has_context=True) return formatted_answer except Exception as e: @@ -310,7 +315,8 @@ def _generate_simple_answer_html(self, query: str) -> str: print(f"[DEBUG] Generated simple response: {answer[:100]}...") # Create formatted HTML answer from markdown - formatted_answer = self._format_html_answer(answer, has_context=False) + formatted_answer = self._format_html_answer( + answer, has_context=False) return formatted_answer except Exception as e: @@ -382,7 +388,8 @@ def _format_search_context(self, search_context: list[dict]) -> str: content = result.get("content", "") if content: # Truncate content to avoid token limits - content = content[:300] + "..." if len(content) > 300 else content + content = content[:300] + \ + "..." if len(content) > 300 else content context_parts.append(f"Content: {content}") source = result.get("engine", "Unknown")