Files
deepseek-harness/packages/web/web-deepseek-api/README.md
T
Yudong HanandLegGasai fda98dadd2 feat(web): add DeepSeek Search and Fetch APIs behind a settings switch (#6103)
* 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]>
2026-10-17 15:08:08 +08:00

7.3 KiB
Raw Blame History

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

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 consume summary, 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_question values 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.