DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

544244857 /

544244857/dsh-work-assistant

Verified

DSH 工作助理插件:微信机器人通道、SQLite 工作账本、知识库与人员关系图谱、定时提醒、任务委派

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@82f85cef

dsh-work-assistant

DSH 的工作助理插件:自带一条微信机器人通道,把你转发过来的消息记成工作项,给建议、能代做的主动请缨,到点提醒还没做完的事。

不依赖任何第三方 IM 插件,通道、账本、知识库、提醒都在这个包里。

想看这个插件到底解决什么问题、长什么样,先读 INTRO.md。这份 README 讲的是怎么装、怎么配、接口长什么样。

先讲清楚一条边界

微信官方机器人只能私聊,读不到群聊,也没有"@我"这种事件。

所以这个插件的做法是:你在群里被 @ 了,自己把那条消息转发给机器人。它记账、分析、提醒。

这不是偷懒。个人微信没有对外开放的群消息接口,逆向客户端违反腾讯服务条款、有封号风险,所以这里不做。企业微信的智能机器人可以收群 @ 消息,那是另一条路,需要的话可以另做渠道。

装

已经发到 npm,从网上装(推荐,装的是预构建产物,不需要本地编译):

dsh plugin --profile <你的 profile> add dsh-work-assistant

从源码改着玩就装本地目录:

dsh plugin --profile <你的 profile> add -w link:<这个目录的绝对路径>

也可以直接从 GitHub Release 的 tarball 装:

dsh plugin --profile <你的 profile> add https://github.com/544244857/dsh-work-assistant/releases/download/v0.5.3/dsh-work-assistant-0.5.3.tgz

装完重启宿主。插件会自己创建数据目录,默认在 ~/.dsh/dsh-work-assistant/。

仓库在 544244857/dsh-work-assistant,npm 包名 dsh-work-assistant。

登录和设置

重启宿主后,打开 DSH 的设置,左边会多出一项「工作助理」。这个页面里什么都有:

  • 登录状态、扫码二维码(没登录时才显示)
  • 账本概览:未完成几件、逾期几件、进行中几件、能代做几件,还有前 10 条工作项
  • 每日摘要时间和提醒检查间隔,改完点保存,立刻生效
  • 「立刻发一条摘要」按钮,用来验证通道通不通
  • 对话记录:跟你聊过的每一天都留在这儿,点一天看当天的往来
  • 会话设置:助手用哪个预设、哪个模型、推理强度多高、什么权限档位,四组下拉直接选,保存后下一条消息就按新的来

二维码本身是 qrcode 包在宿主进程里渲染成 dataURL 的,不联网,不上传。

如果设置页因为某种原因没出来(比如宿主版本差异),也可以直接开这个地址:

http://127.0.0.1:<你的 DSH 端口>/api/dsh-workassistant/login

这是同一个功能的纯网页版,扫码、看状态、换码都在里面。

用手机微信扫码,把机器人加成好友,就好了。凭据只存在本机,不上传。

登录之后,你给这个机器人发消息就等于跟工作助理说话;它的回复会直接推回微信。

它能做什么

记账

收到消息先判断里面有没有"需要被完成的事"。有就记下来,没有就不记。一件事记不住就拆成几条。

记的时候会顺手判断:期限是什么时候、优先级多高、打什么标签、这件事是不是它能直接代做。

记完一定会给回执,形如:

记下了 w-20261020-006:催广超开发票
期限 10/24 18:00,优先级 高
按紧急度排第 1 位(越靠前越该先做)
现在手上共 6 件未完成

看到这段就说明真的写进账本了。同一件事被反复说(你重发、它重试)不会记成多条——标题或内容重合会认出来,只把新信息补进去,回执改说"已经记过了"。

自动排优先级

不用你操心优先级。每条工作项都会算一个紧急度分数,影响排序和摘要顺序:

因素 影响
已逾期 分数最高,一直顶在最前
期限越近 24 小时内最高,一周内次之,之后递减
高优先级措辞 标题或正文出现"催""尽快""马上""今天""急"等,算高
正在做 比同等条件下还没动的稍微靠前

分数只在排序时用,不会覆盖你手动设的优先级。如果你想强按某件的顺序,说一句"这件最高优先级"它就会显式标成 high。

主动请缨

