From f01622ef93da5b88d253434e9a7a2ae6b3a85525 Mon Sep 17 00:00:00 2001 From: Mouse Date: Tue, 14 Apr 2026 18:35:52 -0700 Subject: [PATCH 1/2] fix: align You.com Search endpoint with latest API docs --- README.md | 9 +++++---- agent_harness.py | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 79a91ea..b9037f6 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ If your agents need live web results, register the built-in You.com adapter as a import os from agent_harness import AgentHarness, HarnessConfig, register_you_com_search_tool -os.environ["YOUCOM_API_KEY"] = "your_you_com_api_key" +os.environ["YDC_API_KEY"] = "your_ydc_api_key" register_you_com_search_tool(name="you_search") config = HarnessConfig( @@ -174,7 +174,8 @@ config = HarnessConfig( ``` Environment variables: -- `YOUCOM_API_KEY` (required) +- `YDC_API_KEY` (required, recommended) +- `YOUCOM_API_KEY` (legacy alias supported for compatibility) Fallback/error behavior: - Missing API key returns a non-fatal setup message (no crash) @@ -356,8 +357,8 @@ def get_registry() -> ToolRegistry def register_you_com_search_tool( name: str = "you_search", description: str = "Search the web and return summarized results.", - api_key_env: str = "YOUCOM_API_KEY", - endpoint: str = "https://api.ydc-index.io/search", + api_key_env: str = "YDC_API_KEY", + endpoint: str = "https://ydc-index.io/v1/search", timeout_sec: float = 20.0, ) -> str ``` diff --git a/agent_harness.py b/agent_harness.py index c4ff1ab..916db34 100644 --- a/agent_harness.py +++ b/agent_harness.py @@ -270,8 +270,8 @@ def get_registry() -> ToolRegistry: def register_you_com_search_tool( name: str = "you_search", description: str = "Search the web and return summarized results.", - api_key_env: str = "YOUCOM_API_KEY", - endpoint: str = "https://api.ydc-index.io/search", + api_key_env: str = "YDC_API_KEY", + endpoint: str = "https://ydc-index.io/v1/search", timeout_sec: float = 20.0, ) -> str: """ @@ -285,7 +285,7 @@ def register_you_com_search_tool( """ def _you_search(query: str, num_results: int = 5) -> str: - api_key = os.getenv(api_key_env) + api_key = os.getenv(api_key_env) or (os.getenv("YOUCOM_API_KEY") if api_key_env == "YDC_API_KEY" else None) if not api_key: return ( f"You.com search is not configured. Set {api_key_env} and retry. " @@ -295,7 +295,7 @@ def _you_search(query: str, num_results: int = 5) -> str: if not query.strip(): return "You.com search query is empty." - url = endpoint + "?" + urllib.parse.urlencode({"query": query, "num_web_results": num_results}) + url = endpoint + "?" + urllib.parse.urlencode({"query": query, "count": max(1, min(num_results, 100))}) request = urllib.request.Request( url, headers={ From 6e4c62abc7e97b2619a9356210a9ae3a1790e13c Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Tue, 14 Apr 2026 18:56:43 -0700 Subject: [PATCH 2/2] Fix You.com search review issues --- agent_harness.py | 16 ++++++++++---- tests/test_you_search_tool.py | 39 ++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/agent_harness.py b/agent_harness.py index 916db34..d0f3e69 100644 --- a/agent_harness.py +++ b/agent_harness.py @@ -285,7 +285,9 @@ def register_you_com_search_tool( """ def _you_search(query: str, num_results: int = 5) -> str: - api_key = os.getenv(api_key_env) or (os.getenv("YOUCOM_API_KEY") if api_key_env == "YDC_API_KEY" else None) + api_key = os.getenv(api_key_env) or ( + os.getenv("YOUCOM_API_KEY") if api_key_env == "YDC_API_KEY" else None + ) if not api_key: return ( f"You.com search is not configured. Set {api_key_env} and retry. " @@ -295,7 +297,8 @@ def _you_search(query: str, num_results: int = 5) -> str: if not query.strip(): return "You.com search query is empty." - url = endpoint + "?" + urllib.parse.urlencode({"query": query, "count": max(1, min(num_results, 100))}) + requested_count = max(1, min(num_results, 10)) + url = endpoint + "?" + urllib.parse.urlencode({"query": query, "count": requested_count}) request = urllib.request.Request( url, headers={ @@ -309,7 +312,12 @@ def _you_search(query: str, num_results: int = 5) -> str: try: with urllib.request.urlopen(request, timeout=timeout_sec) as response: payload = json.loads(response.read().decode("utf-8")) - except (urllib.error.HTTPError, urllib.error.URLError, json.JSONDecodeError, OSError) as exc: + except ( + urllib.error.HTTPError, + urllib.error.URLError, + json.JSONDecodeError, + OSError, + ) as exc: return f"You.com search request failed ({type(exc).__name__}): {exc}" results = payload.get("results") @@ -326,7 +334,7 @@ def _you_search(query: str, num_results: int = 5) -> str: return "No web results found." lines = [] - for idx, hit in enumerate(hits[: max(1, min(num_results, 10))], start=1): + for idx, hit in enumerate(hits[:requested_count], start=1): title = hit.get("title") or "Untitled" link = hit.get("url") or hit.get("link") or "" snippets = hit.get("snippets") diff --git a/tests/test_you_search_tool.py b/tests/test_you_search_tool.py index a685c52..84b720b 100644 --- a/tests/test_you_search_tool.py +++ b/tests/test_you_search_tool.py @@ -8,6 +8,7 @@ def test_you_search_tool_requires_api_key(monkeypatch): get_registry().clear() + monkeypatch.delenv("YDC_API_KEY", raising=False) monkeypatch.delenv("YOUCOM_API_KEY", raising=False) register_you_com_search_tool(name="you_search_test") @@ -19,7 +20,7 @@ def test_you_search_tool_requires_api_key(monkeypatch): def test_you_search_tool_formats_results(monkeypatch): get_registry().clear() - monkeypatch.setenv("YOUCOM_API_KEY", "test-key") + monkeypatch.setenv("YDC_API_KEY", "test-key") class FakeResponse: def __enter__(self): @@ -54,3 +55,39 @@ def read(self): assert "https://example.com/agent" in result assert "Useful update. Fresh context." in result assert "Generic page summary." not in result + + +def test_you_search_tool_supports_legacy_api_key_alias(monkeypatch): + get_registry().clear() + monkeypatch.delenv("YDC_API_KEY", raising=False) + monkeypatch.setenv("YOUCOM_API_KEY", "legacy-key") + + class FakeResponse: + def __enter__(self): + payload = { + "results": { + "web": [ + { + "title": "Legacy alias hit", + "url": "https://example.com/legacy", + "snippets": ["Alias still works."], + } + ] + } + } + self._buf = io.BytesIO(json.dumps(payload).encode("utf-8")) + return self + + def __exit__(self, exc_type, exc, tb): + return False + + def read(self): + return self._buf.read() + + monkeypatch.setattr("urllib.request.urlopen", lambda *args, **kwargs: FakeResponse()) + + register_you_com_search_tool(name="you_search_test") + tool = get_registry().get("you_search_test") + + result = tool.callable("agent tooling", num_results=1) + assert "Legacy alias hit" in result