Provider-hosted web search capability

Status: implemented for OpenAI Responses and Anthropic Messages web_search_20250305; other provider-native wires remain explicit follow-ups. Verified against public provider documentation and shipped client/SDK behavior on 2026-08-04.

Problem

Maka originally exposed only a Tavily-backed WebSearch tool. That made live search require a second credential even when the selected model provider already offered a server-side search tool.

The missing abstraction was not another search-provider enum entry. Hosted search depends on all three of:

  1. the configured provider access path;
  2. the exact selected model;
  3. a provider-specific protocol and tool shape.

functionCalling: true does not imply hosted search. OpenAI-compatible chat does not imply Responses web_search, and Anthropic-compatible messages do not imply support for web_search_20250305.

Current routing

The user chooses one explicit search source:

  • model: reuse the current session model connection and credential;
  • tavily: use the separately configured Tavily credential.

There is no silent fallback. If model is selected and the exact provider/model pair is unsupported, Maka omits the native tool from that turn. Tavily remains an explicit alternative rather than taking over after a failed native call.

The capability decision lives in packages/core/src/model-web-search.ts. Stored model metadata can explicitly set capabilities.webSearch; otherwise narrow provider/model rules apply.

The implemented native adapters are:

  • openai-responses for Codex-style web_search;
  • anthropic-messages for Claude Code-compatible web_search_20250305.

Execution surfaces

All production AiSdkBackend composition roots use the same routeWebSearchTools decision:

SurfaceConfiguration authorityRoot behavior
Desktoppersisted webSearch.enabled/defaultProvider settingsMay add provider-native WebSearch
CLI / TUI / maka runthe same persisted settingsMay add provider-native WebSearch
Runtime Hostruntime-policy web-search settingsMay add provider-native WebSearch
Headless Harborexplicit MAKA_WEB_SEARCH_ENABLED=trueMay add provider-native WebSearch

Headless remains opt-in because silently enabling network search would change benchmark semantics and historical baselines. Merely speaking Anthropic Messages is not enough to infer hosted-search support; Maka uses explicit model metadata or narrow model-id rules, including DeepSeek V4 Flash on an anthropic-compatible connection.

An explicit BackendFactoryContext.tools list is a hard ceiling. Root surfaces may add native search, but scoped child agents do not gain it unless their supplied tool list already contains WebSearch. Dedicated model experiments and auxiliary calls such as title generation, history compaction, goal judging, connection tests, and daily review do not receive search implicitly.

Privacy mode removes both provider-native and client-executed WebSearch before the model request is built.

The built-in web_research child profile is derived from that same routed per-session child tool surface. It is not advertised when search is disabled, privacy mode is active, or the selected provider/model wire is unsupported.

turn-start tool surface
  -> provider/model capability resolution
  -> replace client WebSearch with provider-native WebSearch
  -> primary model POST /responses
       tools: [{ type: "web_search" }]
  -> provider-executed search call/result
  -> same model stream continues to final text

The search request uses the existing model credential. It does not duplicate the secret into web-search settings, start a nested model request, or expose the secret to the renderer. Provider search call/results are marked providerExecuted, preserved separately from local ToolRuntime execution, and replayed through the native provider-tool shape.

The durable event keeps normalized result data for the canonical read model, UI, and exports, plus opaque providerOutput data for provider-protocol replay. Anthropic replay places server_tool_use and web_search_tool_result in the same assistant message. Responses replay uses a provider item reference and never emits an orphan function_call_output.

Context budgeting measures the opaque replay payload rather than the smaller display projection. Provider-native results are not partially archived: history compaction removes the complete old turn instead of archiving only result while accidentally retaining an unbounded providerOutput.

DeepSeek live verification on 2026-08-04 completed one real Maka AiSdkBackend turn with two provider-executed WebSearch calls and a final answer in the same stream. DeepSeek returned search actions but no structured source rows or URL annotations in that response, so Maka preserves citations when supplied but does not synthesize or invent them.

The same key was also verified through DeepSeek's Anthropic-compatible endpoint: one real Maka turn sent web_search_20250305, received one provider-executed WebSearch result containing ten source rows, and completed the final answer without a second model call. This pins both the Codex/Responses and Claude Code/Messages wire formats against live provider behavior.

Full production-surface smoke verification on 2026-08-04 then ran:

  • maka run through a persisted DeepSeek Responses connection;
  • maka run through a persisted DeepSeek Anthropic-compatible connection;
  • Headless Harbor with Responses and MAKA_WEB_SEARCH_ENABLED=true;
  • Headless Harbor with Anthropic Messages and the same explicit opt-in.

