Making the code base easy to read and maintain and making it a oneline install
This commit is contained in:
@@ -1,32 +1,75 @@
|
||||
<div align="center">
|
||||
|
||||
[](https://git.tysstech.com/tyler/PacCrypt-Webapp)
|
||||
[](https://github.com/TySP-Dev/ollama-ai-answers-searxng)
|
||||
# ollama-ai-answers-searxng
|
||||
|
||||
<div align="left">
|
||||
**Local AI search overviews for SearXNG, powered by Ollama.**
|
||||
|
||||
# Ollama AI Answers Plugin for SearXNG
|
||||
**Based on [ai-answers-searxng](https://github.com/cra88y/ai-answers-searxng) by [cra88y](https://github.com/cra88y)**
|
||||

|
||||

|
||||

|
||||
|
||||
A SearXNG plugin that generates local AI overviews powered by Ollama, using search results as RAG context.
|
||||
[](https://github.com/TySP-Dev/ollama-ai-answers-searxng)
|
||||
|
||||
Features:
|
||||
- Token-by-token UI streaming
|
||||
- Clickable inline citations
|
||||
- Interactive mode: continue summary, ask follow-ups, copy, or regenerate
|
||||
- Simple response mode with no extras
|
||||
- Internally called low-latency RAG for follow-ups (bypasses HTTP loopback)
|
||||
- Native network integration via `searx.network` (respects proxy/SSL settings)
|
||||
- Stateless conversation persistence/shareability via URL hash
|
||||
- Model selector in the AI overview widget
|
||||
- Does not slow down result loading
|
||||
- One file install
|
||||
</div>
|
||||
|
||||
## Installation
|
||||
## One-line Install
|
||||
|
||||
Place `ollama_answers.py` into the `searx/plugins` directory of your SearXNG instance (or mount it in a container) and enable it in `settings.yml`:
|
||||
```bash
|
||||
bash <(curl -fsSL https://raw.githubusercontent.com/TySP-Dev/ollama-ai-answers-searxng/master/install.sh)
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- AI Overview box at the top of every search result page
|
||||
- Powered entirely by your local Ollama instance — no external API calls
|
||||
- Page content fetching — enriches context beyond SearXNG snippets
|
||||
- Model selector dropdown — switch models per-search without restarting
|
||||
- Inline citations with clickable source links
|
||||
- Citation footer listing all referenced sources
|
||||
- Follow-up questions with conversation history
|
||||
- Copy and Regenerate buttons
|
||||
- Typewriter animation (granian-compatible buffered response)
|
||||
- Ollama-only — no OpenAI, Gemini, or other provider bloat
|
||||
|
||||
## Requirements
|
||||
|
||||
- SearXNG installed via Docker Compose
|
||||
- Ollama running and accessible from the SearXNG container
|
||||
- Python 3.8+ (for `build.py` and `install.sh`)
|
||||
- Docker + Docker Compose
|
||||
|
||||
## Install
|
||||
|
||||
### One-line (recommended)
|
||||
|
||||
```bash
|
||||
bash <(curl -fsSL https://raw.githubusercontent.com/TySP-Dev/ollama-ai-answers-searxng/master/install.sh)
|
||||
```
|
||||
|
||||
The script will clone the repo, build the plugin, detect your SearXNG Docker Compose installation, copy the plugin, update `docker-compose.yml` and `settings.yml`, and optionally restart SearXNG.
|
||||
|
||||
### Manual
|
||||
|
||||
```bash
|
||||
git clone https://github.com/TySP-Dev/ollama-ai-answers-searxng
|
||||
cd ollama-ai-answers-searxng
|
||||
python3 build.py
|
||||
bash install.sh
|
||||
```
|
||||
|
||||
Or manually copy the built plugin and update your config:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml — searxng service
|
||||
environment:
|
||||
- LLM_URL=http://ollama:11434/v1/chat/completions
|
||||
- LLM_MODEL=qwen3.5:9b
|
||||
volumes:
|
||||
- ./plugins/ollama_answers.py:/usr/local/searxng/searx/plugins/ollama_answers.py:Z
|
||||
```
|
||||
|
||||
```yaml
|
||||
# settings.yml
|
||||
plugins:
|
||||
searx.plugins.ollama_answers.SXNGPlugin:
|
||||
active: true
|
||||
@@ -34,102 +77,73 @@ plugins:
|
||||
|
||||
## Configuration
|
||||
|
||||
Configure via environment variables.
|
||||
All configuration is done via environment variables on the SearXNG container.
|
||||
|
||||
### Required
|
||||
|
||||
| Variable | Description | Default |
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `LLM_URL` | Ollama chat completions endpoint | `http://ollama:11434/v1/chat/completions` |
|
||||
| `LLM_MODEL` | Model name as listed in Ollama | `qwen3.5:9b` |
|
||||
| `LLM_URL` | `http://ollama:11434/v1/chat/completions` | Ollama endpoint |
|
||||
| `LLM_MODEL` | `qwen3.5:9b` | Default model |
|
||||
| `LLM_MAX_TOKENS` | `200` | Max response tokens |
|
||||
| `LLM_TEMPERATURE` | `0.2` | Response temperature |
|
||||
| `LLM_TABS` | `general,science,it,news` | Search tabs to show AI overview on |
|
||||
| `LLM_QUESTION_MARK_REQUIRED` | `false` | Only trigger on queries ending with `?` |
|
||||
| `LLM_INTERACTIVE` | `true` | Show copy/regenerate/follow-up UI |
|
||||
| `LLM_SYSTEM_PROMPT` | *(built-in)* | Override the system prompt |
|
||||
| `LLM_CONTEXT_DEEP_COUNT` | `5` | Results fetched for full page content |
|
||||
| `LLM_CONTEXT_SHALLOW_COUNT` | `15` | Results used as headline-only context |
|
||||
|
||||
### Optional
|
||||
## Project Structure
|
||||
|
||||
| Variable | Description | Default |
|
||||
|---|---|---|
|
||||
| `LLM_SYSTEM_PROMPT` | Overrides the default system prompt | `You are a direct, citation-accurate search synthesis engine.` |
|
||||
| `LLM_MAX_TOKENS` | Max tokens in the AI response | `200` |
|
||||
| `LLM_TEMPERATURE` | Sampling temperature | `0.2` |
|
||||
| `LLM_CONTEXT_DEEP_COUNT` | Results used with full snippets | `5` |
|
||||
| `LLM_CONTEXT_SHALLOW_COUNT` | Results with headlines only (breadth) | `15` |
|
||||
| `LLM_TABS` | Comma-delimited tab whitelist | `general,science,it,news` |
|
||||
| `LLM_INTERACTIVE` | Interactive UI mode (copy, regenerate, follow-up) | `true` |
|
||||
| `LLM_QUESTION_MARK_REQUIRED` | Only trigger on queries containing `?` | `false` |
|
||||
|
||||
## How It Works
|
||||
|
||||
1. User performs a search
|
||||
2. Results return server-side
|
||||
3. `post_search` plugin hook fires
|
||||
4. Token-optimized context is extracted from results
|
||||
5. UI/logic shell injected into the standard answers object
|
||||
6. Client-side script calls a signed endpoint (`/ai-stream`)
|
||||
7. Ollama streams a response token-by-token in the UI
|
||||
|
||||
## Docker Compose Example
|
||||
|
||||
```yaml
|
||||
services:
|
||||
searxng:
|
||||
environment:
|
||||
- LLM_URL=http://ollama:11434/v1/chat/completions
|
||||
- LLM_MODEL=qwen3.5:9b
|
||||
volumes:
|
||||
- ./ollama_answers.py:/usr/local/searxng/searx/plugins/ollama_answers.py
|
||||
|
||||
ollama:
|
||||
image: ollama/ollama
|
||||
volumes:
|
||||
- ollama_data:/root/.ollama
|
||||
|
||||
volumes:
|
||||
ollama_data:
|
||||
```
|
||||
ollama-ai-answers-searxng/
|
||||
├── ollama_answers.py # Source plugin — reads UI from assets/
|
||||
├── build.py # Assembles dist/ollama_answers.py (self-contained)
|
||||
├── install.sh # Full automated Docker Compose installer
|
||||
├── assets/
|
||||
│ ├── ui.css # Interactive widget styles
|
||||
│ ├── ui.html # Interactive widget HTML (copy/regen/follow-up bar)
|
||||
│ └── ui.js # Frontend JS (typewriter, citations, streaming)
|
||||
├── dist/ # Output of build.py — gitignored
|
||||
│ └── ollama_answers.py # Self-contained, ready to deploy
|
||||
├── dev/
|
||||
│ └── dev.py # Local Flask dev server (no SearXNG required)
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Remote Ollama
|
||||
|
||||
If your Ollama instance is remote or behind a reverse proxy, set `LLM_URL` to the full endpoint and provide an API key if required. The plugin supports Bearer token auth and follows HTTP redirects.
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- LLM_URL=https://ollama.example.com/v1/chat/completions
|
||||
- LLM_API_KEY=your-bearer-token
|
||||
```
|
||||
|
||||
## Development — Dev Server
|
||||
|
||||
A standalone Flask dev server is included in `tests/dev.py`. It mocks the SearXNG plugin environment so you can test the full UI without a running SearXNG instance.
|
||||
|
||||
### Setup
|
||||
## Development
|
||||
|
||||
```bash
|
||||
pip install flask flask-babel certifi
|
||||
# Edit source files
|
||||
vim ollama_answers.py
|
||||
vim assets/ui.css
|
||||
|
||||
# Build dist file for deployment
|
||||
python3 build.py
|
||||
|
||||
# Deploy to server
|
||||
cp dist/ollama_answers.py ~/searxng/plugins/ollama_answers.py
|
||||
cd ~/searxng && docker compose up -d --force-recreate core
|
||||
|
||||
# Run local dev server
|
||||
PYTHONPATH=. python3 dev/dev.py
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
python tests/dev.py
|
||||
```
|
||||
|
||||
Then open [http://127.0.0.1:5000/](http://127.0.0.1:5000/) in your browser.
|
||||
The dev server mocks the SearXNG plugin environment so you can test the full UI without a running SearXNG instance. Open [http://127.0.0.1:5000/](http://127.0.0.1:5000/) after starting it.
|
||||
|
||||
> **Note:** Use `127.0.0.1:5000`, not `localhost:5000` — macOS AirPlay Receiver can occupy the IPv6 loopback on port 5000.
|
||||
|
||||
### Usage
|
||||
## How It Works
|
||||
|
||||
- Type a query in the search bar and hit **Search** to trigger an AI overview.
|
||||
- Expand **Ollama Configuration** at the top to change the endpoint URL or Bearer token for the current session. Click **Apply** to save and re-run the current query.
|
||||
- The model selector in the AI overview widget (loaded from `/ai-models`) shows all models available on the configured Ollama server and persists your choice in the session URL.
|
||||
1. User searches on SearXNG
|
||||
2. `post_search` hook fires after results are fetched
|
||||
3. Top result URLs are fetched in parallel for full page content
|
||||
4. Context is assembled from page content + snippets + infoboxes
|
||||
5. A signed token is generated and injected into the page
|
||||
6. The browser POSTs to `/ai-stream` with the token and context
|
||||
7. The server calls Ollama with the enriched context
|
||||
8. The response is returned as JSON and animated with a typewriter effect
|
||||
9. Citations are rendered inline and collected in a footer
|
||||
|
||||
### Environment Variables (dev)
|
||||
## License
|
||||
|
||||
The dev reads the same variables as the plugin:
|
||||
|
||||
```bash
|
||||
LLM_URL=http://localhost:11434/v1/chat/completions \
|
||||
LLM_MODEL=qwen3.5:9b \
|
||||
python tests/dev.py
|
||||
```
|
||||
|
||||
Or export them before running. Any values set in the config panel at runtime take priority for that session.
|
||||
MIT License
|
||||
|
||||
Reference in New Issue
Block a user