@deepseek-ai/dsh-web-search-deepseek 0.1.1-rc.2 → 0.1.2-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/web/web-search-deepseek/README.md
5
- README.md: 25162a3e82a05bb17f31a69bc65f6552e42906ad
6
- README.zh.md: 65b3c9175357b44ab07f84bdd10a4a250f55f43f
5
+ README.md: a00bdf206acdf09d008b7e3f5604dec087930aed
6
+ README.zh.md: 578b3efac3fb1bc4bd85ccd05ca92ec3b3707c26
package/README.md CHANGED
@@ -1,53 +1,121 @@
1
+ ---
2
+ description: "The DeepSeek-backed search provider for ctx.web: how deployments mount native DeepSeek web search through the Anthropic-compatible Messages API, with per-search credential resolution."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-web-search-deepseek
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- A [DeepSeek](https://deepseek.com)-backed `WebSearchProvider` for the harness [web capability seam](../web/README.md) (`ctx.web`). It calls DeepSeek's **Anthropic-compatible Messages API** (`POST {baseURL}/messages`) with the native `web_search_20250305` server tool enabled, and maps the structured `web_search_tool_result` blocks DeepSeek returns into the seam's normalized `WebSearchResult`.
10
+ ## Summary
6
11
 
7
- This is an **implementation** package: it registers a provider into `ctx.web`, resolves its credential for each search through the optional `ctx.credentials` seam, records the auxiliary request in the initiating Agent session when one exists, and does not register a model-facing tool. Like `@deepseek-ai/dsh-llm-deepseek`, it is a function/namespace plugin (`inject: ['web']`). The Anthropic wire shape is a provider-private detail — it does **not** make this provider depend on `ctx.llm`.
12
+ With `dsh-web-search-deepseek`, the harness searches the web through DeepSeek's native search using an existing `DEEPSEEK_API_KEY`. Choose it when a deployment wants DeepSeek native search and accepts that one search costs a full model turn in latency and tokens, because DeepSeek exposes no dedicated search endpoint. Results come from the structured search blocks DeepSeek returns, never from scraping text out of a reply. A missing credential fails the call with a structured error; a response without a search-result block fails loudly rather than degrading. The model-facing `web_search` tool lives in `dsh-tool-web`.
8
13
 
9
- ## How it differs from a dedicated search endpoint
14
+ ## Table of Contents
10
15
 
11
- Exa and Perplexity expose dedicated search endpoints; DeepSeek does not. Instead this provider issues a **full Messages model call** carrying the `web_search` server tool, so one search costs a complete model turn in latency and tokens — heavier than a pure retrieval endpoint. DeepSeek runs the search server-side and returns **structured** `web_search_tool_result` blocks; the provider parses those blocks and **never scrapes URLs out of model prose**.
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
12
22
 
13
- **Strict mode**: if the response carries no `web_search_tool_result` block (native search did not trigger), the provider throws `WebError` `WEB_PROVIDER_ERROR` rather than degrading to prose-scraping.
23
+ -----
14
24
 
15
- It reuses the `DEEPSEEK_API_KEY` credential reference (no new secret) but **not** `$DEEPSEEK_BASE_URL`: the search endpoint is the Anthropic-compatible base (`https://api.deepseek.com/anthropic/v1`), distinct from the chat-completions base (`https://api.deepseek.com`) the LLM adapter uses. A mounted credentials service is authoritative; without one, the provider falls back to the launching process environment. The reference is resolved for each search, so a key stored or rotated by the Web Models page reaches the next call without a restart.
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
16
27
 
17
- ## Config
28
+ Mount the provider in a composition that already loads the web service; it registers as the `deepseek-official` search provider, so `ctx.web.search()` resolves it automatically when it is the only usable search backend — or pin it with `searchProvider: deepseek-official`.
18
29
 
19
- | Key | Default | Meaning |
20
- |---|---|---|
21
- | `apiKey` | omitted | Literal DeepSeek API key. Prefer `apiKeyEnv` so no secret enters configuration; a non-empty literal wins. |
22
- | `apiKeyEnv` | `DEEPSEEK_API_KEY` | Credential reference resolved for each search through `ctx.credentials`, or from the process environment when that seam is absent. A missing value fails the call as `WEB_PROVIDER_CREDENTIAL_MISSING`. |
23
- | `baseURL` | `https://api.deepseek.com/anthropic/v1` | Anthropic-compatible endpoint base; `/messages` is appended. Falls back to `$DEEPSEEK_SEARCH_BASE_URL` from any environment layer; do not reuse `$DEEPSEEK_BASE_URL`, which belongs to the chat-completions LLM adapter. An unparseable value makes the provider unavailable. |
24
- | `model` | `deepseek-v4-flash` | Anthropic-format model name. |
25
- | `apiVersion` | `2023-06-01` | `anthropic-version` header value. |
26
- | `maxTokens` | `4096` | Positive-integer upper bound on generated tokens for the Messages request. |
27
- | `maxUses` | `5` | Positive-integer maximum `web_search` server-tool uses per request. |
30
+ ### When to choose it
31
+
32
+ Choose this backend when a deployment wants DeepSeek's native server-side web search and already holds a `DEEPSEEK_API_KEY` — the provider reuses that credential reference. One search is heavier than a dedicated retrieval endpoint: DeepSeek runs the search inside a full model turn, so expect one Messages call's latency and generated tokens per search, with up to `maxUses` server-side searches per request. Avoid it when per-search cost or latency dominates.
33
+
34
+ ### Minimal configuration
35
+
36
+ Load the web service and the provider; the key resolves from `ctx.credentials` when that service is mounted, otherwise from the process environment. The search endpoint uses the Anthropic-compatible base (`https://api.deepseek.com/anthropic/v1`), distinct from the chat-completions base the LLM adapter uses — never reuse `$DEEPSEEK_BASE_URL`.
28
37
 
29
38
  ```yaml
30
- - id: web-search-deepseek
31
- name: '@deepseek-ai/dsh-web-search-deepseek'
39
+ - name: '@deepseek-ai/dsh-web'
40
+ - name: '@deepseek-ai/dsh-web-search-deepseek'
32
41
  config:
33
42
  apiKeyEnv: DEEPSEEK_API_KEY
34
43
  baseURL: https://gateway.internal/anthropic/v1
35
44
  ```
36
45
 
37
- The entry above is the base layer of the `web-search-deepseek` Settings section: a user layer over it reaches the NEXT search, because the provider projects the section per call rather than capturing it at registration. The seam's provider selection therefore never flickers when an endpoint or model changes. `apiKey` carries `role('secret')`, so it never rides a `describe()` response in any layer — a configuration surface learns only whether the credentials domain holds a value for the reference `apiKeyEnv` names, never whether a layer carries a literal key.
46
+ | Field | Default | Meaning |
47
+ |---|---|---|
48
+ | `apiKey` | omitted | Literal DeepSeek API key; prefer `apiKeyEnv` so no secret enters configuration. A non-empty literal wins |
49
+ | `apiKeyEnv` | `DEEPSEEK_API_KEY` | Credential reference resolved for each search through `ctx.credentials`, or from the process environment when that service is absent. A missing value fails the call as `WEB_PROVIDER_CREDENTIAL_MISSING` |
50
+ | `baseURL` | `https://api.deepseek.com/anthropic/v1` | Anthropic-compatible endpoint base; `/messages` is appended. Falls back to `$DEEPSEEK_SEARCH_BASE_URL`; an unparseable value makes the provider unavailable |
51
+ | `model` | `deepseek-v4-flash` | Anthropic-format model name |
52
+ | `apiVersion` | `2023-06-01` | `anthropic-version` header value |
53
+ | `maxTokens` | `4096` | Positive-integer upper bound on generated tokens for the Messages request |
54
+ | `maxUses` | `5` | Positive-integer maximum `web_search` server-tool uses per request |
55
+
56
+ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-web-search-deepseek) is the exhaustive source for every accepted field and its JSDoc. The entry above is the base layer of the provider's Settings section; a user layer over it reaches the next search, because the provider projects the section per call rather than capturing it at registration.
57
+
58
+ ### What a search returns
59
+
60
+ `content` is always omitted: DeepSeek's provider prose is not trusted as an answer. `sources[]` comes from `web_search_result` items inside `web_search_tool_result` blocks — `url`, `title`, and `publishedAt` from `page_age` — with snippets joined from URL-keyed `cited_text` entries where an excerpt exists. Results are deduplicated by URL, and because DeepSeek exposes no result-count knob, the service enforces `maxResults` by truncating and flagging.
61
+
62
+ ### Request logging
63
+
64
+ A search running under an initiating agent appends the log-only `web/deepseek-search-llm-request` session event immediately before dispatch. It carries the resolved endpoint, API version, and the exact secret-free JSON body sent to DeepSeek; headers and credentials are excluded. Credential failures and cancellations before dispatch create no event, while later HTTP or response failures leave the attempted request durable.
65
+
66
+ ### Failures and recovery
67
+
68
+ Failures throw `WebError` with a machine-routable code: a missing credential is `WEB_PROVIDER_CREDENTIAL_MISSING`, caller cancellation is `WEB_ABORTED`, and provider or transport failures — including a response with no `web_search_tool_result` block — are `WEB_PROVIDER_ERROR`. HTTP redirects are rejected before the `Location` target is contacted. Every failure after dispatch names the resolved search endpoint and explains that search endpoint configuration is separate from chat. If the endpoint is unintended, the message tells the conversation model to guide the user to the Endpoint field under Settings > Plugins > Plugin configuration > Web search and save the change. When that page is unavailable, it names `DEEPSEEK_SEARCH_BASE_URL` and `web-search-deepseek.baseURL` as deployment configuration alternatives. The model must not choose or change the endpoint. The model-facing `web_search` tool surfaces this text under its own error wrapper.
69
+
70
+ -----
71
+
72
+ <a id="understand-the-implementation"></a>
73
+ ## Understand the implementation
74
+
75
+ <details>
76
+ <summary>Implementation internals — click to expand</summary>
77
+
78
+ This section explains the design decisions behind the provider; the observable behavior is fully covered in [Use this package](#use-this-package).
38
79
 
39
- ## Mapping
80
+ ### Design philosophy
40
81
 
41
- DeepSeek returns no provider-generated answer content this provider trusts as `content`, so `content` is omitted. `sources[]` comes from `web_search_result` items inside `web_search_tool_result` blocks: `url` ← `url`, `title` ← `title`, and `publishedAt` ← `page_age`. Snippets live separately as URL-keyed `cited_text` entries in a text block's `citations[]`; the provider joins them, leaving `snippet` absent when no excerpt exists.
82
+ The provider is built on two commitments:
42
83
 
43
- Results are deduplicated by URL because one request may surface the same page across searches. DeepSeek exposes `maxUses`, not a result-count knob, so the seam enforces `maxResults` by truncating `sources[]` and setting `truncated`.
84
+ - **Structured blocks only.** DeepSeek runs the search server-side and returns structured `web_search_tool_result` blocks; the provider parses those blocks and never scrapes URLs out of model prose. In strict mode, a response with no such block throws `WEB_PROVIDER_ERROR` instead of degrading.
85
+ - **One credential, resolved per search.** The provider reuses the `DEEPSEEK_API_KEY` reference (no new secret) but not `$DEEPSEEK_BASE_URL`, because search speaks the Anthropic-compatible Messages API. A mounted credentials service is authoritative; without one the provider falls back to the launching process environment. Resolving per call means a key stored or rotated in the Web Models page reaches the next search without a restart.
44
86
 
45
- Provider failures become `WEB_PROVIDER_ERROR`; caller cancellation becomes `WEB_ABORTED`. HTTP redirects are rejected before the `Location` target is contacted and surface as `WEB_PROVIDER_ERROR`.
87
+ ### Source map
46
88
 
47
- ## Request logging
89
+ | File | Role |
90
+ |---|---|
91
+ | [`src/index.ts`](src/index.ts) | Plugin entry: config schema, Settings section installation, per-search option projection |
92
+ | [`src/provider.ts`](src/provider.ts) | The `DeepSeekSearchProvider`: Messages request dispatch, block parsing, citation joining, credential resolution |
93
+ | [`src/types.ts`](src/types.ts) | Anthropic wire types for the search response |
94
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion (no runtime invariant; contracts are enforced at the service) |
48
95
 
49
- Immediately before dispatch, a search running under an initiating Agent appends the log-only `web/deepseek-search-llm-request` session event. It contains the resolved endpoint, API version, and exact secret-free JSON body sent to DeepSeek; headers and credentials are excluded. Credential failures and cancellations before dispatch create no event, while later HTTP or response failures leave the attempted request durable. Direct programmatic provider calls outside an Agent have no initiating session to log.
96
+ ### Request flow
50
97
 
98
+ Each search projects the current Settings section into provider options — endpoint, model, key reference, limits — then resolves the credential reference through `ctx.credentials` (or the environment), appends the log-only session event, and dispatches the Messages request with the native `web_search` server tool. The response's `web_search_tool_result` blocks become `sources[]`; `cited_text` entries from text blocks are joined to their URLs as snippets; results are deduplicated by URL; and the service enforces the requested source bound on the way back.
99
+
100
+ </details>
101
+
102
+ -----
103
+
104
+ <a id="further-exploration"></a>
105
+ ## Further Exploration
106
+
107
+ Read these pages when the package-level contract is not enough. They move from the shared vocabulary to the service, the model-facing tools, and the design rationale.
108
+
109
+ - [Web subsystem](../../../docs/subsystems/web.md) — the exhaustive search request/result vocabulary and error codes.
110
+ - [Web package map](../README.md) — the six-package family and each role.
111
+ - [dsh-web](../web/README.md) — the web service this provider registers into.
112
+ - [dsh-tool-web](../tool-web/README.md) — the model-facing `web_search` tool that renders this provider's sources.
113
+ - [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-web-search-deepseek) — every accepted config field and its source declaration.
114
+ - [Web capability seam decision](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md) — why search and fetch share one provider-selection service.
115
+
116
+ -----
117
+
118
+ <a id="model-experience"></a>
51
119
  ## Model Experience
52
120
 
53
121
  ### Auxiliary DeepSeek search request
@@ -68,11 +136,11 @@ Independent of the conversation request cache. The auxiliary instruction and nat
68
136
 
69
137
  #### What the model sees
70
138
 
71
- Through [`dsh-tool-web`](../tool-web/README.md), the conversation model sees deduplicated URLs, titles, dates, and citation snippets from structured search blocks; provider prose is not trusted as an answer. This provider's exact failures include the actionable missing-credential message, `DeepSeek search credential resolution failed: <error>`, `DeepSeek search aborted`, `DeepSeek search request failed: <error>`, `DeepSeek returned no web_search_tool_result blocks; the request may not have triggered native web search`, and `DeepSeek returned an unprocessable response body: <error>`; HTTP failures preserve the provider message. The consumer owns the error wrapper.
139
+ Through `dsh-tool-web`, the conversation model sees deduplicated URLs, titles, dates, and citation snippets from structured search blocks; provider prose is not trusted as an answer. This provider's exact failures include the actionable missing-credential message, `DeepSeek search credential resolution failed: <error>`, and `DeepSeek search aborted`. Request, HTTP, native-search, and response-body failures append the resolved endpoint and the conditional configuration instruction described above. The consumer owns the error wrapper.
72
140
 
73
141
  #### Token effect
74
142
 
75
- Zero direct conversation tokens from registration. Result tokens scale with returned sources and snippets, then the seam enforces the requested source bound.
143
+ Zero direct conversation tokens from registration. Result tokens scale with returned sources and snippets, then the service enforces the requested source bound.
76
144
 
77
145
  #### KV Cache effect
78
146
 
@@ -80,7 +148,26 @@ Append-only; newly visible content follows the reusable request prefix and does
80
148
 
81
149
  ## Known Limitations and Deferred Work
82
150
 
151
+ <a id="known-limitations-and-deferred-work"></a>
152
+
153
+
154
+ These limits define when the provider is expensive or incomplete. They are current package constraints.
155
+
83
156
  - **One search costs a full Messages model turn** — latency plus generated tokens, with up to `maxUses` server-side searches; DeepSeek exposes no dedicated retrieval endpoint.
84
- - **Dynamic credential availability resolves inside the operation** — the synchronous `available()` contract can establish that a resolver exists but cannot query an asynchronous credential store. A selected keyless provider therefore fails the search with `WEB_PROVIDER_CREDENTIAL_MISSING`; the stable `web_search` schema remains registered. Caller cancellation races this preflight locally, but cannot force an arbitrary credential backend itself to stop work.
85
- - **Over-returned sources still cost tokens** — with no result-count knob on the wire, `maxResults` is enforced only post-hoc by seam truncation.
86
- - **Uncited results carry no `snippet`** — a source gains one only when a `text` block citation (`cited_text`) matches its URL.
157
+ - **Dynamic credential availability resolves inside the operation** — the synchronous availability check can establish that a resolver exists but cannot query an asynchronous credential store, so a selected keyless provider fails the search with `WEB_PROVIDER_CREDENTIAL_MISSING`; the stable `web_search` schema stays registered.
158
+ - **Over-returned sources still cost tokens** — with no result-count knob on the wire, `maxResults` is enforced only post-hoc by service truncation.
159
+ - **Uncited results carry no `snippet`** — a source gains one only when a text-block citation (`cited_text`) matches its URL.
160
+
161
+ <a id="dev-note"></a>
162
+ ### Dev Note
163
+
164
+ <details>
165
+ <summary>Working context for maintainers — click to expand</summary>
166
+
167
+ This Dev Note is working context for maintainers: open questions and undecided directions. It is explicitly non-authoritative — shipped behavior, limits, and rationale live in the sections above and the linked Agent Notes.
168
+
169
+ #### Future: dedicated retrieval endpoint
170
+
171
+ A native DeepSeek search endpoint that avoids the full model turn would remove the dominant cost; until DeepSeek exposes one, this provider stays a Messages-call adapter.
172
+
173
+ </details>
package/README.zh.md CHANGED
@@ -1,53 +1,121 @@
1
+ ---
2
+ description: "ctx.web 的 DeepSeek 搜索提供方:部署方如何通过 Anthropic 兼容 Messages API 挂载 DeepSeek 原生 web 搜索,并逐次解析凭据。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-web-search-deepseek
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 由 [DeepSeek](https://deepseek.com) 支持的 `WebSearchProvider`,用于 harness [web 能力 seam](../web/README.zh.md)(`ctx.web`)。它调用 DeepSeek 的 **Anthropic 兼容 Messages API**(`POST {baseURL}/messages`),启用原生 `web_search_20250305` 服务器工具,并把 DeepSeek 返回的结构化 `web_search_tool_result` 块映射为 seam 规范化的 `WebSearchResult`。
10
+ ## 概述
6
11
 
7
- 这是一个**实现**包:它向 `ctx.web` 注册提供方,通过可选的 `ctx.credentials` seam 为每次搜索解析凭据,若存在发起请求的 agent(智能体)会话,还会在其中记录该辅助请求,且不注册面向模型的工具。与 `@deepseek-ai/dsh-llm-deepseek` 一样,它是函数/命名空间插件(`inject: ['web']`)。Anthropic 协议格式(wire format)是提供方私有细节,并**不**使该提供方依赖 `ctx.llm`。
12
+ 有了 `dsh-web-search-deepseek`,harness 可以通过 DeepSeek 原生搜索检索 web,使用部署已有的 `DEEPSEEK_API_KEY`。当部署希望使用 DeepSeek 原生搜索、并接受一次搜索在延迟与 token 上消耗一个完整模型轮次时选择它,因为 DeepSeek 不提供专用搜索端点。结果来自 DeepSeek 返回的结构化搜索块,绝不会从回复文本中抓取。凭据缺失时调用以结构化错误失败;响应缺少搜索结果块时会响亮地失败,而非降级。面向模型的 `web_search` 工具位于 `dsh-tool-web`。
8
13
 
9
- ## 与专用搜索端点的区别
14
+ ## 目录
10
15
 
11
- Exa 和 Perplexity 提供专用搜索端点,DeepSeek 则没有。该提供方改为发起一次携带 `web_search` 服务器工具的**完整 Messages 模型调用**,因此一次搜索会产生完整模型轮次的延迟与 token 开销,比纯检索端点更重。DeepSeek 在服务器侧执行搜索,返回**结构化** `web_search_tool_result` 块;提供方解析这些块,**绝不会从模型文本中抓取 URL**。
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
12
22
 
13
- **严格模式**:如果响应不含 `web_search_tool_result` 块(未触发原生搜索),提供方会抛出 `WebError` `WEB_PROVIDER_ERROR`,而非降级为文本抓取。
23
+ -----
14
24
 
15
- 它复用 `DEEPSEEK_API_KEY` 凭据引用(不增加密钥),但**不会**复用 `$DEEPSEEK_BASE_URL`:搜索端点使用 Anthropic 兼容基址(`https://api.deepseek.com/anthropic/v1`),不同于 LLM(大语言模型)适配器使用的 chat-completions 基址(`https://api.deepseek.com`)。已挂载的凭据服务具有权威性;没有该服务时,提供方会回退到启动进程的环境变量。每次搜索都会解析该引用,因此在 Web 的 Models 页中存储或轮换的密钥无需重启,即可用于下一次调用。
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
16
27
 
17
- ## 配置
28
+ 在已加载 web 服务的组合中挂载本提供方;它以 `deepseek-official` 搜索提供方身份注册,因此当它是唯一可用的搜索后端时,`ctx.web.search()` 会自动解析到它——也可以用 `searchProvider: deepseek-official` 固定。
18
29
 
19
- | 配置键 | 默认值 | 含义 |
20
- |---|---|---|
21
- | `apiKey` | 未设置 | DeepSeek API 密钥字面值。优先使用 `apiKeyEnv`,避免密钥进入配置;非空字面值优先。 |
22
- | `apiKeyEnv` | `DEEPSEEK_API_KEY` | 每次搜索都会通过 `ctx.credentials` 解析该凭据引用;没有该 seam 时则从进程环境解析。值缺失时,调用以 `WEB_PROVIDER_CREDENTIAL_MISSING` 失败。 |
23
- | `baseURL` | `https://api.deepseek.com/anthropic/v1` | Anthropic 兼容端点基址;追加 `/messages`。缺省时回退到任一环境层中的 `$DEEPSEEK_SEARCH_BASE_URL`;禁止复用属于 chat-completions LLM 适配器的 `$DEEPSEEK_BASE_URL`。无法解析时提供方不可用。 |
24
- | `model` | `deepseek-v4-flash` | Anthropic 格式模型名称。 |
25
- | `apiVersion` | `2023-06-01` | `anthropic-version` 标头值。 |
26
- | `maxTokens` | `4096` | Messages 请求生成 token 的正整数上限。 |
27
- | `maxUses` | `5` | 每次请求使用 `web_search` 服务器工具的正整数上限。 |
30
+ ### 何时选择
31
+
32
+ 当部署希望使用 DeepSeek 原生服务端 web 搜索、且已持有 `DEEPSEEK_API_KEY` 时选择此后端——提供方复用该凭据引用。一次搜索比专用检索端点更重:DeepSeek 在完整模型轮次内执行搜索,因此每次搜索都要预期一次 Messages 调用的延迟与生成 token,每次请求最多 `maxUses` 次服务端搜索。当单次搜索的成本或延迟占主导时避免使用它。
33
+
34
+ ### 最小配置
35
+
36
+ 加载 web 服务与本提供方;密钥在已挂载 `ctx.credentials` 服务时从其解析,否则从进程环境解析。搜索端点使用 Anthropic 兼容基址(`https://api.deepseek.com/anthropic/v1`),不同于 LLM(大语言模型)适配器使用的 chat-completions 基址——绝不复用 `$DEEPSEEK_BASE_URL`。
28
37
 
29
38
  ```yaml
30
- - id: web-search-deepseek
31
- name: '@deepseek-ai/dsh-web-search-deepseek'
39
+ - name: '@deepseek-ai/dsh-web'
40
+ - name: '@deepseek-ai/dsh-web-search-deepseek'
32
41
  config:
33
42
  apiKeyEnv: DEEPSEEK_API_KEY
34
43
  baseURL: https://gateway.internal/anthropic/v1
35
44
  ```
36
45
 
37
- 上面的条目是 `web-search-deepseek` Settings 段的 base 层:叠加其上的用户层会作用于**下一次**搜索,因为提供方是按次投影该段,而不是在注册时固化它。因此端点或模型变化时,seam 的提供方选择不会闪断。`apiKey` 带有 `role('secret')`,所以它在任何一层都不会出现在 `describe()` 响应中——配置表层只能知道 credentials 领域是否为 `apiKeyEnv` 所命名的引用持有值,而无从知道某一层是否带着字面密钥。
46
+ | 字段 | 默认值 | 含义 |
47
+ |---|---|---|
48
+ | `apiKey` | 未设置 | DeepSeek API 密钥字面值;优先使用 `apiKeyEnv`,避免密钥进入配置。非空字面值优先 |
49
+ | `apiKeyEnv` | `DEEPSEEK_API_KEY` | 每次搜索通过 `ctx.credentials` 解析的凭据引用;没有该服务时从进程环境解析。值缺失时调用以 `WEB_PROVIDER_CREDENTIAL_MISSING` 失败 |
50
+ | `baseURL` | `https://api.deepseek.com/anthropic/v1` | Anthropic 兼容端点基址;追加 `/messages`。缺省时回退到 `$DEEPSEEK_SEARCH_BASE_URL`;无法解析时提供方不可用 |
51
+ | `model` | `deepseek-v4-flash` | Anthropic 格式模型名称 |
52
+ | `apiVersion` | `2023-06-01` | `anthropic-version` 标头值 |
53
+ | `maxTokens` | `4096` | Messages 请求生成 token 的正整数上限 |
54
+ | `maxUses` | `5` | 每次请求使用 `web_search` 服务器工具的正整数上限 |
55
+
56
+ 生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-web-search-deepseek)是每个受支持字段及其 JSDoc 的穷尽式真源。上面的条目是提供方 Settings 段的 base 层;叠加其上的用户层会作用于下一次搜索,因为提供方是按次投影该段,而不是在注册时固化它。
57
+
58
+ ### 搜索返回什么
59
+
60
+ `content` 始终省略:DeepSeek 的提供方文本不作为答案受到信任。`sources[]` 来自 `web_search_tool_result` 块内的 `web_search_result` 条目——`url`、`title`、`publishedAt` 取自 `page_age`——snippet 在存在摘录时按 URL 关联的 `cited_text` 条目拼接。结果按 URL 去重,且由于 DeepSeek 不公开结果数量旋钮,服务通过截断并标记来强制执行 `maxResults`。
61
+
62
+ ### 请求日志
63
+
64
+ 由发起 agent(智能体)运行的搜索会在发出请求前一刻,追加仅用于日志的 `web/deepseek-search-llm-request` 会话事件。其中包含已解析端点、API 版本,以及发送给 DeepSeek 且不含密钥的精确 JSON 请求体;不包含标头和凭据。发出请求前发生凭据失败或取消时不会创建事件,而发出请求后的 HTTP 或响应失败会保留本次请求尝试的持久记录。
65
+
66
+ ### 失败与恢复
67
+
68
+ 失败抛出携带可按机器路由 code 的 `WebError`:凭据缺失为 `WEB_PROVIDER_CREDENTIAL_MISSING`,调用方取消为 `WEB_ABORTED`,提供方或传输失败,包括响应中没有 `web_search_tool_result` 块,为 `WEB_PROVIDER_ERROR`。HTTP 重定向会在接触 `Location` 指向的目标之前被拒绝。请求发出后的每项失败都会指出已解析的搜索端点,并说明搜索端点配置独立于聊天端点。如果该端点不符合用户预期,错误消息会要求会话模型指导用户进入 Settings > Plugins > Plugin configuration > Web search,修改 Endpoint 字段并保存。该页面不可用时,消息会把 `DEEPSEEK_SEARCH_BASE_URL` 和 `web-search-deepseek.baseURL` 作为部署配置方式。模型不得替用户选择或修改端点。面向模型的 `web_search` 工具会在自己的错误包装层内呈现这段文本。
69
+
70
+ -----
71
+
72
+ <a id="understand-the-implementation"></a>
73
+ ## 理解实现
74
+
75
+ <details>
76
+ <summary>实现细节——点击展开</summary>
77
+
78
+ 本节解释提供方背后的设计决策;可观察行为已在[使用本包](#use-this-package)中完整说明。
38
79
 
39
- ## 映射
80
+ ### 设计理念
40
81
 
41
- DeepSeek 返回的提供方生成答案均不被该提供方信任为 `content`,因此省略 `content`。`sources[]` 来自 `web_search_result` 条目,这些条目位于 `web_search_tool_result` 块内:`url` ← `url`、`title` ← `title`、`publishedAt` ← `page_age`。`cited_text` 条目按 URL 标识,单独位于文本块的 `citations[]` 中;提供方会按 URL 将它们关联到相应结果,没有摘录时省略 `snippet`。
82
+ 本提供方建立在两项承诺之上:
42
83
 
43
- 结果按 URL 去重,因为一次请求可能在多次搜索中呈现同一页面。DeepSeek 公开 `maxUses` 而非结果数量旋钮,因此 seam 会强制执行 `maxResults`:截断 `sources[]` 并设置 `truncated`。
84
+ - **只取结构化块。** DeepSeek 在服务端执行搜索并返回结构化的 `web_search_tool_result` 块;提供方解析这些块,绝不从模型文本中抓取 URL。严格模式下,没有此类块的响应会抛出 `WEB_PROVIDER_ERROR`,而非降级。
85
+ - **一个凭据,逐次解析。** 提供方复用 `DEEPSEEK_API_KEY` 引用(不新增密钥),但不复用 `$DEEPSEEK_BASE_URL`,因为搜索使用 Anthropic 兼容 Messages API。已挂载的凭据服务具有权威性;没有该服务时回退到启动进程的环境。按次解析意味着在 Web 的 Models 页中存储或轮换的密钥无需重启,即可用于下一次搜索。
44
86
 
45
- 提供方失败变为 `WEB_PROVIDER_ERROR`;调用方取消变为 `WEB_ABORTED`。HTTP 重定向会在接触 `Location` 目标前被拒绝,并以 `WEB_PROVIDER_ERROR` 呈现。
87
+ ### 源码地图
46
88
 
47
- ## 请求日志
89
+ | 文件 | 职责 |
90
+ |---|---|
91
+ | [`src/index.ts`](src/index.ts) | 插件入口:配置 schema、Settings 段安装、逐次选项投影 |
92
+ | [`src/provider.ts`](src/provider.ts) | `DeepSeekSearchProvider`:Messages 请求分发、块解析、引用拼接、凭据解析 |
93
+ | [`src/types.ts`](src/types.ts) | 搜索响应的 Anthropic 协议类型 |
94
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件(无运行时不变式;约定在服务处强制执行) |
48
95
 
49
- 由 agent 发起的搜索会在发出请求前一刻,向相应会话追加仅用于日志的 `web/deepseek-search-llm-request` 会话事件。其中包含已解析端点、API 版本,以及发送给 DeepSeek 且不含密钥的精确 JSON 请求体;不包含标头和凭据。发出请求前发生凭据处理失败或取消时不会创建事件;发出请求后才发生 HTTP 或响应失败时,本次请求尝试仍保留持久记录。在 agent 之外通过程序直接调用提供方时,没有发起会话可供记录。
96
+ ### 请求流程
50
97
 
98
+ 每次搜索先把当前 Settings 段投影为提供方选项——端点、模型、密钥引用、上限——然后通过 `ctx.credentials`(或环境)解析凭据引用,追加仅用于日志的会话事件,并以原生 `web_search` 服务器工具分发 Messages 请求。响应中的 `web_search_tool_result` 块变为 `sources[]`;文本块中的 `cited_text` 条目按其 URL 拼接为 snippet;结果按 URL 去重;服务在返回路径上强制执行请求的来源上限。
99
+
100
+ </details>
101
+
102
+ -----
103
+
104
+ <a id="further-exploration"></a>
105
+ ## 进一步探索
106
+
107
+ 当包级约定不够用时阅读以下页面。它们从共享词汇逐步进入服务、面向模型的工具与设计依据。
108
+
109
+ - [web 子系统](../../../docs/subsystems/web.zh.md)——穷尽式的搜索请求/结果词汇与错误码。
110
+ - [web 包映射](../README.zh.md)——六包家族与各角色。
111
+ - [dsh-web](../web/README.zh.md)——本提供方注册进入的 web 服务。
112
+ - [dsh-tool-web](../tool-web/README.zh.md)——渲染本提供方来源的面向模型 `web_search` 工具。
113
+ - [生成配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-web-search-deepseek)——每个受支持配置字段及其源声明。
114
+ - [web 能力 seam 决策](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.zh.md)——搜索与抓取为何共用一项提供方选择服务。
115
+
116
+ -----
117
+
118
+ <a id="model-experience"></a>
51
119
  ## 模型体验
52
120
 
53
121
  ### 辅助 DeepSeek 搜索请求
@@ -68,19 +136,38 @@ DeepSeek 返回的提供方生成答案均不被该提供方信任为 `content`
68
136
 
69
137
  #### 模型看到的内容
70
138
 
71
- 通过 [`dsh-tool-web`](../tool-web/README.zh.md),会话模型会看到结构化搜索块中去重后的 URL、标题、日期与引用 snippet;提供方文本不会作为答案受到信任。该提供方的具体错误消息包括带有处理指引的凭据缺失消息、`DeepSeek search credential resolution failed: <error>`、`DeepSeek search aborted`、`DeepSeek search request failed: <error>`、`DeepSeek returned no web_search_tool_result blocks; the request may not have triggered native web search` 和 `DeepSeek returned an unprocessable response body: <error>`;HTTP 失败保留提供方消息。错误包装属于消费方。
139
+ 通过 `dsh-tool-web`,会话模型会看到结构化搜索块中去重后的 URL、标题、日期与引用 snippet;提供方文本不会作为答案受到信任。该提供方的具体失败消息包括带有处理指引的凭据缺失消息、`DeepSeek search credential resolution failed: <error>` 和 `DeepSeek search aborted`。请求、HTTP、原生搜索和响应正文失败会追加已解析端点及前述条件式配置指引。错误包装属于消费方。
72
140
 
73
141
  #### Token 影响
74
142
 
75
- 注册不会直接产生会话 token。结果 token 随返回源与 snippet 增长,随后 seam 会强制执行请求的源数量上限。
143
+ 注册不会直接产生会话 token。结果 token 随返回源与 snippet 增长,随后服务强制执行请求的来源上限。
76
144
 
77
145
  #### KV Cache 影响
78
146
 
79
147
  仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
80
148
 
81
- ## 已知限制与暂缓事项
149
+ ## 已知限制与延期工作
150
+
151
+ <a id="known-limitations-and-deferred-work"></a>
152
+
153
+
154
+ 这些限制说明提供方在哪些情况下昂贵或不完整。它们是当前包约束。
155
+
156
+ - **一次搜索消耗一个完整的 Messages 模型轮次**——产生延迟与生成 token,最多执行 `maxUses` 次服务端搜索;DeepSeek 不公开专用检索端点。
157
+ - **动态凭据的可用性在操作内部解析**——同步可用性检查可以确认解析器存在,但无法查询异步凭据存储,因此选中的无密钥提供方会使搜索以 `WEB_PROVIDER_CREDENTIAL_MISSING` 失败;稳定的 `web_search` schema 仍保持注册。
158
+ - **超量返回的来源仍消耗 token**——协议没有结果数量旋钮,`maxResults` 只能由服务在事后截断。
159
+ - **未引用的结果没有 `snippet`**——只有当文本块引用(`cited_text`)匹配其 URL 时,来源才会获得 snippet。
160
+
161
+ <a id="dev-note"></a>
162
+ ### 开发备注
163
+
164
+ <details>
165
+ <summary>维护者的工作上下文——点击展开</summary>
166
+
167
+ 本开发备注是维护者的工作上下文:开放问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文和相关 Agent Note 为准。
168
+
169
+ #### 未来:专用检索端点
170
+
171
+ 能够避免完整模型轮次的 DeepSeek 原生搜索端点将消除主要成本;在 DeepSeek 公开此类端点之前,本提供方仍是 Messages 调用适配器。
82
172
 
83
- - **一次搜索需要完整的 Messages 模型轮次**:会产生延迟与生成 token,并且最多执行 `maxUses` 次服务器侧搜索;DeepSeek 不公开专用检索端点。
84
- - **动态凭据的可用性在操作内部解析**:同步的 `available()` 约定可以确认解析器存在,但无法查询异步凭据存储。因此,选中的无密钥提供方会使搜索以 `WEB_PROVIDER_CREDENTIAL_MISSING` 失败;稳定的 `web_search` schema 仍保持注册。调用方取消在本地与该预检存在竞态,但无法强制任意凭据后端自行停止工作。
85
- - **超量返回的源仍消耗 token**:协议没有结果数量旋钮,`maxResults` 只能由 seam 在事后截断。
86
- - **未引用的结果没有 `snippet`**:只有 `text` 块中的引用(`cited_text`)匹配其 URL 时,源才会获得 snippet。
173
+ </details>
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
3
- import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
4
3
  import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
5
4
  import { WebError } from "@deepseek-ai/dsh-web";
6
5
  //#region lib/types/provider.js
@@ -81,7 +80,10 @@ function mapAnthropicResponse(response) {
81
80
  truncated: false
82
81
  };
83
82
  }
84
- /** The DeepSeek-backed search provider; HTTP redirects fail as `WEB_PROVIDER_ERROR`. */
83
+ /**
84
+ * The DeepSeek-backed search provider. HTTP redirects fail as `WEB_PROVIDER_ERROR`;
85
+ * failures after dispatch name the endpoint and tell the model how the user can configure it.
86
+ */
85
87
  var DeepSeekSearchProvider = class {
86
88
  resolveOptions;
87
89
  id = DEEPSEEK_PROVIDER_ID;
@@ -144,25 +146,24 @@ var DeepSeekSearchProvider = class {
144
146
  });
145
147
  } catch (error) {
146
148
  if (signal?.aborted === true || isAbortError(error)) throw searchAborted(signal, error);
147
- throw new WebError(`DeepSeek search request failed: ${String(error)}`, "WEB_PROVIDER_ERROR", { cause: error });
149
+ throw searchEndpointError(endpoint, `DeepSeek search request failed: ${String(error)}`, error);
148
150
  }
