dsh-free-search 0.9.26 → 0.9.27

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 CHANGED
@@ -524,7 +524,7 @@ Search engine test:
524
524
 
525
525
  #### 离线自检断言(tools/)
526
526
 
527
- 仓库自带 **35 个**零依赖断言脚本(合计 **649 项**),**不需要 API key、不联网、不需要测试框架**,Node ≥ 20 即可跑:
527
+ 仓库自带 **35 个**零依赖断言脚本(合计 **653 项**),**不需要 API key、不联网、不需要测试框架**,Node ≥ 20 即可跑:
528
528
 
529
529
  | 脚本 | 覆盖 | 运行(项数) |
530
530
  |---|---|---|
@@ -550,7 +550,7 @@ Search engine test:
550
550
  | `assert-prompt-language.mjs` | 提示词语言(en/zh):语言回退、9 个工具双语文案、标识符不被翻译、占位符插值、切换时只重注册一次 | `node tools/assert-prompt-language.mjs`(7) |
551
551
  | `assert-tool-schema-size.mjs` | 工具 schema 体积(#94):共享引擎 id 常量、`domain_search` 不内嵌逐引擎句子、三处合计 < 1.6k 字符 | `node tools/assert-tool-schema-size.mjs`(5) |
552
552
  | `assert-config-seat.mjs` | 配置入口(#101):卡片同时挂在 `plugins.bundle.config`(key = 包名,渲染在包页)与 `plugins.row.config`(老入口),两者共用同一渲染器 | `node tools/assert-config-seat.mjs`(4) |
553
- | `assert-prompt-injection.mjs` | 提示词分页(#102):两页内置在前、自定义页在后、当前页即注入、空页不注入、内置页分状态/工具/约束三块、内置随 describe 下发不再单独请求、工具开关落到每个注册点、第七段 UI | `node tools/assert-prompt-injection.mjs`(11) |
553
+ | `assert-prompt-injection.mjs` | 提示词分页(#102):两页内置在前、自定义页在后、当前页即注入、空页不注入、内置页分状态/工具/约束三块、内置随 describe 下发不再单独请求、工具开关落到每个注册点、第七段 UI | `node tools/assert-prompt-injection.mjs`(15) |
554
554
  | `assert-rail-section.mjs` | 页内目录的机器可读当前段:卡片根 `data-dsh-fs-section` 与 `railActive` 绑定、六段 id 固定、滚动监听仍在更新 | `node tools/assert-rail-section.mjs`(4) |
555
555
  | `assert-package-files.mjs` | 发布清单闸门(#97):`files` 展开后必须覆盖被引用的本地模块、入口点与 `cordis.patch.yml`,并确认 `prepack` 守卫生效 | `node tools/assert-package-files.mjs`(4) |
556
556
  | `assert-key-rotation.mjs` | 多 key 轮换(#96):round-robin 与 peek、单 key 不推进、配额优先于 429 的分类、轮换候选集合、`multi` 模式内重试与预检不消耗 key | `node tools/assert-key-rotation.mjs`(7) |
@@ -1106,7 +1106,7 @@ Restart `dsh web` after switching to apply changes.
1106
1106
 
1107
1107
  #### Offline self-check assertions (`tools/`)
1108
1108
 
1109
- **Thirty-five** zero-dependency assertion scripts ship with the repo (**649 assertions** total): **no API keys, no network, no test framework**, Node ≥ 20:
1109
+ **Thirty-five** zero-dependency assertion scripts ship with the repo (**653 assertions** total): **no API keys, no network, no test framework**, Node ≥ 20:
1110
1110
 
1111
1111
  | Script | Covers | Run (count) |
1112
1112
  |---|---|---|
@@ -1132,7 +1132,7 @@ Restart `dsh web` after switching to apply changes.
1132
1132
  | `assert-prompt-language.mjs` | Prompt language (en/zh): fallback rules, bilingual copy for all 9 tools, identifiers left untranslated, placeholder interpolation, and one re-registration per language change | `node tools/assert-prompt-language.mjs` (7) |
1133
1133
  | `assert-tool-schema-size.mjs` | Tool schema budget (#94): one shared engine-id constant, no per-engine sentences in `domain_search`, the three schemas under 1.6k chars combined | `node tools/assert-tool-schema-size.mjs` (5) |
1134
1134
  | `assert-config-seat.mjs` | Config entry point (#101): the card is registered on `plugins.bundle.config` (keyed by the package name, rendered on the bundle page) and on `plugins.row.config` (older entry), both sharing one renderer | `node tools/assert-config-seat.mjs` (4) |
1135
- | `assert-prompt-injection.mjs` | Paged prompt (#102): two built-in pages first, user pages after, the current page is what gets injected, an empty page injects nothing, the generated page split into State/Tools/Constraints blocks, built-ins delivered with describe instead of a second request, tool switches wired into every registrar, and the seventh section UI | `node tools/assert-prompt-injection.mjs` (11) |
1135
+ | `assert-prompt-injection.mjs` | Paged prompt (#102): two built-in pages first, user pages after, the current page is what gets injected, an empty page injects nothing, the generated page split into State/Tools/Constraints blocks, built-ins delivered with describe instead of a second request, tool switches wired into every registrar, and the seventh section UI | `node tools/assert-prompt-injection.mjs` (15) |
1136
1136
  | `assert-rail-section.mjs` | Machine-readable active section for the in-page rail: the card root's `data-dsh-fs-section` tracks `railActive`, the six section ids are fixed, and the scroll spy still updates it | `node tools/assert-rail-section.mjs` (4) |
1137
1137
  | `assert-package-files.mjs` | Packaging gate (#97): after expanding `files`, every imported local module, the entry points and `cordis.patch.yml` must be published, and the `prepack` guard must be wired | `node tools/assert-package-files.mjs` (4) |
1138
1138
  | `assert-key-rotation.mjs` | Multi-key rotation (#96): round-robin and peek, single keys never advancing, quota classification ahead of 429, the rotation-candidate set, and in-engine retries that keep multi-mode preflight from consuming keys | `node tools/assert-key-rotation.mjs` (7) |
package/lib/client.js CHANGED
@@ -562,7 +562,7 @@ window.__ModuleLoader__.load({
562
562
  "cache_search",
563
563
  "domain_search",
564
564
  ];
565
- const PLUGIN_VERSION = "0.9.26";
565
+ const PLUGIN_VERSION = "0.9.27";
566
566
  const PLUGIN_REPO_URL = "https://github.com/DDDMUC/dsh-free-search";
567
567
  // 右侧浮动目录(#85):条目顺序即页面顺序,anchor 是页面里对应 field 的 id。
568
568
  const NAV_ITEMS = [
package/lib/index.js CHANGED
@@ -3594,6 +3594,19 @@ function makeBridgeRoutes(settings, search, testEngine, getCredentials) {
3594
3594
  // 九个工具的固定顺序,提示词与设置页都用它。
3595
3595
  export const TOOL_IDS = ["free_search_test", "platform_search", "video_search", "weather", "advanced_search", "multi_search", "research", "cache_search", "domain_search"];
3596
3596
 
3597
+ // #102:三段拼起来就是注入给模型的提示词。空字符串表示整段不注入。
3598
+ export function composeInjectedPrompt(cfg) {
3599
+ const blocks = buildBuiltinPromptBlocks(cfg);
3600
+ const toolsLang = promptLanguageOf({ promptLanguage: cfg.promptToolsLang || cfg.promptLanguage });
3601
+ return [
3602
+ effectivePromptText({ builtins: blocks.state, pages: cfg.promptStatePages, index: cfg.promptStateIndex }),
3603
+ blocks.tools[toolsLang],
3604
+ effectivePromptText({ builtins: blocks.constraints, pages: cfg.promptConstraintsPages, index: cfg.promptConstraintsIndex }),
3605
+ ]
3606
+ .filter(Boolean)
3607
+ .join("\n\n");
3608
+ }
3609
+
3597
3610
  // #102:三段内置内容,按当前配置插值。都不入盘,跟插件更新走。
3598
3611
  function buildBlocksForLang(cfg, lang) {
3599
3612
  const copy = systemCopy(lang);
@@ -5764,16 +5777,14 @@ function apply(ctx, config) {
5764
5777
  refreshPrompt = () => {
5765
5778
  if (disposeSection) { disposeSection(); disposeSection = null; }
5766
5779
  const cfg = current();
5767
- // #102:状态与约束各取当前页;工具段只有语言开关,勾选决定列哪几个。
5768
- const blocks = buildBuiltinPromptBlocks(cfg);
5769
- const toolsLang = promptLanguageOf({ promptLanguage: cfg.promptToolsLang || cfg.promptLanguage });
5770
- const injected = [
5771
- effectivePromptText({ builtins: blocks.state, pages: cfg.promptStatePages, index: cfg.promptStateIndex }),
5772
- blocks[toolsLang].tools,
5773
- effectivePromptText({ builtins: blocks.constraints, pages: cfg.promptConstraintsPages, index: cfg.promptConstraintsIndex }),
5774
- ]
5775
- .filter(Boolean)
5776
- .join("\n\n");
5780
+ // #102:三段拼起来就是注入内容;拼装出错要报出来,不能静默少一段。
5781
+ let injected = "";
5782
+ try {
5783
+ injected = composeInjectedPrompt(cfg);
5784
+ } catch (error) {
5785
+ logger.warn(`free-search: could not build the prompt section (${error instanceof Error ? error.message : String(error)})`);
5786
+ return;
5787
+ }
5777
5788
  if (!injected) return;
5778
5789
  disposeSection = sctx.systemPrompt.section({ name: "free-search:engines", order: 500, text: injected });
5779
5790
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-free-search",
3
- "version": "0.9.26",
3
+ "version": "0.9.27",
4
4
  "description": "Free web search for DeepSeek Harness: 27 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel/You.com keyless; Zhihu global/site via MCP and Perplexity/SerpBase/DeepSeek (official + native tools/search)/Baidu/Kimi/Aliyun/Doubao with key; OpenAI/Gemini/Claude model built-in search, explicit-only) + auto smart routing + global engine enable/disable & fallback priority + editable zh/en language pools + multi mode (parallel full language-pool merge) + multi_search cross-source tool + failure-aware fallback (quota/auth cooldown, transient retry, fallbackOn) + time filtering + platform search + domain blocklist (blockedDomains) + web_fetch, with web settings UI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",