| 2026-11-03 |

navi-web: make the batch shape the schema, drop Brave
...
Every recorded web_search and web_view call in production carried a scalar
(20 of 20, 8 of 8), including sessions where three searches on one topic went
out one after another. The recommendation was already written in three
places — the parameter description, the tool docstring and the server's
summary line — so prose was not the problem: `str | list[str]` renders as
`anyOf: [string, array]`, and the model took the first branch.
The parameter is now a pure array with minItems/maxItems and an examples
entry. A BeforeValidator folds a bare "query": "…" into a one-item list, so a
laxer caller still works; the cap rides in json_schema_extra rather than
pydantic's max_length, so four queries reach the code that runs three and
names the rest instead of failing validation.
Brave is gone on both paths: the keyed Search API (signup answers 403, so a
third backend that can never be enabled) and the ddgs engine of the same name,
which answers nothing from this host. The chain is SearXNG -> ddgs.
The persona's parallelism rule now separates "several items in one call" from
"several calls in one message" — it used to read "when the profile allows
parallel tool calls", which the model could only read as "not here".
Eugene Sukhodolskiy
committed
9 hours ago
|

navi-web: pin the ddgs engines, drop bing, and give the fallback room
...
SearXNG answered the session's searches with noise. Bing, asked explicitly,
returns trending/homepage blocks for queries it cannot match (Block Blast for
a motherboard query); because the list is non-empty the chain accepted it as an
answer and never reached the working fallback. The request now pins
google,duckduckgo and asks for language=all — the pinned uk-UA was what made the
instance's DDG engine return CAPTCHA (kl=ua-uk) on every request.
The ddgs leg had a quieter bug. ddgs v9 has no "html" backend, and an unknown
name does not fail: it silently means "auto" — all engines shuffled together,
yandex and grokipedia included. That is where the slow, flaky, mixed-provenance
results came from. The engine set is now explicit and yandex-free. The 4s client
timeout and 12s chain budget also could not fit a real 1-13s multi-engine scrape,
so they become 10s and 20s.
Wire the Brave key placeholder the docs already described: optional, mapped
with a ":-" fallback so an empty value means off.
Eugene Sukhodolskiy
committed
9 hours ago
|
| 2026-11-01 |

navi-web: search backends, three-at-a-time batches, and pages read as markdown
...
web_search runs SearXNG first, DuckDuckGo with one retry after a real failure,
and Brave last; measured 0.2-1.4s through SearXNG against 1.7-11.8s on
scraping. Both tools take one item or up to three and run them concurrently —
three pages went from 17.3s to 1.9s, three searches from 3.5s to 0.6s — each
under its own deadline, so one hung backend or page is named in the output
instead of erasing what the others already returned. Text is capped at 20k for
one page and 40k for a batch. A call that opened nothing now raises: a green
journal line carrying "success": false is how a server whose browser could not
launch at all looked like a working one, and how 604 search calls in two weeks
reported no errors.
web_view returns the main content as markdown, not innerText after a tag
kill-list. The old path could not tell navigation from prose (462 of the asyncio
page's 1018 lines were shorter than 40 characters), collapsed tables into one
line per thousand characters — news.ycombinator.com came back as four lines —
marked no headings and dropped every link. trafilatura now picks the content by
density, and its html output keeps the whitespace inside <pre> that its markdown
output throws away, so the fragment is rendered here: # headings, fenced code
with its indentation, table rows joined by |, and up to 40 links lifted into a
"Links on this page" appendix rather than sprinkled through the sentences.
Threads are read again with comments when the extractor keeps less than a
quarter of the visible text; if it still finds nothing, the old visible-text
read answers and metadata.extractor says which one did.
trafilatura goes into the server's own venv, which deploy/install.sh does not
build — docs/mcp.md and deploy/UPDATE.md carry the install line. The tests load
the server by path, so it also joins Navi's dev extra.
Eugene Sukhodolskiy
committed
2 days ago
|
| 2026-05-13 |
Rename MCP tools to mcp:server:tool format and restore human-readable names
...
- Core naming: mcp_server_tool → mcp:server:tool (colon-delimited)
- navi-web tools: search/view/request → web_search/web_view/http_request
- navi-3d tools: compile_scad/render_stl/lint_scad (unchanged names)
- Updated all profile configs, system prompts, docs, manuals, tests
- Added new lint_scad.md manual
- Fixed modeler_3d prompt stale references (scad_lint, model_3d, render_3d)
- All 240 tests pass
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 13 May
|
Rename navi-web MCP tools and compact search output
...
- web_search → search, web_view → view, http_request → request
This removes the redundant 'web' prefix from tool names in the
navi-web MCP server, making them cleaner: mcp_navi-web_search etc.
- Compact search output: output string now contains only
[Source] + [N] Title — URL, without duplicating the body snippet.
Full results with body/description remain in metadata for
programmatic use.
- Updated mcp_servers.json groups and all profile configs.
Tests: 240 passed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 13 May
|
Migrate web tools (web_search, web_view, http_request) to navi-web MCP server
...
New MCP server: mcp-servers/navi-web/
- app/search.py — SearXNG primary, DDG fallback, Brave tertiary
- app/browse.py — Playwright headless browser page extraction
- app/request.py — httpx raw HTTP requests
- app/mcp_server.py — FastMCP entry point with stdio transport
- pyproject.toml — deps: mcp, httpx, ddgs, playwright, pydantic
Changes:
- Added "navi-web" block to mcp_servers.json (stdio transport)
- Removed web_search, web_view, http_request from built-in registry
- Removed them from navi/tools/__init__.py
- Removed them from enabled_tools / subagent_tools in all profiles
- Added "navi-web": ["search", "browse", "request"] to mcp_servers
in all profiles (developer, secretary, server_admin, tool_developer,
modeler_3d, discuss)
Tests: 240 passed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 13 May
|