* fix(web-search-deepseek): disable thinking for auxiliary search requests The provider discards the generated text of the auxiliary Messages turn, so reasoning tokens have no consumer. DeepSeek enables thinking by default, which adds latency and output tokens to every search. Fixes #6099. * feat(web): add opt-in traditional Search and Fetch APIs * test(web): verify API settings persistence and refresh Session evidence * fix(web): require an explicit Search API base with its route prefix * docs(web): document direct Search and Fetch API decisions * fix(web): keep Messages search default behind the new Web Search API switch - Rename useTraditionalApi/traditionalBaseURL to useSearchApi/searchApiBaseURL and label the switch "Use the new Web Search API"; Messages search stays the default. - Default the Search / Fetch API base to https://api.deepseek.com/v1/tools. - Authenticate the Search API with an API key only: DeepSeek Account tokens returned an empty HTTP 404 on /v1/tools/* when probed on 2026-10-16. - Remove the count setting, which tool-web's maxResults always overrides, and the undocumented DeepSeek-API-Version header. - Name the active API's base URL field and the current settings path in endpoint guidance; re-record the endpoint guidance Session. - Keep WebFetchResult.statusCode required: DeepSeek Fetch reports HTTP 200 and drops the page title, so the fetch-metadata widening and its upgrade guide are removed. * fix(web): accept account sign-in on the live Search API The public Search and Fetch routes went live on 2026-10-16 and accept the DeepSeek Account token, so account-route Sessions send it to the Search API as they do for Messages search, and the settings copy no longer says account sign-in does not apply. Record the live behavior in the README and Agent Note: summaries of 1,000-2,300 characters, an HTTP 500 for an unresolvable Fetch target, and migration notes for gateways without /v1/tools routes. Test doubles now use the live response fields and RFC 3339 offsets. * feat(web): configure Search API result count and send the triggering question - Add web-search-deepseek.count (1-50, default 10, the service default) and show it as "Results per search" in Search API mode, where "Max searches per request" applies only to Messages; a smaller request maxResults still wins. - Send the initiating Session's latest human prompt as ori_question, with whitespace collapsed and cut to the API's 128-character limit; blank or absent prompts omit it, and sendOriginalQuestion: false disables it. The settings hint states that the question is sent. - Match the web search double on the request's query field, since ori_question now carries every query in the prompt. * fix(client): unify web search endpoint override controls * feat(web): configure registered search and fetch providers through shared settings * feat(web): include Exa and Perplexity in provider settings * test(web): cover provider settings branches and refresh plugin snapshots * revert(web): drop the provider dropdown, schema-driven form, and Exa/Perplexity settings Revert aed8c5cb609, d88c47dcd80, and 036a5a337d3. The Web search settings page returns to the DeepSeek toggle; the DeepSeek Search and Fetch API split is reintroduced as one plugin in the following commit. * feat(web): move the DeepSeek Search and Fetch APIs into web-deepseek-api The new web-deepseek-api plugin registers deepseek-search-api and deepseek-fetch-api over one credential and API base, and exports the authentication and redirect-rejecting transport that web-search-deepseek now reuses for Messages search only. The web service reads searchProvider and fetchProvider for each operation, so the Web search settings switch selects both APIs together on save and restores Messages search with local HTTP fetch when turned off. The switch hint links to the DeepSeek search and fetch guide. * refactor(client): keep the web search endpoint fields on the shared override controls Drop the always-visible reset and the inherited-address placeholder from the Web search page, restoring ui-primitives to its base. Each endpoint field shows the selected section's effective value and offers Reset to default only for an override, like every other settings field. * refactor(web): keep Messages search independent of web-deepseek-api Restore dsh-web-search-deepseek to its own credential and transport code, keeping only the disabled-thinking request and the current settings guidance, so the Messages plugin no longer depends on the Search and Fetch API package. dsh-web-deepseek-api keeps its transport internal; the regions that repeat the Messages helpers carry jscpd:ignore markers, with the rationale recorded in the Search and Fetch API Agent Note. * refactor(web): keep the web-deepseek-api request type module-private --------- Co-authored-by: LegGasai <[email protected]>
7.3 KiB
description, kind
| description | kind |
|---|---|
| DeepSeek Search and Fetch API providers, their shared authentication and transport, endpoint configuration, and normalized results. | package-reference |
@deepseek-ai/dsh-web-deepseek-api
English | 中文
Summary
Search and fetch the web through the DeepSeek Search and Fetch APIs: one direct request per operation, without an auxiliary model request. The plugin registers deepseek-search-api and deepseek-fetch-api, which share one credential and one API base, and authenticates with an API key or the configured account integration. Search returns titles, URLs, available snippets, and available publication dates; Fetch returns page Markdown. Messages search stays in dsh-web-search-deepseek; the model-facing tools live in dsh-tool-web.
Table of Contents
- Use this package
- Understand the implementation
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount the plugin alongside dsh-web and select its providers. Shipped profiles mount it while selecting Messages search and local HTTP fetch. Turning on Use the new Web Search API in Plugins > Built-in plugin settings > Web search and saving selects both providers of this package; turning it off restores the shipped selection. A saved selection applies to the next operation.
- name: '@deepseek-ai/dsh-web'
config:
searchProvider: deepseek-search-api
fetchProvider: deepseek-fetch-api
- name: '@deepseek-ai/dsh-web-deepseek-api'
config:
apiKeyEnv: DEEPSEEK_API_KEY
| Field | Default | Meaning |
|---|---|---|
apiKey |
omitted | Literal API key; prefer a credential reference |
apiKeyEnv |
DEEPSEEK_API_KEY |
Credential reference resolved for each operation |
baseURL |
https://api.deepseek.com/v1/tools |
Search and Fetch API base including its deployment path prefix; append /search or /fetch |
count |
10 |
Search API results per search, an integer from 1 to 50; a smaller maxResults on the request wins |
sendOriginalQuestion |
true |
Send the triggering human prompt, cut to 128 characters, as the Search API's ori_question |
Fill baseURL with the complete API base, including its path prefix and excluding the operation name. The default reaches https://api.deepseek.com/v1/tools/search and https://api.deepseek.com/v1/tools/fetch; a deployment with another prefix, such as /api/v1/tools, needs its complete base.
Run the real API tests with DEEPSEEK_API_KEY and DEEPSEEK_SEARCH_API_TEST_BASE_URL; both are required, and the latter includes the API path prefix.
Authentication
A Session using the deepseek-account route asks the account service for a token authorized for the resolved endpoint and sends it as x-dsh-auth-token; the public Search and Fetch routes accepted it on 2026-10-16. Otherwise a non-empty literal apiKey wins over apiKeyEnv; the reference resolves through ctx.credentials, or the launch environment when that service is absent. API keys use Authorization: Bearer. Credential resolution and endpoint selection share one settings snapshot.
Results and failures
The Search API receives query, count (the configured count, or the request's smaller maxResults), need_content: false, and, unless sendOriginalQuestion is off, ori_question: the text of the initiating Session's latest human prompt with whitespace collapsed and cut to 128 characters. A search outside a Session or without such a prompt omits it. The provider maps results[].snippet directly and maps nullable date to optional publishedAt. An empty results array is successful. Fetch sends url and returns the original Markdown as a text body with HTTP status 200, because the API answers with an error status when the target yields no usable content. Its URL is the requested URL: the API reports no final redirected URL.
A blank or unparseable baseURL makes both providers unavailable, and a count outside 1 to 50 makes Search unavailable. Missing credentials fail with WEB_PROVIDER_CREDENTIAL_MISSING; cancellation uses WEB_ABORTED; transport, HTTP, and malformed response failures use WEB_PROVIDER_ERROR. Redirects are rejected before contacting their target. Non-success Fetch API statuses are retrieval failures, not target-page statuses. Account-authenticated HTTP 401 responses provide sign-in guidance; other dispatch failures identify the endpoint and the baseURL settings field. No automatic retry or provider fallback occurs.
Understand the implementation
Implementation internals — click to expand
The plugin reads its settings once per operation and registers both providers. The Search provider validates response JSON before returning service results; the Fetch provider validates the Markdown body. The transport owns credential resolution, cancellation, redirect rejection, and failure guidance; a recording hook runs before dispatch and prevents it by throwing. Search and Fetch API calls emit no auxiliary request event. Tool calls and results retain their normal Session logging.
See the web subsystem for service types and tool-web for bounded model output.
Model Experience
Conversation tool results
What the model sees
The web_search and web_fetch tools render sources or Markdown with an external-content notice. Fetch results carry the requested URL and HTTP 200. Errors retain actionable credential or endpoint guidance. Search sends the query, with the triggering question, directly to the Search API.
Token effect
No auxiliary model tokens are consumed. Conversation result tokens scale with returned snippets or Markdown and are bounded by the consumer. API retrieval billing is independent of model tokens.
KV Cache effect
Tool results append after the existing conversation prefix. Provider registration adds no model context.
Known Limitations and Deferred Work
- The shared search request does not expose
localization; the provider requests snippets only and does not consumesummary,site_name,site_icon, or full search content. Returned summaries measured 1,000–2,300 characters on 2026-10-16. - In 2026-10-16 probes, different
ori_questionvalues left result order, scores, and summaries unchanged; the provider still sends it because the guide documents it as an intent signal. - API query and URL constraints are enforced by the remote service. An unresolvable Fetch target returned HTTP 500 rather than the documented 404 on 2026-10-16, and its failure carries the same endpoint guidance as an endpoint failure. Fetch exposes neither the target status nor the final redirect URL, so results report HTTP 200 and the requested URL; the provider discards the API's page title.
- Availability checks cannot query asynchronous credential stores. A configured resolver can still fail with a missing-credential error when called.
Dev Note
None.