遇到查资料、改表格、整理文件、写文档、核对数据这类它手上能干的活,它会主动问一句"这个我可以直接做,要我做吗"。你说"做吧"或者"做第 3 件",它就去干。

干完会汇报结果,并把过程要点存进知识库。

提醒

  • 单条到期提醒:给某件事设了提醒时间,到点推一条。创建时如果只填了期限没填提醒时间,默认提前一小时。
  • 每日摘要:默认 09:00 和 18:30 各推一次,列出逾期、今天到期、本周内要交的。手上没活就不推。
  • 安静时段:默认 22:00 到 08:00 一条都不推。落在这段时间里的提醒不会丢,也不会被标成已发,等时段结束一起补给你。
  • 每周复盘:默认周五 18:00 推一次,说这一周做完了哪些、还欠着哪些。设成"关掉"就不推。

提醒是模板直发,不烧 token。所有"今天是否已经推过"的状态都落盘,重启不会重复轰炸。

重复的事

「每月五号交报表」这种可以直接记成重复任务。做完一件会自动滚出下一件,不用每个月重新说一遍。

让人去办

「等广超给发票」这类不是自己动手的事,可以记成「等某人」并约好什么时候去问一句。到点提醒你"该问问广超了",而不是提醒你去做那件你本来也做不了的事。

具体行为:

  • 说了「下周问他」「周五再催」→ 按那个时间提醒。
  • 没说 → 默认记下来那天往后 3 天。回执里会给确切时刻,不用猜。
  • 到点推一条「该去问一句了:等广超给发票,等 广超」。催过就把下一次往后推 3 天,不会反复轰炸。
  • 第二次起措辞变成「还没回音:…」,提醒你这事还悬着。
  • 标成已完成或放弃后就不再催。
  • 推送失败不动时间,下一轮接着试,不会静默漏掉。

副手:把活儿派出去

有些活儿不是一两句话能办完的——要把三个月的报销单理成一张表、要把一份合同逐条比对模板、要翻一堆资料查清楚某件事。这种活儿交给微信那头等着不合适,你在那儿干等,它也不一定一次干得完。

现在可以派出去。派出去之后它在一个独立的会话里干,你继续在微信里跟助理说话,两边不耽误。干完它会回来汇报,报告直接推到微信。

用法就是在微信里说一句"这个你派个人去做",助理会调 assign_create 开一个副手。也可以自己在整页视图的「副手」卡片里点「派一个」,写清楚要什么结果。

几个细节:

  • 副手是独立的会话,会出现在 GUI 的会话列表里。这是故意的,不是 bug——你想看它到底在干什么,可以直接点进去看它的完整过程,或者点卡片上的「去看」跳过去。
  • 默认最多同时开 3 个。开满了再派会直接失败并告诉你哪几个还占着,不会排队、不会假装派出去了。要改上限改 maxAssignments(1 到 32)。
  • 助手随时能跟它说话。派完想起来还有要求,用 assign_send 补一句;默认算"新的一轮",它会接着干。也能用 assign_inspect 看它最近几步干了什么,assign_stop 停掉。
  • 它交的报告可能是在问你。报告可以标"等你回话",这时候卡片上会亮黄,微信那头也会提示。名额开满时它还是会交报告,只是状态不会切到"等回话"——话照样送到你手上,回执里会说清这一点。
  • 宿主重启后副手会标成"掉线"。下次给它发消息时会自动把会话恢复起来;真找不回来了(比如会话被删了)就如实报错,不会假装还活着。
  • 副手可以绑一个工作区(assignmentCwd)、用别的模型(assignmentModel)、换预设(assignmentPreset)。默认跟助手一样。

一句话总结:助理是那个记事和派活的,副手是那个埋头干活的。

附件

微信里发来的图片、文件、语音会自动收进账本,挂在对应的工作项上。设置页能看到挂了哪些附件,助手也能读图说话。

知识库

客户是谁、同事负责什么、某件事的来龙去脉,都可以存进知识库,以后按关键词搜。

认识的人(知识图谱)

聊天、工作项、知识库里出现过的人名,会被定期整理成一张关系表:谁是你的同事、谁是下属、谁是客户、谁在替谁办事。

举个例子:知识库里那篇"值班表排法"写着"值班共 5 人轮转——舒子淇、彭喻、肖航、余鹏、曹曼",跑一次分析之后,这五个人就进了名单,并带上"同事"或"下属"这种关系判断,而不是当成五个陌生字符串。

