omp packages

@someok/pi-deepseek-web-tools0.3.0

pi 扩展:DeepSeek 网页搜索(ds_search)与网页抓取(ds_fetch),GitHub 链接自动 clone 仓库并渲染 PR/Issue

someokpub Published 5 hours ago MIT ~382 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-deepseek-web-tools

简体中文 | English


给 pi 加两个工具:ds_search(DeepSeek 网页搜索)和 ds_fetch(网页抓取)。普通网页走 DeepSeek 官方 Search / Fetch API;GitHub 链接自动改走本地 git / gh,仓库直接克隆到本地让模型翻源码,PR/Issue 渲染成结构化文档。

配置齐全时两个工具都可用;没配 DeepSeek key 时 ds_search 和普通网页抓取不可用,但 ds_fetch 的 GitHub 部分照常工作。

安装

# 从 npm 安装(推荐),之后每次启动都加载
pi install npm:@someok/pi-deepseek-web-tools

# 只试一次,不写设置
pi -e npm:@someok/pi-deepseek-web-tools

# 开发时从本地目录加载
pi -e ./

之前用 pi install ./ 装过本地路径的,先用 pi list 找到那一条并 pi remove <本地路径>,再装 npm 包。两个入口同时存在会重复加载同一个扩展,工具名冲突会直接报错。

配置

两个配置文件结构相同,项目级优先:

层级 路径
项目级 <项目>/.pi/deepseek-web-tools.json
用户级 ~/.pi/agent/deepseek-web-tools.json($PI_CODING_AGENT_DIR 覆盖时按该目录)
环境变量 DEEPSEEK_API_KEY

项目级配置只在项目已受信任时读取,和 pi 处理 .pi/ 的规则一致。

完整示例(也见仓库里的 deepseek-web-tools.example.json):

{
  "enabled": true,
  "apiKey": "sk-...",
  "baseUrl": "https://api.deepseek.com",
  "exposure": {
    "search": "codemode",
    "fetch": "direct"
  },
  "search": {
    "timeoutMs": 30000,
    "count": 10,
    "needContent": false
  },
  "fetch": {
    "timeoutMs": 90000
  },
  "github": {
    "enabled": true,
    "prIssue": true,
    "maxRepoSizeMB": 350,
    "cloneTimeoutSeconds": 30,
    "clonePath": "~/pi-github-repos"
  }
}

合并规则:逐字段取「项目级 → 用户级 → 默认值」;apiKey 再回退到 DEEPSEEK_API_KEY。

字段 默认 说明
enabled 有 apiKey 即启用 false 强制关闭,即使环境变量有 key
apiKey 无 空白字符串视为没写
baseUrl https://api.deepseek.com 尾部斜杠会被去掉
exposure { "search": "codemode", "fetch": "direct" } 按工具分别配:codemode 隐藏声明、只能从脚本调用,direct 直接声明给模型。写字符串("direct" / "codemode")表示两个工具都用这个值
search.timeoutMs 30000 1000~300000
search.count 不发送(API 默认 10) 1~50
search.needContent false 是否在搜索结果里带网页正文
fetch.timeoutMs 90000 1000~300000
github.enabled true 关掉后 ds_fetch 不再走 GitHub 专用路径
github.prIssue true 是否用 gh 把 PR/Issue 渲染成结构化文档
github.maxRepoSizeMB 350 超过这个体积改用 GitHub API 轻量视图,不克隆
github.cloneTimeoutSeconds 30 1~600,超时后连 git 子进程一起杀掉
github.clonePath 系统临时目录下 pi-github-repos 支持 ~ 和 $HOME 这类写法

配置写错(坏 JSON、字段类型不对、拼错键名)不会让扩展崩掉:出问题的字段被忽略并记一条告警,启动时和 /ds-tool-config 里能看到。改完配置执行 /reload 生效。

工具

ds_search

参数 必填 说明
query 是 1~128 字符,支持 site:、-site:、"短语"、lang:、after:、before:
count 否 1~50,不传时用 search.count
needContent 否 是否返回正文,默认用 search.needContent

返回带编号的结果列表(标题 / URL / 站点与发布时间 / 摘要)。结果超过 2000 行或 50KB 时会截断,完整 JSON 落到临时文件,路径写在结尾。

ds_fetch

参数 必填 说明
url 是 必须是带 host 的 HTTP/HTTPS 地址,不带用户名密码,长度 ≤8192

返回页面标题加 Markdown 正文。正文同样按 2000 行 / 50KB 截断,完整内容落临时文件。

遇到 github.com 链接会自动改走专用路径,详见下一节。

GitHub 链接

ds_fetch 拿到 github.com 的 URL 时不再走 DeepSeek,而是按 URL 类型分派:

URL 处理方式
github.com/owner/repo 克隆到本地,返回目录树 + README + 本地路径
.../tree/main/src 返回该目录的文件列表(带大小)
.../blob/main/src/index.ts 返回文件内容;二进制文件只说明类型和大小
.../pull/123、.../issues/7 用 gh 取数,渲染成一份带状态、分支、CI、review、文件、commits、评论的文档
超过 maxRepoSizeMB 的仓库 自动改用 GitHub API 的轻量视图(tree + README)
.../commit/<sha> 直接走 API,不为看一个提交克隆整个仓库

克隆只拉一个分支的一层历史(--depth 1 --single-branch),同一个仓库重复抓取会复用本地目录。

依赖:git 必需;gh 可选,但装了才有完整的 PR/Issue 视图和私有仓库访问,没有 gh 时 PR/Issue 会回落到普通网页抓取。GitHub 这条路不消耗 DeepSeek 额度。

界面上的显示

  • 工具行默认折叠,只显示结果条数或字符数;展开后显示工具返回的全部文本,不再按行数二次截断。
  • /ds-search、/ds-fetch 的结果同样默认折叠,展开方式:Ctrl+O 或鼠标点击;抓取结果按 Markdown 渲染(标题、列表、代码块、链接)。
  • DeepSeek 的 Fetch 接口会把正文里的标点全转义(\#、\-、\,、\/),插件进来时先统一去转义,再渲染和给模型,所以界面上看不到反斜杠。Markdown 渲染关掉了 LaTeX 解析,(a 100K context is enough) 这类括号不会当成公式。
  • 唯一的上限是 2000 行 / 50KB(pi 对模型可见内容的约定):超过时正文末尾会写一行 [输出已截断:… 完整内容:/tmp/…],需要全文时让模型 read 那个临时文件。

命令

命令 作用
/ds-search <搜索词> 手动跑一次搜索
/ds-fetch <网址> 手动抓一个网页,支持 /ds-fetch <https://...> 这种粘贴形式
/ds-tool-config 查看当前生效的配置:启用状态、key 来源(脱敏)、超时、两个配置文件是否读到

只注册 ds- 前缀的命令,不用 /search、/fetch 这种裸名:/search 已被别的扩展(如 pi-web-access)占用,pi 会给重名命令加 :1、:2 后缀,自己都不知道会拿到哪个。

命令结果写成 custom entry:只在界面上展示,不进模型上下文,模型看不到你手动抓的内容。它们会存进当前会话,恢复会话后仍能翻看。

错误提示

状态码 含义 提示
400 参数不合法 检查 query 长度、count 范围、URL 格式
401 key 缺失或无效 检查配置文件或 DEEPSEEK_API_KEY
402 余额不足 先充值
403 Fetch 被安全策略拒绝 换站点或跳过
404 Search 路径不存在 / Fetch 拿不到正文 检查 baseUrl;或目标页不可抓
408 / 504 超时 稍后重试
413 请求体过大 URL 过长
429 触发 QPS 限制 稍后重试
5xx 服务端错误 稍后重试

超时由 search.timeoutMs / fetch.timeoutMs 控制,按本地计时中断请求。命令失败会弹 error 提示;工具调用失败表现为失败的工具结果。

限额与计费

  • Search 与 Fetch 各自限速 5 QPS(账号级),Fetch 另有目标域名级限制。
  • 按成功请求计费:每 1000 次 5 元;Search 无结果、Fetch 没拿到正文、请求失败都不计费。
  • DeepSeek 说明:第三方工具直接调用 Search / Fetch 会从 2026-11-01 起按次计费。

开发

npm install
npm run check   # tsc --noEmit + vitest
  • 运行时不依赖任何 npm 包:普通网页用 Node 内置 fetch,GitHub 用内置 child_process 调 git / gh。
  • 测试全部走注入的 fetchImpl 或纯函数,不联网。
  • src/config.ts 是纯函数,方便单独测配置合并。

发布到 npm

npm login
npm version patch   # 可选:打版本、提交、打 tag
npm publish         # 或在 VS Code 的 NPM Scripts 面板里点 release(就是这条)
  • 脚本名用 release 而不是 publish:npm 把 publish 当成发布后的生命周期钩子,"publish": "npm publish" 会发一次再被钩子发一次,第二次因版本已存在而报错。
  • prepublishOnly 会先跑 npm run check,typecheck 或测试挂了就不发。
  • 演练用 npm run release -- --dry-run,不会真的上传。
  • publishConfig.access 已是 public(scoped 包不显式声明会默认私有,发布失败)。
  • 先 npm pack --dry-run 看打包内容:当前 14 个文件,只含 src/、中英文 README、LICENSE、示例配置,不含测试和计划文档。

安全

apiKey 只出现在发给 DeepSeek 的请求头里,不会写进工具输出、details、structuredContent 或日志。/ds-tool-config 只显示掩码(如 sk-****abcd)。项目级配置含 key 时建议加入 .gitignore(本仓库已忽略 .pi/deepseek-web-tools.json)。