149
151
  if (!response.ok) {
150
152
  let message = `DeepSeek API error (HTTP ${response.status})`;
151
153
  try {
152
154
  const parsed = await response.json();
153
155
  const detail = typeof parsed.error === "string" ? parsed.error : parsed.error?.message ?? parsed.message;
154
- if (detail !== void 0 && detail.length > 0) message = detail;
156
+ if (detail !== void 0 && detail.length > 0) message += `: ${detail}`;
155
157
  } catch (error) {
156
158
  if (signal?.aborted === true || isAbortError(error)) throw searchAborted(signal, error);
157
159
  }
158
- throw new WebError(message, "WEB_PROVIDER_ERROR");
160
+ throw searchEndpointError(endpoint, message);
159
161
  }
160
162
  try {
161
163
  return mapAnthropicResponse(await response.json());
162
164
  } catch (error) {
163
165
  if (signal?.aborted === true || isAbortError(error)) throw searchAborted(signal, error);
164
- if (error instanceof WebError) throw error;
165
- throw new WebError(`DeepSeek returned an unprocessable response body: ${String(error)}`, "WEB_PROVIDER_ERROR", { cause: error });
166
+ throw searchEndpointError(endpoint, error instanceof WebError ? error.message : `DeepSeek returned an unprocessable response body: ${String(error)}`, error);
166
167
  }
