aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-31 18:36:13 +0200
committerDanilo M. <danix@danix.xyz>2026-07-31 18:36:13 +0200
commit283fc9ae0371f4d318a539f021a4b88e05fac190 (patch)
tree0bf03685df84c275cb7ab3af3e20d94781a078cc /docs
parent8bda554af191c5749459cd258c793e4826c3f9c7 (diff)
downloadllamachat-283fc9ae0371f4d318a539f021a4b88e05fac190.tar.gz
llamachat-283fc9ae0371f4d318a539f021a4b88e05fac190.zip
feat: web search via SearXNG
The model is offered a web_search tool and decides when a question needs current information. llamachat runs the query against SearXNG's JSON API, feeds the results back, and the model answers from them. Off unless both search_enabled and search_url are set, so an upgrade never starts talking to the network on its own. The loop lives in backend.stream_chat: a round ending in tool_calls is searched for, the result appended, and the request re-sent. After max_searches rounds the tool is withdrawn, which forces an answer rather than letting an uncertain model search forever. Searches show as a collapsible block above the thinking block, listing each query and its sources. The queries are visible on purpose: when an answer is wrong it is usually the query that was wrong, and without seeing it a bad search and a bad answer look identical. Two failures found while testing against the live stack shaped the design: The model has no clock, so it falls back on its training cutoff and writes that year into the query itself ("latest kernel ... 2025"), poisoning the results before they are fetched. The current date now goes into the system prompt whenever search is on, with an instruction not to date its own queries. A SearXNG whose engines are all rate-limited or CAPTCHA'd returns a valid response with zero results. Reporting that as "no results" tells the model the web is empty and invites a confident answer from stale training data, so a search where every engine failed is now an error naming the engines. Results are attacker-influenced text entering the model's context. Only title, url and the snippet survive, snippets are truncated, result text is escaped on display, result links are never fetched automatically, and a reply forging the search block's URL scheme has it defused as the reasoning scheme already was. None of that stops a poisoned snippet from influencing the answer, which is why the sources stay visible. Adds eight test groups, 23 to 31, all hermetic behind a fake HTTP layer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/specs/2026-07-31-web-search-design.md2
1 files changed, 1 insertions, 1 deletions
diff --git a/docs/superpowers/specs/2026-07-31-web-search-design.md b/docs/superpowers/specs/2026-07-31-web-search-design.md
index f7895b8..7e14b2d 100644
--- a/docs/superpowers/specs/2026-07-31-web-search-design.md
+++ b/docs/superpowers/specs/2026-07-31-web-search-design.md
@@ -1,7 +1,7 @@
# Web search via SearXNG
Date: 2026-07-31
-Status: approved, not yet implemented
+Status: implemented
## Problem