Skip to content

feat(runtime): restore DeepSeek native WebSearch - #3694

Draft
MoonOld wants to merge 5 commits into
apache:mainfrom
MoonOld:feat/deepseek-native-websearch
Draft

feat(runtime): restore DeepSeek native WebSearch#3694
MoonOld wants to merge 5 commits into
apache:mainfrom
MoonOld:feat/deepseek-native-websearch

Conversation

@MoonOld

@MoonOld MoonOld commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Restores first-party DeepSeek V4 model-native WebSearch after #2972 deliberately disabled it on the @ai-sdk/open-responses adapter boundary.

  • marks the shared Open Responses search adapter implemented for first-party DeepSeek;
  • keeps the existing exact model boundary (deepseek-v4-flash and deepseek-v4-pro) and explicit openai-chat override veto;
  • restores root WebSearch routing without widening scoped child tool ceilings;
  • documents the 2026-08-24 first-party live revalidation and the existing grounded-text replay boundary.

Fixes #3689

Dependencies

This is a stacked Draft PR on #3685, which adds the common Open Responses request/stream transport and preserves search, open_page, and find_in_page. #3685 is itself stacked on the Alibaba Token Plan Responses foundation in #3255.

The branch currently includes those preceding commits and should be rebased after #3255 and #3685 merge. The DeepSeek-only commit is 0099fe751.

Live verification

A normal routed smoke passed on exact DeepSeek head 0099fe751 using the first-party DEEPSEEK_API_KEY from the ignored local /Users/moonold/.env file. The credential was read only in process and was never printed, placed in command arguments, persisted, or attached.

Execution path:

routeWebSearchTools (enabled/model, non-incognito)
  -> canonical openai-web-search descriptor
  -> production getAIModel + ModelAdapter
  -> https://api.deepseek.com/responses

Observed:

  • the ordinary capability route injected one provider WebSearch descriptor;
  • six calls were marked providerExecuted: true;
  • normalized actions preserved search, openPage, and findInPage with URL/pattern fields;
  • the grounded final answer completed with stop;
  • usage: 31,063 input / 2,193 output / 1,068 reasoning / 33,256 total tokens;
  • no Tavily or local ToolRuntime WebSearch execution occurred.

Verification

  • npm run format:check
  • npm run lint
  • npm run check:asf-headers
  • Core full suite: 652 passed, 0 failed
  • Runtime full suite: 3,025 passed, 13 skipped, 0 failed
  • focused capability, routing, and Responses wire suites: 31 passed
  • affected Core, Storage, and Runtime builds passed

Replay boundary

@ai-sdk/open-responses still cannot safely round-trip a provider-executed call/result pair embedded in assistant history. Maka retains the durable search episode and grounded answer, but omits the provider-owned pair from the next request rather than emitting a dangling function output. This is the same explicit fail-closed boundary established by #2972 and is not widened here.

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

OpenAI Codex assisted with implementation, protocol analysis, automated tests, live verification, and PR drafting. The human contributor reviewed the scope and remains responsible for the contribution. The commit carries a Generated-by: OpenAI Codex trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

A consumer that stops the adapter mid-stream (the reasoning-mismatch
throw, a user stop) leaves the SDK without a finish chunk, so teardown
rejects every result promise. usage and finishReason were already
consumed, but response was only read on the completed continuation
path — its rejection could surface as an unhandled rejection after the
turn unwound, scheduler-timing owned (observed post-test on Windows,
where Node makes it a crash). Sink it unconditionally in the teardown
finally, and pin the property with an unhandledRejection trap in the
mismatch test so every event loop proves the path leaves none behind.
Route Qwen3.8 Max Token Plan sessions to provider-executed Responses web search, and extend the pinned open-responses adapter with the published web_search request and web_search_call stream shapes.

Generated-by: OpenAI Codex
Map search, open_page, and find_in_page into the canonical provider-executed WebSearch output instead of collapsing every hosted action to search.

Generated-by: OpenAI Codex
Enable provider-executed WebSearch for first-party DeepSeek V4 Responses models now that the shared Open Responses adapter preserves all observed search actions.

Generated-by: OpenAI Codex
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.

feat(runtime): restore DeepSeek native WebSearch on Open Responses

1 participant