Pull requests / #2826
#2826 Web search for the web app (DuckDuckGo default, SearXNG, Brave, Tavily, Serper)
open · draft · @c-OOL-io · 0 comentários · No GitHub
Server & APIModels & quantsWindowsLinux
Descrição
## Web search for the web app The Chat tab gets a built-in web search, modeled after how Open WebUI and similar chat tools do it: the model can look the question up before answering, and the answer shows its sources. ### What it looks like in the UI - A globe button in the composer (first icon, before the paperclip) toggles search for the next message. - **Chat Settings** (gear) has a *Web search* section: enable/disable, engine picker, SearXNG URL, API key field, max results, page reading (see below). - When search is on, the results are injected as context before the model's turn, with an instruction to answer from them and cite by `[n]`. - Under each answer the sources appear as `Sources (DuckDuckGo): [1] … | [2] …` (clickable, engine named, read pages get a `read` badge), and they are included in the "Save this chat as Markdown" export. ### Reading result pages in full Snippets alone often miss the details, so search can also fetch the top result pages and inject their extracted text (Open WebUI's "Web Loader" idea, stdlib `html.parser` based — skips nav/footer/scripts, prefers `main`/`article`): - **"Read result pages"** toggle + **"Pages to read"** (1–5). - **"Limit page text"** toggle (on by default) with a **"Max characters per page"** field (default 5000). Turning it off sends whole pages — see the budget below for why that is still safe. ### Context-aware reading budget How much search text goes into the prompt scales with the model's own context window (`reported_ctx()`), so small-context instances are never overloaded: - The reading budget is a slice of the window (~3 chars/token): **10 %** normally, **25 %** when the user explicitly turns the per-page limit off — the per-page cap is then derived from the budget instead of a fixed number. - First-use defaults scale the same way from `/health`'s `max_context` (e.g. 16K ctx → 4 results / 1 page × 3000 chars; 128K → 6 / 2 × 5000; 262K → 8 / 3 × 5000). - Unknown context falls back to the plain 5000/page default. ### Distinct, persistent search warnings A failed search no longer fails silently — the reason stays on the message (in the sources line, warning-colored) and in the Markdown export, with a different message per cause: - **no API key set** → `Brave Search needs its API key (Chat Settings > Web search)` (same for Tavily/Serper) - **engine unreachable** (e.g. SearXNG not running) → `SearXNG at http://127.0.0.1:8888 is not reachable (…); start it or pick another engine` - **engine reachable but nothing found** → `no results` ### Settings drawer updates - The drawer was titled **"Sampling"**; since it now also holds web search settings it is renamed to **"Chat Settings"** (gear tooltip: "Chat Settings: Thinking & Web Search"), and the close button got a proper "Close" tooltip. - The **Reset** button resets the web search settings to the same defaults as first use (DuckDuckGo, no key, off) instead of leaving a stale engine behind. - The empty-state privacy note is qualified: "Nothing leaves it — unless Web search is on: the search query then goes out to the engine." ### Scroll fix (drive-by) Auto-follow-to-bottom was broken for turns where content grows past the stick threshold mid-stream (the thinking panel expanding could pin the view at the user's own message). Stickiness is now captured *before* the content grows, so the view keeps following the answer. ### Engines | engine | needs | |---|---| | DuckDuckGo (default, labeled "anonymous – no key needed") | nothing (lite endpoint) | | SearXNG | a running instance (default `http://127.0.0.1:8888`) | | Brave Search | API key | | Tavily | API key | | Serper (Google) | API key | ### Design notes - `serve/websearch.py` is **stdlib-only** (`urllib`, `json`, `re`, `html.parser`) — no new dependencies, cross-platform (Windows/Linux/macOS). - `POST /search` carries its own engine config per request; **nothing is stored on the server** — API keys stay in the browser's localStorage, like the existing API-key field. - All providers are fetched through the Strata server (a browser could not call them directly because of CORS). - Page fetches are capped (10 s timeout, 2 MB download) and failed pages degrade to a readable reason instead of breaking the search. ### Tested Interactively on Windows with the live web app: DuckDuckGo and SearXNG return real results; each failure mode (missing key, unreachable engine, no results) shows its own warning on the message; sources appear in the answer and in the Markdown export; Reset restores DuckDuckGo defaults; the chat view now follows long answers to the bottom. Page reading: real pages extract correctly (JS-heavy pages degrade gracefully); the budget math was unit-tested across context sizes (16K/128K, limit on/off, unknown context). Happy to adjust anything (naming, where the settings live, engine list, budget shares) if this should look different.
No site
Links install, modelos, releases.