Skip to content

feat: built-in web search with auto-search, citation audit, and progressive trace#312

Open
quiet-node wants to merge 106 commits into
mainfrom
feat/builtin-search-revamp
Open

feat: built-in web search with auto-search, citation audit, and progressive trace#312
quiet-node wants to merge 106 commits into
mainfrom
feat/builtin-search-revamp

Conversation

@quiet-node

Copy link
Copy Markdown
Owner

Overview

Thuki's web search is now fully built in. This replaces the old separately installed SearXNG + Docker reader stack with a search pipeline that runs inside the app on the built-in inference path, so search works out of the box with nothing to set up. The app decides on its own when a message needs the web, grounds its answer in what it finds, and verifies the citations before showing them.

Highlights

  • Auto search. A lightweight prepass classifies each plain chat turn and only reaches for the web when the question needs it. A Settings toggle and an askbar globe control let the user steer this; /search forces a web search regardless of the setting.
  • Grounded answers with a citation audit. Answers stream live, then citations are verified against the fetched sources. Failed citations are repaired (up to two rounds) and stripped if they still cannot be grounded, with an honest note when a claim is unverifiable.
  • Conflict-aware sufficiency judge. A deterministic pre-check plus a judge decides whether the gathered sources actually answer the question before writing, and requeries once when they fall short.
  • Progressive search UI. A unified request status strip, a live source list, a verifying-sources pill, and a search to reasoning handoff animation replace the old search chrome, backed by an opt-in trace.
  • Legacy pipeline removed, safely. The entire [search] config section, the SearXNG/Docker search-box sandbox, and the old agentic pipeline surfaces are gone. Existing configs that still carry a [search] section load cleanly with no panic.

How it works

A prepass classifier decides whether a turn needs the web. When it does, queries run against keyless engines (DuckDuckGo, Mojeek) and results are fused, then the top pages are fetched and extracted under a first-K completion bound so slow pages cannot stall the turn. Extracted text is chunked, ranked, and handed to the writer as fenced source material; the sufficiency judge gates writing, and a citation audit verifies the result. Untrusted web content is fenced with a per-turn nonce and never treated as instructions.

Security and robustness

  • Outbound fetches are default-deny for non-global-unicast targets, with a second check inside the DNS resolver so rebinding cannot bypass the pre-flight screen, and a hard response-size cap against oversized-response denial of service.
  • Fetched and search-derived text is nonce-fenced into the judge and writer prompts as data, not instructions.
  • Caches, chunk counts, citation-repair rounds, and requery are all bounded by explicit constants; the SERP cache stores a size-capped list so a pathological search response cannot grow memory unbounded, while normal result pages still reach fusion untruncated.
  • Page fetching is preemptively cancellable, so a user cancel is honored mid-fetch rather than after the soft deadline.

Testing

  • bun run test:all:coverage: frontend Vitest and backend cargo llvm-cov both green at 100% coverage.
  • bun run validate-build: ESLint, cargo clippy -D warnings, format check, typecheck, and a signed production bundle all pass.

Note: two ESLint warnings remain in src/App.tsx and src/view/onboarding/ModelCheckStep.tsx. Both pre-date this branch on main and are unrelated to search; they are tracked for a separate cleanup.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…ocks (T6d)

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
… (T6/T2)

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
… (T10 minimal)

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
… tracing

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…le disclosure

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…ertical

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
… gpt-oss reasoning

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…iki vertical

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…oreboards

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…replies

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…egacy pipeline docs

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…ackend doc comments

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…remove the legacy search UI

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…n-avatar helpers

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant