Skip to content

feat: more dials for web search providers - #103

Merged
1ay1 merged 4 commits into
agentty-org:masterfrom
sail3r:feat/search-dials
Oct 16, 2026
Merged

1ay1 merged 4 commits into
agentty-org:masterfrom
sail3r:feat/search-dials

Conversation

@sail3r

@sail3r sail3r commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Merge agentty-org/mcp-cpp#5 first. This branch moves third_party/mcp-cpp to 791957d, a commit from that PR that is not in mcp-cpp's master yet. Until that PR is merged, the submodule points at a commit that only exists on the fork (sail3r/mcp-cpp, branch feat/search-dials), so a fresh clone or a CI run can't fetch it. Once it is merged, this branch builds as is.

Settings > Web Search: more settings per service, typed settings, Firecrawl research papers, Perplexity exclusions

Follow-up to #87. Branch feat/search-dials, 4 commits on 9aa4f173.

Most of the work is in mcp-cpp, which owns the list of search services and what each one is sent. Its PR describes every new setting and why it was added. This PR is the agentty side:

  • the pane shows the new settings;
  • it can show a setting you type rather than pick;
  • the settings file has room for a longer value;
  • the docs are updated.

What you'll see

Ctrl+K > Settings > Web Search. Under each slot (Primary, Secondary, Fallback), the service chosen for it shows its settings, as before. There are more of them now:

  • Tavily (Free and API key): Exact phrases, Language match, Country and Safe search. Tavily Free also gets Depth, which only the API key version had.
  • Brave API key: Spell correction, and Goggle (a typed setting, see below). Country gains All regions.
  • Firecrawl (Free and API key): Safe search, Sort (newest first) and Location (typed). Freshness gains Past hour. Category is now Developer, Research, PDF and Government.
  • Exa: Safe search and Country. Mode lists all six modes, and Freshness gains Past hour.
  • Perplexity: Mode (Web or Fast).
  • Serper: Freshness gains Past hour.
  • DuckDuckGo Free: Region lists all 68 regions DuckDuckGo documents, up from 13. The list scrolls.

With the shipped defaults (Brave Free, then DuckDuckGo Free, then Tavily Free), the Fallback slot now shows seven settings instead of two.

Typed settings: Brave Goggle and Firecrawl Location

These two rows take text instead of offering a list:

  • Goggle takes the web address of a hosted Goggle, a rules file that re-ranks Brave's results. For example: https://raw.githubusercontent.com/brave/goggles-quickstart/main/goggles/tech_blogs.goggle.
  • Location takes a place, such as San Francisco,California,United States.

How they behave:

  • Type or paste into the row. The value is saved when you leave the row, the same as Never return. It is not saved on every keystroke, which would write half-typed values to settings.json.
  • Spaces at either end are dropped.
  • A value the service would not accept is not saved, and the row goes back to what was saved before. For a Goggle that means an address not starting with https://, an address with a space in it, Goggle rules typed in instead of an address, or anything too long. The pane uses the same check mcp-cpp makes before every search, so it never stores something a search would quietly ignore.
  • Empty the row to clear it.

Saved settings

Settings are stored per service in settings.json under web_search.dials, as before. The only change is that a value may now be up to 2048 bytes instead of 64, so a Goggle address fits. Existing files load unchanged.

Firecrawl no longer offers a GitHub category. A saved GitHub choice is no longer sent, and the row shows Any.

Firecrawl's Research category after 2026-11-16

On that date Firecrawl starts answering Research searches with research papers instead of web pages. mcp-cpp now reads those papers and gives each one a link to its page on arXiv, PubMed, PubMed Central or doi.org, or to Firecrawl's page for the paper when it has none of those. The paper's abstract is used as the text. Without this, Research searches would fail from that date. Nothing in agentty needed to change for it, apart from moving the submodule.

Never return on Perplexity

Sites listed in Never return used to be added to Perplexity searches as -site:example.com words. Perplexity doesn't document that form for its Search API, so whether those sites were actually kept out was never certain. They now go through Perplexity's own exclusion filter, which it does document, the same way they already did for Tavily, Firecrawl and Exa. Perplexity takes up to 20 sites in that filter; any beyond 20 are still added as -site: words. Nothing changes in the pane: Never return works as before.

Exa's Deep reasoning mode