整理是模型做的,节奏有两条:

  1. 每天一次,默认凌晨 3 点(analysisDailyTime)。
  2. 闲时一次:只要新消息攒着、而且最后一条已经过了 analysisIdleMinutes 分钟没人说话,就顺手跑一遍。

整页视图里有"认识的人"卡片,点名字能看这个人的关系卡;微信里也可以直接问"你认识哪些人""舒子淇是谁"。

关系是模型根据上下文猜的,不确定的会标低把握度——它认错的时候你直接说"舒子淇不是我下属,是同事",它会改。

看现有任务

五个地方都能看,看到的是同一份账本、同一个紧急度顺序:

  1. 侧边栏的整页面板(左边一排图标里那个勾选框)。这是主入口:六个数字、四张图、能直接改的任务清单、知识库全在里面。往下看"整页视图"。
  2. 微信里问一句"现在有哪些活""哪几件最急"。它会调 work_list 把条目念出来,不是只说个数。
  3. 设置页的任务清单卡片(DSH 设置 → 工作助理)。能切"未完成 / 已完成 / 全部",能按关键词和标签搜,每条右边有"标完成"按钮。
  4. 设置页的知识库卡片,能搜、能翻全文。
  5. 每日摘要,按逾期、今天到期、本周内分节列。

整页视图

侧边栏点进去是一整页,不用挤在设置面板那一小块里。里面分四段:

上面六个数字:未完成、已逾期、进行中、本周做完、本周新记、压了一周还没动。逾期那个只要不是 0 就变红。

四张图,都是拿 SVG 和 div 现画的(宿主没给插件图表库,也不该为这个塞一个进去):

  • 优先级分布:一圈环形图,按高 / 普通 / 低切片。
  • 近 14 天趋势:两条折线,一条是新建、一条是做完。能看出这周是在往里堆还是在往外清。
  • 标签排行:横条,哪个标签的事最多。
  • 等谁排行:横条,谁欠你的事最多。
  • 最老的几件:横条长度是压了多少天,颜色是优先级。压过 30 天就顶格。

任务清单:四个筛选页签(未完成 / 进行中 / 已完成 / 全部)+ 关键词搜索。点任意一条展开,能就地改标题、优先级、期限、标签,改完点保存。也能一键标完成 / 重新打开。不用回微信说,也不用跳去设置页。

知识库和运行参数:左边能搜能翻全文,右边只读显示数据目录、预设、权限档位——这些要改还是去设置页或者 cordis.patch.yml。

右上角有"刷新"和"回到对话"两个按钮。页面每 15 秒自己拉一次数据,切页签、改完东西也会立刻刷。

回看以前的对话

每一条进来的微信、每一条回出去的答复,都会按「谁 + 哪一天」存一份。三处能看:

  1. 侧边栏的「对话」页签(和「任务」「频道」并排)。这一页只做一件事:列会话。一行一个——左边小圆点是在不在跑(蓝的在干活、黄的在等你回话、灰的歇着),中间是会话名,右边是「多久以前」。点一行不是在这里展开,而是把那个会话直接开到右边主区去:思考过程、工具调用、接着打字,全跟平时用会话一样。做法和「频道」页签一致——侧栏负责挑,主区负责聊,同一条会话只有一个界面,不会两边不同步。
  2. 整页面板上的「对话记录」卡片:一行是一天(日期、当天几条、最后一句的开头几个字),点开看全文,左上角「返回」回到列表。想按天翻旧账就来这里。
  3. 设置页里的同一张卡片,列表短一些,适合顺手翻一翻。

关于这个侧栏页签:宿主本身只声明了 sidebar.panellist / sidebar.workspaces / sidebar.settings / sidebar.footer.action 这四个侧栏座位,没有 sidebar.channels。你截图里那个「频道」页签是 im 助理插件自己包了 sidebar.workspaces、再往它私有的 __dshNativeTabs 页签表里插了一条造出来的。我们没有第二套侧栏可用,所以这里的做法是:等 im 助理把页签表挂好,再往同一张表里插一条自己的(id 是 work-assistant-chats,order 45)。这意味着两件事:没装 im 助理插件时这个页签不会出现(面板里那张卡片照常可用);im 助理哪天改了这套私有机制,页签可能会掉,但页签组件外面包了错误边界,掉了也不会把整个侧栏带崩。

