dsh-web-search-plugin 0.3.1 → 0.4.0
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/CHANGELOG.md +10 -1
- package/README.md +4 -4
- package/lib/client.js +15 -15
- package/lib/index.js +9 -12
- package/lib/shared.js +1 -1
- package/package.json +7 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
本项目的重要变更都记录在此。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.4.0] - 2026-09-02
|
|
6
|
+
|
|
7
|
+
### 变更
|
|
8
|
+
|
|
9
|
+
- **适配 DeepSeek Harness 最新 main(`0.1.2-alpha.4`)**:`@deepseek-ai/dsh-settings` 已移除顶层 `installSettingsSection` / `settingsNamespace`,Host 侧改为在 `ctx.inject(['settings'])` 后调用 `settingsCtx.settings.installSection(ctx, ...)`;settings namespace 直接使用普通字符串。
|
|
10
|
+
- **浏览器端移除对 `@deepseek-ai/dsh-client-runtime` / 旧 `connection` 的依赖**:该包已不在最新 Harness workspace / 客户端模块表中。`createSnapshotStore` 改从平台常驻模块 `@deepseek-ai/dsh-client-store` 导入;`dsh.client.inject` 与客户端 `inject` 对齐为 `slots` / `locale` / `remote` / `settingsScope`。
|
|
11
|
+
- **凭据远端接口迁移到 `ctx.remote`**:`credentials.describe(refs[])` / `set(ref, value)` 使用最新 Remote 参数与响应形状(`{ ok, value }`);凭据变更事件从 `credentials/updated` 改为 `credentials/reference-updated`;不再经旧 `connection.api` 调用。
|
|
12
|
+
- peerDependencies 中 dsh 包版本从 `0.1.0-rc.7` 提升到 `0.1.2-alpha.4`;`@deepseek-ai/cordis` / `@deepseek-ai/schemastery` 分别对齐 `^4.0.2` / `^3.18.2`;版本号升至 `0.4.0`,`User-Agent` 同步。
|
|
13
|
+
|
|
5
14
|
## [0.3.1] - 2026-08-30
|
|
6
15
|
|
|
7
16
|
### 修复
|
|
@@ -99,7 +108,7 @@
|
|
|
99
108
|
|
|
100
109
|
### 修复
|
|
101
110
|
|
|
102
|
-
- **客户端 bundle 缺少 `exports.inject`**(`lib/client.js`)。浏览器插件原先只导出 `apply`,cordis 的 `fiber.inject` 为空,访问 `ctx.locale` 等服务会抛 `cannot get property "locale" without inject`。现在导出 `inject = ["slots", "locale", "
|
|
111
|
+
- **客户端 bundle 缺少 `exports.inject`**(`lib/client.js`)。浏览器插件原先只导出 `apply`,cordis 的 `fiber.inject` 为空,访问 `ctx.locale` 等服务会抛 `cannot get property "locale" without inject`。现在导出 `inject = ["slots", "locale", "remote", "settingsScope"]`。
|
|
103
112
|
- **插件卡片的 slot 注册**(`lib/client.js`)。卡片按 rc.6 的 `id`/`order` 形状注册进 `settings.plugin.item`;该 slot 从 rc.6+ 起是 keyed 的,必须带 `key: "dsh-web-search-plugin"`。
|
|
104
113
|
- **`CardForm.field("apiKey")` 崩溃**(`lib/client.js`)。只写凭据字段没有 section spec,对 `undefined` 调用 `spec.format(...)` 会在卡片投影时抛 `Cannot read properties of undefined (reading 'format')`。已加上 secret 字段分支(对齐官方 `CardForm`)。
|
|
105
114
|
- **`dsh.client.inject` 补上 `@deepseek-ai/dsh-client-ui-slots`**(`package.json`),与社区插件的加载集合一致。
|
package/README.md
CHANGED
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
|
|
18
18
|
## 特性
|
|
19
19
|
|
|
20
|
-
- 与官方 `@deepseek-ai/dsh-web-search-deepseek` 相同的提供方约定:`inject: ['web']` + `
|
|
20
|
+
- 与官方 `@deepseek-ai/dsh-web-search-deepseek` 相同的提供方约定:`inject: ['web']` + `ctx.settings.installSection` + `ctx.web.registerSearchProvider`。
|
|
21
21
|
- 顶层 **设置 → 网页搜索** 分区:两列布局、未保存草稿、保存 toast;结果数量为 1–20 下拉。
|
|
22
22
|
- **默认引擎为 DeepSeek(官方)**:新装 / 未显式改动时,搜索直接走 `deepseek-official`,不再依赖 keyless 的 Tavily。
|
|
23
23
|
- 纯 REST 后端由**静态元数据表 + 通用后端**驱动,新增 provider 即"表里加一行 + 官方跳转链接",无定制执行代码。
|
|
24
24
|
- Tavily keyless 无需密钥即可用;Brave 需要订阅 token(若本机已有 `BRAVE_API_KEY` 凭据,可直接复用)。
|
|
25
25
|
- Tavily keyed / Brave 在设置卡展示额度进度条(DeepSeek 官方与 Tavily keyless / 其余 REST 后端不展示)。
|
|
26
26
|
- 各引擎结果都规范化为接缝的 `WebSearchResult`(可选 `content` + `sources[]`),按 URL 去重。
|
|
27
|
-
- 设置段 `dsh-web-search-plugin` 通过
|
|
27
|
+
- 设置段 `dsh-web-search-plugin` 通过 dsh 的 `settings.installSection` 注册、由 `settings.describe()` 动态暴露,不需要宿主白名单补丁,也不需要自建回环 settings 桥。
|
|
28
28
|
- 错误映射为 `WEB_PROVIDER_ERROR` / `WEB_ABORTED` / `WEB_PROVIDER_CREDENTIAL_MISSING`。
|
|
29
29
|
|
|
30
30
|
## 运行要求
|
|
31
31
|
|
|
32
|
-
- DeepSeek Harness `0.1.
|
|
32
|
+
- DeepSeek Harness `0.1.2-alpha.4`(最新 main)或更新
|
|
33
33
|
- pnpm,用于通过 `dsh plugin` 把插件装进 profile
|
|
34
34
|
|
|
35
35
|
## 安装
|
|
@@ -189,7 +189,7 @@ dsh plugin --profile web remove @dsh-ltctfer/dsh-web-search-brave
|
|
|
189
189
|
npm run check
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
客户端 bundle 必须保持 `window.__ModuleLoader__.load({ id, factory })` 线格式 — 由 `dsh-client-modules` 加载,不是打包器。必须同时导出 `apply` 和 `inject`(`slots`、`locale`、`
|
|
192
|
+
客户端 bundle 必须保持 `window.__ModuleLoader__.load({ id, factory })` 线格式 — 由 `dsh-client-modules` 加载,不是打包器。必须同时导出 `apply` 和 `inject`(`slots`、`locale`、`remote`、`settingsScope`),并把分区注册进 `settings.section`(`id: "web-search"`)。
|
|
193
193
|
|
|
194
194
|
## 发布
|
|
195
195
|
|
package/lib/client.js
CHANGED
|
@@ -21,7 +21,7 @@ window.__ModuleLoader__.load({
|
|
|
21
21
|
var exports = module.exports;
|
|
22
22
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
23
23
|
let react = require("react");
|
|
24
|
-
let
|
|
24
|
+
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
25
25
|
|
|
26
26
|
/** Settings namespace of this plugin. */
|
|
27
27
|
const NS = "dsh-web-search-plugin";
|
|
@@ -334,9 +334,9 @@ window.__ModuleLoader__.load({
|
|
|
334
334
|
* spec and are written through the credentials domain.
|
|
335
335
|
*/
|
|
336
336
|
var SearchCardForm = class {
|
|
337
|
-
constructor(scope,
|
|
337
|
+
constructor(scope, remote) {
|
|
338
338
|
this.scope = scope;
|
|
339
|
-
this.
|
|
339
|
+
this.remote = remote;
|
|
340
340
|
this.specs = new Map([
|
|
341
341
|
choiceField("provider"),
|
|
342
342
|
choiceField("mode"),
|
|
@@ -391,7 +391,7 @@ window.__ModuleLoader__.load({
|
|
|
391
391
|
this.readCredential();
|
|
392
392
|
}
|
|
393
393
|
bind(project) {
|
|
394
|
-
const store = (0,
|
|
394
|
+
const store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(project());
|
|
395
395
|
this.listeners.add(() => {
|
|
396
396
|
store.set(project());
|
|
397
397
|
});
|
|
@@ -591,12 +591,12 @@ window.__ModuleLoader__.load({
|
|
|
591
591
|
}
|
|
592
592
|
let response;
|
|
593
593
|
try {
|
|
594
|
-
response = await this.
|
|
594
|
+
response = await this.remote.credentials.describe([ref]);
|
|
595
595
|
} catch (_credentialReadFailure) {
|
|
596
596
|
return;
|
|
597
597
|
}
|
|
598
|
-
if (!response.
|
|
599
|
-
const view = response.
|
|
598
|
+
if (!response.ok || ref !== this.refOf()) return;
|
|
599
|
+
const view = response.value[ref];
|
|
600
600
|
const next = {
|
|
601
601
|
ref,
|
|
602
602
|
configured: view?.configured ?? false,
|
|
@@ -619,7 +619,8 @@ window.__ModuleLoader__.load({
|
|
|
619
619
|
ref = rest !== void 0 ? this.restKeyRef(rest) : this.tavilyRef();
|
|
620
620
|
}
|
|
621
621
|
try {
|
|
622
|
-
await this.
|
|
622
|
+
const response = await this.remote.credentials.set(ref, value);
|
|
623
|
+
if (!response.ok) return false;
|
|
623
624
|
} catch (_credentialWriteFailure) {}
|
|
624
625
|
await this.readCredential();
|
|
625
626
|
return this.credential.ref === ref ? this.credential.configured : true;
|
|
@@ -628,10 +629,10 @@ window.__ModuleLoader__.load({
|
|
|
628
629
|
|
|
629
630
|
/** Bridges the plugin scope and the credentials domain onto the card. */
|
|
630
631
|
var SearchCardController = class {
|
|
631
|
-
constructor(scope,
|
|
632
|
+
constructor(scope, remote) {
|
|
632
633
|
this.scope = scope;
|
|
633
|
-
this.
|
|
634
|
-
this.form = new SearchCardForm(scope,
|
|
634
|
+
this.remote = remote;
|
|
635
|
+
this.form = new SearchCardForm(scope, remote);
|
|
635
636
|
this.store = this.form.bind(() => this.projection());
|
|
636
637
|
scope.subscribe(() => {
|
|
637
638
|
this.form.readCredential();
|
|
@@ -1150,11 +1151,10 @@ window.__ModuleLoader__.load({
|
|
|
1150
1151
|
|
|
1151
1152
|
/** Mount the top-level "Web search" settings section. */
|
|
1152
1153
|
function apply(ctx) {
|
|
1153
|
-
const { api } = ctx.get("connection");
|
|
1154
1154
|
const t = ctx.locale.bind(NS);
|
|
1155
1155
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "dsh-web-search-plugin: card dictionaries");
|
|
1156
|
-
const controller = new SearchCardController(ctx.settingsScope.bind({ namespace: NS }),
|
|
1157
|
-
ctx.effect(() => ctx.remote.$on("credentials/updated", (ref) => {
|
|
1156
|
+
const controller = new SearchCardController(ctx.settingsScope.bind({ namespace: NS }), ctx.remote);
|
|
1157
|
+
ctx.effect(() => ctx.remote.$on("credentials/reference-updated", (ref) => {
|
|
1158
1158
|
controller.form.refreshCredential(ref);
|
|
1159
1159
|
}), "dsh-web-search-plugin: credential invalidations");
|
|
1160
1160
|
ctx.effect(() => usageStore.start(), "dsh-web-search-plugin: usage poll");
|
|
@@ -1168,7 +1168,7 @@ window.__ModuleLoader__.load({
|
|
|
1168
1168
|
}, makeSection(ctx, controller)));
|
|
1169
1169
|
}
|
|
1170
1170
|
|
|
1171
|
-
const inject = ["slots", "locale", "
|
|
1171
|
+
const inject = ["slots", "locale", "remote", "settingsScope"];
|
|
1172
1172
|
|
|
1173
1173
|
exports.apply = apply;
|
|
1174
1174
|
exports.inject = inject;
|
package/lib/index.js
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
* @module dsh-web-search-plugin
|
|
18
18
|
*/
|
|
19
19
|
import z from "@deepseek-ai/schemastery";
|
|
20
|
-
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
21
20
|
import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
22
21
|
import { MAX_RESULTS_CAP } from "./shared.js";
|
|
23
22
|
import { TAVILY_DEFAULT_API_KEY_ENV, TAVILY_DEFAULT_BASE_URL, TavilySearchProvider, resolveTavilyOptions } from "./tavily.js";
|
|
@@ -34,6 +33,8 @@ const SEARCH_PROVIDER_ID = "dsh-web-search";
|
|
|
34
33
|
const name = "dsh-web-search-plugin";
|
|
35
34
|
/** The web seam this provider registers into. */
|
|
36
35
|
const inject = ["web"];
|
|
36
|
+
/** Settings namespace carrying this plugin's backend switch and options. */
|
|
37
|
+
const WEB_SEARCH_SETTINGS_NAMESPACE = "dsh-web-search-plugin";
|
|
37
38
|
|
|
38
39
|
/** Plugin config (all optional — `apply` fills defaults). */
|
|
39
40
|
const Config = z.object({
|
|
@@ -117,11 +118,6 @@ const Config = z.object({
|
|
|
117
118
|
maxUses: z.number().step(1).min(1).default(5)
|
|
118
119
|
});
|
|
119
120
|
|
|
120
|
-
/** Settings namespace carrying this plugin's backend switch and options. */
|
|
121
|
-
const WEB_SEARCH_SETTINGS_NAMESPACE = settingsNamespace("dsh-web-search-plugin");
|
|
122
|
-
/** @deprecated Use {@link WEB_SEARCH_SETTINGS_NAMESPACE}. */
|
|
123
|
-
const WEB_SEARCH_TAVILY_SETTINGS_NAMESPACE = WEB_SEARCH_SETTINGS_NAMESPACE;
|
|
124
|
-
|
|
125
121
|
/**
|
|
126
122
|
* One seam-facing provider whose `id` stays `dsh-web-search`. The active
|
|
127
123
|
* backend is read from the live settings section on every `available` /
|
|
@@ -254,11 +250,13 @@ function sendJson(res, statusCode, data) {
|
|
|
254
250
|
/** Register the dispatched search provider with `ctx.web`. */
|
|
255
251
|
function apply(ctx, config) {
|
|
256
252
|
let current = () => config;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
253
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
254
|
+
settingsCtx.settings.installSection(ctx, WEB_SEARCH_SETTINGS_NAMESPACE, Config, config, {
|
|
255
|
+
setSource: (source) => {
|
|
256
|
+
current = source;
|
|
257
|
+
},
|
|
258
|
+
onChange: () => {}
|
|
259
|
+
});
|
|
262
260
|
});
|
|
263
261
|
const live = () => resolveOptions(ctx, current());
|
|
264
262
|
const usage = new UsageTracker({
|
|
@@ -335,7 +333,6 @@ export {
|
|
|
335
333
|
TavilySearchProvider,
|
|
336
334
|
UsageTracker,
|
|
337
335
|
WEB_SEARCH_SETTINGS_NAMESPACE,
|
|
338
|
-
WEB_SEARCH_TAVILY_SETTINGS_NAMESPACE,
|
|
339
336
|
apply,
|
|
340
337
|
findProvider,
|
|
341
338
|
inject,
|
package/lib/shared.js
CHANGED
|
@@ -7,7 +7,7 @@ import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
|
7
7
|
import { WebError } from "@deepseek-ai/dsh-web";
|
|
8
8
|
|
|
9
9
|
/** Attribution header sent on every request. */
|
|
10
|
-
export const USER_AGENT = "dsh-web-search-plugin/0.
|
|
10
|
+
export const USER_AGENT = "dsh-web-search-plugin/0.4.0";
|
|
11
11
|
/** Shared cap: Tavily `max_results` and Brave `count` both accept 1..20. */
|
|
12
12
|
export const MAX_RESULTS_CAP = 20;
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-web-search-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Unified web search for the DeepSeek Harness seam (ctx.web): DeepSeek (official), Tavily, Brave, Serper, SerpApi, Exa, SearXNG, Scavio, and Firecrawl backends",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh-plugin",
|
|
@@ -43,9 +43,7 @@
|
|
|
43
43
|
"client": {
|
|
44
44
|
"platform": "web",
|
|
45
45
|
"inject": [
|
|
46
|
-
"@deepseek-ai/dsh-client-connection",
|
|
47
46
|
"@deepseek-ai/dsh-client-locale",
|
|
48
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
49
47
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
50
48
|
"@deepseek-ai/dsh-client-ui-slots",
|
|
51
49
|
"@deepseek-ai/dsh-api-remotes"
|
|
@@ -59,12 +57,12 @@
|
|
|
59
57
|
"undici": "^6.21.0"
|
|
60
58
|
},
|
|
61
59
|
"peerDependencies": {
|
|
62
|
-
"@deepseek-ai/dsh-web": "^0.1.
|
|
63
|
-
"@deepseek-ai/dsh-credentials": "^0.1.
|
|
64
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
65
|
-
"@deepseek-ai/dsh-launch-environment": "^0.1.
|
|
66
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
67
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
60
|
+
"@deepseek-ai/dsh-web": "^0.1.2-alpha.4",
|
|
61
|
+
"@deepseek-ai/dsh-credentials": "^0.1.2-alpha.4",
|
|
62
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-alpha.4",
|
|
63
|
+
"@deepseek-ai/dsh-launch-environment": "^0.1.2-alpha.4",
|
|
64
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
65
|
+
"@deepseek-ai/cordis": "^4.0.2"
|
|
68
66
|
},
|
|
69
67
|
"license": "MIT",
|
|
70
68
|
"repository": {
|