Exa says Deep reasoning takes 12-40 seconds, and agentty stops waiting for a web request after 30. So a Deep reasoning search will sometimes time out, and the next service in the chain answers instead. The setting's help text says so. This PR doesn't change the 30-second limit.

How it works

  • The pane (src/runtime/panel/web_search_form.cpp) draws a typed setting as a text row and every other setting as a dropdown. When the pane saves, a text row's value is trimmed and checked with mcp-cpp's web_search_dial_value_ok. Only a value that passes is stored.
  • The settings file: the size limit on a stored value (dial_entry_ok) is now kMaxDialValueBytes (2048), the longest typed setting mcp-cpp declares. The limits on the key and on the number of stored settings (64) are unchanged. All services together have 45 settings, so even with every one of them set the total stays under 64.

Known limitations, not in this PR

  • No message for a refused typed value. The row just goes back to the saved value. The form can show a message under a row, but the pane rebuilds its rows after every edit, which would clear it. Making the message stay needs a separate change.
  • Brave's query limit. Brave counts -site: exclusions towards its limit of 600 characters and 75 words, so a long Never return list could make Brave searches fail.

Testing

tests/web_search_services_test.cpp:

  • A typed setting is drawn as a text row. Its value is saved trimmed and shown again after a rebuild. A value the service refuses doesn't replace the saved one, and emptying the row clears it.

  • A value longer than the old 64-byte limit survives a save and a reload.

  • The stored-value size limit is exactly 2048 bytes.

  • The test that stored a Firecrawl category now uses Developer, because GitHub is no longer one.

  • The changed files compile with g++ 16.2 (-std=c++23 -Wall -Wextra) against the mcp-cpp branch, with no warnings in web search code.

  • The pane checked by hand: the new settings under each service, and typing, saving and clearing the Goggle and Location rows.

  • Full build (no warnings) and ctest (100% of 1622) on Linux (arch, btw).

Commits

  • 63cf8963 Web Search: the pane shows free-text dials; bump mcp-cpp
  • e0952145 docs: Web Search's new per-service settings and typed rows
  • 8dec03d2 docs: changelog for Firecrawl research results
  • 7b424668 docs: Never return reaches Perplexity's own domain filter

The first commit holds all the code, including the submodule move. The docs commits update the Unreleased section of CHANGELOG.md and the Web Search part of docs/website/configuration.md.

mcp-cpp (feat/search-dials, 791957d, 5 commits on edc3186):
- adds dials to most services and lists every documented value on the
  existing ones; a service may now declare up to seven dials;
- adds free-text dials: Brave API's Goggle (a hosted Goggle URL) and
  Firecrawl's Location;
- reads Firecrawl's data.research. From 2026-11-16 the Research category
  answers with paper records there, and without this a research search
  would be reported unreadable. Each paper gets a link to its own page
  (arXiv, PubMed, PubMed Central, doi.org), or to Firecrawl's paper page
  for any other kind of id;
- sends Never return sites to Perplexity as its domain filter
  (search_domain_filter, "-" in front of each host, at most 20) instead
  of -site: words in the query. Perplexity documents the deny form for
  its Search API; -site: in the query was never documented there.

The pane built every dial as a dropdown, and apply_form read only
dropdown rows. A free-text dial (WebSearchDial::text set) is now a Text
row. Its value is trimmed and checked with mcp-cpp's own
web_search_dial_value_ok before it is stored, so the pane never saves a
value a search would drop: a value that fails is not stored and the
rebuild shows what was on record. An emptied row erases the entry, as a
dropdown set back to its default does. Text rows commit on leaving the
field, as the registry's text rows already do.

Stored dial values were capped at 64 bytes on load and save
(dial_entry_ok). A Goggle URL can be longer, so the value cap is now
kMaxDialValueBytes (2048), the longest text dial mcp-cpp declares; the
key cap and the 64-entry cap are unchanged. All services together have
45 dials, under the 64-entry cap.

github is no longer a Firecrawl category, so the plan test that used it
uses developer. web_search_config.hpp's note on -site: support lists
Perplexity among the services with a native domain filter.
@1ay1
1ay1 merged commit 7ab4d57 into agentty-org:master Oct 16, 2026
9 checks passed
1ay1 added a commit that referenced this pull request Oct 16, 2026
#103 pinned 791957d, the PR branch's last commit. Point at mcp-cpp master's merge commit f78af9f instead; same tree, so no code changes.
@sail3r
sail3r deleted the feat/search-dials branch October 18, 2026 10:15
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.

2 participants