dsh-1bot
为 dsh 中的 AI 与其他插件提供 OneBot 连接能力。协议通信、API 与事件分发由
onebot.js 提供;本插件负责连接生命周期、
工具入口,以及 AI 的事件预处理订阅。
安装与启动
将插件装入要使用它的 profile。以下以 onebot 为例,请替换成实际 profile 名称:
dsh plugin --profile onebot add dsh-1bot
dsh --profile onebot
首次运行若当前 profile 的用户 patch 中还没有本插件的配置条目,会在宿主提供的
profileContext.patchPath 追加注释模板并退出。按提示打开该文件,取消模板注释并填写
连接配置;若文件原本是空列表 [],删除它,其他插件配置保持不动,然后重启当前宿主。
模板只追加一次,已有内容不会被覆盖,也不会读取或修改其他 profile 的文件。
普通 cordis 宿主没有 profile 信息时,跳过文件引导,直接使用宿主传入的配置。
已有交互 profile 中的 agent 可以使用这些工具;仅加载连接插件不会自行创建 AI 会话。
- id: onebot
config:
url: 'ws://127.0.0.1:3001'
access_token: ''
只支持正向 WebSocket。实现端需要先开启相应服务;插件主动连接它。
模型与登录凭据沿用宿主 profile,本插件不配置模型。加载插件即建立连接,停用或卸载由宿主管理。
配置
| 字段 | 默认值 | 说明 |
|---|
url | ws://127.0.0.1:3001 | OneBot 实现端地址 |
access_token | 空字符串 | OneBot 实现端的访问令牌,须与实现端配置一致 |
connect_retries | 5 | 首次连接失败后的重试次数 |
connect_retry_delay_secs | 1 | 重试间隔,秒 |
console_log | true | 将本插件日志输出到控制台 |
log_local_time | true | 日志采用本机时间;关闭时使用 UTC |
控制台日志使用紧凑的数字时间(含毫秒和时区偏移),保留日志级别与来源。
多行诊断和堆栈的续行以 │ 标记;长对象按宽度展开,便于查看字段与错误详情。
id 定向 patch 整段替换 config,不是逐字段合并。首次连接失败且重试耗尽时,进程
输出包含脱敏地址、配置路径、重试预算和 TCP 探测结果的诊断后退出。连接建立后还会
立即调用一次 get_login_info 校验 access_token:令牌缺失、与实现端不一致或实现端
不回应时,输出 token 校验失败 诊断后退出,不会留下一个连不上协议的插件。运行期
重连由 SDK 负责,预算耗尽后需要重启。连接失败不会写配置。
AI 工具
所有工具使用 onebot_ 前缀。
| 工具 | 用途 |
|---|
onebot_query | 查询 SDK 的 API、事件和类型定义 |
onebot_invoke | 传入 action 与完整 JSON 对象 params 调用 API |
onebot_status | 查看本地连接状态 |
onebot_subscribe | 为当前 session 保存并启用一个事件预处理脚本 |
onebot_subscriptions | 查看当前 session 的订阅、源码、计数与错误 |
onebot_unsubscribe | 按订阅 id 取消当前 session 的订阅 |
onebot_query() 默认列出 API;query 按名称或说明搜索,events: true 改为列出
事件。name 精确查询方法的参数和返回值、事件的载荷类型,或继续查询引用的类型。
接口与事件清单直接来自所安装的 SDK,不另维护一份清单。
调用 API 前先查询定义,再用 onebot_invoke({action: "查到的方法名", params: {...}})
执行;无参数方法使用 {}。原始响应 data 保持不变,服务端错误直接报告,不自动重试。
SDK 支持某接口不代表实现端支持或账号有权限。
协议调用包括消息发送和管理操作。本插件不加聊天白名单、前缀、文本分块或回复策略,
也不暴露 SDK 连接生命周期方法作为模型可调用的协议 API。
事件订阅脚本
先用 onebot_query({events: true}) 查询事件,再查询具体事件和载荷类型。
订阅时提交事件名与同步 JavaScript 函数体,函数可使用 event 与 state:
// onebot_subscribe 的参数示意
{
event: "从查询结果选择的事件名",
script: `
if (!event.message) return null;
state.count = (state.count || 0) + 1;
return { message: event.message, count: state.count };
`
}
event 是 SDK 事件的 JSON 数据,函数等非 JSON 字段不传入脚本;state 是该订阅私有、
跨事件保留的对象。返回 null 或 undefined 表示忽略事件,其他 JSON 结果会形成
{subscription_id, event, data} 消息,送入发起订阅的 agent inbox。投递时 agent 空闲则
唤醒并开启后续回合;正在运行则注入下一执行步骤的上下文,不额外排一个独立回合。
注入不会强制继续执行,尚未消费的上下文等待后续执行时使用。
脚本在独立 Worker 中执行,只有同步数据预处理能力;不提供宿主 API、导入、定时器或
直接调用协议的能力。发送操作由 AI 后续调用工具完成。执行与资源消耗受限;脚本报错、
超时或返回不可序列化结果时停止订阅,错误可通过列表工具查看。
同一订阅正在处理事件时,新事件会丢弃并计数,避免积累无界预处理队列;过大的输入也会
丢弃。列表中的接收、处理、投递和丢弃计数可用于检查实际行为。匹配并投递的结果仍由
agent 自己的 inbox 排队,脚本应在投递前完成必要的过滤。
订阅在工具调用结束后继续运行。脚本、订阅 id 与停止错误随当前 session 日志保存,
持久化由宿主的 session 存储负责;未配置 session 持久化时不会跨进程保留。
重启后恢复该 session 会重新启用其订阅,只向该 session 投递。其他 session 无法查看或
取消它的订阅。fork 会继承所复制日志中的订阅,之后各自修改和取消,互不影响。
已因错误停止的订阅恢复后仍保持停止。
agent 释放或插件卸载时清理运行中的监听器与 Worker,保留已保存的订阅;session 未加载
期间不接收、不补发事件。连接重连不清除订阅;session 恢复后 state 与运行计数重新开始。
主动取消会更新保存的订阅列表,之后恢复也不会重新启用。替换脚本时先取消旧订阅,再创建
新订阅。没有订阅的事件不会进入任何 AI 会话。
供其他插件使用
在插件依赖中声明 onebot 服务,通过 ctx.onebot.client 使用 SDK 的类型化 API、
事件订阅与取消订阅。消费方负责清理自己注册的回调,通常放进自己的 ctx.effect。
需要给现有 agent 安装同样的预处理脚本时,可使用 ctx.onebot.subscribe(agent, event, script);list(agent) 与 unsubscribe(agent, id) 管理其订阅。服务类型从本包入口导出。
开发与贡献
开发说明见 CONTRIBUTING.md。
License
Apache-2.0。