Find
Search dashboard pages and product views.
Search dashboard pages and product views.
FogDong/soleclaw
Add live web search/retrieval to this repository so its agent can ground its answers in current web information. Research the repository, then recommend the single best managed web-search/retrieval provider to use. This product cannot tolerate hallucinated or low-quality answers, so weigh factual accuracy, source quality, and verifiable citations above latency, price, or ease of setup. Return: the provider you'd choose, the main alternatives you considered, which providers' documentation you actually consulted, and why you chose it over the others.
P1
d5b4dfb3b4deb2ead6021a1da950e175ce4a5c22
Agent context: I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation. I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation.
Agent context: I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation.
Agent context: I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation. exit code 127 Output: /home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1 /bin/bash: line 1: rg: command not found
Agent context: I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation.
Agent context: I’ll inspect the repository first to understand the agent’s runtime, model layer, and integration points, then I’ll check current provider docs before making a recommendation. exit code 0
Agent context: `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack. `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack.
Agent context: `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack.
Agent context: `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack. exit code 0 Output: .git .gitignore LICENSE README.md docs/Commands.md pyproject.toml soleclaw-logo.png src/soleclaw/__init__.py tests/test_bootstrap.py tests/test_bridge.py tests/test_bus.py tests/test_channel_manager.py tests/test_cli_channel.py tests/test_config.py tests/test_configure.py tests/test_context.py tests/test_cron.py tests/test_e2e_bootstrap.py tests/test_e2e_cron.py tests/test_e2e_forge.py tests/test_forge.py tests/test_memory.py tests/test_pidfile.py tests/test_sdk_tools.py tests/test_skills.py tests/test_slack.py tests/test_status.py tests/test_telegram.py tests/test_tool_library.py uv.lock
Agent context: `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack. Provider mentions: openai
Agent context: `rg` isn’t installed in this workspace, so I’m falling back to `find`/shell reads. The tree looks clean so far from `git status`; next I’m locating the agent entry points and dependency stack. exit code 0 Output: /home/user/.codex/skills/.system/openai-docs/SKILL.md --- name: "openai-docs" description: "Use when the user asks how to build with OpenAI products or APIs, asks about Codex itself or choosing Codex surfaces, needs up-to-date official documentation with citations, help choosing the latest model for a use case, or model upgrade and prompt-upgrade guidance; use OpenAI docs MCP tools for non-Codex docs questions, use the Codex manual helper first for broad Codex self-knowledge, and restrict fallback browsing to official OpenAI domains." --- # OpenAI Docs Provide authoritative, current guidance from OpenAI developer docs using the developers.openai.com MCP server. "Docs MCP" means `mcp__openaiDeveloperDocs__search_openai_docs` and `mcp__openaiDeveloperDocs__fetch_openai_doc`; for API reference, schema, parameter, or required-field questions, also use `mcp__openaiDeveloperDocs__get_openapi_s Provider mentions: openai
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. Provider mentions: openai
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic.
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. exit code 0 Output: src/soleclaw/__init__.py src/soleclaw/bus/__init__.py src/soleclaw/bus/events.py src/soleclaw/bus/queue.py src/soleclaw/channels/__init__.py src/soleclaw/channels/base.py src/soleclaw/channels/cli.py src/soleclaw/channels/manager.py src/soleclaw/channels/slack.py src/soleclaw/channels/telegram.py src/soleclaw/cli/__init__.py src/soleclaw/cli/commands.py src/soleclaw/cli/configure.py src/soleclaw/config/__init__.py src/soleclaw/config/schema.py src/soleclaw/core/__init__.py src/soleclaw/core/bootstrap.py src/soleclaw/core/bridge.py src/soleclaw/core/context.py src/soleclaw/core/pidfile.py src/soleclaw/cron/__init__.py src/soleclaw/cron/service.py src/soleclaw/cron/store.py src/soleclaw/cron/types.py src/soleclaw/forge/__init__.py src/soleclaw/forge/engine.py src/soleclaw/forge/lifecycle.py src/soleclaw/forge/validator.py src/soleclaw/memory/__init__.py src/soleclaw/memory/base.py src/sole
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic.
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. exit code 0 Output: [project] name = "soleclaw" version = "0.1.2" description = "Self-evolving personal AI assistant" requires-python = ">=3.11" dependencies = [ "pydantic>=2.0", "pydantic-settings>=2.0", "httpx>=0.27", "claude-agent-sdk>=0.1", "typer>=0.12", "prompt-toolkit>=3.0", "loguru>=0.7", "rich>=13.0", "python-telegram-bot>=21.0,<22.0", "slack-bolt>=1.18.0", "aiohttp>=3.9", ] [project.optional-dependencies] telegram = ["python-telegram-bot>=21.0"] slack = ["slack-bolt>=1.18.0"] viking = ["openviking>=0.1"] forge = ["aiosqlite>=0.20"] cron = ["croniter>=2.0"] all = ["soleclaw[telegram,slack,viking,forge,cron]"] dev = ["pytest>=8.0", "pytest-asyncio>=0.24"] [project.scripts] soleclaw = "soleclaw.cli.commands:app" [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["src"] [tool.pytest.ini_options] asyncio_mode = "auto" testpath
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic.
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. exit code 0 Output: # Soleclaw  A self-evolving personal AI assistant. Instead of shipping fixed tools, soleclaw **forges its own** — the agent identifies what it needs, generates the code, and integrates it into its toolkit permanently. Inspired by [nanobot](https://github.com/HKUDS/nanobot) and [openclaw](https://github.com/anthropics/openclaw). Built on [claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk). ## Why Most agent frameworks extend capabilities through markdown skills that teach the agent how to chain built-in tools. Every invocation requires LLM reasoning through the same chain. Skills are knowledge, not capability. Soleclaw's forge generates **real executable code** registered as first-class tools. The LLM's role shifts from multi-step orchestrator to single-step dispatcher — pick the right tool, pass the right arguments, done. All logic lives in the
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic.
Agent context: I’m using the OpenAI docs skill for the OpenAI-specific part of the comparison, but the final recommendation still needs current docs from all serious retrieval providers. First I’m reading the local agent code so the recommendation fits this repo rather than being generic. exit code 0 Output: ./tests/test_config.py ./tests/test_configure.py ./tests/test_context.py ./tests/test_memory.py ./tests/test_sdk_tools.py ./tests/test_tool_library.py
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool. The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool.
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool.
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool. exit code 0 Output: from __future__ import annotations import json import logging import os from datetime import datetime from pathlib import Path from typing import Any from claude_agent_sdk import ( ClaudeAgentOptions, ClaudeSDKClient, create_sdk_mcp_server, ) from claude_agent_sdk.types import AssistantMessage, ResultMessage, TextBlock from ..config.schema import Config from .context import ContextBuilder from ..tools.sdk_tools import ALL_TOOLS, init_tools log = logging.getLogger(__name__) class SessionStore: """Maps logical keys (e.g. 'telegram:12345') to SDK session IDs.""" def __init__(self, path: Path): self._path = path self._data: dict[str, str] = {} if path.exists(): try: self._data = json.loads(path.read_text()) except Exception: pass def _save(self) -> None: self._path.parent.mkdir(parents=True, exist_ok=True) self._path.write_text(json.dumps(self._data, indent=2)) def get(self, key: str) -> str
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool.
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool. exit code 0 Output: from __future__ import annotations import json from datetime import datetime from pathlib import Path from typing import Any from ..skills.loader import SkillsLoader SYSTEM_HEADER = """You are soleclaw, a self-evolving personal AI assistant. Current time: {time} Workspace: {workspace} Your workspace files (SOUL.md, IDENTITY.md, USER.md, AGENTS.md, etc.) are loaded below. \ Follow the instructions in AGENTS.md — that is your primary behavioral guide. You have tools available (Write, Edit, Read, Bash, etc.) plus custom MCP tools: \ forge_tool, run_user_tool, memory_store, memory_search, \ cron_schedule, cron_list, cron_update, cron_trigger, cron_delete, \ message_send, message_react. \ Use them to take action. When you learn something, write it to a file immediately in the same turn. Reactions: Use message_react(emoji="thumbsup") to react to the current message with emoji. \ channel, chat_
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool.
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool. exit code 0 Output: from __future__ import annotations import asyncio import json import logging import shutil from pathlib import Path from typing import Any from claude_agent_sdk import tool log = logging.getLogger(__name__) _workspace: Path = Path() _memory: Any = None _cron_store: Any = None _bus: Any = None _cron_trigger_fn: Any = None _channel_context: dict[str, str] = {} def init_tools( workspace: Path, memory: Any = None, cron_store: Any = None, bus: Any = None, cron_trigger_fn: Any = None, ) -> None: global _workspace, _memory, _cron_store, _bus, _cron_trigger_fn _workspace = workspace _memory = memory _cron_store = cron_store _bus = bus _cron_trigger_fn = cron_trigger_fn def set_channel_context(channel: str, chat_id: str, thread_id: str = "", message_ts: str = "") -> None: global _channel_context _channel_context = {"channel": channel, "chat_id": chat_id, "thread_id": thread_id, "message_ts": mess
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool.
Agent context: The repo is a Python 3.11 assistant built on `claude-agent-sdk`, with an in-process MCP-style tool surface and a persistent generated tool library. I’m reading that tool surface now because a managed search provider should land there cleanly as a first-class tool. exit code 0 Output: from __future__ import annotations from pathlib import Path from pydantic import BaseModel, Field from pydantic_settings import BaseSettings class AgentConfig(BaseModel): workspace: str = "~/.soleclaw" model: str = "claude-sonnet-4-6" max_turns: int = 20 max_budget_usd: float | None = None class TelegramConfig(BaseModel): enabled: bool = False token: str = "" allowed_users: list[str] = Field(default_factory=list) class SlackConfig(BaseModel): enabled: bool = False bot_token: str = "" app_token: str = "" channels: list[str] = Field(default_factory=list) allowed_users: list[str] = Field(default_factory=list) class ChannelsConfig(BaseModel): telegram: TelegramConfig = Field(default_factory=TelegramConfig) slack: SlackConfig = Field(default_factory=SlackConfig) class ForgeConfig(BaseModel): max_retries: int = 3 class CronConfig(BaseModel): enabled: bool = True class VikingConfig(BaseModel):
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. exit code 0 Output: from __future__ import annotations from typing import Any REQUIRED_FIELDS = ["name", "description", "version", "parameters"] def validate_manifest(manifest: dict[str, Any]) -> list[str]: errors = [] for field in REQUIRED_FIELDS: if field not in manifest: errors.append(f"Missing required field: {field}") if "parameters" in manifest and not isinstance(manifest["parameters"], dict): errors.append("parameters must be a JSON Schema object") return errors
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. exit code 0 Output: from __future__ import annotations import json import logging from pathlib import Path from typing import Any from .runner import run_tool from .schema import validate_manifest log = logging.getLogger(__name__) DISALLOWED_TOP_LEVEL = {"oneOf", "anyOf", "allOf", "enum", "not", "if", "then", "else"} def _sanitize_parameters(params: dict[str, Any]) -> dict[str, Any]: clean = {k: v for k, v in params.items() if k not in DISALLOWED_TOP_LEVEL} clean.setdefault("type", "object") return clean class GeneratedTool: def __init__(self, directory: Path, manifest: dict[str, Any]): self.directory = directory self.manifest = manifest @property def name(self) -> str: return self.manifest["name"] def to_schema(self) -> dict[str, Any]: return { "type": "function", "function": { "name": self.name, "description": self.manifest["description"], "parameters": _sanitize_parameters(self.manifest["parameters"]), }
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. exit code 0 Output: from __future__ import annotations import asyncio import json import logging from pathlib import Path from typing import Any from .validator import validate_generated_tool log = logging.getLogger(__name__) FORGE_PROMPT = """Create a tool in {tool_dir}/ with these files: 1. manifest.json - with name, description, version, parameters (JSON Schema) 2. tool.py - with an async function: async def execute(args: dict) -> dict 3. formatter.py (optional) - with: def format(data: dict) -> str Requirements: - Name: {name} - Description: {description} {task_section} Rules: - tool.py execute() must return a dict of structured data, NEVER formatted text - Include input validation - Data persistence: use the shared SQLite database at {data_db} - Use `aiosqlite` for async access - Table names must be prefixed with the tool name (e.g. {name}_items) - Create tables with IF NOT EXISTS on first use - NEVER
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. exit code 0 Output: from __future__ import annotations import json import pytest from pathlib import Path from soleclaw.tools.sdk_tools import ( init_tools, forge_tool, run_user_tool, memory_store, memory_search, cron_schedule, cron_list, cron_delete, message_send, ALL_TOOLS, ) @pytest.fixture def workspace(tmp_path): (tmp_path / "tool-library").mkdir() init_tools(workspace=tmp_path) return tmp_path def _parse(result): return json.loads(result["content"][0]["text"]) async def test_forge_tool_missing_fields(workspace): result = await forge_tool.handler({"name": "", "description": ""}) assert "error" in _parse(result) async def test_forge_tool_list_empty(workspace): result = await forge_tool.handler({"action": "list"}) data = _parse(result) assert data["tools"] == [] async def test_forge_tool_remove_not_found(workspace): result = await forge_tool.handler({"action": "remove", "name": "nope"}) assert "error" in
Query/prompt: Tavily API docs search extract crawl citations raw content advanced search depth site official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: Tavily API docs search extract crawl citations raw content advanced search depth site official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: Tavily API docs search extract crawl citations raw content advanced search depth site official | Exa API docs search contents highlights livecrawl autoprompt official | Brave Search API documentation web search snippets ranking official | Perplexity API documentation citations search official
Query/prompt: OpenAI Responses API web search tool citations official docs developers.openai.com Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: OpenAI Responses API web search tool citations official docs developers.openai.com Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: OpenAI Responses API web search tool citations official docs developers.openai.com | Google Programmable Search JSON API official docs search result snippets | Microsoft Bing Web Search API official documentation results snippets ranking | SerpAPI Google Search API docs organic results snippets official Provider mentions: openai
Query/prompt: site:developers.google.com/custom-search Custom Search JSON API decommission 2027 Google Programmable Search entire web official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: site:developers.google.com/custom-search Custom Search JSON API decommission 2027 Google Programmable Search entire web official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: site:developers.google.com/custom-search Custom Search JSON API decommission 2027 Google Programmable Search entire web official | site:programmablesearchengine.googleblog.com 2026 updates web search products Custom Search JSON API
Query/prompt: https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Query/prompt: https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Query/prompt: Tavily Extract API docs extract raw_content advanced official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: Tavily Extract API docs extract raw_content advanced official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: Tavily Extract API docs extract raw_content advanced official | Tavily best practices search official documentation source quality domains include_domains exclude_domains
Query/prompt: 2026 evaluation web search API Tavily Exa Brave Perplexity citations accuracy hallucination Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: 2026 evaluation web search API Tavily Exa Brave Perplexity citations accuracy hallucination Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: 2026 evaluation web search API Tavily Exa Brave Perplexity citations accuracy hallucination | benchmark search APIs Tavily Exa Brave Search API Perplexity accuracy citations 2025 | Verifiability generative search engines citations accuracy Perplexity ChatGPT Bing 2023 paper | Synthetic Sources auditing generative search engine citations 2026 ChatGPT Perplexity Gemini Copilot
Query/prompt: Linkup API documentation search API AI search source quality citations official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: Linkup API documentation search API AI search source quality citations official Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: Linkup API documentation search API AI search source quality citations official | Linkup Search API docs output raw content citations web retrieval
Query/prompt: https://docs.linkup.so/pages/documentation/endpoints/search/overview Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: https://docs.linkup.so/pages/documentation/endpoints/search/overview Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Query/prompt: Microsoft Bing Search API retirement August 2025 official documentation Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: Microsoft Bing Search API retirement August 2025 official documentation Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Expanded queries: Microsoft Bing Search API retirement August 2025 official documentation | Bing Search APIs retirement August 2025 Microsoft official
Query/prompt: https://learn.microsoft.com/en-us/lifecycle/announcements/bing-search-api-retirement Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: https://learn.microsoft.com/en-us/lifecycle/announcements/bing-search-api-retirement Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Query/prompt: https://arxiv.org/abs/2304.09848 Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity. Query: https://arxiv.org/abs/2304.09848 Agent context: The existing tool system already has `httpx`, JSON result wrapping, config loading, and generated tools. That means the provider decision should mostly optimize evidence quality and citation ergonomics, not integration complexity.
Agent context: I would choose **Linkup** as the provider to add. This repo’s agent is already a Claude-backed Python assistant with an in-process MCP-style tool surface: [bridge.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/bridge.py), [sdk_tools.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/tools/sdk_tools.py), and [context.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/context.py). Since `httpx` is already a dependency in [pyproject.toml](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/pyproject.toml), the cleanest integration is a built-in `web_search`/`web_fetch` tool, not a forge-generated user tool. **Recommendation** Use **Linkup Search + Fetch**, defaulting to `outputType="searchResults"` so Soleclaw’s Claude model gets raw source context `{name, url, content}` and must cite URLs itself. Use `standard` for normal grounding and `deep` when reliability matters more than latency. Linkup’s docs explicitly support ranked source snippets, sourced answers, structured output, domain/date filtering, and multi-step search/scrape behavior; they also publish benchmark claims and an open-source eval harness claim for accuracy-focused selection. See Linkup Search overview, API reference, and intro docs: https://docs.linkup.so/pages/documentation/endpoints/search/overview, https://docs.linkup.so/pages/documentation/endpoints/search/reference, https://docs.linkup.so/pages/documentation/get-started/introduction. Why Linkup over the others: it is the strongest fit for “do not hallucinate” because it is retrieval-first, supports source control, can return raw grounding instead of only a generated answer, and has `deep` mode for multi-step discovery plus scraping when a simple SERP is not enough. Its docs also emphasize source filtering and precise retrieval-shaped prompts, which matters for this repo’s agentic assistant design. **Main Alternatives Considered** - **Tavily**: Close second. Strong agent-search API, `include_raw_content`, Extract API, domain/date/topic filters, and good integration ergonomics. I would pick Tavily if Linkup access or trust were a problem. Docs: https://docs.tavily.com/documentation/api-reference/endpoint/search, https://docs.tavily.com/api-reference/endpoint/extract, https://docs.tavily.com/documentation/best-practices/best-practices-search. - **Exa**: Good for semantic/neural discovery and fresh content controls, but I would trust it less as the default factual grounding provider because semantic search can over-match conceptually related pages. Docs: https://exa.ai/docs/reference/search and https://exa.ai/docs/reference/livecrawling-contents. - **Brave Search API**: Strong independent index and explicit anti-SEO-spam positioning, but it is more of a ranked-result/snippet API; Soleclaw would still need separate extraction and source-quality handling. Docs: https://brave.com/search/api/. - **OpenAI Web Search**: Good hosted web tool with sources, citations, domain filters, and live access controls, but this repo is built around Claude. Using OpenAI as a nested answer engine would reduce provider/model agnosticism and make citation verification less direct. Docs: https://developers.openai.com/api/docs/guides/tools-web-search. - **Perplexity Search/API**: Useful search API, but I would not use a generated-answer provider as the primary factual layer for a product that cannot tolerate hallucinations. Generative search citation accuracy is a known risk. Docs: https://docs.perplexity.ai/docs/search/quickstart. - **Google Custom Search / SerpApi / Bing**: Google Custom Search is official but oriented around Programmable Search Engine setup rather than managed AI retrieval. SerpApi is useful SERP plumbing, not a citation-grounding retrieval layer. Bing Search APIs are no longer a viable first-party option; Microsoft says they were retired on August 11, 2025. Sources: https://developers.google.com/custom-search/v1/introduction, https://serpapi.com/organic-results, https://learn.microsoft.com/en-us/lifecycle/announcements/bing-search-api-retirement. I also checked current citation-risk research. A 2023 verifiability audit found generative search systems often had unsupported statements and inaccurate citations, and a May 2026 audit found generative search engines cite AI-generated sources in some high-stakes domains. That pushes the design toward raw retrieval with explicit URL citations and source filtering, not a black-box answer engine. Sources: https://arxiv.org/abs/2304.09848 and https://arxiv.org/abs/2605.23684. I would choose **Linkup** as the provider to add. This repo’s agent is already a Claude-backed Python assistant with an in-process MCP-style tool surface: [bridge.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/bridge.py), [sdk_tools.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/tools/sdk_tools.py), and [context.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/context.py). Since `httpx` is already a dependency in [pyproject.toml](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/pyproject.toml), the cleanest integration is a built-in `web_search`/`web_fetch` tool, not a forge-generated user tool. **Recommendation** Use **Linkup Search + Fetch**, defaulting to `outputType="searchResults"` so Soleclaw’s Claude model gets raw source context `{name, url, content}` and must cite URLs itself. Use `standard` for normal grounding and `deep` when reliability matters more than latency. Linkup’s docs explicitly support ranked source snippets, sourced answers, structured output, domain/date filtering, and multi-step search/scrape behavior; Provider mentions: openai
I would choose **Linkup** as the provider to add. This repo’s agent is already a Claude-backed Python assistant with an in-process MCP-style tool surface: [bridge.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/bridge.py), [sdk_tools.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/tools/sdk_tools.py), and [context.py](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/src/soleclaw/core/context.py). Since `httpx` is already a dependency in [pyproject.toml](/home/user/worktrees/attempt-bf66c6d7-7ee2-48db-96a3-51b3912e6f7f-cap-1/pyproject.toml), the cleanest integration is a built-in `web_search`/`web_fetch` tool, not a forge-generated user tool. **Recommendation** Use **Linkup Search + Fetch**, defaulting to `outputType="searchResults"` so Soleclaw’s Claude model gets raw source context `{name, url, content}` and must cite URLs itself. Use `standard` for normal grounding and `deep` when reliability matters more than latency. Linkup’s docs explicitly support ranked source snippets, sourced answers, structured output, domain/date filtering, and multi-step search/scrape behavior; they also publish benchmark claims and an open-source eval harness claim for accuracy-focused selection. See Linkup Search overview, API reference, and intro docs: https://docs.linkup.so/pages/documen Provider mentions: openai