老对话怎么补进来的:这份记录是从这个版本开始写的,之前版本只把消息喂给模型、没有落库。所以升级后第一次启动会去读一遍助手会话自己的事件日志(wa:main),把里面真正的用户发言和助手正文抽出来补进库,只补一次(meta 表里记 messages_seed)。读完会跳过工具调用、思考块、以及运行时注入的上下文(时间、技能目录之类),只留人话。会话日志读不到就跳过、不写标记,下次启动再试,所以不会把"没读到"当成"补过了"。

存的是文本,不是聊天记录的备份:图片、文件只记一句说明,原文在微信里。默认全留在本地 SQLite 里,不会上传。

会话设置(预设 / 模型 / 强度 / 权限)

设置页里「助手会话」卡片有四组下拉,和 im 助理那边一个套路:

  • Agent 预设:助手会话挂哪套人格和工具(列的是宿主里能用的预设)。第一项是「跟随宿主默认」:选它就挂宿主自己的默认预设,插件不替你挑。别人装这个插件时,他那边配的默认预设(或者他自己建的人格预设)才是对的,所以出厂值也是空。
  • 模型:怎么选模型。第一项是「跟随宿主默认」,选了就用宿主当前的默认模型;要指定就从列表里挑一个,提供方和模型名是一起选的,只能选一个会报错。模型列表和每个模型的推理强度都由宿主的 llm 服务现读,不写死在插件里。
  • 推理强度:只有当前模型真的声明了强度档位才出现这一栏,否则藏起来(不同模型支持的范围不一样,硬塞一个会失败)。
  • 权限:助手会话用哪一档权限,档位描述也是宿主给的。

保存之后不会立刻把会话拆掉——万一这时候正有一轮在回,拆了就丢回复。做法是打一个"过期"标记,等你下一条微信消息进来,才按新配置重开一个助手会话;旧会话留在宿主的会话列表里,不会丢。

有一件事容易踩:如果你在 Web 界面里点开过助手会话直接聊天,那个会话是宿主自己建的,只挂了界面那一侧的预设——台账工具一个都没有,人格也不是这里配的那个,模型会说「工具不存在」。现在复用这种已经开着的会话时,会先就地补挂本插件的工具、人格、权限和提示词,再交回去用;GUI 里点开会话刚开始跑的那一刻也会补挂一次。会话正被宿主写的时候(报 already owned by an active write handle),会先退让等一会儿再把活着的会话接管下来,不再把消息直接丢掉。

这几项写进 state 表的 settingsOverrides,重启也在。也可以直接改 cordis.patch.yml 的 agentPreset / permissionPreset / agentProvider / agentModel / agentReasoningEffort。

预设和插件提示词是什么关系:人格、自称、称呼、句子长短,全部由预设决定,插件不掺和。插件只往会话里加一段「台账工具怎么用」的约定(什么时候记、怎么派副手、文件怎么发),开头就写明「以这个会话挂的人格设定为准」。老版本这里是写死的「你是工作助理、对方叫老板、短句分点」,结果和人格预设互相打架——用户配的狼娘人格被压住,自称、渠道全说错。现在换成中立写法,挂谁就是谁,工具照常可用。

同理,预设名和模型名都从宿主现读,没有写死任何一个。agentPreset 留空就是跟宿主默认;万一填的名字在别人机器上不存在,会自动退回默认,不让会话起不来(副手的 assignmentPreset 也一样)。

微信里的"正在输入"

你发完消息,微信顶部就会显示"对方正在输入…",模型想事情、调工具的十几秒里一直亮着,回复发出来才消失。

这件事没有想象中直白:微信的输入状态是一次性的,发一次几秒后就自己没了。所以插件内部每 5 秒补发一次,一轮结束时立刻撤掉。撤不干净的话你会看到"回复都已经到了,顶上还写着对方正在输入",那是骗人的。

它只是锦上添花——取不到票据、网络抖动都只是悄悄跳过,绝不会影响正经回复。

微信里发不出文件?现在堵住了

微信会话只认一件事:文件必须走 work_send_file 才可能到手机上。

之前踩过的坑:模型生成完文件,调了 present(那是 Web 界面里的"交付物卡片"工具),返回写着"Presented C:...\测试图片.png",模型就以为发过去了,回一句"已发送,请查收"——微信那边一个字节都没到。visualize、ask_user_question 同理,都是只在电脑界面上才有意义的工具。

