dsh-search-enhance 0.1.13 → 0.2.1
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.md +15 -16
- package/README.zh.md +15 -16
- package/client/client.js +180 -31
- package/client/types/client/locales.d.ts +9 -2
- package/client/types/web-config/contracts.d.ts +19 -3
- package/lib/config.d.ts +10 -33
- package/lib/config.js +16 -25
- package/lib/contracts/sources.d.ts +1 -1
- package/lib/contracts/sources.js +1 -0
- package/lib/diagnostics/orchestrator.js +4 -0
- package/lib/diagnostics/probes.d.ts +2 -2
- package/lib/diagnostics/status.js +8 -2
- package/lib/diagnostics/types.d.ts +3 -1
- package/lib/diagnostics/types.js +2 -0
- package/lib/documentation/service.d.ts +2 -3
- package/lib/documentation/service.js +17 -8
- package/lib/index.js +22 -69
- package/lib/orchestration/orchestrator.d.ts +1 -0
- package/lib/orchestration/orchestrator.js +16 -1
- package/lib/orchestration/types.d.ts +2 -1
- package/lib/orchestration/types.js +2 -0
- package/lib/presentation/index.d.ts +0 -1
- package/lib/presentation/index.js +0 -1
- package/lib/presentation/render.d.ts +6 -8
- package/lib/presentation/render.js +65 -145
- package/lib/presentation/web-card.js +16 -6
- package/lib/prompt/tool-discovery.js +7 -12
- package/lib/providers/context7.js +11 -1
- package/lib/providers/index.d.ts +2 -0
- package/lib/providers/index.js +2 -0
- package/lib/providers/parallel-extract.d.ts +20 -0
- package/lib/providers/parallel-extract.js +83 -0
- package/lib/providers/parallel.d.ts +20 -0
- package/lib/providers/parallel.js +94 -0
- package/lib/providers/types.d.ts +1 -1
- package/lib/tool-discovery/capabilities.d.ts +8 -19
- package/lib/tool-discovery/capabilities.js +13 -96
- package/lib/tool-discovery/fold.d.ts +8 -39
- package/lib/tool-discovery/fold.js +45 -105
- package/lib/tool-discovery/manager.d.ts +10 -17
- package/lib/tool-discovery/manager.js +41 -77
- package/lib/tools/docs-search.d.ts +1 -3
- package/lib/tools/docs-search.js +5 -4
- package/lib/tools/index.d.ts +0 -5
- package/lib/tools/index.js +0 -5
- package/lib/tools/schemas.d.ts +9 -751
- package/lib/tools/schemas.js +8 -464
- package/lib/tools/search-tools.d.ts +12 -101
- package/lib/tools/search-tools.js +34 -191
- package/lib/tools/web-extract.js +1 -1
- package/lib/tools/web-search.d.ts +0 -2
- package/lib/tools/web-search.js +7 -6
- package/lib/web-config/contracts.d.ts +19 -3
- package/lib/web-config/contracts.js +10 -2
- package/lib/web-config/host.js +14 -1
- package/lib/web-extract/orchestrator.js +1 -0
- package/lib/web-extract/types.d.ts +3 -2
- package/lib/web-extract/types.js +2 -0
- package/package.json +81 -67
- package/lib/presentation/diagnostics-card.d.ts +0 -8
- package/lib/presentation/diagnostics-card.js +0 -91
- package/lib/presentation/research-plan-card.d.ts +0 -10
- package/lib/presentation/research-plan-card.js +0 -90
- package/lib/research-plan/index.d.ts +0 -28
- package/lib/research-plan/index.js +0 -692
- package/lib/tools/context7.d.ts +0 -1295
- package/lib/tools/context7.js +0 -969
- package/lib/tools/research-plan.d.ts +0 -13
- package/lib/tools/research-plan.js +0 -44
- package/lib/tools/search-call.d.ts +0 -75
- package/lib/tools/search-call.js +0 -334
- package/lib/tools/search-diagnostics.d.ts +0 -22
- package/lib/tools/search-diagnostics.js +0 -147
package/README.md
CHANGED
|
@@ -2,31 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
English | [简体中文](README.zh.md)
|
|
4
4
|
|
|
5
|
-
`dsh-search-enhance` is a search extension for DeepSeek Harness. It uses a Grok-compatible Search API for primary web answers and can optionally use Context7, Exa, Tavily, and
|
|
5
|
+
`dsh-search-enhance` is a search extension for DeepSeek Harness. It uses a Grok-compatible Search API for primary web answers and can optionally use Context7, Exa, Tavily, Firecrawl, and Parallel for documentation lookup, supplementary discovery, page extraction, and site mapping.
|
|
6
6
|
|
|
7
|
-
The plugin
|
|
7
|
+
The plugin presents search results, sources, and page content separately. Searches return an answer or documentation snippets with source links; you can ask for more sources when needed. To check important details, ask it to read the original page. Search snippets remain distinct from fetched page content.
|
|
8
8
|
|
|
9
|
-
> Bring your own endpoints and credentials. The plugin ships no API keys. A Grok-compatible endpoint is required for `web_search`; Context7, Exa, Tavily, and
|
|
10
|
-
|
|
11
|
-

|
|
9
|
+
> Bring your own endpoints and credentials. The plugin ships no API keys. A Grok-compatible endpoint is required for `web_search`; Context7, Exa, Tavily, Firecrawl, and Parallel are optional.
|
|
12
10
|
|
|
13
11
|
## Key characteristics
|
|
14
12
|
|
|
15
|
-
- `web_search` uses the Grok-compatible endpoint for the main answer and runs all user-selected supplemental Providers (Exa, Tavily, Firecrawl) in parallel, with an independent per-Provider source limit.
|
|
13
|
+
- `web_search` uses the Grok-compatible endpoint for the main answer and runs all user-selected supplemental Providers (Exa, Tavily, Firecrawl, Parallel) in parallel, with an independent per-Provider source limit.
|
|
16
14
|
- Sources are normalized, de-duplicated, and reordered using source category, requested version, and publication-time signals before they are shown.
|
|
17
15
|
- `source_ref` keeps the complete source record in private durable storage, allowing the Agent to paginate beyond the links included in the initial result.
|
|
18
16
|
- `docs_search` uses Context7 only with an explicit `library_name` or `library_id`; requests without a library identity use Exa discovery.
|
|
19
|
-
- `web_extract` requires one explicit `provider` from the user-enabled set: `tavily_extract`, `firecrawl_scrape`, `smart_direct`, or `direct`. It reports the route, evidence level, and available page metadata; failures never switch Providers.
|
|
20
|
-
-
|
|
17
|
+
- `web_extract` requires one explicit `provider` from the user-enabled set: `tavily_extract`, `firecrawl_scrape`, `parallel_extract`, `smart_direct`, or `direct`. It reports the route, evidence level, and available page metadata; failures never switch Providers.
|
|
18
|
+
- Ask for more sources or related pages on a specific website when needed; no manual tool loading is required.
|
|
21
19
|
- Supplemental search defaults to no Providers selected. Unselected Providers are never requested; missing credentials and failures of selected Providers remain visible as warnings.
|
|
22
20
|
|
|
23
|
-
For
|
|
21
|
+
For implementation details, see [Search workflow architecture](https://github.com/umineko987/dsh-search-enhance/blob/main/guides/search-workflow.md).
|
|
24
22
|
|
|
25
23
|
## Quick start
|
|
26
24
|
|
|
27
25
|
### 1. Install
|
|
28
26
|
|
|
29
|
-
Supports DSH `0.
|
|
27
|
+
Supports DSH `0.2.0-rc.2`. DSH dependencies are pinned to this exact release; upgrade the DSH CLI first if you are running an older version.
|
|
30
28
|
|
|
31
29
|
Install the [published npm bundle](https://www.npmjs.com/package/dsh-search-enhance) into the DSH `web` profile:
|
|
32
30
|
|
|
@@ -73,7 +71,7 @@ Use normal language; the plugin gives the Agent routing guidance.
|
|
|
73
71
|
- “Look up the current FastAPI JWT authentication API and show a minimal example from the official documentation.”
|
|
74
72
|
- “Read and summarize `https://example.com/article`, separating what the page states from your inference.”
|
|
75
73
|
|
|
76
|
-
Ask explicitly when you need
|
|
74
|
+
Ask explicitly when you need more sources or pages from a specific website. Check the plugin settings for service configuration status.
|
|
77
75
|
|
|
78
76
|
## Providers
|
|
79
77
|
|
|
@@ -86,20 +84,21 @@ Configure only the routes you need.
|
|
|
86
84
|
| Exa | Broad documentation and supplementary discovery | `EXA_API_KEY` | No |
|
|
87
85
|
| Tavily | Supplementary search, page extraction, and site mapping | `TAVILY_API_KEY` | No |
|
|
88
86
|
| Firecrawl | Supplementary search and page extraction | `FIRECRAWL_API_KEY` | No |
|
|
87
|
+
| Parallel | Supplementary search and Markdown page extraction | `PARALLEL_API_KEY` | No |
|
|
89
88
|
|
|
90
89
|
In the plugin settings, select any combination of **supplemental search Providers**. Each selected Provider runs alongside the main search, using `supplementalSearch.maxSourcesPerProvider` (default `5`, maximum `100`). This selection applies to all search profiles.
|
|
91
90
|
|
|
92
|
-
Separately, select the **extraction Providers** available to the Agent. Each `web_extract` call must choose exactly one enabled Provider, for example `{ "url": "https://example.com/", "provider": "direct", "format": "markdown" }`. Disabled, unconfigured, unsupported, or failed Providers do not trigger automatic fallback.
|
|
91
|
+
Separately, select the **extraction Providers** available to the Agent. Each `web_extract` call must choose exactly one enabled Provider, for example `{ "url": "https://example.com/", "provider": "direct", "format": "markdown" }`. Disabled, unconfigured, unsupported, or failed Providers do not trigger automatic fallback. Parallel extraction supports Markdown only and is disabled by default; enable it explicitly. Other extraction Providers are enabled by default; disable any you do not want the Agent to use.
|
|
93
92
|
|
|
94
93
|
For `docs_search`, Context7 requires an explicit `library_name` or `library_id`. Without one, `provider: "auto"` uses Exa instead of guessing a package name from the full question.
|
|
95
94
|
|
|
96
|
-
##
|
|
95
|
+
## On-demand features
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
To see more sources from a search, ask: “Show me the other sources from this search.”
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
To find relevant pages on a website, ask: “Find pages about authentication on this website.” This feature requires Tavily to be configured.
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
The assistant uses these features when needed. You do not have to call tools manually or switch modes. To verify an important claim, you can then ask it to read the original pages.
|
|
103
102
|
|
|
104
103
|
## Update and uninstall
|
|
105
104
|
|
package/README.zh.md
CHANGED
|
@@ -2,31 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 简体中文
|
|
4
4
|
|
|
5
|
-
`dsh-search-enhance` 是 DeepSeek Harness 的搜索增强插件。它使用 Grok-compatible Search API 生成普通网页搜索的主要回答,并可选用 Context7、Exa、Tavily 和
|
|
5
|
+
`dsh-search-enhance` 是 DeepSeek Harness 的搜索增强插件。它使用 Grok-compatible Search API 生成普通网页搜索的主要回答,并可选用 Context7、Exa、Tavily、Firecrawl 和 Parallel 完成文档检索、补充来源、网页正文提取和站点页面发现。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
插件将搜索结果、参考来源和网页正文分开呈现。搜索时先给出回答或文档片段及来源链接,需要更多来源时可以继续追问;核对重要内容时,再要求读取原网页。搜索摘要与实际读取的正文会明确区分。
|
|
8
8
|
|
|
9
|
-
> 你需要自行提供所选服务的端点和凭据,插件不内置任何 API Key。`web_search` 需要 Grok-compatible 端点;Context7、Exa、Tavily 和
|
|
10
|
-
|
|
11
|
-

|
|
9
|
+
> 你需要自行提供所选服务的端点和凭据,插件不内置任何 API Key。`web_search` 需要 Grok-compatible 端点;Context7、Exa、Tavily、Firecrawl 和 Parallel 均为可选 Provider。
|
|
12
10
|
|
|
13
11
|
## 主要特点
|
|
14
12
|
|
|
15
|
-
- `web_search` 使用 Grok-compatible 端点生成主要回答,并行调用用户勾选的全部补充搜索 Provider(Exa、Tavily、Firecrawl),每家使用独立的来源数量上限。
|
|
13
|
+
- `web_search` 使用 Grok-compatible 端点生成主要回答,并行调用用户勾选的全部补充搜索 Provider(Exa、Tavily、Firecrawl、Parallel),每家使用独立的来源数量上限。
|
|
16
14
|
- 来源在展示前会经过 URL 标准化、去重,并根据来源类别、目标版本和发布时间信号重新排序。
|
|
17
15
|
- `source_ref` 将完整来源记录保存在插件私有持久存储中,Agent 可以继续分页读取首次结果未展示的来源。
|
|
18
16
|
- `docs_search` 只在提供明确 `library_name` 或 `library_id` 时使用 Context7;没有库身份的请求使用 Exa 发现。
|
|
19
|
-
- `web_extract` 每次必须通过 `provider` 指定一家用户已启用的服务:`tavily_extract`、`firecrawl_scrape`、`smart_direct` 或 `direct`。结果报告提取路径、证据等级和页面元数据,失败不自动换服务。
|
|
20
|
-
-
|
|
17
|
+
- `web_extract` 每次必须通过 `provider` 指定一家用户已启用的服务:`tavily_extract`、`firecrawl_scrape`、`parallel_extract`、`smart_direct` 或 `direct`。结果报告提取路径、证据等级和页面元数据,失败不自动换服务。
|
|
18
|
+
- 需要时可继续查看更多来源,或查找某个网站下的相关页面,无需手动加载工具。
|
|
21
19
|
- 补充搜索默认不选择任何 Provider。未选中的服务不会被请求;选中服务缺少凭据或执行失败会在结果中显示警告。
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
实现细节见[搜索链路架构](https://github.com/umineko987/dsh-search-enhance/blob/main/guides/search-workflow.zh.md)。
|
|
24
22
|
|
|
25
23
|
## 快速开始
|
|
26
24
|
|
|
27
25
|
### 1. 安装
|
|
28
26
|
|
|
29
|
-
支持 DSH `0.
|
|
27
|
+
支持 DSH `0.2.0-rc.2`,DSH 依赖精确锁定到该版本;使用旧版本时,请先升级 DSH CLI。
|
|
30
28
|
|
|
31
29
|
将 [npm 上发布的 bundle](https://www.npmjs.com/package/dsh-search-enhance) 安装到 DSH `web` profile:
|
|
32
30
|
|
|
@@ -73,7 +71,7 @@ dsh web
|
|
|
73
71
|
- “查找 FastAPI 当前 JWT 认证 API,并根据官方文档给出最小示例。”
|
|
74
72
|
- “读取并总结 `https://example.com/article`,区分页面原文与推断。”
|
|
75
73
|
|
|
76
|
-
|
|
74
|
+
需要更多参考来源或网站内的相关页面时,可以继续追问;服务配置状态可在插件设置中查看。
|
|
77
75
|
|
|
78
76
|
## Provider
|
|
79
77
|
|
|
@@ -86,20 +84,21 @@ dsh web
|
|
|
86
84
|
| Exa | 广泛文档发现和补充发现 | `EXA_API_KEY` | 否 |
|
|
87
85
|
| Tavily | 补充搜索、网页提取和站点映射 | `TAVILY_API_KEY` | 否 |
|
|
88
86
|
| Firecrawl | 补充搜索和网页提取 | `FIRECRAWL_API_KEY` | 否 |
|
|
87
|
+
| Parallel | 补充搜索和 Markdown 网页提取 | `PARALLEL_API_KEY` | 否 |
|
|
89
88
|
|
|
90
89
|
在插件设置中,可以多选 **补充搜索 Provider**。选中项与主搜索并行执行,每家使用 `supplementalSearch.maxSourcesPerProvider` 限制来源数量(默认 `5`,最大 `100`)。选择对所有搜索 profile 生效。
|
|
91
90
|
|
|
92
|
-
另外,多选 **网页提取 Provider** 可以限制 Agent 可用的服务范围。每次 `web_extract` 必须明确选择一家已启用服务,例如 `{ "url": "https://example.com/", "provider": "direct", "format": "markdown" }
|
|
91
|
+
另外,多选 **网页提取 Provider** 可以限制 Agent 可用的服务范围。每次 `web_extract` 必须明确选择一家已启用服务,例如 `{ "url": "https://example.com/", "provider": "direct", "format": "markdown" }`。服务被禁用、缺少凭据、不支持格式或执行失败时,直接报告错误,不自动回退。Parallel 提取仅支持 Markdown,默认关闭,需要手动启用;其他提取服务默认启用,可取消勾选不希望使用的服务。
|
|
93
92
|
|
|
94
93
|
对于 `docs_search`,Context7 需要明确的 `library_name` 或 `library_id`。两者都未提供时,`provider: "auto"` 使用 Exa,不会根据完整问题猜测包名。
|
|
95
94
|
|
|
96
|
-
##
|
|
95
|
+
## 按需功能
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
想查看更多搜索来源时,可以直接追问:“把这次搜索的其他来源也列出来。”
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
想查找某个网站下的相关页面时,可以提出:“查找这个网站下与认证有关的页面。”该功能需要先配置 Tavily。
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
助手会按需使用这些功能,你不必手动调用工具或切换模式。核对重要结论时,还可以继续要求读取原网页。
|
|
103
102
|
|
|
104
103
|
## 更新与卸载
|
|
105
104
|
|
package/client/client.js
CHANGED
|
@@ -18,16 +18,19 @@ window.__ModuleLoader__.load({
|
|
|
18
18
|
"context7",
|
|
19
19
|
"exa",
|
|
20
20
|
"tavily",
|
|
21
|
-
"firecrawl"
|
|
21
|
+
"firecrawl",
|
|
22
|
+
"parallel"
|
|
22
23
|
];
|
|
23
24
|
const WEB_SUPPLEMENTAL_SEARCH_PROVIDERS = [
|
|
24
25
|
"exa",
|
|
25
26
|
"tavily",
|
|
26
|
-
"firecrawl"
|
|
27
|
+
"firecrawl",
|
|
28
|
+
"parallel"
|
|
27
29
|
];
|
|
28
30
|
const WEB_EXTRACT_PROVIDER_KEYS = [
|
|
29
31
|
"tavily",
|
|
30
32
|
"firecrawl",
|
|
33
|
+
"parallel",
|
|
31
34
|
"smartDirect",
|
|
32
35
|
"direct"
|
|
33
36
|
];
|
|
@@ -35,6 +38,24 @@ window.__ModuleLoader__.load({
|
|
|
35
38
|
["defaultProfile"],
|
|
36
39
|
["defaultDepth"],
|
|
37
40
|
["toolTimeoutMs"],
|
|
41
|
+
["retention", "docsSearchMaxResults"],
|
|
42
|
+
...[
|
|
43
|
+
"auto",
|
|
44
|
+
"coding_docs",
|
|
45
|
+
"code_examples",
|
|
46
|
+
"project_research",
|
|
47
|
+
"academic",
|
|
48
|
+
"fact_check"
|
|
49
|
+
].flatMap((profile) => [
|
|
50
|
+
"compact",
|
|
51
|
+
"normal",
|
|
52
|
+
"deep"
|
|
53
|
+
].map((depth) => [
|
|
54
|
+
"budgets",
|
|
55
|
+
profile,
|
|
56
|
+
depth,
|
|
57
|
+
"maxVisibleSources"
|
|
58
|
+
])),
|
|
38
59
|
["toolDiscovery", "mode"],
|
|
39
60
|
...WEB_SUPPLEMENTAL_SEARCH_PROVIDERS.map((provider) => ["supplementalSearch", provider]),
|
|
40
61
|
["supplementalSearch", "maxSourcesPerProvider"],
|
|
@@ -109,6 +130,26 @@ window.__ModuleLoader__.load({
|
|
|
109
130
|
"firecrawl",
|
|
110
131
|
"timeoutMs"
|
|
111
132
|
],
|
|
133
|
+
[
|
|
134
|
+
"providers",
|
|
135
|
+
"parallel",
|
|
136
|
+
"baseUrl"
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
"providers",
|
|
140
|
+
"parallel",
|
|
141
|
+
"credentialRef"
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
"providers",
|
|
145
|
+
"parallel",
|
|
146
|
+
"timeoutMs"
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
"providers",
|
|
150
|
+
"parallel",
|
|
151
|
+
"mode"
|
|
152
|
+
],
|
|
112
153
|
[
|
|
113
154
|
"webExtract",
|
|
114
155
|
"smartDirect",
|
|
@@ -220,7 +261,8 @@ window.__ModuleLoader__.load({
|
|
|
220
261
|
"context7",
|
|
221
262
|
"exa",
|
|
222
263
|
"tavily",
|
|
223
|
-
"firecrawl"
|
|
264
|
+
"firecrawl",
|
|
265
|
+
"parallel"
|
|
224
266
|
];
|
|
225
267
|
const PROXY_ROUTES = [["smartDirect", "smartDirectProxy"], ["direct", "directProxy"]];
|
|
226
268
|
const CREDENTIAL_NAME_KEYS = {
|
|
@@ -228,7 +270,8 @@ window.__ModuleLoader__.load({
|
|
|
228
270
|
context7: "context7",
|
|
229
271
|
exa: "exa",
|
|
230
272
|
tavily: "tavily",
|
|
231
|
-
firecrawl: "firecrawl"
|
|
273
|
+
firecrawl: "firecrawl",
|
|
274
|
+
parallel: "parallel"
|
|
232
275
|
};
|
|
233
276
|
const cardStyle = {
|
|
234
277
|
overflow: "hidden",
|
|
@@ -407,6 +450,8 @@ window.__ModuleLoader__.load({
|
|
|
407
450
|
defaultProfile: config.defaultProfile,
|
|
408
451
|
defaultDepth: config.defaultDepth,
|
|
409
452
|
toolTimeoutMs: config.toolTimeoutMs,
|
|
453
|
+
retention: { ...config.retention },
|
|
454
|
+
budgets: Object.fromEntries(Object.entries(config.budgets).map(([profile, depths]) => [profile, Object.fromEntries(Object.entries(depths).map(([depth, budget]) => [depth, { ...budget }]))])),
|
|
410
455
|
toolDiscovery: { ...config.toolDiscovery },
|
|
411
456
|
supplementalSearch: { ...config.supplementalSearch },
|
|
412
457
|
searchApi: { ...config.searchApi },
|
|
@@ -414,11 +459,13 @@ window.__ModuleLoader__.load({
|
|
|
414
459
|
context7: { ...config.providers.context7 },
|
|
415
460
|
exa: { ...config.providers.exa },
|
|
416
461
|
tavily: { ...config.providers.tavily },
|
|
417
|
-
firecrawl: { ...config.providers.firecrawl }
|
|
462
|
+
firecrawl: { ...config.providers.firecrawl },
|
|
463
|
+
parallel: { ...config.providers.parallel }
|
|
418
464
|
},
|
|
419
465
|
webExtract: {
|
|
420
466
|
tavily: { ...config.webExtract.tavily },
|
|
421
467
|
firecrawl: { ...config.webExtract.firecrawl },
|
|
468
|
+
parallel: { ...config.webExtract.parallel },
|
|
422
469
|
smartDirect: { ...config.webExtract.smartDirect },
|
|
423
470
|
direct: { ...config.webExtract.direct }
|
|
424
471
|
}
|
|
@@ -667,7 +714,7 @@ window.__ModuleLoader__.load({
|
|
|
667
714
|
]);
|
|
668
715
|
const mutations = (0, react.useMemo)(() => snapshot === void 0 || draft === void 0 ? [] : mutationsFor(snapshot.value, draft), [draft, snapshot]);
|
|
669
716
|
const dirty = mutations.length > 0;
|
|
670
|
-
const valid = draft !== void 0 && snapshot !== void 0 && validTimeouts(draft) && validSupplementalSearch(draft, snapshot.options.supplementalSearchMaxSources);
|
|
717
|
+
const valid = draft !== void 0 && snapshot !== void 0 && validTimeouts(draft) && validSupplementalSearch(draft, snapshot.options.supplementalSearchMaxSources) && Number.isInteger(draft.retention.docsSearchMaxResults) && draft.retention.docsSearchMaxResults >= snapshot.options.docsSearchMinResults && draft.retention.docsSearchMaxResults <= snapshot.options.docsSearchMaxResults && Object.values(draft.budgets).every((depths) => Object.values(depths).every((budget) => Number.isInteger(budget.maxVisibleSources) && budget.maxVisibleSources >= 0 && budget.maxVisibleSources <= snapshot.options.visibleSourcesMax));
|
|
671
718
|
const editable = phase === "ready" && snapshot?.writable === true && !saving;
|
|
672
719
|
const updateProvider = (provider, value) => {
|
|
673
720
|
setDraft((current) => current === void 0 ? current : provider === "searchApi" ? {
|
|
@@ -989,6 +1036,60 @@ window.__ModuleLoader__.load({
|
|
|
989
1036
|
}
|
|
990
1037
|
})
|
|
991
1038
|
}),
|
|
1039
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1040
|
+
label: t("maxVisibleSources"),
|
|
1041
|
+
overridden: isOverridden(snapshot.user, [
|
|
1042
|
+
"budgets",
|
|
1043
|
+
draft.defaultProfile,
|
|
1044
|
+
draft.defaultDepth,
|
|
1045
|
+
"maxVisibleSources"
|
|
1046
|
+
]),
|
|
1047
|
+
t,
|
|
1048
|
+
hint: t("maxVisibleSourcesHint"),
|
|
1049
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInput, {
|
|
1050
|
+
label: t("maxVisibleSources"),
|
|
1051
|
+
value: draft.budgets[draft.defaultProfile][draft.defaultDepth].maxVisibleSources,
|
|
1052
|
+
min: 0,
|
|
1053
|
+
max: snapshot.options.visibleSourcesMax,
|
|
1054
|
+
disabled: !editable,
|
|
1055
|
+
onChange: (maxVisibleSources) => {
|
|
1056
|
+
setDraft((current) => current === void 0 ? current : {
|
|
1057
|
+
...current,
|
|
1058
|
+
budgets: {
|
|
1059
|
+
...current.budgets,
|
|
1060
|
+
[current.defaultProfile]: {
|
|
1061
|
+
...current.budgets[current.defaultProfile],
|
|
1062
|
+
[current.defaultDepth]: { maxVisibleSources }
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
setFeedback("idle");
|
|
1067
|
+
}
|
|
1068
|
+
})
|
|
1069
|
+
}),
|
|
1070
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1071
|
+
label: t("docsSearchMaxResults"),
|
|
1072
|
+
overridden: isOverridden(snapshot.user, ["retention", "docsSearchMaxResults"]),
|
|
1073
|
+
t,
|
|
1074
|
+
hint: t("docsSearchMaxResultsHint"),
|
|
1075
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInput, {
|
|
1076
|
+
label: t("docsSearchMaxResults"),
|
|
1077
|
+
value: draft.retention.docsSearchMaxResults,
|
|
1078
|
+
min: snapshot.options.docsSearchMinResults,
|
|
1079
|
+
max: snapshot.options.docsSearchMaxResults,
|
|
1080
|
+
disabled: !editable,
|
|
1081
|
+
onChange: (docsSearchMaxResults) => {
|
|
1082
|
+
setDraft((current) => current === void 0 ? current : {
|
|
1083
|
+
...current,
|
|
1084
|
+
retention: {
|
|
1085
|
+
...current.retention,
|
|
1086
|
+
docsSearchMaxResults
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
setFeedback("idle");
|
|
1090
|
+
}
|
|
1091
|
+
})
|
|
1092
|
+
}),
|
|
992
1093
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
993
1094
|
label: t("toolTimeoutMs"),
|
|
994
1095
|
overridden: isOverridden(snapshot.user, ["toolTimeoutMs"]),
|
|
@@ -1027,30 +1128,60 @@ window.__ModuleLoader__.load({
|
|
|
1027
1128
|
...gridStyle,
|
|
1028
1129
|
alignItems: "end"
|
|
1029
1130
|
},
|
|
1030
|
-
children: [
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
t,
|
|
1036
|
-
onToggle: (provider) => {
|
|
1037
|
-
updateSupplementalSearch({ [provider]: !draft.supplementalSearch[provider] });
|
|
1038
|
-
}
|
|
1039
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1040
|
-
label: t("maxSourcesPerProvider"),
|
|
1041
|
-
overridden: isOverridden(snapshot.user, ["supplementalSearch", "maxSourcesPerProvider"]),
|
|
1042
|
-
t,
|
|
1043
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInput, {
|
|
1044
|
-
label: t("maxSourcesPerProvider"),
|
|
1045
|
-
value: draft.supplementalSearch.maxSourcesPerProvider,
|
|
1046
|
-
min: 1,
|
|
1047
|
-
max: snapshot.options.supplementalSearchMaxSources,
|
|
1131
|
+
children: [
|
|
1132
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderSelect, {
|
|
1133
|
+
label: t("extraSourcesHeading"),
|
|
1134
|
+
providers: WEB_SUPPLEMENTAL_SEARCH_PROVIDERS,
|
|
1135
|
+
selected: WEB_SUPPLEMENTAL_SEARCH_PROVIDERS.filter((provider) => draft.supplementalSearch[provider]),
|
|
1048
1136
|
disabled: !editable,
|
|
1049
|
-
|
|
1050
|
-
|
|
1137
|
+
t,
|
|
1138
|
+
onToggle: (provider) => {
|
|
1139
|
+
updateSupplementalSearch({ [provider]: !draft.supplementalSearch[provider] });
|
|
1051
1140
|
}
|
|
1141
|
+
}),
|
|
1142
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1143
|
+
label: t("maxSourcesPerProvider"),
|
|
1144
|
+
overridden: isOverridden(snapshot.user, ["supplementalSearch", "maxSourcesPerProvider"]),
|
|
1145
|
+
t,
|
|
1146
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberInput, {
|
|
1147
|
+
label: t("maxSourcesPerProvider"),
|
|
1148
|
+
value: draft.supplementalSearch.maxSourcesPerProvider,
|
|
1149
|
+
min: 1,
|
|
1150
|
+
max: snapshot.options.supplementalSearchMaxSources,
|
|
1151
|
+
disabled: !editable,
|
|
1152
|
+
onChange: (value) => {
|
|
1153
|
+
updateSupplementalSearch({ maxSourcesPerProvider: value });
|
|
1154
|
+
}
|
|
1155
|
+
})
|
|
1156
|
+
}),
|
|
1157
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
1158
|
+
label: t("parallelSearchMode"),
|
|
1159
|
+
overridden: isOverridden(snapshot.user, [
|
|
1160
|
+
"providers",
|
|
1161
|
+
"parallel",
|
|
1162
|
+
"mode"
|
|
1163
|
+
]),
|
|
1164
|
+
t,
|
|
1165
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Select, {
|
|
1166
|
+
value: draft.providers.parallel.mode,
|
|
1167
|
+
options: snapshot.options.parallelSearchModes,
|
|
1168
|
+
disabled: !editable,
|
|
1169
|
+
onChange: (mode) => {
|
|
1170
|
+
setDraft((current) => current === void 0 ? current : {
|
|
1171
|
+
...current,
|
|
1172
|
+
providers: {
|
|
1173
|
+
...current.providers,
|
|
1174
|
+
parallel: {
|
|
1175
|
+
...current.providers.parallel,
|
|
1176
|
+
mode
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
setFeedback("idle");
|
|
1181
|
+
}
|
|
1182
|
+
})
|
|
1052
1183
|
})
|
|
1053
|
-
|
|
1184
|
+
]
|
|
1054
1185
|
})]
|
|
1055
1186
|
}),
|
|
1056
1187
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
@@ -1086,6 +1217,10 @@ window.__ModuleLoader__.load({
|
|
|
1086
1217
|
setFeedback("idle");
|
|
1087
1218
|
}
|
|
1088
1219
|
}),
|
|
1220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1221
|
+
style: noteStyle,
|
|
1222
|
+
children: t("parallelExtractHint")
|
|
1223
|
+
}),
|
|
1089
1224
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1090
1225
|
style: sectionStyle,
|
|
1091
1226
|
"aria-labelledby": "search-enhance-proxy-heading",
|
|
@@ -1380,11 +1515,16 @@ window.__ModuleLoader__.load({
|
|
|
1380
1515
|
strategyIntro: "Defaults used when a tool call does not choose its own profile or depth.",
|
|
1381
1516
|
defaultProfile: "Default profile",
|
|
1382
1517
|
defaultDepth: "Default depth",
|
|
1518
|
+
maxVisibleSources: "Initial web_search source limit",
|
|
1519
|
+
maxVisibleSourcesHint: "Applies to the profile/depth selected above, not Provider collection or storage. Use source_ref for retained sources; model-text byte limits still apply.",
|
|
1520
|
+
docsSearchMaxResults: "docs_search request ceiling",
|
|
1521
|
+
docsSearchMaxResultsHint: "Allows max_results values from 1 up to this ceiling (default call: 6). Does not override an explicit smaller value. Collect more by increasing max_results and rerunning; pagination reads only retained records.",
|
|
1383
1522
|
toolDiscoveryMode: "Tool discovery",
|
|
1384
1523
|
toolTimeoutMs: "Whole tool timeout (ms)",
|
|
1385
1524
|
extraSourcesHeading: "Supplemental search providers",
|
|
1386
|
-
extraSourcesIntro: "Select any of Exa, Tavily, and
|
|
1525
|
+
extraSourcesIntro: "Select any of Exa, Tavily, Firecrawl, and Parallel. Every selected provider searches in parallel.",
|
|
1387
1526
|
selectProviders: "Select providers (multiple allowed)",
|
|
1527
|
+
parallelSearchMode: "Parallel search mode",
|
|
1388
1528
|
maxSourcesPerProvider: "Maximum sources per selected provider",
|
|
1389
1529
|
extractHeading: "Available extraction providers",
|
|
1390
1530
|
extractIntro: "Select the providers the Agent may use. Each web_extract call must explicitly choose one enabled provider. Failure never triggers automatic fallback.",
|
|
@@ -1394,6 +1534,8 @@ window.__ModuleLoader__.load({
|
|
|
1394
1534
|
exa: "Exa",
|
|
1395
1535
|
tavily: "Tavily",
|
|
1396
1536
|
firecrawl: "Firecrawl",
|
|
1537
|
+
parallel: "Parallel",
|
|
1538
|
+
parallelExtractHint: "Parallel returns Markdown only. It may use indexed content up to 10 minutes old, but does not fall back to older cached content when live fetching fails.",
|
|
1397
1539
|
proxyHeading: "Web extraction proxies",
|
|
1398
1540
|
proxyIntro: "Optional HTTP proxies for the local smart_direct and direct extraction routes. Leave a field blank to remove its user override.",
|
|
1399
1541
|
smartDirectProxy: "smart_direct HTTP proxy",
|
|
@@ -1432,7 +1574,7 @@ window.__ModuleLoader__.load({
|
|
|
1432
1574
|
conflict: "The configuration changed elsewhere. Reload before saving again.",
|
|
1433
1575
|
saveFailed: "The configuration could not be saved.",
|
|
1434
1576
|
readOnly: "The Settings document is read-only.",
|
|
1435
|
-
invalidNumber: "Timeouts must be positive whole numbers
|
|
1577
|
+
invalidNumber: "Timeouts must be positive whole numbers; source and request limits must be whole numbers within their allowed range.",
|
|
1436
1578
|
overridden: "User override",
|
|
1437
1579
|
inherited: "Inherited"
|
|
1438
1580
|
};
|
|
@@ -1458,11 +1600,16 @@ window.__ModuleLoader__.load({
|
|
|
1458
1600
|
strategyIntro: "工具调用未显式选择 profile 或 depth 时使用这些默认值。",
|
|
1459
1601
|
defaultProfile: "默认 Profile",
|
|
1460
1602
|
defaultDepth: "默认深度",
|
|
1603
|
+
maxVisibleSources: "web_search 首次展示来源上限",
|
|
1604
|
+
maxVisibleSourcesHint: "只影响上方所选 Profile / 深度的首次展示,不限制服务收集或存储;已保留来源可通过 source_ref 分页,模型文本仍受字节上限约束。",
|
|
1605
|
+
docsSearchMaxResults: "docs_search 请求数量最高值",
|
|
1606
|
+
docsSearchMaxResultsHint: "允许 max_results 从 1 到此最高值(调用默认 6 条),不会覆盖模型明确传入的较小值。需要更多结果时提高 max_results 后重搜;分页只能读取已保留记录。",
|
|
1461
1607
|
toolDiscoveryMode: "工具披露模式",
|
|
1462
1608
|
toolTimeoutMs: "工具总超时(毫秒)",
|
|
1463
1609
|
extraSourcesHeading: "补充搜索服务",
|
|
1464
|
-
extraSourcesIntro: "可多选 Exa、Tavily、Firecrawl;每次搜索都会并行请求选中项。",
|
|
1610
|
+
extraSourcesIntro: "可多选 Exa、Tavily、Firecrawl、Parallel;每次搜索都会并行请求选中项。",
|
|
1465
1611
|
selectProviders: "选择服务(可多选)",
|
|
1612
|
+
parallelSearchMode: "Parallel 搜索模式",
|
|
1466
1613
|
maxSourcesPerProvider: "每个选中服务的来源上限",
|
|
1467
1614
|
extractHeading: "可用网页提取服务",
|
|
1468
1615
|
extractIntro: "可多选允许 Agent 使用的服务。每次 web_extract 必须明确指定其中一家;失败不自动回退。",
|
|
@@ -1472,6 +1619,8 @@ window.__ModuleLoader__.load({
|
|
|
1472
1619
|
exa: "Exa",
|
|
1473
1620
|
tavily: "Tavily",
|
|
1474
1621
|
firecrawl: "Firecrawl",
|
|
1622
|
+
parallel: "Parallel",
|
|
1623
|
+
parallelExtractHint: "Parallel 仅返回 Markdown 正文,可能使用最近 10 分钟内的缓存;实时读取失败时不退回更旧的缓存。",
|
|
1475
1624
|
proxyHeading: "网页提取代理",
|
|
1476
1625
|
proxyIntro: "分别为本地 smart_direct 与 direct 提取路线设置可选 HTTP 代理;留空会删除对应的用户覆盖。",
|
|
1477
1626
|
smartDirectProxy: "smart_direct HTTP 代理",
|
|
@@ -1510,7 +1659,7 @@ window.__ModuleLoader__.load({
|
|
|
1510
1659
|
conflict: "配置已在其他位置发生变化。请重新读取后再保存。",
|
|
1511
1660
|
saveFailed: "无法保存配置。",
|
|
1512
1661
|
readOnly: "Settings 文档为只读。",
|
|
1513
|
-
invalidNumber: "
|
|
1662
|
+
invalidNumber: "超时必须是正整数;来源与请求数量上限必须是允许范围内的整数。",
|
|
1514
1663
|
overridden: "用户覆盖",
|
|
1515
1664
|
inherited: "继承值"
|
|
1516
1665
|
};
|
|
@@ -20,11 +20,16 @@ export declare const en: {
|
|
|
20
20
|
readonly strategyIntro: "Defaults used when a tool call does not choose its own profile or depth.";
|
|
21
21
|
readonly defaultProfile: "Default profile";
|
|
22
22
|
readonly defaultDepth: "Default depth";
|
|
23
|
+
readonly maxVisibleSources: "Initial web_search source limit";
|
|
24
|
+
readonly maxVisibleSourcesHint: "Applies to the profile/depth selected above, not Provider collection or storage. Use source_ref for retained sources; model-text byte limits still apply.";
|
|
25
|
+
readonly docsSearchMaxResults: "docs_search request ceiling";
|
|
26
|
+
readonly docsSearchMaxResultsHint: "Allows max_results values from 1 up to this ceiling (default call: 6). Does not override an explicit smaller value. Collect more by increasing max_results and rerunning; pagination reads only retained records.";
|
|
23
27
|
readonly toolDiscoveryMode: "Tool discovery";
|
|
24
28
|
readonly toolTimeoutMs: "Whole tool timeout (ms)";
|
|
25
29
|
readonly extraSourcesHeading: "Supplemental search providers";
|
|
26
|
-
readonly extraSourcesIntro: "Select any of Exa, Tavily, and
|
|
30
|
+
readonly extraSourcesIntro: "Select any of Exa, Tavily, Firecrawl, and Parallel. Every selected provider searches in parallel.";
|
|
27
31
|
readonly selectProviders: "Select providers (multiple allowed)";
|
|
32
|
+
readonly parallelSearchMode: "Parallel search mode";
|
|
28
33
|
readonly maxSourcesPerProvider: "Maximum sources per selected provider";
|
|
29
34
|
readonly extractHeading: "Available extraction providers";
|
|
30
35
|
readonly extractIntro: "Select the providers the Agent may use. Each web_extract call must explicitly choose one enabled provider. Failure never triggers automatic fallback.";
|
|
@@ -34,6 +39,8 @@ export declare const en: {
|
|
|
34
39
|
readonly exa: "Exa";
|
|
35
40
|
readonly tavily: "Tavily";
|
|
36
41
|
readonly firecrawl: "Firecrawl";
|
|
42
|
+
readonly parallel: "Parallel";
|
|
43
|
+
readonly parallelExtractHint: "Parallel returns Markdown only. It may use indexed content up to 10 minutes old, but does not fall back to older cached content when live fetching fails.";
|
|
37
44
|
readonly proxyHeading: "Web extraction proxies";
|
|
38
45
|
readonly proxyIntro: "Optional HTTP proxies for the local smart_direct and direct extraction routes. Leave a field blank to remove its user override.";
|
|
39
46
|
readonly smartDirectProxy: "smart_direct HTTP proxy";
|
|
@@ -72,7 +79,7 @@ export declare const en: {
|
|
|
72
79
|
readonly conflict: "The configuration changed elsewhere. Reload before saving again.";
|
|
73
80
|
readonly saveFailed: "The configuration could not be saved.";
|
|
74
81
|
readonly readOnly: "The Settings document is read-only.";
|
|
75
|
-
readonly invalidNumber: "Timeouts must be positive whole numbers
|
|
82
|
+
readonly invalidNumber: "Timeouts must be positive whole numbers; source and request limits must be whole numbers within their allowed range.";
|
|
76
83
|
readonly overridden: "User override";
|
|
77
84
|
readonly inherited: "Inherited";
|
|
78
85
|
};
|
|
@@ -4,10 +4,10 @@ export declare const WEB_BASE_URL_MAX_CHARACTERS = 8192;
|
|
|
4
4
|
export declare const WEB_MODEL_MAX_CHARACTERS = 4096;
|
|
5
5
|
export declare const WEB_CREDENTIAL_REF_MAX_CHARACTERS = 256;
|
|
6
6
|
export declare const WEB_CREDENTIAL_VALUE_MAX_CHARACTERS: number;
|
|
7
|
-
export declare const WEB_CREDENTIAL_SLOTS: readonly ["searchApi", "context7", "exa", "tavily", "firecrawl"];
|
|
7
|
+
export declare const WEB_CREDENTIAL_SLOTS: readonly ["searchApi", "context7", "exa", "tavily", "firecrawl", "parallel"];
|
|
8
8
|
export type WebCredentialSlot = (typeof WEB_CREDENTIAL_SLOTS)[number];
|
|
9
|
-
export declare const WEB_SUPPLEMENTAL_SEARCH_PROVIDERS: readonly ["exa", "tavily", "firecrawl"];
|
|
10
|
-
export declare const WEB_EXTRACT_PROVIDER_KEYS: readonly ["tavily", "firecrawl", "smartDirect", "direct"];
|
|
9
|
+
export declare const WEB_SUPPLEMENTAL_SEARCH_PROVIDERS: readonly ["exa", "tavily", "firecrawl", "parallel"];
|
|
10
|
+
export declare const WEB_EXTRACT_PROVIDER_KEYS: readonly ["tavily", "firecrawl", "parallel", "smartDirect", "direct"];
|
|
11
11
|
export declare const WEB_EDITABLE_PATHS: readonly (readonly string[])[];
|
|
12
12
|
export interface WebSearchApiConfig {
|
|
13
13
|
baseUrl: string;
|
|
@@ -30,6 +30,12 @@ export interface WebEditableConfig {
|
|
|
30
30
|
defaultProfile: string;
|
|
31
31
|
defaultDepth: string;
|
|
32
32
|
toolTimeoutMs: number;
|
|
33
|
+
retention: {
|
|
34
|
+
docsSearchMaxResults: number;
|
|
35
|
+
};
|
|
36
|
+
budgets: Record<string, Record<string, {
|
|
37
|
+
maxVisibleSources: number;
|
|
38
|
+
}>>;
|
|
33
39
|
toolDiscovery: {
|
|
34
40
|
mode: string;
|
|
35
41
|
};
|
|
@@ -42,6 +48,9 @@ export interface WebEditableConfig {
|
|
|
42
48
|
exa: WebDiscoveryProviderConfig;
|
|
43
49
|
tavily: WebDiscoveryProviderConfig;
|
|
44
50
|
firecrawl: WebDiscoveryProviderConfig;
|
|
51
|
+
parallel: WebDiscoveryProviderConfig & {
|
|
52
|
+
mode: string;
|
|
53
|
+
};
|
|
45
54
|
};
|
|
46
55
|
webExtract: {
|
|
47
56
|
tavily: {
|
|
@@ -50,6 +59,9 @@ export interface WebEditableConfig {
|
|
|
50
59
|
firecrawl: {
|
|
51
60
|
enabled: boolean;
|
|
52
61
|
};
|
|
62
|
+
parallel: {
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
};
|
|
53
65
|
smartDirect: WebProxyConfig;
|
|
54
66
|
direct: WebProxyConfig;
|
|
55
67
|
};
|
|
@@ -67,8 +79,12 @@ export interface WebConfigOptions {
|
|
|
67
79
|
protocols: readonly string[];
|
|
68
80
|
thinkingLevels: readonly string[];
|
|
69
81
|
toolDiscoveryModes: readonly string[];
|
|
82
|
+
parallelSearchModes: readonly string[];
|
|
70
83
|
proxyUrlMaxCharacters: number;
|
|
71
84
|
supplementalSearchMaxSources: number;
|
|
85
|
+
docsSearchMinResults: number;
|
|
86
|
+
docsSearchMaxResults: number;
|
|
87
|
+
visibleSourcesMax: number;
|
|
72
88
|
}
|
|
73
89
|
export interface WebCredentialState {
|
|
74
90
|
ref: string;
|