167
168
  }
168
169
  /**
@@ -185,6 +186,10 @@ var DeepSeekSearchProvider = class {
185
186
  throw new WebError(`DeepSeek search has no API key for "${options.apiKeyEnv ?? "DEEPSEEK_API_KEY"}"; store it through the credentials service (the web Models page writes it), export it in the launching environment, or set a literal "apiKey" in the web-search-deepseek config`, "WEB_PROVIDER_CREDENTIAL_MISSING");
186
187
  }
187
188
  };
189
+ /** Add endpoint recovery instructions to failures that occur after request dispatch begins. */
190
+ function searchEndpointError(endpoint, message, cause) {
191
+ return new WebError(`${message}\n\nThe web search request used endpoint ${JSON.stringify(endpoint)}. Search endpoint configuration is separate from chat. If that endpoint is not intended, guide the user to Settings > Plugins > Plugin configuration > Web search, where they can change and save Endpoint. If that settings page is unavailable, the user can set DEEPSEEK_SEARCH_BASE_URL or configure web-search-deepseek.baseURL to a trusted Anthropic-compatible Messages API base. Only the user should choose or change the endpoint.`, "WEB_PROVIDER_ERROR", cause === void 0 ? void 0 : { cause });
192
+ }
188
193
  /**
189
194
  * Race a same-process asynchronous preflight against caller cancellation. The
190
195
  * attached settlement handlers keep observing an uncooperative operation after
@@ -253,7 +258,7 @@ const Config = z.object({
253
258
  */
