feat(web): use shared user-agent and send X-Keenable-Title
Drop the bespoke nanobot/<version> User-Agent in favor of self.user_agent for consistency with every other search provider, and add an X-Keenable-Title: nanobot header so Keenable can attribute traffic. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Xubin Ren
co-authored by
Claude Opus 4.8
parent
83cb296cdc
commit
092b07c7aa
@@ -489,10 +489,12 @@ class WebSearchTool(Tool):
|
||||
return f"Error: {e}"
|
||||
|
||||
async def _search_keenable(self, query: str, n: int) -> str:
|
||||
from nanobot import __version__
|
||||
api_key = self.config.api_key or os.environ.get("KEENABLE_API_KEY", "")
|
||||
# First-party API: identify honestly instead of the spoofed browser UA.
|
||||
headers = {"Content-Type": "application/json", "User-Agent": f"nanobot/{__version__}"}
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": self.user_agent,
|
||||
"X-Keenable-Title": "nanobot",
|
||||
}
|
||||
if api_key:
|
||||
headers["X-API-Key"] = api_key
|
||||
try:
|
||||
|
||||
@@ -143,7 +143,8 @@ async def test_keenable_search(monkeypatch):
|
||||
async def mock_post(self, url, **kw):
|
||||
assert "keenable" in url
|
||||
assert kw["headers"]["X-API-Key"] == "keen-key"
|
||||
assert kw["headers"]["User-Agent"].startswith("nanobot/")
|
||||
assert kw["headers"]["User-Agent"] == "nanobot-search-test"
|
||||
assert kw["headers"]["X-Keenable-Title"] == "nanobot"
|
||||
return _response(json={
|
||||
"results": [{"title": "Keen", "url": "https://keenable.ai", "description": "short", "snippet": "longer excerpt"}]
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user