现在助手会话里这三个工具被摘掉了(lib/assistant.js 的 WECHAT_HIDDEN_TOOLS),而且是两道锁:

  1. 名单屏蔽:从可见工具列表里拿掉,模型根本看不见,就不会去调。
  2. 执行期闸门:万一名单漏了(预设被换掉、工具被别的插件重新注册),真调下去那一刻也会被拒,返回"present 在微信里发不出任何东西,要给他看文件请用 work_send_file"。

这里有个时序坑值得记一笔:present、visualize 是 agent 预设带进来的工具,预设挂载完成之前它们不在可见名单里。这时候去屏蔽会报 unknown global tool,被 catch 吞掉,"屏蔽"就成了一句空话——第一版就是这么漏的。所以 setupScope 现在先 await presets.mount(...) 等预设真的挂完,再动屏蔽;这个方法也因此改成了 async(宿主会 await setup 回调,所以安全)。

系统提示词里也写死了两条:发文件只有 work_send_file 一条路;文件发成功之前不许说"已发送"。

给模型用的工具

这些工具只注册在助手会话里,不污染你的其他对话。

工具 干什么
work_capture 记一条工作项,自动去重、自动判优先级,回执带紧急度排名
work_list 查工作项,可按状态、期限、标签、关键词、等谁筛,默认按紧急度排
work_update 改状态、改期限、加备注、标记"我接了"
work_snooze 把一条的提醒往后推,比如"这事下周再说"
work_digest 生成当前的工作摘要
work_review 生成这一周的复盘(做完的 / 还欠着的)
work_assign 记成"等某人办",并约好什么时候去问一句
work_attach 把图片/文件挂到某条工作项上
work_send_file 把本机文件或知识库里的内容发到微信
kb_write 往知识库写一条
kb_search 搜知识库
kb_read 读知识库某一条
kb_list 列出知识库条目
work_notify 主动往微信推一条消息
work_people 看整理出来的认识的人,按提及次数排
work_person 看某个人的关系卡,以及这个人在哪些事里出现过
assign_create 派一个副手出去干一件大事
assign_list 看现在有哪些副手、都在干什么
assign_inspect 看某个副手最近几步的动静
assign_send 给副手补一句要求(不唤醒 / 下一步 / 新的一轮三档)
assign_stop 停掉一个副手
assign_wait 等副手交报告,默认等 60 秒,最多 120 秒
assign_report 副手用它往回交活(只注册在副手会话里)

配置

在 cordis.patch.yml 里改:

项 默认值 说明
stateDir 空 数据目录。留空则用 ~/.dsh/dsh-work-assistant/
agentPreset 空 助手会话用的预设。留空=用宿主自己的默认预设
permissionPreset workspace-write 助手会话的权限档位
agentProvider 空 助手用哪个模型提供方。留空跟随宿主默认
agentModel 空 助手用哪个模型。留空跟随宿主默认
agentReasoningEffort 空 助手的推理强度,取值随模型而定。留空用模型默认
dailyBriefTimes ['09:00', '18:30'] 每日摘要时间,可多个
tickIntervalSeconds 60 定时器多久检查一次,最小 10
mergeWindowMs 1500 消息合并窗口。微信常把一句话拆成几条发,合并后再交给模型
maxMessageChars 1200 单条微信消息的字数上限,超了自动分段
timeZone 空 时区。留空用系统时区
quietHoursStart '22:00' 安静时段开始。和结束一起留空表示关掉
quietHoursEnd '08:00' 安静时段结束
weeklyReviewWeekday 5 每周复盘的日子,1-7 是周一到周日,0 表示关掉
weeklyReviewTime '18:00' 每周复盘的时间
maxAssignments 3 最多同时开几个副手,1 到 32
assignmentCwd 空 副手在哪个目录干活。留空跟助手一样
assignmentModel 空 副手用哪个模型,写成 provider/model。留空跟助手一样
assignmentPreset 空 副手用的预设。留空=跟随宿主的默认预设
analysisEnabled true 要不要自动整理知识库、认人
analysisDailyTime '03:00' 每天几点整理一次,格式 HH:mm
analysisIdleMinutes 30 闲多少分钟没新消息就跑一次,0 表示关掉闲时分析
analysisProvider 空 分析用的模型提供方,留空跟助手一样(只能在 cordis.patch.yml 里改)
analysisModel 空 分析用的模型,留空跟助手一样