254
259
  const SEARCH_BASE_URL_ENV = "DEEPSEEK_SEARCH_BASE_URL";
255
260
  /** Settings namespace carrying this provider's endpoint, model, and key reference. */
256
- const WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE = settingsNamespace("web-search-deepseek");
261
+ const WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE = "web-search-deepseek";
257
262
  /**
258
263
  * Project one resolved section into the options the provider serves its next
259
264
  * search with. Environment fallbacks stay here rather than in the provider:
@@ -287,11 +292,13 @@ function resolveOptions(ctx, config) {
287
292
  /** Register the DeepSeek search provider with `ctx.web`. */
288
293
  function apply(ctx, config) {
289
294
  let current = () => config;
290
- installSettingsSection(ctx, WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE, Config, config, {
291
- setSource: (source) => {
292
- current = source;
293
- },
294
- onChange: () => {}
295
+ ctx.inject(["settings"], (settingsCtx) => {
296
+ settingsCtx.settings.installSection(ctx, WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE, Config, config, {
297
+ setSource: (source) => {
298
+ current = source;
299
+ },
300
+ onChange: () => {}
301
+ });
295
302
  });
296
303
  ctx.web.registerSearchProvider(new DeepSeekSearchProvider(() => resolveOptions(ctx, current())));
297
304
  }
@@ -31,7 +31,7 @@ export interface Config {
31
31
  }
32
32
  export declare const Config: z<Config>;
33
33
  /** Settings namespace carrying this provider's endpoint, model, and key reference. */
34
- export declare const WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
34
+ export declare const WEB_SEARCH_DEEPSEEK_SETTINGS_NAMESPACE = "web-search-deepseek";
35
35
  /** Register the DeepSeek search provider with `ctx.web`. */
36
36
  export declare function apply(ctx: Context, config: Config): void;
37
37
  //# sourceMappingURL=index.d.ts.map
@@ -110,7 +110,10 @@ export declare function citationSnippets(blocks: readonly ContentBlock[]): Map<s
110
110
  * @throws {@link WebError} when native search produced no result block.
111
111
  */
112
112
  export declare function mapAnthropicResponse(response: AnthropicResponse): WebSearchResult;
113
- /** The DeepSeek-backed search provider; HTTP redirects fail as `WEB_PROVIDER_ERROR`. */
113
+ /**
114
+ * The DeepSeek-backed search provider. HTTP redirects fail as `WEB_PROVIDER_ERROR`;
115
+ * failures after dispatch name the endpoint and tell the model how the user can configure it.
116
+ */
114
117
  export declare class DeepSeekSearchProvider implements WebSearchProvider {
115
118
  private readonly resolveOptions;
116
119
  readonly id = "deepseek-official";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-web-search-deepseek",
3
3
  "description": "DeepSeek-backed search provider (native web_search via the Anthropic-compatible API) for the DeepSeek Harness web capability seam (ctx.web)",
4
- "version": "0.1.1-rc.2",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,27 +32,27 @@
32
32
  ],
33
33
  "license": "MIT",
34
34
  "peerDependencies": {
35
- "@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
36
- "@deepseek-ai/dsh-launch-environment": "^0.1.1-rc.2",
37
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
38
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
39
- "@deepseek-ai/dsh-web": "^0.1.1-rc.2",
40
- "@deepseek-ai/cordis": "^4.0.1",
41
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
42
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2"
35
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
36
+ "@deepseek-ai/dsh-credentials": "^0.1.2-alpha.2",
37
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
38
+ "@deepseek-ai/dsh-launch-environment": "^0.1.2-alpha.2",
39
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
40
+ "@deepseek-ai/dsh-web": "^0.1.2-alpha.2",
41
+ "@deepseek-ai/cordis": "^4.0.2",
42
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2"
43
43
  },
44
44
  "dependencies": {
45
- "@deepseek-ai/schemastery": "^3.18.1"
45
+ "@deepseek-ai/schemastery": "^3.18.2"
46
46
  },
47
47
  "devDependencies": {
48
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
49
- "@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
50
- "@deepseek-ai/dsh-credentials-local": "^0.1.1-rc.2",
51
- "@deepseek-ai/dsh-launch-environment": "^0.1.1-rc.2",
52
- "@deepseek-ai/dsh-web": "^0.1.1-rc.2",
53
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
54
- "@deepseek-ai/cordis": "^4.0.1",
55
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
56
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2"
48
+ "@deepseek-ai/dsh-launch-environment": "^0.1.2-alpha.2",
49
+ "@deepseek-ai/dsh-credentials-local": "^0.1.2-alpha.2",
50
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
51
+ "@deepseek-ai/dsh-web": "^0.1.2-alpha.2",
52
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
53
+ "@deepseek-ai/cordis": "^4.0.2",
54
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
55
+ "@deepseek-ai/dsh-credentials": "^0.1.2-alpha.2",
56
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2"
57
57
  }
58
58
  }