Skip to content

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

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

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
@github-actions github-actions Bot added the effort/XL Under 2500 readable lines label Aug 27, 2026
@github-actions github-actions Bot added effort/XXL Over 2500 readable lines and removed effort/XL Under 2500 readable lines labels Sep 3, 2026
@github-actions github-actions Bot added the stale No qualifying activity within the lifecycle policy window label Sep 24, 2026
@github-actions

Copy link
Copy Markdown

This pull request has had no new commits for 30 days and has been marked stale. It will be closed in 7 days unless a new commit is pushed.

Comments do not reset this timer: only a new commit does. If the pull request is intentionally long-lived, a maintainer can apply the pinned label.

@me2seeks me2seeks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review notice: This comment was posted by an automated review agent operated by me2seeks make. It is not an independent human review and does not replace one.

Summary

Restores DeepSeek native WebSearch: flips the DeepSeek adapter from implemented: false (with its old "SDK serializes function tools only, so a native search tool would be silently filtered" comment) to implemented: true, and also adds the alibaba-token-plan cases with the qwen3.8-max gating. Registry, llm-connections, model-metadata, the capability doc, and the backend/adapter/native-web-search tests move in step.

Findings

  1. [P2] Overlaps #3685 (feat(runtime): add Qwen3.8-Max native WebSearch, also open, same author): both add the identical alibaba-token-plan-cn/alibaba-token-plan cases with the qwen3.8-max gate in model-web-search.ts. Whichever lands second will conflict on those hunks — land the DeepSeek restore and the Qwen gating as one change (here) or sequence them explicitly, but not both independently.
  2. [P2] The implemented: false → true flip retires a comment claiming the SDK would silently filter a native search tool from the request. The PR is a draft with no CI run ("no checks reported") — the native-web-search and responses-wire tests that prove the tool actually reaches the provider (not filtered) must run green before this assumption is trusted; the flip without a green wire test would silently restore the original silent-filter bug.

Verdict

needs-changes — plausible restore, but reconcile with #3685 and prove in CI that the hosted search tool actually reaches the wire.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

This pull request has been closed because it received no new commits during the 7-day grace period. This is not a judgement on the merit of the change; it only keeps the review queue aligned with work that is actively in flight.

The branch and review history are preserved. Push a new commit and reopen the pull request whenever the work is ready to continue.

@github-actions github-actions Bot closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/XXL Over 2500 readable lines stale No qualifying activity within the lifecycle policy window

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants