# dsh-web-kimi **一把 Kimi Coding 密钥,贯通网页管道的两半——为 DeepSeek Harness 同时提供网页搜索与网页抓取。** [![CI](https://github.com/kenny2077/dsh-web-kimi/actions/workflows/ci.yml/badge.svg)](https://github.com/kenny2077/dsh-web-kimi/actions/workflows/ci.yml) [![npm version](https://img.shields.io/npm/v/dsh-web-kimi)](https://www.npmjs.com/package/dsh-web-kimi) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [English](README.md) | 中文 - [它是什么](#它是什么) - [为什么](#为什么) - [工作原理](#工作原理) - [快速开始](#快速开始) - [设置界面卡片](#设置界面卡片) - [配置](#配置) - [字段映射](#字段映射) - [故障排查](#故障排查) - [同类插件对比](#同类插件对比) - [已知限制](#已知限制) - [仓库架构](#仓库架构) - [开发](#开发) - [致谢](#致谢) - [许可证](#许可证) ## 它是什么 一个向 **`ctx.web` 接缝注册两个提供方** 的 DSH 插件: - **`kimi-coding`** —— 由 Kimi Coding API 搜索端点(`POST /v1/search`)支撑的 `WebSearchProvider`。搜索结果映射为 harness 的 `WebSearchSource` 结构:`url`、`title`、`snippet` 与 `publishedAt`(来自结果中的 `date`)。 - **`kimi-coding-fetch`** —— 由 Kimi Coding API 抓取端点(`POST /v1/fetch`)支撑的 `WebFetchProvider`。任意 http(s) 网址都由服务端完成提取(含 JavaScript 渲染),返回干净的 Markdown。 两半共用**同一凭证**、读取**同一设置分区**——密钥保存一次,所有网页操作全部覆盖。GUI 中专门的设置卡片经 DSH 凭据服务保存密钥,保存后的值在下一次搜索或抓取即生效,无需重启。 ``` ┌─────────────────────────────────────────────┐ │ ctx.web 接缝 │ ├──────────────────────┬──────────────────────┤ │ web_search 工具 │ web_fetch 工具 │ │ WebSearchProvider │ WebFetchProvider │ │ kimi-coding │ kimi-coding-fetch │ └──────────┬───────────┴──────────┬───────────┘ │ POST /v1/search │ POST /v1/fetch ▼ ▼ ┌─────────────────────────────────────────────┐ │ api.kimi.com/coding/v1 │ │ 一个 Bearer 密钥,一份订阅 │ └─────────────────────────────────────────────┘ ``` ## 为什么 DSH 生态里已有搜索聚合器与 OAuth 桥接,缺的是 **Kimi 的厂商原生双接缝集成**。本插件把你已订阅的 Coding 计划直接接入 `web_search` 与 `web_fetch` 两条链路——没有按次计费的搜索账单,没有第二个账号,中间也没有聚合层。 如果你已在用 Kimi Code(CLI),本插件**零配置**:凭据链会自动回退到 `~/.kimi-code/config.toml` 并读取其中的密钥。 ## 工作原理 1. **注册** —— 插件注入 `ctx.web` 并注册两个提供方。安装时 bundle 覆盖层选择 `searchProvider: kimi-coding` 与 `fetchProvider: kimi-coding-fetch`。 2. **凭证解析**(每次操作执行,无需重启)—— 卡片保存值优先,其后依次是凭据服务的次级引用、配置字面量、启动环境变量、Kimi CLI 配置文件: ``` 设置卡片 → KIMI_CODING_API_KEY → KIMI_API_KEY → 配置 apiKey → 启动环境 → ~/.kimi-code/config.toml → ~/.kimi/config.toml ``` 3. **请求组装** —— `text_query` 加服务端 `limit`(钳制在 API 的 1–20 区间)、开关对应的 `enable_page_crawling`、`timeout_seconds`,以及每次调用全新的 `X-Msh-Tool-Call-Id` 关联 id。 4. **加固** —— 仅转发或呈现绝对 http(s) 网址;搜索响应体在缓冲前以 5 MB 为上限;抓取内容以 2 MB 封顶并带 `truncated` 标记。所有失败都以带类型的 `WebError` 呈现(`WEB_PROVIDER_ERROR`、`WEB_PROVIDER_CREDENTIAL_MISSING`、`WEB_ABORTED`),错误消息中保留上游 HTTP 状态码。 `web_fetch` **工具**本身仍由 `dsh-tool-web` 把关(harness 出于 SSRF 考虑默认关闭抓取);本插件只注册提供方与路由,供你启用工具后使用。 ## 快速开始 ```bash dsh plugin --profile web add dsh-web-kimi ``` 然后在 DSH web GUI 打开 **设置 → Web Search (Kimi)**,粘贴你的 Kimi Coding API Key 并保存。密钥进入 DSH 凭据服务(`~/.dsh/.credentials.yaml`)——绝不会写入 `settings.yaml`。 没有 GUI?以下任一方式同样可行: ```bash export KIMI_CODING_API_KEY=sk-... # 启动环境变量 # 或者:经凭据服务保存在 KIMI_CODING_API_KEY / KIMI_API_KEY 名下 # 或者:~/.kimi/config.toml 中 api_key = "..." (Kimi Code CLI 用户——自动读取) ``` 提供方 id `kimi-coding` 刻意与 [quei4r/dsh-host-kimi-search](https://github.com/quei4r/dsh-host-kimi-search) 一致,安装本插件即是对该脚本的**原地替换**,而非 id 冲突。 ## 设置界面卡片 卡片包含三个字段,全部以凭据引用存储: | 字段 | 类型 | 存储引用 | | --- | --- | --- | | API Key | 密码 | `KIMI_CODING_API_KEY` | | 接口地址 | 文本 | `KIMI_SEARCH_BASE_URL` | | 页面抓取 | 选择(`true` / `false`) | `KIMI_SEARCH_PAGE_CRAWLING` | - 掩码输入框、直达 [Kimi 控制台](https://platform.kimi.com/console/account)的「获取 API Key ↗」链接,以及保存后实时刷新的已配置/未配置徽标。 - 字段留空表示保留当前值;重置将清空全部三个引用。 - CLI 配置回退是**只读的**——本插件绝不写 `~/.kimi/config.toml`。 ## 配置 设置分区 `web-kimi`(与卡片写入的同一批字段的文件编辑方式): | 字段 | 默认值 | 含义 | | --- | --- | --- | | `apiKey` | — | 字面量密钥;凭据引用中存储的值优先于它 | | `apiKeyEnv` | `KIMI_CODING_API_KEY` | 主凭据引用 | | `baseURL` | `https://api.kimi.com/coding/v1` | 端点基址(自动追加 `/search`、`/fetch`) | | `pageCrawling` | `false` | 发送 `enable_page_crawling`,使结果携带全文 `content` | | `timeoutSeconds` | `30` | 服务端 `timeout_seconds` | ## 字段映射 | Kimi `/v1/search` 字段 | `WebSearchSource` | | --- | --- | | `url` | `url`(必填;非 http(s) 结果被丢弃) | | `title` | `title`(为空时省略) | | `snippet`,其次 `content` | `snippet`(取第一个非空值) | | `date` | `publishedAt`(为空时省略) | | `site_name`、`icon`、`mime` | 不映射 | `/v1/fetch` 响应以 Markdown 返回,映射为 `WebFetchResult { statusCode, body: { kind: 'text' }, truncated }`——超过 2 MB 的内容被截断并标记。 ## 故障排查 每条失败消息都带 HTTP 状态码,多数问题一眼可断: | 看到的报错 | 含义 | 处理 | | --- | --- | --- | | `url.not_found` | 基址指向没有 `/search` 的服务面——典型是把聊天 API(`https://api.moonshot.cn/v1`)填了进来 | 基址改为 `https://api.kimi.com/coding/v1`;coding 端点需要 coding 凭证 | | `Kimi search error (HTTP 401): …` | 密钥被识别但被拒绝——它不是 Coding 凭证 | 使用 Kimi Coding API Key,而非聊天/开放平台密钥 | | `Kimi search error (HTTP 403): …` | 密钥有效,但计划未含搜索/抓取服务 | 在 coding 计划上开通该服务 | | `… (HTTP 5xx): …` / 非 JSON 响应体 | 上游侧故障 | 重试;状态码说明与你的配置无关 | | `WEB_PROVIDER_CREDENTIAL_MISSING` | 凭据链全程未解析到密钥 | 在设置卡片粘贴,或存于 `KIMI_CODING_API_KEY` / `KIMI_API_KEY` 名下,或导出环境变量,或写入 `~/.kimi/config.toml` | | 结果没有 `content` | 页面抓取关闭 | 打开页面抓取开关 | ## 同类插件对比 | | dsh-web-kimi | dsh-web-search-doubao | dsh-web-search-zai | quei4r/dsh-host-kimi-search | | --- | --- | --- | --- | --- | | 覆盖接缝 | 搜索 + 抓取 | 搜索 | 搜索 | 搜索 | | 凭证 | 一把 coding 计划密钥 | 独立的豆包搜索密钥 | 复用 `ZAI_API_KEY` | coding 密钥链 | | 设置 GUI 卡片 | 有 | 有 | — | — | | CLI 配置回退 | 有 | — | — | 有 | | 带类型的错误分类 | 有 | 有 | 有 | 部分 | | 已上架 npm | 有 | 有 | 有 | — | ## 已知限制 - **权益**:coding 计划账户须包含搜索/抓取服务,否则端点返回 403。 - **`content` 依赖抓取**:不开 `pageCrawling` 时结果正文为空。 - **抓取工具把关**:需在 `dsh-tool-web` 中启用 `web_fetch` 才会路由到本提供方。 - **每个 profile 只有一个 `searchProvider`**:安装本插件会把 profile 的选择从原搜索插件切换过来;移除(或覆盖配置)即可切回。 - **不做 DeepSeek 密钥回退**(与 quei4r 链路的刻意差异):DeepSeek API Key 在 `api.kimi.com` 只会得到 401。 ## 仓库架构 ``` dsh-web-kimi/ ├── package.json # dsh.bundle.patch + dsh.client 清单,导出 ./client ├── tsdown.config.ts # 客户端半构建(ModuleLoader 包装的浏览器 bundle) ├── cordis.patch.yml # searchProvider + fetchProvider 选择与插入条目 ├── src/ │ ├── index.ts # 节点入口:Config、凭据链、apply() │ ├── provider.ts # KimiSearchProvider 与共享的请求头/中止管线 │ ├── fetch-provider.ts # KimiFetchProvider(第二条接缝) │ ├── types.ts # 线路类型 │ ├── invariant.ts # no-op invariant 伴生导出 │ └── client/ │ ├── card.tsx # 可复用的设置卡片工厂 │ └── index.tsx # Kimi 实例化(引用、语言、控制台链接) ├── tests/ # 覆盖搜索、抓取、卡片的 79 个单元测试 └── lib/ # 已提交的构建产物——git 安装无需构建步骤 ``` ## 开发 ```bash pnpm install pnpm typecheck && pnpm build && pnpm test ``` - Node 22.19+ / 24,pnpm 11——与 harness 相同的下限。 - 测试套件针对 mock 的 `fetch` 运行(79 个测试);`tests/kimi.e2e.ts` 的在线冒烟在无 `$KIMI_CODING_API_KEY` 时自动跳过。 - CI 在每次 push 与 PR 上运行完整关卡(typecheck、build、test),矩阵为 Node 22/24 × Ubuntu/Windows。 ## 致谢 多来源凭据链(`KIMI_CODING_API_KEY` → `KIMI_API_KEY` → Kimi CLI 配置)与仅限 http(s)/体积上限的加固思路源自 [quei4r/dsh-host-kimi-search](https://github.com/quei4r/dsh-host-kimi-search)——本插件把这一思路扩展到抓取接缝、设置卡片、测试套件与 npm 发行。卡片架构沿用同级 DSH 搜索插件验证过的 `settings.section`/凭据引用约定。 ## 许可证 [MIT](LICENSE)