All four runs completed with provider-executed WebSearch call/result pairs, final model text, no local ToolRuntime execution of WebSearch, and durable runtime events. Both headless runs also persisted token summaries. The Responses CLI turn emitted search plus page-open actions; the Anthropic CLI turn returned ten structured source rows.

After review fixes, local HTTP wire conformance also verified second-turn replay through the real AI SDK provider converters for both protocols. A later live-provider rerun on 2026-08-04 timed out before either provider returned its first model event, so it did not replace the earlier successful live smoke or the deterministic second-turn wire tests.

Dual-wire selection

Native search never switches protocol independently from the primary model request. The selected connection wire is authoritative:

  • an OpenAI Responses session receives openai.web_search;
  • an Anthropic Messages session receives anthropic.web_search_20250305.

For a provider that supports both, an explicit connection/model apiProtocol wins. An ambiguous standard DeepSeek V4 Flash connection defaults to Responses; using the CC wire requires an explicit Anthropic-compatible connection. Maka does not retry a failed native search over the other protocol.

A single same-prompt DeepSeek V4 Flash comparison on 2026-08-04 observed:

WireLatencySearch callsVisible source rowsTokensEstimated cost
Responses9.46 s205,943$0.00046
Anthropic Messages3.13 s1109,638$0.00134

This is a smoke comparison, not a latency benchmark. It shows the trade-off: the CC wire provided stricter maxUses, lower observed latency, and structured source rows; Responses used much more cache, cost about one third as much, and matched the general Codex/coding-agent wire. The default therefore remains Responses, while the Anthropic-compatible route stays an explicit choice for search-heavy workflows that value source visibility over cache economics.

Provider matrix

Provider or access pathOfficial hosted search surfaceModel boundaryMaka state
DeepSeekResponses web_search, server-executeddeepseek-v4-flash; DeepSeek documents V4 Pro as not yet supported by ResponsesIntegrated through openai-responses
OpenAI APIResponses web_search toolMaka currently enables the native path for GPT-5 families, whose runtime wire is already ResponsesIntegrated through openai-responses
Custom Responses relayResponses web_search tool when explicitly declared by model metadataopenai-responses-compatible connections with apiProtocol=openai-responses and capabilities.webSearch=trueIntegrated through openai-responses
xAI API / OAuthResponses Agent Tools web_searchMaka currently enables the verified Grok 4.5 Responses routeIntegrated through openai-responses
Alibaba Model StudioResponses web_searchQwen 3.5 Plus/Flash provider support is recordedProvider supports it; Maka Responses adapter pending
Anthropic / Claude subscriptionMessages web_search_20250305Current Claude Opus/Sonnet/Haiku/Fable familiesIntegrated through anthropic-messages
MiniMax API / Coding PlanAnthropic-compatible web_search_20250305MiniMax M2.7/M3 familiesIntegrated through anthropic-messages; live provider verification pending
Google GeminiGemini API grounding with Google SearchSupported Gemini 2.0+ model families vary by releaseProvider supports it; Maka adapter pending
Z.AI / GLM Coding PlanChat tool and standalone Web Search APIGLM model/tool availability varies by endpointProvider supports it; Maka adapter pending
MistralAgents/Conversations websearch connectorAgent-capable modelsProvider supports it; Maka adapter pending
GroqCompound systems with built-in web searchgroq/compound and groq/compound-miniProvider supports it; Maka adapter pending
OpenRouterWeb plugin and :online variantsDepends on routed model/plugin supportProvider supports it; Maka adapter pending
Moonshot APINo general model-API hosted search contract foundKimi Code exposes SearchWeb, but that is a managed coding-platform toolNot treated as Moonshot model capability
Cohere, Together, Fireworks, SiliconFlowNo general hosted-search contract found in the reviewed API docsClient tools or external search remain requiredUse Tavily or another future external provider

Official references

Follow-up adapters

Add adapters in this order:

  1. Add an opt-in web_search_20260209 capability for Anthropic deployments that support dynamic filtering; retain 20250305 as the compatibility baseline used by Claude Code and third-party Anthropic-compatible services.
  2. Gemini grounding with Google Search.
  3. Z.AI native model tool. Keep its standalone Search API outside the provider-native path.
  4. OpenRouter web plugin.
  5. Mistral Agents and Groq Compound, after defining their cost and result-row projection contracts.

Every adapter must execute in the primary model request, preserve provider tool events and citation metadata, keep credential isolation, and retain explicit no-fallback behavior.