dailyBriefTimes、tickIntervalSeconds、安静时段、每周复盘,以及会话的预设 / 权限 / 模型 / 推理强度,这几项在设置页里改更方便,改完会写进 state.json,重启也不会丢。其余几项得改 cordis.patch.yml 再重启宿主。

会话设置保存后不重建会话:下一条微信消息进来时,会用新的预设、模型和权限档位重开一个助手会话。旧会话留在宿主的会话列表里,不会丢。

数据放在哪

全在 stateDir 下。主要是一个 SQLite 数据库文件,可以直接备份、也可以用任何 SQLite 工具打开看:

文件 内容
work-assistant.db SQLite 数据库:工作账本、副手登记簿、知识库、人物图谱、运行状态全在这里
media/ 微信里收下来的图片、文件、语音
gateway.log 排错日志,超过 1MB 自动截断

删掉整个目录等于重置。

数据库用的是 Node 自带的 node:sqlite(宿主是 Node 24),不需要装任何依赖,也不需要编译原生模块。表结构在 lib/db.js 里,第一次启动自动建表。

旧版本留下的 state.json / ledger.json / assignments.json / kb/index.json(以及 kb/*.md 正文)会在第一次启动时读进数据库。账本、副手登记和知识库索引搬完会改名成 *.migrated-<时间戳> 留档;state.json 只读不删。迁移是否做过记在库里的 meta 表,中途失败(比如正文文件读不到)不会写标记,下次启动会接着迁。

如果数据库文件真的坏了(SQLite 报 SQLITE_CORRUPT / SQLITE_NOTADB),插件会把主库和 -wal / -shm 一起改名成 work-assistant.db.corrupt-<时间戳> 留着,再写一行日志说明。只是被别的进程占着写锁(SQLITE_BUSY)不算坏库,会等 5 秒而不是改名。

HTTP 接口

都挂在 /api/dsh-workassistant 下,只接受本机访问:

路径 方法 说明
/login GET 扫码登录页(设置页不可用时的备用入口)
/login/scan GET 查当前二维码和登录状态
/login/status GET 只看登录状态
/status GET 运行状态
/relogin POST 重新登录(换一张码)
/overview GET 设置页用:登录状态 + 账本概览 + 生效中的设置
/stats GET 整页视图用:优先级分布、14 天趋势、标签/等谁排行、最老的几件、六个汇总数字
/items GET 设置页和整页视图共用:按紧急度排好的任务清单,?status=open|doing|done|dropped|all,可加 &query= 和 &tag=
/item POST 改一条任务,body 形如 {"id":"w-20261020-001","status":"done"};除了 status 还能改 title / priority / dueAt / tags
/kb GET 设置页用:知识库目录,?query= 走搜索、?limit= 限条数
/kb/doc GET 设置页用:读知识库某一条全文,?id=k-20261020-001
/kb/doc POST 设置页用:新建知识库条目,body 形如 {"title":"报销流程","content":"先填单"}
/conversations GET 对话记录目录:按「天 + 联系人」分好组,?limit= 限条数
/conversation GET 读某一天的往来,必须给 ?day=2026-10-22,可加 &chatId= 和 &limit=
/options GET 设置页的下拉项:可用预设、各提供方的模型与推理强度、权限档位,带上当前选中值
/sessions GET 侧栏「对话」页签用:能点开的助手会话(主会话 + 每个副手),带会话 id、名字、状态、最后活动时间
/settings POST 设置页用:改每日摘要时间、检查间隔、安静时段、每周复盘
/digest POST 立刻推一条摘要,验证通道
/assignments GET 整页视图用:副手列表,?status=active|all
/assignment GET 整页视图用:一个副手的详情和最近几步,?id=a-20261021-001
/assignment POST 整页视图用:{"action":"create","purpose":"..."} / {"action":"send","id":"...","message":"..."} / {"action":"stop","id":"..."}
/people GET 整页视图用:认识的人名单,?limit= 限条数
/person GET 整页视图用:一个人的关系卡,?name=舒子淇
/analysis GET 整理任务的状态:上次跑的结果、还有多少条消息没整理
/analysis POST 立刻整理一次(不等定时)

/login/scan 是只读的:页面每 2 秒问一次,它只把同一张码和状态返回去,不会换码。换码只在你点"重新获取"或者码过期时才发生。

设置页改的值写进 state.json 的 settingsOverrides,重启后会被盖回配置,不会又被 cordis.patch.yml 里的默认值冲掉。

设计上的几个取舍

为什么不用宿主的 schedule 服务? 那个服务只是往会话里注入一条消息唤醒模型,发不到微信。定时提醒要真推微信,所以这里自己起一个 60 秒的 ticker,到点用模板拼文本直接发。

为什么工具定义是手写的字面对象? 在 profile 目录下 require.resolve('@deepseek-ai/dsh-tools') 是解析不到的——核心包在宿主的 app.asar 里。宿主对工具注册的要求只是「有 name、description、parameters、output.schema、output.render、execute」,所以不需要 import 那个包。

为什么要做消息合并? 微信里人习惯一句一句发。逐条交给模型既碎又费 token。1.5 秒的窗口把连续几条拼成一段,模型看到的是完整意图。

为什么只认 owner? 机器人加上好友后,别人也可能给它发消息。不设防的话,谁都能指挥你的助理去改文件。所以只认登录的那个微信账号,陌生人一律丢。

为什么设置页是单独的 lib/client.js? DSH 的设置面板跑在浏览器里,跟宿主进程是两种环境。lib/client.js 用 window.__ModuleLoader__.load 注册一个工厂,再往 settings.section 插槽里塞一个 React 组件;React 由宿主的模块基座提供,插件不自己装。它跟 index.js 各跑一边,靠 /api/dsh-workassistant/* 这几个 HTTP 接口通信——所以就算设置页没显示出来,用浏览器直接开 /login 也一样能扫码。

为什么"正在输入"要自己定时补发? 微信的输入状态不是常驻开关,发一次过几秒就自动消失。想让它一直亮着只能定时补发(这里 5 秒一次),一轮结束再显式发一个"停止"。另外这个状态要先拿 typing_ticket,票有有效期,按用户缓存 5 分钟,失效了下次重新取。

已知限制

  • 只有私聊,没有群聊,没有 @ 事件。
  • 一个账号只能跑一个实例,多开会抢同一个轮询。
  • 副手是独立的顶层会话,所以关掉宿主时它们也跟着停;重启后标记"掉线",第一次发消息时才恢复。
  • 副手的报告是它自己调的 assign_report。它要是忘了调、直接结束回合,你在卡片上只会看到"空闲",得点「去看」问它。
  • 停掉一个"之前就开着、被复用上"的副手时,只能叫停它、没法把那个会话从列表里抹掉(宿主没给释放别人会话的接口)。这种情况回执里会明说,你自己把那个会话关掉即可。
  • 数据目录默认是 ~/.dsh/dsh-work-assistant/,跟 profile 无关。两个宿主同时开时,账本写入靠 SQLite 事务串行化、不会互相覆盖,但两个宿主都会跑定时器,提醒可能被推两遍,微信轮询也会互抢。要并行跑就在配置里给其中一个改 stateDir。
  • 认人靠模型从上下文里抽,会认错、会漏。名字越常见("小王""张经理")越容易和别人的事串在一起,拿不准的时候它会标低把握度。
  • 同名的人会合并成一条档案(库里按名字做唯一键)。真遇到两个「王伟」,现在只能看到一个;等以后加了人工合并/拆分再补。
  • 分析要调模型,会花 token。analysisEnabled 关掉就完全不跑。
  • 建议用专用小号,别拿主号当机器人。
  • 提醒靠本地进程活着。宿主关了就发不出来,下次启动会补发没发过的摘要。
  • 安静时段结束后的补发是"有什么补什么",不会按原定时间重排。半夜错过的三条会在早上一起到。
  • 侧栏那个「对话」页签是借 im 助理插件的私有页签表插进去的(宿主没有 sidebar.channels 这个座位)。没装或停用 im 助理时页签不出现,整页面板里的对话记录照常可用;im 助理以后改这套私有机制,页签可能会掉,掉了不影响其它页签。
  • 对话记录存的是文字,不是聊天备份。图片、语音、文件在记录里只有一句说明;回填也只能补回会话日志里还在的部分(宿主自己清理过的日志补不回来)。

许可

MIT。协议实现参考了 @michengai/dsh-im-connect(Apache-2.0)中腾讯 iLink Bot 的调用方式。

—/ 5

No ratings yet

Verified DSH bundle

Commit 82f85cef5db0

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout