feat: add Serply as a WebSearchTool engine - #197
Conversation
Register a fourth web_search_tool engine, "serply", next to tavily, brave and perplexity. The handler follows the pattern from vamplabAI#177: a _convert_serply_response / _search_serply pair in _ENGINE_HANDLERS with its default URL in _ENGINE_DEFAULT_URLS. It calls the Serply Search API over httpx (already a core dependency) with the key in X-Api-Key, caps the page size at the API's maximum of 10 and passes offset natively as start. Tavily remains the default engine. Docs and config examples list the new engine; docs/*/framework/tools.md gets a short paragraph on the serply engine with links to the provider and its API reference.
vamplabAI#196 documents brave and perplexity as the engines that work without the [search] extra; serply also only needs httpx, so add it to those lists. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Thanks for the contribution — the handler follows the Brave pattern cleanly and the tests cover conversion, request shape, Pushed to this branch (maintainer edit):
Questions / non-blocking remarks:
Not for this PR: |
|
Thanks @hijera for the merge of On the three points:
Nothing else pending from my side. Let me know if you want either of the optional edits above in this PR. |
What and why
Adds
serplyas a fourthweb_search_toolengine next totavily,braveandperplexity. Serply (https://serply.io) is a Google SERP API; teams that already hold a Serply key can point their research agents at it without a Tavily account. Tavily stays the default engine, nothing changes for existing configs.The change follows the engine-handler pattern introduced in #177:
_convert_serply_response/_search_serplyregistered in_ENGINE_HANDLERS, default URL in_ENGINE_DEFAULT_URLS,engineLiteral extended.GET https://api.serply.io/v1/search/with the key in theX-Api-Keyheader, paramsqandnum. The API serves at most 10 results per page, sonumis capped at 10 andoffsetis passed natively asstart(same shape as the Brave handler, rather than Tavily's over-fetch and slice).httpxis used, which is already a core dependency, so no new packages. This also fits the lite-core split proposed in Make heavy integrations optional dependencies (lite core install) #196, wherebraveandperplexitystay in the core install.Docs: the engine lists in
config.yaml.example(root and the 3 examples),docs/en|ru/framework/configuration.mdanddocs/en|ru/framework/tools.mdnow includeserply, andtools.mdgets a short paragraph on the engine with links to https://serply.io and the API reference at https://serply.io/docs. I leftdocs/*/framework/tools/web-search-tool.mdalone: it still documents the old Tavily-onlysearch:block and #196 is already rewriting it.Verification
pytest: 591 passed. The one failure,tests/test_acp_bridge.py::test_acp_new_session_advertises_agent_and_model_options, fails identically onmain(ACP optioncategory), unrelated to this change.TestSerplySearchHandlerintests/test_search_providers.py: response conversion (skips results without a link), request shape (URL, header, params),offsetmapped tostartwith the page-size cap, and engine registration.pre-commit run --files ...clean (ruff, ruff-format, docformatter).offset=10returns the second page, tool-level dispatch throughWebSearchToolfillscontext.sourceswith renumbered citations, an invalid key raisesHTTPStatusError(401).Disclosure
I work with Serply. Happy to adjust naming, docs placement, or drop the
tools.mdparagraph if you prefer the docs to stay provider-neutral.