Bundle
@deepseek-ai/dsh-weixin
微信 iLink 通道与 DSH 的流式智能代理插件
- Source
- Stu-KatoMegumi
- stars
- 2 stars
- License
- MIT
- Updated
- Updated 11 days ago
Readme
# 开发人员:STU-XIE
# dsh-weixin
`dsh-weixin` 把微信 iLink/ClawBot 私聊接入 DSH agent。插件模式直接使用 DSH `apiProxy`,独立模式通过 DSH Web HTTP RPC + WebSocket 事件流连接。
## 功能
- 流式回复按模型分段:单独一行的 `---` = 新气泡(单/双换行、句子内 `---` 不切分),一轮最多 10 条;长度上限按当前气泡累计,空闲超时自动兜底
- 用户每条新消息可打断上一轮仍在生成的回复,最新输入优先处理
- Prompt 定制:system-prompt / soul / rules 三个静态文件,以及由 LLM 自动维护、网页可编辑的长期记忆
- 微信“正在输入”状态,任务结束自动关闭
- 长轮询看门狗、指数退避重连和连接状态记录
- 登录约 24 小时到期前在本地生成续签二维码图片并提醒全部已知用户,旧 token 在扫码前继续工作
- 图片、语音、视频、文件接收(AES-128-ECB 解密)与文件发送
- 私聊访问策略、白名单、发送目录边界和 50 MB 媒体上限
- 用户→DSH 会话映射、按会话分隔的对话历史、错误日志和单实例锁持久化
- DSH“设置 → 微信”页面,支持状态、扫码、权限、流式参数和定时任务热更新
- 五段 cron 定时提示任务
## 安装到 DSH
```powershell
# 可选:默认 DSH_ROOT 为 D:\Program Files\dsh,profile 为 web
$env:DSH_ROOT = 'D:\Program Files\dsh'
$env:DSH_PROFILE = 'web'
npm install
npm run install:dsh
```
安装脚本调用 DSH 官方 `plugin add` 逻辑。Windows 上源码路径含空格时,脚本会使用 `$DSH_HOME/bundles/dsh-weixin` 稳定缓存,避免生成无法解析的 profile 包链接。
```powershell
cd 'D:\Program Files\dsh'
pnpm dsh --profile web --dump-config
pnpm dsh --profile web
```
首次启动会打开扫码窗口(独立应用窗口,扫码成功后自动关闭)。登录凭据、会话映射和设置默认持久保存在 `$DSH_HOME/channels/dsh-weixin`(通常是 `~/.dsh/channels/dsh-weixin`),更新或卸载插件不会删除它。
> **插件模式不输出日志**:dsh-weixin 由 DSH 加载时给自身组件注入静默 logger(不动 DSH 自己的 `console`,因此 DSH 的启动横幅、状态输出等都保持正常);插件自身的收发/扫码日志不打印到 DSH 终端。扫码/续期窗口在 DSH 所在机器上用独立应用窗口弹出,扫码成功后自动关闭。需要完整日志排查时请改用独立模式 `npm start`。
## 卸载
```powershell
npm run uninstall:dsh
```
卸载会从指定 DSH profile 移除 bundle,并清理安装脚本创建的稳定缓存;不删除你的会话数据。
## 微信命令
- `/help`、`/?`:查看命令(两者功能相同)
- `/new`:创建并切换到新 DSH 会话,同时创建新的 JSONL 历史记录
- `/stop`:取消当前任务
- `/status`:查看连接和会话状态
- `/renew`:立即获取续签二维码图片
- `/send <相对路径>`:发送 `outboxDir` 内的文件
- `/users`、`/allow add|remove <ID>`、`/cron`:查看用户、管理白名单和查看定时任务
会话按用户独立维护:同一自然日内继续复用当前 DSH 会话;跨过本机日历日期后,下一条消息会自动创建新 DSH 会话和新的 `history/*.jsonl` 文件。执行 `/new` 会立即切换到新会话,即使仍在同一天也会新建历史文件。旧文件只作为本地归档,不会被重新拼接到新请求中。
## 微信续签
续签功能在本地使用 `qrcode` 把 iLink 返回的二维码内容生成 PNG,再通过微信图片消息发送给所有已有 context token 的已知用户。每个用户继续使用自己的微信 context token 和 DSH session;多个用户共享同一轮续签二维码,任一用户扫码成功后,本轮收到二维码的用户都会收到续期成功提示。二维码图片属于通道管理消息,不受“媒体/文件收发”开关影响。设置页的“扫码续期”仍只在 DSH 所在机器打开本机扫码窗口。
自动提醒按运行机器的本地时间判断:通常从凭据到期前 2 小时开始,在 08:00–22:00(含 22:00)内对每个用户每 10 分钟最多提醒一次。若凭据将在夜间到期,首次提醒提前到前一天 21:30;若程序错过晚间提醒窗口后才在夜间恢复,并且旧 token 仍有效,则每个用户只紧急补发一次。所有通过现有私聊访问策略的用户都能使用全部 `/` 命令,主动执行 `/renew` 不受工作时间限制。
收到二维码后,请在电脑或另一台设备上展示图片,再打开需要续签的手机微信“扫一扫”,使用摄像头扫描并确认授权。微信聊天内长按识别不能完成该续签流程。
提醒会标明预计到期时间。二维码生成或图片上传最终失败时,机器人发送“二维码发送失败,请在电脑端完成微信续签!”并附原始续签页面链接作为兜底;失败不会清空仍有效的旧 token。扫码确认后,插件先持久化新凭据并初始化新连接,再向本轮实际收到二维码的用户发送“✅ 微信登录续期成功,连接已更新。”;二维码超时、过期或取消时发送“❌ 微信续签二维码已超时或失效,请重新发送 /renew 获取新二维码。”。主动停止插件不会发送失败提示,暂时发送失败的结果通知会在后续微信轮询恢复后补发。
## 定时任务
在设置页填写 JSON 数组:
```json
[
{
"id": "morning-summary",
"cron": "0 9 * * 1-5",
"userId": "微信用户ID",
"prompt": "总结今天的待办事项",
"enabled": true
}
]
```
cron 按运行 DSH 的本地时区解析,五个字段依次是分、时、日、月、星期。
## 独立模式
```powershell
npm start
```
默认连接 `http://127.0.0.1:3080`。配置集中放在 `config/.env`(参考 `config/.env.example`,该文件不进入版本库):进程已有的环境变量优先,`.env` 只补充缺失项;`DSH_URL`、`WX_BOT_CWD`、`WX_BOT_SESSION_DIR`、`WX_BOT_PRESET`、`WX_BOT_ACCESS_POLICY`、`WX_BOT_ALLOWLIST`、`WX_BOT_STREAMING`、`WX_BOT_TYPING` 等均可在其中配置。
模型策略固定为 `deepseek-official/deepseek-v4-flash`:普通消息使用 `off`(关闭思考),复杂消息使用 `max`(最高思考挡位)。复杂消息仍按现有规则判断:消息长度超过 40 个字符,或包含操作类关键词时,使用 `flash + max`;其他消息使用 `flash + off`。`WX_BOT_FAST_MODEL`、`WX_BOT_COMPLEX_MODEL` 以及对应的 reasoning 环境变量不再参与模型选择,旧的持久化模型设置也会在运行时归一化为这两种组合。若 DSH 未确认目标组合,本轮会停止,不会沿用会话中的旧模型。
`WX_BOT_SEND_INTERVAL_MS`(默认 200)控制两次微信消息发送的最小间隔(毫秒),用于降低 iLink 发送限流概率;设 `0` 可关闭节流。
独立模式会在启动微信连接前调用只读 DSH API 检查服务。如果 DSH 未启动、地址错误或端口上不是 DSH,程序会提示先运行 `pnpm dsh web` 并以退出码 1 结束,不会启动扫码和微信轮询。检测超时默认为 3000 ms,可用 `DSH_STARTUP_CHECK_TIMEOUT_MS` 调整。
## 气泡与流式输出
微信一次只显示一条消息气泡。回复由模型按下列契约切成多条气泡:
- **单独一行的 `---` = 一个气泡结束**:模型在输出中用单独占一行、前后带换行的 `---`(等价于 `\n---\n`)主动切气泡,程序把它前面的内容立即作为一条消息发送(分隔符本身不进入微信文案)。单个/双换行只是段落排版,句子中间嵌入的 `---` 也只是普通文字,都不会触发切分。此契约写在 `src/prompt/system-prompt.md`,可在设置页修改。
- **一轮最多 10 条气泡**:整轮回复分隔出的气泡总数不超过 10 条,内容多时合并、精简,避免触发微信 iLink 发送限流。
- **长度兜底(按当前气泡累计)**:当前这一个气泡累计超过 `streamFlushChars`(默认 800 字符)时,在最近的标点/换行处强制切分;每切出一个气泡后从下一个气泡重新计数,不从整条回复头部累计。
- **空闲兜底**:模型超过 `streamFlushMs`(默认 30000 ms)没有新内容时,强制发出当前气泡,避免“没反应”。
## Prompt 定制与长期记忆
项目自带默认 prompt 文件:
```text
src/prompt/
system-prompt.md 系统设定与气泡契约
soul.md 人设与灵魂
rules.md 行为规则
memory.md 背景记忆的初始化模板
```
首次启动会把 system-prompt / soul / rules 复制到频道数据目录的 `prompt/`,并在记忆文件缺失时把 `src/prompt/memory.md` 复制到 `memory/memory.md`。独立模式默认路径为 `session/memory/memory.md`;插件模式位于该插件的频道数据目录中。已有记忆文件永远不会被初始化覆盖,也不会读取或迁移旧的 `prompt/memory.md`。
每个 DSH 会话只在第一条消息前注入一次渲染后的静态 Prompt 和当时的记忆快照。静态 Prompt 内容变化时,下一条消息自动创建新会话;自动记忆变化不会打断当前会话,执行 `/new`、跨日或首次创建的新会话会读取最新记忆。静态 Prompt 支持 `{date}` 占位符(当前日期)。
LLM 会根据用户意图维护长期记忆:用户明确要求“记住/忘记”时按要求处理,也可主动记录稳定偏好、身份关系、长期目标、项目背景和反复出现的重要约束。新增、替换和删除通过不会显示在微信中的结构化控制块提交,程序只接受严格校验后的操作,并优先使用稳定记忆 ID 精确替换或删除;当前会话尚不知道新 ID 时可用原事实全文精确匹配,不做模糊删除。临时任务、短期情绪、推测以及密码、token、密钥等凭据不会写入。单轮最多处理 5 个操作,单条记忆最多 500 字符,文件上限 60 KiB、最多 200 条自动记忆。
DSH“设置 → 微信”页面仍可查看、编辑或重置背景记忆,实际读写的是 `memory/memory.md`。
## 开发验证
```powershell
npm test
npm run check
```
Install
dsh plugin --profile web add github:Stu-KatoMegumi/dsh-weixin#f9792095688d26229d8e402493ae44ff2bfec18a
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install deepseek-ai-dsh-weixin from the hub