← 返回列表
需源码安装
聚合七源 AI 资讯,卡片内一键生成中文总结
暂不能直接安装(需源码编译或环境不满足):仓库 package.json 标记 private,未发布到 npm,需从源码安装。 · 最近上游提交 2026/9/15 · 已提供中文文档
DeepSeek Harness AI 新闻插件:多源聚合(HN/ArXiv/官方博客/中文媒体)+ 侧边栏大弹窗新闻流 + 面板内 LLM 总结
综合分
30.7
GitHub 分
30.7
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add KeynoWu/dsh-ai-news仓库 package.json 标记 private,未发布到 npm,需从源码安装,改用 GitHub 源安装
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查需源码安装
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-ai-news @ 1.0.1
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
仓库 package.json 标记 private,未发布到 npm,需从源码安装
验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/19 10:25:40
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools@deepseek-ai/schemastery@deepseek-ai/dsh-typert-protocol@deepseek-ai/dsh-api-remotes@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-ui-renderer@deepseek-ai/dsh-client-ui-layout@deepseek-ai/dsh-client-ui-sidebar@deepseek-ai/dsh-client-ui-slots用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-ai-news
DeepSeek Harness AI 新闻插件:多源聚合最新 AI 动态(国际媒体 / 中文媒体 / 论文),侧栏图标打开全局面板新闻流(2-3 列自适应),每条新闻支持卡片内一键 LLM 总结。
能力
| 能力 | 说明 |
|---|---|
| 多源聚合 | Hacker News(AI 过滤)、ArXiv(cs.AI 论文)、OpenAI Blog、Google AI Blog、The Verge AI、量子位、InfoQ 中文,共 7 个默认源(全部可在 Config 增删) |
| 分类筛选 | 全部 / 国际 / 中文 / 论文 四个 tab,切换即按来源类型过滤(maxDays 窗口内) |
| 时间窗口 | 只显示最近 N 天新闻(Config.maxDays,默认 3;缓存保留全量,仅显示层过滤) |
| 排序规则 | 发布时间降序(最新在前);时间戳缺失的条目沉底(源未提供时间时用抓取时刻兜底并标记 timeFallback) |
| 全局面板入口 | 侧栏图标行(sidebar.panellist,v0.3.0 起)→ 中央全局面板(main 的 ai-news key);按钮、tooltip、选中态都由外壳拥有,面板内 × 调 ctx.layout.selectPanel(null) 把中央区域还给对话 |
| 自适应网格 | 新闻流 2-3 列自适应(auto-fill minmax(320px, 1fr)):窄窗 2 列、宽窗 3 列 |
| 面板内总结 | 每条新闻的「总结 ✦」→ 后台抓正文 + 调默认模型生成中文要点总结(3-5 条 + 原文链接),卡片内展开显示;不进对话、不唤醒 agent,结果按条目缓存(重复查看零成本) |
| 文本清洗 | 所有摘要/总结展示前经解码→去 HTML 标签→压缩空白,杜绝 等源码泄漏 |
| ai_news 工具 | 模型可直接调用 ai_news(refresh / limit / kind 参数)拉取新闻,Markdown 渲染 |
| 事件 | 抓取完成 ctx.emit('ai-news/updated')(当前为手动刷新模式,事件为后续自动推送预留) |
架构
┌─────────── node half(Host 侧,strip-types 直载)───────────┐
│ src/index.ts 插件入口:Config + apply + ai_news 工具 │
│ src/engine.ts NewsEngine:内存缓存 + id 去重 + 并发刷新 │
│ src/fetchers.ts 多源抓取:RSS(轻量 XML 解析)/HN/ArXiv │
│ src/extract.ts 文章正文提取(抓 HTML → 去噪 → 段落文本) │
│ lib/gateway.js NewsGateway(预编译,@Remote 装饰器) │
│ aiNews.list / refresh / summarize → /api/aiNews/* │
│ summarize:正文 → ctx.llm.stream(默认模型)→ 要点总结 │
└──────────────────────────────────────────────────────────────┘
┌─────────── browser half(client 插件,esbuild bundle)───────┐
│ src/client/index.tsx 全局面板 main + 侧栏图标 + 2-3 列网格 │
│ (lib/client.js 由 scripts/build-client.mjs 构建) │
└──────────────────────────────────────────────────────────────┘
为什么 Gateway 要预编译?
@Remote 是标准装饰器(addInitializer),Node 的 strip-types 不支持装饰器语法。
沿用 dsh-omp-tools 同款方案:scripts/build-gateway.mjs 用 esbuild 把 src/gateway.ts
转译为 lib/gateway.js(@deepseek-ai/ external),src/index.ts 运行时 import 构建产物。
模块实例一致性(关键!)
Host 的 dsh-api-gateway 通过同一模块实例的私有 markers WeakMap 发现 @Remote 方法。
因此本插件的 node_modules/@deepseek-ai 必须解析到 dsh 安装树的 @deepseek-ai
(/…/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai),与 api-gateway 保持一致;
否则装饰器标记互相不可见,remote 端点 404。@deepseek-ai/dsh-client-ui-slots 仅 tsc 需要,
通过 tsconfig paths 指向 omp-tools 的副本(dsh 树没有此包)。
总结链路
点击「总结 ✦」 → /api/aiNews/summarize {itemId}
→ engine.get(itemId) → 命中缓存? 直接返回
→ fetchArticleText(url) 抓正文(≤8000 字符)
→ ctx.agentDefaultModel.currentSelection() 取默认模型(provider/model)
→ ctx.llm.stream({provider, model, messages, temperature:0.3, maxTokens:800})
→ 聚合 text-delta → 中文要点总结 → 写入缓存 → 返回
client 面板内展开显示;按钮变「总结 ✓」;再点直接读缓存
开发
0) 依赖(symlink 复用 dsh 安装树 + omp-tools 工具链)
node_modules/@deepseek-ai -> dsh 安装树(模块实例一致性,见上文)
esbuild/typescript/react/zod 等 -> dsh-omp-tools/node_modules(工具链)
1) 构建(Gateway 装饰器转译 + client bundle)
npm run build # = build:gateway + build:client
2) 类型检查 + 模块表门禁
npm run typecheck
npm run check:client # bundle 的 require 列表必须 ⊆ 外壳基座表 ∪ dsh.client.external
(build:client 末尾也会自动跑;漂移 = 浏览器 boot 失败,见下)
3) 起隔离验证实例(插件已在 profile cordis.patch.yml,无需 --patch)
dsh web --port 3100 --no-open
4) 浏览器验证(headless Chrome + CDP)
起 headless Chrome: Google Chrome --headless=new --window-size=1600,1000 \
--remote-debugging-port=9222 about:blank
用 CDP 脚本断言:侧栏图标 → 全局面板 → 分类 tab → 列表 → 面板内总结
(验证脚本为开发期工具,不入库;本机保留在 scratch 目录即可)
dsh 版本要求
| 插件版本 | dsh 版本 | 说明 |
|---|---|---|
| v0.3.0 | ≥ 0.1.5-rc.1 | 自绘大弹窗换成官方全局面板(main + sidebar.panellist);面板 API 随 rc.1 落地 |
| v0.2.0 | ≥ 0.1.5 | 按 0.1.5 的浏览器模块表契约重写 client 侧 |
| v0.1.0 | 0.1.0-rc.x | 依赖已删除的 @deepseek-ai/dsh-client-runtime,在 0.1.5 上会让整站 boot 失败 |
0.1.5 起插件 bundle 运行期只认外壳播种的模块表(react、react/jsx-runtime、react-dom、
react-dom/client、@deepseek-ai/cordis、dsh-client-store、dsh-client-ui-slots、
dsh-client-ui-primitives、dsh-client-ui-dockkit)+ dsh.client.external 声明的精确请求名,
dsh.client.inject 只是说明性列表、不再注入模块。所以 src/client/index.tsx 里平台各包的 /client
面一律写成 import type(只要 cordis Context 类型增强,不产生 require);本插件运行时真正请求的只有
react 与 react/jsx-runtime。dsh-client-runtime 删除后的去向:ctx.slots →
dsh-client-ui-renderer/client,ctx.remote → dsh-api-remotes/client。
v0.3.0:大弹窗 → 官方全局面板
0.1.5-rc.1 起 Web 端把右侧/中央面板开放给插件:中央区域的「页」是 main 这个 keyed slot
(保留 key conversation,其余 key 由注册者自取),侧栏那一列图标是 sidebar.panellist
这个 list slot。本插件因此删掉了自绘的 position: fixed 遮罩弹窗,改成两条注册:
tsx
ctx.slots.inject('main', () => ctx.slots.register(
{ name: 'main', key: PANEL_ID, locale: NS },
(props) => ctx.layout.selectPanel(null)} />,
))
ctx.slots.inject('sidebar.panellist', () => ctx.slots.register(
{ name: 'sidebar.panellist', id: PANEL_ID, order: 40, label: () => t('panelLabel') },
NewsGlyph,
))
踩过的四个点,写给下一个改这里的人:
1. 两条注册共用一个 id。main 的 key 与 sidebar.panellist 的 id 必须是同一字符串:
侧栏图标行就是拿这个 id 去 ctx.layout.selectPanel(id) 的,对不上就是「图标点了没面板」。
2. 图标只会被喂 { size, active }。按钮、tooltip、选中态、点击全归 sidebar(PanelRow),
occupant 只要按 size 画字形、配色跟 currentColor——自己再套一层 会双重按钮。
3. selectPanel(id) 不是 toggle。点已经选中的图标只是重新选中,不会回对话;
所以面板头部保留一个 ×,显式 selectPanel(null) 把中央区域还给 Conversation。
4. MainPanelId 是品牌字符串,别去 import brandString()。@deepseek-ai/dsh-brand 的
brandString 是运行时值,一旦值 import 就产出 require("@deepseek-ai/dsh-brand")——
它不在外壳播种的模块表里,boot 会整站失败(就是 v0.1.0 那次的死法)。这里用 'ai-news' as MainPanelId。
顺带把原先本地复述 SlotMap['sidebar.footer.action'] 的 declare module 删了:现在类型直接从
官方包取(dsh-client-ui-layout/client 给 Context.layout + main,dsh-client-ui-sidebar/client
给 sidebar.panellist),契约一变 tsc 会当场拦住,而不是等运行时错配。
使用(正式接入)
~/.dsh/profiles/web/cordis.patch.yml:
yaml
- insert:
- id: dsh-ai-news
name: dsh-ai-news
config:
fetchTimeoutMs: 15000
maxItems: 50
maxDays: 3 # 只显示最近 N 天(0 = 不限)
可选配置(覆盖默认源 / 抓取参数):
yaml
config:
sources:
- id: my-rss
name: 我的源
kind: international
type: rss
url: https://example.com/feed.xml
已知限制
- 缓存为进程内内存:新闻与总结缓存随插件卸载 / dsh web 重启清空(重启后首次打开会自动重新抓取)。
- 手动刷新按钮:页面内保留「刷新」按钮可随时重新抓取;尚未做后台定时自动拉取(ai-news/updated 事件已预留,后续可加 timer)。
- 总结走默认模型:用 ctx.agentDefaultModel 的当前选择(默认 deepseek-v4-flash),每篇首次总结消耗一次模型调用。
- 正文提取为启发式:抓 HTML 提取段落,部分站点(JS 渲染、反爬)可能拿不到正文,总结会报"无法获取文章内容"。同作者(KeynoWu)的其他插件
扫码进群