Skip to content

fix(eve): recover when an OpenAI-compatible endpoint rejects the injected web_search tool - #1453

Open
lucasdoell wants to merge 1 commit into
vercel:mainfrom
lucasdoell:fix/web-search-openai-compatible-recovery
Open

fix(eve): recover when an OpenAI-compatible endpoint rejects the injected web_search tool#1453
lucasdoell wants to merge 1 commit into
vercel:mainfrom
lucasdoell:fix/web-search-openai-compatible-recovery

Conversation

@lucasdoell

@lucasdoell lucasdoell commented Jul 31, 2026

Copy link
Copy Markdown

Fixes #1451

Problem

eve auto-injects OpenAI's provider-managed web_search tool for any BYO model whose id looks OpenAI-shaped (resolveWebSearchBackend). When the model is actually served by an OpenAI-compatible endpoint without native web search — e.g. GPT 5.6 Sol/Luna through AWS Bedrock Mantle via createOpenAI({ baseURL }) — the AI SDK adds include: ["web_search_call.action.sources"] to every Responses API request and the endpoint rejects it:

{"error":{"message":"Invalid value: 'web_search_call.action.sources'. Supported values are: 'reasoning.encrypted_content'.","type":"invalid_request_error","param":"include","code":"invalid_value"}}

The 400 is classified terminal and the existing unsupported-provider-tool recovery never fires (its detection is anchored on the gateway's tool type 'X' is not supported phrasing), so every model call fails — the agent cannot complete a single turn. The only workaround is a disableTool() file at agent/tools/web_search.ts in every agent.

Solution

Extend the existing recovery flow (the one already used when a gateway fallback provider rejects web_search_20250305) to recognize this rejection shape:

  • model-call-error.ts: extractUnsupportedProviderToolTypes now also matches an upstream Invalid value: 'web_search_call.action.sources' rejection, in both the structured scan and the truncated-responseBody raw scan. The regex is anchored on the invalid value phrasing so supported-value enumerations (an endpoint rejecting a different include) and request-snapshot echoes in truncated error bodies cannot trigger a false drop. That include is added by the AI SDK only when the injected OpenAI web-search tool is present, so mapping the rejection back to web_search is safe.
  • provider-tools.ts: map web_search_call.action.sourcesweb_search in UPSTREAM_TOOL_TYPE_TO_FRAMEWORK_NAME.

The harness then drops web_search, retries the step once with the standard system note, and the retry no longer carries the include — agents on such endpoints self-heal instead of hard-failing.

Validation

  • Reproduced the failure mechanism locally against a mock Mantle-style server using the vendored @ai-sdk/openai: with web_search in the tool set the SDK sends the include and the call 400s; without it, the call succeeds.
  • Confirmed live by a self-hosted fleet on eve 0.24.6 (every agent ships the disableTool() workaround); injection/detection paths unchanged on main.
  • New unit tests: include-rejection via structured data, via responseBody only, via truncated-body raw scan; negative tests for supported-value enumeration and request-echo shapes; mapping test for resolveFrameworkToolFromUpstreamType.
  • pnpm lint, pnpm typecheck, pnpm test (unit 5600 passed, integration 567 passed) all green; changeset (patch) included.

Notes

  • Matching the existing recovery's semantics, the disabled set applies to the recovery retry only, so on affected endpoints each step still pays one failed call before recovering. Persisting the disabled set for the remainder of the turn/session would remove that overhead — happy to file a follow-up issue if there's interest.

…cted web_search tool

eve injects OpenAI's provider-managed web_search tool for any BYO model
whose id looks OpenAI-shaped, which makes the AI SDK add the
web_search_call.action.sources include to every Responses API request.
OpenAI-compatible endpoints without native web search (e.g. AWS Bedrock
Mantle) reject that include with HTTP 400, failing every model call
before the agent can complete a single turn.

Teach the unsupported-provider-tool recovery to recognize the include
rejection shape, map it back to the framework web_search tool, drop the
tool, and retry the step — the same recovery flow used when a gateway
fallback provider rejects web_search_20250305. The regex is anchored on
the "invalid value" phrasing so supported-value enumerations and
request-snapshot echoes in truncated error bodies cannot trigger a
false drop.

Fixes vercel#1451

Claude-Session: https://claude.ai/code/session_019EdUqspQPvUwPAUxMRvSDu
Signed-off-by: Lucas Doell <lucas@lux.dev>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@lucasdoell is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-injected provider web_search breaks every model call on OpenAI-compatible endpoints without native web search (e.g. Bedrock Mantle)

1 participant