dsh-web-search-enhanced 0.0.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/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-web-search-enhanced contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # dsh-web-search-enhanced
2
+
3
+ <strong>dsh-web-search-enhanced</strong> 是一个第三方 DeepSeek Harness <code>ctx.web</code> 搜索提供方。它保留模型看到的原生 <code>web_search</code> 工具与 <code>WebSearchResult</code> 输出,但允许 Web Profile 在三种上游协议之间切换:Anthropic Messages v1、OpenAI Responses API 和 OpenAI Chat Completions API。
4
+
5
+ ## 功能
6
+
7
+ - 通过 <code>modelMode</code> 选择固定搜索路由,或跟随当前会话模型及其调用协议;
8
+ - 跟随模式无法解析当前路由时,使用可配置的 <code>fallbackModel</code>;
9
+ - 通过 <code>protocol</code> 切换固定/兜底路由的三种非流式 HTTP 协议;
10
+ - 通过 <code>toolIdentifier</code> 覆盖上游内置搜索标识符;
11
+ - 通过 <code>maxTokens</code> 配置 <code>max_tokens</code> 或 <code>max_output_tokens</code>;
12
+ - 将三种响应中的来源与引用归一化为 DSH <code>WebSearchResult</code>;
13
+ - 在「设置 → 插件 → 插件配置」中提供可暂存、校验、保存、放弃和恢复 Profile 默认值的双语配置卡片;
14
+ - 拒绝携带凭据的 HTTP 重定向,并把取消、缺少凭据和上游错误映射为可路由的 <code>WebError</code> code。
15
+
16
+ ## 安装
17
+
18
+ ~~~bash
19
+ dsh plugin --profile web add /path/to/dsh-web-search-enhanced
20
+ ~~~
21
+
22
+ 安装后完整重启 <code>dsh web</code>。随包 <code>cordis.patch.yml</code> 会把 <code>ctx.web</code> 的 <code>searchProvider</code> 指向 <code>enhanced-search</code>,并禁用原生 <code>web-search-deepseek</code> provider;模型侧仍使用稳定的 <code>web_search</code> 工具。
23
+
24
+ ## 配置
25
+
26
+ 默认配置与 DSH 原生 DeepSeek 搜索兼容:
27
+
28
+ ~~~yaml
29
+ - id: web-search-enhanced
30
+ config:
31
+ modelMode: configured
32
+ protocol: anthropic-messages
33
+ baseURL: https://api.deepseek.com/anthropic/v1
34
+ model: deepseek-v4-flash
35
+ fallbackModel: deepseek-v4-flash
36
+ apiKeyEnv: WEB_SEARCH_ENHANCED_API
37
+ maxTokens: 4096
38
+ ~~~
39
+
40
+ | 字段 | 默认值 | 说明 |
41
+ | --- | --- | --- |
42
+ | <code>modelMode</code> | <code>configured</code> | <code>configured</code> 使用固定路由;<code>current-session</code> 跟随当前模型、Provider 和调用协议 |
43
+ | <code>fallbackModel</code> | 固定 <code>model</code> | 当前 Session 路由无法解析时使用的模型 |
44
+ | <code>protocol</code> | <code>anthropic-messages</code> | 固定/兜底路由使用的协议 |
45
+ | <code>toolIdentifier</code> | 按协议推导 | Anthropic/Responses 的 tool type;Chat 的 vendor-options 模式为自定义选项字段名 |
46
+ | <code>maxTokens</code> | <code>4096</code> | Anthropic/Chat 写入 <code>max_tokens</code>,Responses 写入 <code>max_output_tokens</code> |
47
+ | <code>baseURL</code> | DeepSeek Anthropic base | 按协议追加 <code>/messages</code>、<code>/responses</code> 或 <code>/chat/completions</code> |
48
+ | <code>model</code> | <code>deepseek-v4-flash</code> | 支持服务端网页搜索的模型 ID |
49
+ | <code>apiKeyEnv</code> | <code>WEB_SEARCH_ENHANCED_API</code> | 固定/兜底路由读取 API Key 的凭据引用;当前会话模式优先使用当前 LLM 路由引用 |
50
+ | <code>maxUses</code> | <code>5</code> | 仅 Anthropic Messages 的 <code>max_uses</code> |
51
+ | <code>chatSearchMode</code> | <code>search-model</code> | 官方专用搜索模型,或明确声明的 <code>vendor-options</code> 扩展 |
52
+ | <code>searchContextSize</code> | 上游默认 | OpenAI 兼容模式可选 <code>low</code>、<code>medium</code>、<code>high</code> |
53
+
54
+ <code>toolIdentifier</code> 留空时:Anthropic 使用 <code>web_search_20250305</code>;Responses 使用 <code>web_search</code>;Chat 的 vendor-options 模式使用 <code>web_search_options</code>。官方 Chat Completions 只在专用搜索模型上提供联网搜索,使用固定顶层 <code>web_search_options</code> 字段,而不是 Responses 风格的 <code>tools[]</code>;只有网关明确声明自定义字段时才选择 vendor-options。
55
+
56
+ 设置页面提供一次性 API Key 输入框。密钥通过 <code>ctx.remote.credentials.set()</code> 保存到 Harness credentials,成功后清空输入框;普通 settings document 永远不会回显密钥。
57
+
58
+ ## Standalone 限制
59
+
60
+ 本插件与参考实现 <code>dsh-web-search-responses</code> 一样直接从 <code>ctx.web</code> 调用上游搜索模型,不新增 SessionEvent。DSH 当前持久化层只接受编译进 Host runtime catalog 的事件,外部插件仅做 TypeScript declaration merge 会导致会话恢复拒绝未知事件,因此本插件不会写入自定义事件。
61
+
62
+ 原始 <code>web_search</code> query 仍由 DSH 的 <code>tool/call</code> 记录,但实际 endpoint、model 和协议请求 body 不能从当前 session log 完整重建。这是纯外部插件且不修改 Core 时无法消除的限制;需要严格辅助模型请求重放的部署不应启用本插件。
63
+
64
+ ## 开发
65
+
66
+ ~~~bash
67
+ pnpm install
68
+ pnpm run check
69
+ ~~~
70
+
71
+ 若系统 pnpm 状态目录不可写:
72
+
73
+ ~~~bash
74
+ XDG_DATA_HOME=$PWD/.xdg/data XDG_CONFIG_HOME=$PWD/.xdg/config PNPM_HOME=$PWD/.pnpm-home pnpm install
75
+ ~~~
76
+
77
+ 详细需求分析、架构与风险见 [docs/design.zh-CN.md](docs/design.zh-CN.md)。
@@ -0,0 +1,20 @@
1
+ # Select the enhanced provider for DSH's stable model-facing web_search tool.
2
+ # The WebRuntime row is replaced as a whole, so keep both selectors here.
3
+ - id: web
4
+ config:
5
+ searchProvider: enhanced-search
6
+ fetchProvider: http
7
+
8
+ # Avoid registering two implementations under separate selectable ids by default.
9
+ - id: web-search-deepseek
10
+ disabled: true
11
+
12
+ - insert:
13
+ - id: web-search-enhanced
14
+ name: dsh-web-search-enhanced
15
+ config:
16
+ modelMode: configured
17
+ protocol: anthropic-messages
18
+ apiKeyEnv: WEB_SEARCH_ENHANCED_API
19
+ fallbackModel: deepseek-v4-flash
20
+ maxTokens: 4096
@@ -0,0 +1,79 @@
1
+ # dsh-web-search-enhanced 需求分析与架构设计
2
+
3
+ ## 1. 需求评估
4
+
5
+ DSH 的模型侧 <code>web_search</code> 并不直接绑定某个 HTTP 协议。调用链是 <code>dsh-tool-web → ctx.web.search() → WebSearchProvider</code>,因此正确扩展点不是覆盖工具注册表,也不是修改 agent loop,而是注册新的 <code>ctx.web</code> search provider,并在 WebRuntime 配置中选择该 provider。这样可保持模型工具名称、参数、权限、超时与结果渲染不变。
6
+
7
+ 本插件必须支持三种协议切换、上游内置搜索标识符和最大输出 Token 配置、Web Profile 可视化编辑,以及统一的 <code>WebSearchResult</code>。为使协议可实际调用,还必须配置 <code>baseURL</code>、<code>model</code> 和 <code>apiKeyEnv</code>。<code>maxUses</code>、<code>apiVersion</code> 与 <code>searchContextSize</code> 是协议适配需要的窄扩展字段。
8
+
9
+ 插件在 <code>current-session</code> 模式下读取当前 Agent 的模型选择与 <code>llm-pi-ai</code> 路由配置,跟随模型、Provider、调用协议、接口地址和凭据;无法解析时使用固定配置及 <code>fallbackModel</code>。非目标包括重新注册模型侧工具、通用函数工具执行、浏览器写入 settings document 明文 API Key,以及修改 deepseek-harness 源码。
10
+
11
+ ## 2. 组件与数据流
12
+
13
+ ~~~mermaid
14
+ flowchart LR
15
+ M[Agent model] --> T[dsh-tool-web / web_search]
16
+ T --> W[ctx.web]
17
+ W --> P[EnhancedSearchProvider]
18
+ S[Web Profile settings] --> P
19
+ P --> A[Protocol request adapter]
20
+ A --> H[Credentialed HTTPS request]
21
+ H --> R[Protocol response parser]
22
+ R --> N[WebSearchResult]
23
+ N --> T
24
+ ~~~
25
+
26
+ Host 入口通过 <code>installSettingsSection</code> 注册 <code>web-search-enhanced</code> namespace。每次搜索开始时只读取一次 resolved settings,保证一次调用不会混用更新前后的 endpoint、协议和 Token 上限。provider ID 在注册时固定;实时设置不能修改该字段,否则 <code>ctx.web</code> 的 provider 选择会与已注册对象不一致。
27
+
28
+ Client 入口把相同 namespace 绑定到 <code>settings.plugin.item</code> keyed slot。插件配置页只在 Host 暴露 namespace 时渲染卡片,未加载 Host 插件时不会出现不可用配置项。
29
+
30
+ ## 3. 协议映射
31
+
32
+ | 协议 | Endpoint | 搜索标识符位置 | Token 字段 | 响应来源 |
33
+ | --- | --- | --- | --- | --- |
34
+ | Anthropic Messages v1 | <code>/messages</code> | <code>tools[0].type</code>,默认 <code>web_search_20250305</code> | <code>max_tokens</code> | <code>web_search_tool_result</code> + text citations |
35
+ | OpenAI Responses | <code>/responses</code> | <code>tools[0].type</code> 与 <code>tool_choice.type</code>,默认 <code>web_search</code> | <code>max_output_tokens</code> | <code>web_search_call</code>、sources、message annotations |
36
+ | OpenAI Chat Completions | <code>/chat/completions</code> | 官方模式固定 <code>web_search_options</code>;vendor 模式可配置字段名 | <code>max_tokens</code> | assistant message annotations 与顶层 citations |
37
+
38
+ Chat Completions 与 Responses 的联网搜索表示不同。官方 Chat Completions 仅支持专用搜索模型,并通过固定 <code>web_search_options</code> 启用搜索,不接收 Responses 的 built-in <code>tools[]</code>。默认 <code>chatSearchMode=search-model</code> 固定使用该官方字段;只有网关明确声明自定义顶层选项字段时才选择 <code>vendor-options</code>,此时 <code>toolIdentifier</code> 才控制字段名。
39
+
40
+ 所有请求设置 <code>stream: false</code>。Responses 强制 <code>tool_choice</code> 为配置的 built-in 类型;Anthropic 通过 <code>max_uses</code> 约束服务端搜索次数;Chat 由专用搜索模型与搜索选项字段决定搜索执行;普通 Chat 模型不构成可用的 web search capability。
41
+
42
+ ## 4. 配置模型
43
+
44
+ Schema defaults → Profile composition base → 用户持久化覆盖构成设置层级。resolved config 在操作入口校验 provider ID、绝对 URL、必填字符串、安全标识符、正整数 Token/使用次数和封闭 context-size 枚举。配置卡片采用暂存编辑;客户端即时校验,Host 执行权威校验。恢复 Profile 清除用户层字段,不复制默认值。
45
+
46
+ ## 5. 错误与安全
47
+
48
+ | code | 条件 |
49
+ | --- | --- |
50
+ | <code>WEB_PROVIDER_CREDENTIAL_MISSING</code> | literal key、<code>ctx.credentials</code> 与 launch environment 均不可用 |
51
+ | <code>WEB_ABORTED</code> | 调用前、请求中或读取响应时取消 |
52
+ | <code>WEB_PROVIDER_ERROR</code> | 网络、HTTP、JSON、协议结果或服务端搜索失败 |
53
+
54
+ 所有凭据请求设置 <code>redirect: error</code>,在跟随重定向前失败,避免 Authorization 或 <code>x-api-key</code> 自动转发到其他 origin。Anthropic 同时发送 <code>x-api-key</code> 与 Bearer 以兼容 DeepSeek 和 Anthropic-compatible gateway;OpenAI 协议仅发送 Bearer。错误消息不包含密钥。<code>baseURL</code> 禁止 userinfo、query 和 fragment,避免 URL 本身携带凭据。
55
+
56
+ Parser 不从自然语言伪造来源。Anthropic 或 Responses 没有服务端搜索执行标记时直接失败;Chat Completions 公开响应没有独立 search-call item,因此以 assistant message 为最小成功条件,并从 annotations/citations 提取来源。
57
+
58
+ ## 6. UX 设计
59
+
60
+ 卡片复用 DSH 设置页语义:12px 卡片圆角、14×16px header、<code>--dsw-alias-*</code> token、折叠箭头、未保存徽标、34px 表单控件、帮助文本,以及保存/放弃/恢复 Profile footer。界面提供中英文 typed dictionary、可访问 label、<code>aria-expanded</code>、<code>aria-invalid</code> 与错误状态。
61
+
62
+ 协议切换会改变高级字段:Anthropic 显示 <code>maxUses</code> 与 <code>apiVersion</code>;OpenAI 显示 <code>searchContextSize</code>。<code>toolIdentifier</code> 帮助文案随协议说明准确 wire 位置。
63
+
64
+ ## 7. 测试策略
65
+
66
+ - 协议单元测试固定 endpoint、搜索标识符位置与 Token 字段;
67
+ - parser 测试覆盖引用合并、去重与缺少 search-call 失败;
68
+ - provider 测试覆盖重定向策略、取消、缺少凭据、HTTP 错误与成功归一化;
69
+ - settings 测试覆盖默认值、非法字段与动态协议更新;
70
+ - Client helper 测试覆盖 draft、输入校验、凭据引用默认值与双语字典;
71
+ - 跟随模式测试覆盖当前模型、三种协议、路由凭据、fallbackModel 与预算字段;
72
+ - 发布验证检查 Host ESM、Client bundle、类型声明、协议子路径与 Cordis patch。
73
+
74
+ ## 8. 已知风险与后续工作
75
+
76
+ 1. DSH 当前没有外部插件可注册的持久化 SessionEvent catalog。参考插件 <code>dsh-web-search-responses</code> 也不记录其辅助 Responses 请求。本插件不会伪造现有 DeepSeek 专用事件,也不会写出 Host 无法恢复的未知事件;因此实际 endpoint、model 与完整协议 body 不可由 session log 重建。严格执行辅助模型请求可重放的部署不能使用本 standalone 插件。
77
+ 2. OpenAI-compatible 网关可能只实现部分官方字段。Adapter 保持严格,不做静默 fallback。
78
+ 3. Responses 的完整 <code>action.sources</code> 可能要求提供方支持显式 include;message annotations 仍可提供引用。应在确认目标网关后再增加兼容开关。
79
+ 4. API Key 设置 UI 通过 <code>ctx.remote.credentials.set()</code> 写入 Harness credentials;输入框只持有待写入值,成功后清空,普通 settings document 不保存密钥。
@@ -0,0 +1,30 @@
1
+ # Harness Contract
2
+
3
+ ## Source of truth
4
+
5
+ Extracted from DeepSeek Harness commit `cd5ef8148158c3a752a658978873241fdf8e2bbc` and source package line `0.1.2-alpha.1`. Installable dependencies use the npm `next` line `0.1.1-rc.2`; source and registry baselines are intentionally recorded separately.
6
+
7
+ Representative sources:
8
+
9
+ - `packages/fs/tool-fs/src/index.ts`: named Cordis exports, Schemastery config, required and conditional injection.
10
+ - `packages/core/tools/src/schema.ts`: tool definitions and execution contracts.
11
+ - `packages/client/tsdown.client.ts`: ModuleLoader output, external purity, CSS, and build faces.
12
+ - `packages/client/ui-settings-plugins/package.json`: `dsh.client`, exports, peers, and files.
13
+ - `packages/client/ui-settings-plugins/src/client/index.ts`: browser surface ownership.
14
+ - `packages/api/settings-controller/src/index.ts`: redacted settings namespaces and Remote ownership.
15
+
16
+ ## Portable contract retained here
17
+
18
+ One package exposes a Node host half and optional browser half. `dsh.bundle.patch` publishes composition defaults; `dsh.client` declares browser dependencies. Client output calls `window.__ModuleLoader__.load` and resolves shared identity through injected `require`. TypeScript uses strict NodeNext semantics, relative runtime imports end in `.js`, declarations live under `lib/types`, and published files are explicit.
19
+
20
+ ## Deliberately not copied
21
+
22
+ The internal monorepo uses `workspace:^`, project references, generated catalogs, build faces, Typert generators, oxlint, package-invariant gates, static-linked client channels, and root release orchestration. Those are repository infrastructure, not portable plugin API. Typert generation is especially monorepo-bound today, so this basic template demonstrates a narrow optional RPC adapter instead of copying generated internals.
23
+
24
+ ## Upgrade checklist
25
+
26
+ - Compare DSH package versions and Node/pnpm engines.
27
+ - Inspect `packages/client/tsdown.client.ts` for loader, external, CSS, and build changes.
28
+ - Inspect a current tool package for `defineTool` changes.
29
+ - Inspect a current client package for slot, locale, and `dsh.client.inject` changes.
30
+ - Run `pnpm run check`, then verify the packed plugin in the current DSH GUI after refresh.
@@ -0,0 +1,35 @@
1
+ # Existing Template Comparison
2
+
3
+ Audited on 2026-08-28 against DeepSeek Harness `cd5ef8148158c3a752a658978873241fdf8e2bbc`.
4
+
5
+ | Area | bugmaker2 | kun2-5code | sunshine-lang | This template |
6
+ | --- | --- | --- | --- | --- |
7
+ | Audit commit | `31af7eb` | `0b4fbda` | `6417045` | harness-derived |
8
+ | Shape | Dual host/client, Typert, React | Six host shapes, 14 UI surfaces | Minimal host-only tool | Small host/tool plus optional UI/RPC |
9
+ | Build | esbuild + tsc | tsdown + loader wrapper | tsc only | tsc declarations + tsdown adapter |
10
+ | Tests | Vitest contracts/runtime | One build smoke | Unwired integration file | Vitest + build + tarball gate |
11
+ | Publish gate | check, no packed consumer | prepare only | none | prepublish check and pack extraction |
12
+ | Scaffolding | Manual rename checklist | Fork/edit | Script with weak exclusions | Validated name, excludes VCS/build state |
13
+ | DSH baseline | old rc.6, wildcard peers | rc.5/rc.6, obsolete settings docs | rc.1 tools | documented alpha baseline |
14
+
15
+ ## Assessment
16
+
17
+ ### bugmaker2/dsh-web-search-enhanced
18
+
19
+ The strongest contract-oriented example. Shared Zod/Typert descriptors, lifecycle handling, React, i18n, lint and CI are useful. Its handwritten loader, duplicated manifest, wildcard optional peers, manual ten-point rename, old rc.6 baseline, and missing packed-consumer gate increase drift risk.
20
+
21
+ ### kun2-5code/dsh-web-search-enhanced
22
+
23
+ The best catalog of extension shapes and UI slots, useful as an API showcase rather than a minimal production baseline. Its README still describes a settings whitelist and internal paths absent from the current settings controller. It lacks lint, Vitest, package verification, compatibility engines, and prepublish checks.
24
+
25
+ ### sunshine-lang/dsh-web-search-enhanced
26
+
27
+ The clearest host-only starter and only compared repository with a scaffold script. Its exports and tool example are sound, but it lacks client/RPC/UI, package exports, peer separation, typecheck/test/publish gates, and a wired integration test. Its scaffold may copy `lib` and handles arguments weakly.
28
+
29
+ ## Material differences here
30
+
31
+ - Internal package files are evidence, while nonportable monorepo machinery is called out explicitly.
32
+ - One example is kept per important boundary instead of maximizing feature count.
33
+ - Client externals derive from peers and the ModuleLoader compatibility adapter is isolated.
34
+ - The exact tarball is extracted and checked.
35
+ - Host-only deletion and deterministic scaffolding are documented.