dsh-matrix-agent
Matrix agent bridge for DeepSeek Harness (dsh): multi-twin per-room agent sessions, in-chat approval, media/rich-text/reply/edit-aware message intake
安装
此插件尚未提供可验证的 bundle,或兼容性检查未通过。请先阅读仓库说明。 阅读完整 README ↗
说明文档
阅读完整 README ↗配置
在 profile 的 cordis.patch.yml 行上覆盖(整个 config 值替换,不深合并):
| 字段 | 默认 | 说明 |
|---|---|---|
homeserverUrl | 必填 | homeserver 的 client-server API base URL |
accessToken | '' | 分身 access token;为空回退环境变量 DSH_MATRIX_TOKEN,两者都缺则插件加载失败 |
userId | 必填 | 本进程登录的数字分身账号,如 @ai-niukunliang:example.org |
owner | '' | 工作责任负责人(真人账号,仅客户端登录);设置后审批/吊销仅其可应答 |
respondToAll | true | 响应房间所有消息;设为 false 则仅 @提及/私聊 响应 |
allowedUserIds | [] | 白名单;为空且 allowAllUsers=false 时拒绝所有人(fail closed) |
allowAllUsers | false | 允许任意用户(仅开发用) |
provider | deepseek-official | 每个房间 agent 的 LLM provider |
model | deepseek-v4-flash | 每个房间 agent 的模型 |
agentPreset | standard | room agent 挂载的 agent preset(决定工具集与角色提示);留空则无工具 |
chunkMaxChars | 4000 | 出站单条消息字符上限(含分段前缀) |
mergeTimeoutSecs | 5 | 裸文本合并窗口(秒) |
approvalTimeoutSecs | 300 | 审批推送后等待聊天答复的秒数 |
stateDir | .dsh-matrix | 状态目录(state.json 房间映射 + 去重 + sync token) |
maxRetriesBeforeAbort | 5 | 同一房间 turn 内 LLM 受限自动重试达到该次数时主动 cancel 止损 |
retryCircuitBreakerEnabled | true | 是否启用重试熔断兜底 |
digitalTwinMode | false | 可选:同一进程挂载多个分身(见下方示例) |
digitalTwins | [] | 额外分身账号列表(通常每个分身一个进程,无需配置此项) |
authStoreFile | auth-store.json | 记忆授权库文件名(相对 stateDir) |
redlineTools | ['bash','pwsh','write','edit'] | 红线工具:即使有记忆授权也每次强制房间确认 |
cwdCandidates | [进程 cwd] | 新房间工作目录引导的候选目录列表;首项作为缺省 |
taskQueueMax | 20 | 单个房间 matrix 任务队列上限,超出后最早 pending 任务自动拒绝 |
matrixTools | true | 是否注册 10 个 Matrix 工具(成员/消息/房间/用户查询、主动发送、媒体下载、自我时间线) |
notifyRoomEvents | false | 是否把入群/离群/资料变更等房间事件注入 agent 会话(供主动打招呼等) |
proactiveSendRequiresApproval | true | 主动消息工具(matrix_send_dm/send_room_message/mention_member)首用是否需 Owner 批准 |
preserveRichText | true | 是否保留富文本(formatted_body)/回复上下文/编辑语义,结构化注入 agent(类人信息完整);false 回退纯文本 |
soul.enabled | true | 是否启用灵魂注入(性格/风格/口头禅/习惯注入 room agent 的 system prompt) |
soul.persona | '你叫小灵…' | 性格/人设描述(自由文本) |
soul.style | 'friendly' | 说话风格:concise/friendly/formal/humorous/sassy |
soul.catchphrase | '交给我吧' | 口头禅(可选) |
soul.habits | '先确认需求再动手…' | 工作习惯(自由文本) |
soul.replyLength | 'short' | 回复长度偏好:short/normal/detailed |
testRoomPrefix | '【测试】' | 房间名前缀匹配即视为测试房间,给数字人注入测试声明(「当前是测试环境,请勿真实执行任务/修改文件/向真实用户发送消息」);空=关闭 |
twinModeRoomPrefix | '' | 房间名前缀匹配即启用秘书编排(任务入队/开工请示/交付确认),即使 digitalTwinMode=false;用于「只给测试房间开秘书编排」;空=不启用 |
roomRoles | {} | 房间 → 灵魂预设 id 的固定角色映射(如 { '!room:hs': 'dev' });未配置用百变员工 |
taskClarifyBeforeStart | true | 开工前是否私下 DM 老板请示要求/优先级;超时按原任务开工 |
taskClarifyTimeoutSecs | 120 | 开工请示等待秒数 |
taskConfirmBeforeDeliver | true | 交付前是否私下 DM 老板结果摘要请求确认 |
taskConfirmTimeoutSecs | 600 | 交付确认等待秒数 |
taskConfirmTimeoutAction | 'hold' | 确认超时行为:hold(挂起待确认)/deliver(自动交付)/cancel(取消) |
taskConfirmExemptMatters | [] | 豁免交付确认的事分类(低风险任务跳过确认) |
内置灵魂预设(设置页「选择预设」一键填充,可再微调后保存):
| 预设 | 适用 |
|---|---|
dynamic 百变员工(默认) | 根据房间氛围/语境自动切换人设与语气 |
default 综合助手 | 通用助手,靠谱有人情味 |
pm 产品经理 | 关注用户价值与目标拆解,习惯先对齐需求 |
dev 研发工程师 | 技术扎实、沟通直接,先说根因再给方案 |
qa 测试工程师 | 细心严谨,问题描述带复现步骤/预期/实际 |
leader 领导(负责人) | 看全局抓重点,协调资源推动决策 |
newbie 新入职员工 | 谦虚好学,持续学习完善,不懂就问 |
autoIntroduce | true |
maxSelfIntroMentions | 20 |
memberMemory | true |
autoGreet | true |
selfIntroTemplate | 模板 |
配置示例
推荐:每个分身一个 harness 进程(单账号模式)
### 配置示例
**推荐:每个分身一个 harness 进程(单账号模式)**
```yaml
# 分身 @ai-niukunliang 的 profile 配置
userId: '@ai-niukunliang:example.org' # 本进程登录的分身
accessToken: '...' # 分身的 token(或 tokenEnv 环境变量)
owner: '@niukunliang:example.org' # 真人账号(仅客户端登录):审批仅其可应答
respondToAll: true # 参与房间协作,响应所有消息
allowAllUsers: false # 生产建议用白名单 fail closed
allowedUserIds: ['@niukunliang:example.org', '@tianjintao:example.org']
可选:同一进程挂载多个分身(digitalTwinMode)
digitalTwinMode: true
digitalTwins:
- userId: '@ai-niukunliang-pm:example.org' # 分身账号(需预先注册并取得 access token)
tokenEnv: 'DSH_MATRIX_AI_NIUKUNLIANG_PM_TOKEN' # 从环境变量读 token(推荐);或直接 accessToken
owner: '@niukunliang:example.org' # 工作责任负责人:仅其可在房间应答审批
role: 'pm' # 角色标签(展示用)
respondToAll: false # 默认仅 @提及/私聊 响应;true 则响应所有消息
provider: '' # 留空回退顶层 provider/model
model: ''
每个分身独立 sync 循环、独立状态文件(/twins/.json)、独立 per-room agent 会话;审批按「分身×房间」维度记录记忆授权,Owner 变更不影响其他分身。
使用
- 真实人在 Matrix 客户端登录自己的账号(如
@niukunliang),把它加进目标房间 - 每个分身账号各启动一个 harness:
dsh --profile,插件自动加入房间(邀请自动接受) - 房间里 @提及 分身即可让它干活;分身要执行红线工具时会推送审批,Owner 在客户端回复「批准/拒绝」(超时按 unavailable 处理)
- 常用命令:
/status(看会话)、/auth list(看记忆授权)、/auth revoke(吊销,仅 Owner) dsh plugin --profile web remove dsh-matrix卸载;组合层变更需重启 dsh 进程(不参与 HMR)
安全红线
- Matrix 通道等于绕过本机批准体系:approval 应答必须来自白名单 sender 且对应本房间真实 pending 的审批
- 聊天内容只能进会话流(
source.kind = 'plugin'),绝不允许直接执行 shell - access token 不进日志、不落盘;
state.json不包含任何聊天内容
开发
corepack pnpm install
corepack pnpm test # tsc + node --test(format 单测 + 假 homeserver 端到端)+ esbuild 打包 client
corepack pnpm build # tsc(lib/ 产物)+ esbuild 打包 src/client-main.js → lib/client.js
改完代码必须重新 build 并重启 dsh 进程(ESM 缓存 + web bundle 重新扫描)。
Client 半构建约定:dsh web 的 client-modules 加载器要求
exports["./client"]指向window.__ModuleLoader__.load({ id, factory })注册格式的自包含 bundle。 本项目用 esbuild 打包:src/client-main.js(ES module 源码,import React) → CJS bundle → banner/footer 包装成__ModuleLoader__.load格式 →lib/client.js(见scripts/build-client.mjs)。react外部化(dsh 模块系统的 shell seed, 由 factory(require) 注入,避免与 shell 的 React 实例冲突);其余代码内联自包含。 构建后自动node --check语法自检。改 client 半时改src/client-main.js,不要改lib/client.js。
测试系统(test-system)
独立于插件仓库根项目的 Node 测试项目(test-system/):连真实 Matrix homeserver,
模拟多个群 + 多个 AI 同事(LLM 扮演),对运行中的数字人发起真实对话,实时网页查看过程、
断言评估、出测试报告——支撑「设计 → 开发 → 测试 → 改进」闭环。
- 多群 + AI 同事:同时跑多个测试房间(群),每房间独立对话循环;OpenAI 兼容 LLM 扮演同事 (角色 persona + 房间上下文 + 测试目标),动态发言、追问细节
- 实时网页:SSE 推送房间列表 + 对话流(同事↔数字人气泡)+ 状态徽标(进行中/完成/失败)
- 干预控制:每房间暂停/继续/跳过等待/停止/换同事/注入消息,全局全部暂停/继续/停止
- 场景生命周期:Web 顶部场景下拉 + 开始/重新开始/停止(stop 清空、重跑 run 计数 +1)、单房间重跑
- 断言引擎:场景房间定义断言(
twin-replied/twin-responded-in-time/twin-mentioned-colleague/message-count/twin-sent-dm/boss-approved/task-delivered/custom),房间跑完自动评估, 房间卡显示 ✔/✘ 徽标、对话流逐条显示、聚合场景报告——失败的断言即改进清单,改完插件点「重新开始」重测 - 秘书流程场景:
task-flow场景 +BossAgent(模拟老板:监听数字人私聊,「任务请示」→批准、 「交付确认」→确认交付)——数字人侧把twinModeRoomPrefix设为测试房间前缀即可在测试房间开秘书编排 (见test-system/README.md完整说明)
已知限制与路线图
- 仅非加密房间:
m.room.encrypted事件只提示不支持(E2EE 二期:Rust crypto + 设备验证) - 媒体已支持,但无 OCR/转写:图片/文件/音视频会下载落盘并作为多模态附件/路径交给 agent;暂不内置 OCR、音频转写、视频抽帧等解析(可用 agent 自身能力或外部工具处理已保存的文件)
- 不流式推送工具进度:每条
assistant/message一条(或多条分段)消息 - 仅长轮询:无 appservice/webhook 模式,主机需可出站访问 homeserver
使用
- 真实人在 Matrix 客户端登录自己的账号(如
@niukunliang),把它加进目标房间 - 每个分身账号各启动一个 harness:
dsh --profile,插件自动加入房间(邀请自动接受) - 房间里 @提及 分身即可让它干活;分身要执行红线工具时会推送审批,Owner 在客户端回复「批准/拒绝」(超时按 unavailable 处理)
- 常用命令:
/status(看会话)、/auth list(看记忆授权)、/auth revoke(吊销,仅 Owner) dsh plugin --profile web remove dsh-matrix卸载;组合层变更需重启 dsh 进程(不参与 HMR)