All docs

Web search

Web search is the only chat feature that reaches the network for content. It is controlled by user settings and routing logic.

Service boundary

WebSearchService defines four operations:

  • search: return ranked search results for a query.
  • fetchPageText: download and extract readable text from a page.
  • rerank: order results by relevance.
  • buildContext: format results for prompt context.

The production implementation is DuckDuckGoSearchService.

Network behavior

DuckDuckGo search uses the keyless HTML endpoint at https://html.duckduckgo.com/html/. The app sends the query text only. It does not send chat history or local memory.

Result pages are parsed on a background isolate with compute, so HTML parsing does not block the UI thread.

Search result parsing

parseDuckDuckGoHtml extracts:

  • Result title.
  • Result URL.
  • Snippet text.

DuckDuckGo redirect URLs are unwrapped through the uddg query parameter when present.

Page reading

fetchPageText downloads a page and extracts readable text. The extractor removes script, style, nav, header, footer, aside, form, svg, and button nodes. It then prefers article or main content and collects headings, paragraphs, and list items.

The extracted text is capped before entering the prompt.

Search decision

ToolRouter.shouldSearch decides whether live web information is needed.

Fast local checks run first:

  • Math does not search.
  • Device commands do not search.
  • Device info questions do not search.
  • Alarm and timer shaped requests do not search.
  • Ordinary writing, rewriting, translation, and conversation do not search.
  • Obvious live facts such as weather, prices, news, sports, and "near me" do search.

If the request is ambiguous, the utility model answers with a strict YES or NO. Only a response beginning with YES enables autonomous search.

Query planning

For searched turns, ToolRouter.planQueries creates 1 to 4 self-contained queries. It includes names, places, and the current year when the answer changes over time.

For follow-up messages, standaloneQuery rewrites fragments into complete requests using recent turns. Example: "I'm in Jordan" after a weather question becomes a complete weather request for Jordan.

Multi-hop research

The chat controller can reflect on gathered evidence and ask for a focused follow-up query. reflectNextQuery returns either:

  • One next query aimed at the missing fact.
  • DONE when evidence is sufficient.

This allows cross-checking and multi-step lookup without sending the whole conversation to the search provider.

Grounding and sources

Search results and fetched page text are formatted into a compact context block for the model. URLs are not placed directly in the prompt because small models can read them aloud. The UI stores source title and URL separately as MessageSource.

Search sources are attached to the final assistant message and persisted with the message row.

Offline behavior

DuckDuckGoSearchService throws WebSearchException with isOffline for connectivity failures. The chat controller uses that information to tell the system prompt that web search is unavailable, so the model does not claim it searched.