dsh-weknora
Tencent/WeKnora把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己带引用的 RAG 或 ReAct agent 回答(含可续聊的 session id)。
DSH 的 RSS/新闻聚合插件:内置渠道库 + awesome-rsshub-routes 精选订阅源目录 + 自定义源(保存时真实抓取校验),每天自动汇总成「今日值得读」Markdown 并注入 systemPrompt;带 Web 设置卡片与侧边栏阅读弹窗。
中文 | English
DSH 的 RSS / 新闻聚合插件:订阅多个 RSS / Atom 源,每天自动汇总一篇「今日值得读」,并把结果注入 systemPrompt 让模型直接引用。
systemPrompt section 注入,模型可直接引用当天条目,问「今天有什么值得读」即得内容。开关(announceToAgent)热生效——保存即出现 / 撤下,不用重启;注入段落按条数收口(最多列前 8 条,按 digest.items 原序、分类标题保留),其余条数在段尾指向当天的 digest 文件,避免每一轮请求都发一份超长列表。「今日值得读」弹窗与设置卡刷新时,会出现与 dsh-docker「切目标过渡」同一套语言的提示:内容区顶部一条 2px 不定长流光进度条,一行蓝色胶囊(⟳ 正在刷新订阅源 · 当前数据生成于 14:29,完整解释在 title);进度条落在分类行下沿、胶囊骑线居中,绝对定位、不推版。只在慢刷新时出现(沿用已有的 180ms 消抖),毫秒级请求不会闪;数据落地时正文 8px 上滑 + 淡入,动效尊重 prefers-reduced-motion。
刷新期间正文仍按原行为压暗(opacity:.55),旧内容继续可读;stale-while-revalidate、骨架屏消抖、刷新后搜索框焦点/光标与列表滚动位置还原全部保留。弹窗的慢加载路径刻意不重渲染整棵树,所以过渡层是「只插两个绝对定位节点」而不是靠重渲染——这条路径漏了注入,浮层就永远不出现。
实现取舍(强调色 token 的坑、为什么必须绝对定位、6 条回归断言)见 ROADMAP § 已完成。
ai-cache.json),重复条目不会重复请求;单条失败(超时 / 非 stop 终止 / 空输出)只回落原文摘要,不影响其它条目,路由缺失时本次生成整体跳过并在 digest 中记录原因;08:00 自动生成当天 digest;插件启动时若当天 digest 不存在也会自动补生成;systemPrompt,模型在用户问“今日值得读”时可以直接引用;~/.dsh/rss-digest/YYYY-MM-DD.md,同时写入 latest.json 便于外部读取。「RSS / 新闻聚合」卡片(内置渠道勾选 + 自定义渠道 + 新闻分类):
设置面在宿主里的位置随 DSH 版本变,但始终是同一份表单:0.2.0-rc.1 起挂 plugins.bundle.config——插件详情页「说明」正下方内联,不必再点「>」进二级页;旧宿主 (0.1.6 线)自动回退到侧边栏「插件」页里该行的「>」子页。
侧边栏「今日值得读」弹窗(按分类分组、来源带「查看更多」直达官网、底部可手动刷新):
向模型询问当天新闻时,直接引用当天 digest(无需打开弹窗):
在 DSH 的插件配置中传入 Config:
{
sources: [
{ name: '阮一峰的网络日志', url: 'https://www.ruanyifeng.com/blog/atom.xml', category: '技术' },
{ name: '少数派', url: 'https://sspai.com/feed', category: '效率' },
],
maxItemsPerSource: 5,
maxTotalItems: 30,
dailyTime: '08:00',
digestDir: '~/.dsh/rss-digest',
}不传sources时默认启用全部内置渠道;传入sources则以内置渠道全部关闭、只使用该列表。
常用配置项:
字段 · 说明 · 默认 enabled · 是否启用插件 · true announceToAgent · 是否把 digest 注入 systemPrompt(热生效:保存即出现 / 撤下,不用重启) · true includeCatalog · 是否提供订阅源目录(/api/dsh-rss/catalog) · true sources · 自定义订阅源列表;传入后替代全部内置渠道 · 内置 7 个渠道 maxItemsPerSource · 每个源最多取多少条 · 5 maxTotalItems · 每天最多汇总多少条 · 30 dailyTime · 每天自动生成时间(HH:mm) · 08:00 autoGenerateOnMount · 启动时若当天 digest 不存在是否自动生成 · true digestDir · 输出目录 · ~/.dsh/rss-digest requestTimeoutMs · 单次请求超时 · 10000
AI 摘要默认关闭,配置只走可编辑 store ~/.dsh/rss.json 的 ai 字段(设置卡片「AI 摘要」区块可改,不新增 Config 字段):
{
"ai": {
"enabled": true,
"provider": "deepseek",
"model": "deepseek-chat",
"maxItems": 20,
"concurrency": 3,
"timeoutMs": 20000
}
}字段 · 说明 · 默认 enabled · 是否启用 AI 摘要 · false provider / model · 模型路由,必须成对填写;都留空则跟随宿主默认模型(agentDefaultModel / settings 的 agent-default-model;都取不到则本次生成跳过 AI 摘要) · 留空 maxItems · 单次 digest 最多摘要条数(列表前 N 条),夹紧 1..50 · 20 concurrency · 并发请求数,夹紧 1..6 · 3 timeoutMs · 单条请求超时毫秒数,夹紧 5000..60000 · 20000
只填 provider / model 之一时整段 ai 配置会被忽略并在保存响应里给出告警。
两个容易踩的点(都是真机上实测出来的):
共享这个上限,太小会让模型还没写出正文就把预算耗在推理上,finish 变成 max-tokens、 该条摘要判失败。实测(commandcode/deepseek/deepseek-v4.1-flash,20 条):200 → 7 条成功、 1024 → 12 条、4096 → 20 条全成功(整轮 48s,单条约 7s,仍在 timeoutMs 内)。换更重的 推理模型若再撞上限,失败原因里会直接写出当前 maxTokens 值。
aiSummary.failures 给出原因分布(最多 3 类,含次数),Markdown 的「抓取失败」小节也会写上去(例:原因:终止原因 max-tokens(…)×8)。 早先只有一句「N 条失败」,既分不清超时 / 限流 / provider 报错,也无从判断是不是插件的问题。摘要结果写入 digest 目录的 ai-cache.json({ version: 1, entries: { : { text, model, at } } }),命中且未过期(30 天)直接复用;超出 500 条按写入时间淘汰最旧。
pnpm --filter @hyzyn/dsh-rss build
pnpm --filter @hyzyn/dsh-rss typecheckdsh plugin --profile web add link:$(pwd)或从仓库根目录:
dsh plugin --profile web add link:$(pwd)/packages/rss文件 · 说明 package.json · dsh.bundle.patch 指向 cordis.patch.yml;main / exports["."] 指向 lib/index.js cordis.patch.yml · bundle 补丁:insert: { id: rss-digest, name: '@hyzyn/dsh-rss' } 把本插件行插入 profile 阵容 src/index.ts · 插件宿主半体:RSS/Atom 解析、抓取、digest 生成、AI 摘要、定时调度、HTTP API、systemPrompt 注入 client.js · 浏览器半体:「RSS / 新闻聚合」卡片 test/ai-summary.test.ts · AI 摘要的回归测试(消息构造 / 清洗、缓存 TTL·LRU、路由解析、store 白名单、渲染、LLM 终止分支、生成降级路径) tsconfig.json · 继承根 tsconfig.base.json,tsc 产出 lib/