# dsh-free-web — 免费联网搜索 给 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)用的免费联网搜索插件:**不用搜索 API,也不需要 API Key**。 它向 `ctx.web` 注册一个搜索提供方,直接读取 Bing 的公开结果页,失败时改用 RSS 视图,再失败才调用本机 Chrome/Edge 做一次无头渲染。它同时为 DSH 内置的 `web_search` 提供搜索能力,在输入框权限选项右侧加入「关闭 / 智能 / 始终」三档开关,并在左侧栏加入一个可交互的搜索面板。 这里没有浏览器扩展:DSH 的界面本身就是 Web 页面,所以插件由 Host 半(Node)和 Client 半(DSH 自己加载的 React 组件)组成;Chrome 只是 Host 可选调用的无头渲染器。 [English](README.md) ## 功能 - **不用搜索 API、不用 Key**:抓的是浏览器同样会加载的公开结果页。 - **按会话三档联网开关**(输入框工具栏,权限选项右边): - **关闭联网**:`web_search` 被 Host 门禁拒绝;`web_fetch` 仍可用于打开你给的链接。 - **智能联网**(默认):模型在推理中自行判断何时搜索,可以多次检索、换关键词、再用 `web_fetch` 打开具体页面。 - **始终联网**:Host 在每轮用户消息进入模型前自动检索一次(15 秒上限),把结果作为运行时上下文注入;结果不足时模型仍可自己再搜。 - **左侧栏搜索面板**:手动搜索、引擎状态、结果跳转。 - **Web 与 Desktop 都能用**:路由挂在 `/api/dsh-free-web/` 下,Client 半用相对 URL,`dsh web` 和桌面端 `dsh-app://` 页面走同一套代码。 - **失败不阻塞**:三条链路都失败时,工具返回正常的错误结果,本轮对话继续。 ## 界面截图 输入框联网开关——按会话选择「关闭 / 智能 / 始终」: ![输入框联网开关与三档模式](docs/composer-toggle.png) 左侧栏搜索面板——引擎状态、手动搜索、结果跳转: ![左侧栏搜索面板](docs/sidebar-panel.png) ## 环境要求 - DSH **0.2.1-rc.3** 或更新版本(在 0.2.1-rc.3、`desktop` profile、Windows 11 上开发与测试)。 - Host 端 Node.js 20+(DSH 自带运行时)。 - 可选:Google Chrome 或 Microsoft Edge,用于 HTTP 抓取失败时的无头渲染兜底;会自动探测,没有也能只用 HTTP。 ## 安装 把仓库克隆到一个固定目录(profile 会链接到这个目录,安装后不要删除): ```bash git clone https://github.com/skyhome000/dsh-free-web.git ``` 然后在 DSH 里作为本地 bundle 安装:图形界面走「插件 → 添加插件 → 从目录安装」,或用插件管理器工具: ```text plugin_manager install_bundle target: /absolute/path/to/dsh-free-web ``` 安装或更新后刷新一次 DSH 页面(`Ctrl+R`),让浏览器端模块重新加载。 bundle patch 会把内置 `web` 服务切换到本插件,同时保留官方的 HTTP 抓取提供方: ```yaml - id: web name: '@deepseek-ai/dsh-web' config: searchProvider: free-web fetchProvider: http ``` 卸载 bundle 后 patch 一并移除,`web.searchProvider` 回到 DSH 默认值。 ## 使用 ### 输入框联网开关 按钮在输入框工具栏、权限预设的右边,显示当前模式(`🌐 智能联网`): | 模式 | 行为 | | --- | --- | | **关闭联网** | `web_search` 调用被 Host 门禁拒绝;`web_fetch` 仍可用,便于打开你给出的链接。 | | **智能联网**(默认) | 模型在需要最新/可核验信息时自行搜索,并可在推理过程中多次检索。 | | **始终联网** | 每轮对话的第一个模型步骤前,Host 自动检索一次(15 秒上限)并作为运行时上下文注入;模型使用这些结果,必要时继续补充搜索。 | 模式按会话保存在 `%DSH_HOME%/free-web/session-modes.json`(最多 500 个会话),切换后对下一步立即生效,不需要新开会话。 ### 左侧栏面板 点击左侧栏的「联网搜索」即可打开: - 关键词输入、回车搜索; - 搜索方式:自动 / HTTP / Chrome; - 引擎状态:HTTP 就绪、本机 Chrome/Edge 版本、`web_search` 接入状态,可重新检测; - 结果卡片:标题、URL、摘要,点击标题在新标签页打开原文; - 失败时显示回退记录(哪条链路、什么原因)。 ## 工作原理 1. **搜索提供方**——`index.js` 向 `ctx.web` 注册 id 为 `free-web` 的 `WebSearchProvider`;`available()` 恒为 true,`search()` 按下面的链路执行并返回 `{ sources, truncated }`。 2. **搜索链路** 1. `https://www.bing.com/search?q=…`,解析 `li.b_algo` 的标题、链接与摘要; 2. 同一查询的 `&format=rss` 视图,解析 RSS; 3. 本机 Chrome/Edge 的 `--headless=new --dump-dom` 渲染同一页面后解析,使用 `%TEMP%` 下的临时 profile。 3. **按 Agent 的策略**——在 `agent/created` 时(以及插件挂载时已存在的 Agent)在 **agent 自己的 context** 上注册: - `ctx.tools.guard`:会话为「关闭」时拒绝 `web_search`; - `systemPrompt.section`:文本跟随当前模式; - `systemPrompt.context`:「始终」模式下携带自动检索结果; - `agent/pre-step` 监听器:在每轮第一步执行自动检索。 4. **界面**——`client.js` 注册左侧栏入口、主面板(`main`,key `free-web`)和输入框开关(`conversation.input.left`),通过相对地址 `api/dsh-free-web/status`、`/search`、`/mode` 访问 Host。 ## 配置 | 项 | 值 | | --- | --- | | `DSH_FREE_WEB_CHROME` / `CHROME_PATH` | 指定浏览器可执行文件路径。 | | 自动探测路径 | Windows 下的 Chrome / Edge(Program Files、Program Files (x86)、LocalAppData);macOS 的 `/Applications/Google Chrome.app/…`;Linux 的 `google-chrome`、`chromium`、`microsoft-edge`。 | | 结果条数 | `web_search` 最多 8 条;面板请求 8 条。 | | 超时 | HTTP 网页 7s、RSS 6s、本机浏览器 22s、面板请求 40s、自动检索 15s。 | | 模式存储 | `%DSH_HOME%/free-web/session-modes.json`。 | 没有插件 `Config` schema;以上是代码常量与环境变量。 ## 安全边界 - 路由只接受本机来源:`Origin` 缺失、`null`、`dsh-app:` 桌面壳来源,或 `127.0.0.1` / `localhost` / `[::1]`;其他来源返回 403。 - `POST` 必须是 `application/json`——跨站 JSON 请求需要预检,而预检只为本机来源放行;请求体上限 64 KiB,查询长度上限 400 字符。 - 不读取 Cookie、浏览器会话或登录态;可选的无头浏览器使用全新的临时 profile,用完删除。 - 抓取结果是外部数据,按不可信内容处理;`web_search` 工具原本就带这一标注,面板沿用同样的提示。 ## 开发 ```bash npm test # node:test,15 个离线单测 npm run check # 对两个半端做 node --check ``` 测试覆盖 HTML/RSS 解析(含 Bing 跳转链接还原)、路由与门禁接线、按会话模式路由、Client 半的 slot 注册与开关渲染;使用临时 `DSH_HOME`,不访问网络。 ```text index.js Host 半:搜索提供方、路由、模式存储、Agent 策略 client.js Client 半:左侧栏面板、输入框开关 cordis.patch.yml bundle patch:插件行 + web.searchProvider 切换 locale/{en,zh}.json 插件管理器里的标题与描述 icon.svg 插件图标 test/ 离线单测 .github/workflows/ CI(Ubuntu 与 Windows 上的语法检查 + 测试) ``` ## 已知限制 - Bing 可能改版、限流或按地区返回不同结果;链路会依次退到 RSS 和本机浏览器,但相关性由 Bing 决定。 - 「始终联网」的自动查询词是用户消息原文(最多 400 字符);很长的口语化问题可能得到较宽泛的结果,提示词会要求模型按需继续检索。 - Chrome 兜底较慢(通常 6–15 秒),且只在 HTTP 解析失败时才会使用。 - 本项目与 DeepSeek、Microsoft、Google 均无关联。 ## License [MIT](LICENSE)