🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

Telegram 桥接 SMMURDA/dsh-paean-telegram

DeepSeek Harness
SMMURDA14 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek HarnessDSH的原生 Telegram 桥接,专为 Paean Harness…

30.3/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add SMMURDA/dsh-paean-telegram
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · platform
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(dependency_conflict),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/11/02·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 14 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(dependency_conflict · 2026/11/2) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 39 处,展示前 39 条)
  • 读取本地文件
    dist/index.js:239
    if (activePath !== undefined && existsSync(activePath)) {
  • 读取本地文件
    dist/index.js:1577
    if (existsSync(state.config.workspace.activePath)) {
  • 读取本地文件
    dist/config.js:386
    raw = readFileSync(path, 'utf8');
  • 读取本地文件
    dist/config.js:425
    raw = readFileSync(file, 'utf8');
  • 写入本地文件
    dist/config.js:444
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    dist/config.js:445
    writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
  • 读取本地文件
    dist/harness/adapters/mode.js:29
    if (!existsSync(dir))
  • 读取本地文件
    dist/harness/adapters/mode.js:32
    return readdirSync(dir, { withFileTypes: true })
  • 读取本地文件
    dist/harness/adapters/host.js:64
    const names = await withFsTimeout(readdir(target));
  • 读取本地文件
    dist/harness/adapters/host.js:67
    const info = await withFsTimeout(stat(join(target, name)));
  • 读取本地文件
    dist/harness/adapters/host.js:105
    const info = await withFsTimeout(stat(resolve(path)));
  • 写入本地文件
    dist/harness/adapters/host.js:115
    await withFsTimeout(mkdir(resolve(path), { recursive: false }));
  • 发起网络请求
    dist/telegram/transport.js:267
    const response = await fetch(url, { signal: AbortSignal.timeout(60_000) }).catch((err) => {
  • 请求外部主机api.telegram.org
    dist/telegram/transport.js:509
    const response = await fetch(`https://api.telegram.org/bot${this.bot.token}/sendMessage`, {
  • 发起网络请求
    dist/telegram/transport.js:509
    const response = await fetch(`https://api.telegram.org/bot${this.bot.token}/sendMessage`, {
  • 读取本地文件
    dist/core/chat-bindings.js:25
    raw = readFileSync(bindingsFilePath(configRoot), "utf8");
  • 写入本地文件
    dist/core/chat-bindings.js:66
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    dist/core/chat-bindings.js:68
    writeFileSync(tmp, `${JSON.stringify(prune(bindings), null, 2)}\n`, "utf8");
  • 写入本地文件
    dist/core/chat-bindings.js:69
    renameSync(tmp, file);
  • 读取本地文件
    dist/workspace.js:6
    const names = readdirSync(dir);
  • 写入本地文件
    dist/workspace.js:38
    mkdirSync(piDir(workspaceRoot), { recursive: true });
  • 读取本地文件
    dist/media/attachments.js:50
    const root = await realpath(resolvedRoot).catch(() => resolvedRoot);
  • 读取本地文件
    dist/media/attachments.js:57
    const real = await realpath(abs).catch(() => abs);
  • 读取本地文件
    dist/media/attachments.js:62
    const info = await stat(real);
  • 读取本地文件
    dist/media/attachments.js:71
    const buffer = await readFile(real);
  • 读取本地文件
    dist/media/image-refs.js:114
    const root = await realpath(resolvedRoot).catch(() => resolvedRoot);
  • 读取本地文件
    dist/media/image-refs.js:134
    const real = await realpath(abs).catch(() => abs);
  • 读取本地文件
    dist/media/image-refs.js:137
    const info = await stat(real).catch(() => undefined);
  • 写入本地文件
    dist/harness/adapters/media.js:50
    await mkdir(dir, { recursive: true });
  • 写入本地文件
    dist/harness/adapters/media.js:51
    await writeFile(path, data);
  • 读取本地文件
    dist/harness/adapters/session-lifecycle.js:551
    for (const project of await readdir(root, { withFileTypes: true })) {
  • 读取本地文件
    dist/harness/adapters/session-lifecycle.js:556
    if (existsSync(dir)) {
  • 删除本地文件递归
    dist/harness/adapters/session-lifecycle.js:557
    await rm(dir, { recursive: true, force: true });
  • 写入本地文件
    dist/harness/adapters/plugins.js:120
    writeFileSync(tmp, content, "utf8");
  • 写入本地文件
    dist/harness/adapters/plugins.js:121
    renameSync(tmp, target);
  • 删除本地文件
    dist/harness/adapters/plugins.js:125
    rmSync(tmp, { force: true });
  • 读取本地文件
    dist/harness/adapters/plugins.js:138
    if (!existsSync(target))
  • 读取本地文件
    dist/harness/adapters/plugins.js:140
    const source = readFileSync(target, "utf8");
  • 读取本地文件
    dist/harness/adapters/downloads.js:43
    for (const entry of readdirSync(join(home, "profiles"))) {
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:api.telegram.org

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-loader@deepseek-ai/dsh-agent@deepseek-ai/dsh-commands@deepseek-ai/dsh-compaction@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
DSH Paean Telegram DeepSeek Harness(DSH)的原生 Telegram 桥接,专为 Paean Harness 发行版打造——该发行版本身不带 Telegram 桥接,现在可以用手机驱动它。发一条消息,智能体就在聊天里回复;其余一切(会话、模型、工作区、目标、技能、插件、主机文件)都在常驻按钮栏上,一键可达。 无需运行服务器:插件挂载在 Harness Host 进程内部,通过长轮询直接与 Telegram Bot API 通信。 | 包名 | dsh-telegram(保持不变:配置档安装会引用它) | | 版本 | 0.4.0 | | 依赖 | Node.js >= 22,一个 DSH 配置档(在 Harness 0.1.0-rc.21 搭配 @deepseek-ai/ 0.2.1-alpha.1 上测试通过) | | 运行时依赖 | grammy | | 许可证 | MIT(见 LICENSE) | 本仓库是 fork。 基于 xqicxx/dsh-telegram(MIT),保留原许可证与版权声明。本次构建新增了针对 dsh 0.2.x 主机 API 的运行时兼容工作——见本次构建的本地改动。 仅英文。 文档、机器人按钮标签、卡片、回执和日志行全部为英文。 主要目标:Paean Harness。
展开完整文档(README 剩余 1 节)
DSH Paean Telegram

DeepSeek Harness(DSH)的原生 Telegram 桥接,专为 Paean Harness 发行版打造——该发行版本身不带 Telegram 桥接,现在可以用手机驱动它。发一条消息,智能体就在聊天里回复;其余一切(会话、模型、工作区、目标、技能、插件、主机文件)都在常驻按钮栏上,一键可达。

无需运行服务器:插件挂载在 Harness Host 进程内部,通过长轮询直接与 Telegram Bot API 通信。

| 包名 | dsh-telegram(保持不变:配置档安装会引用它) |
| 版本 | 0.4.0 |
| 依赖 | Node.js >= 22,一个 DSH 配置档(在 Harness 0.1.0-rc.21 搭配 @deepseek-ai/ 0.2.1-alpha.1 上测试通过) |
| 运行时依赖 | grammy |
| 许可证 | MIT(见 LICENSE) |

本仓库是 fork。 基于 xqicxx/dsh-telegram(MIT),保留原许可证与版权声明。本次构建新增了针对 dsh 0.2.x 主机 API 的运行时兼容工作——见本次构建的本地改动。

仅英文。 文档、机器人按钮标签、卡片、回执和日志行全部为英文。

主要目标:Paean Harness。 Paean Harness 发行版不带 Telegram 桥接;本仓库正是为填补这一空白而存在。它在 Paean Harness 0.1.0-rc.21(@paean-ai/harness)搭配 @deepseek-ai/ 0.2.1-alpha.1 上开发和测试——上游插件正是在这个组合上失败,见 Paean Harness 和运行时兼容。

其他 DSH 配置档:尽力支持,欢迎反馈。 代码中没有任何 Paean 专属内容——只需要 Node.js >= 22 和 @deepseek-ai/dsh 对等包——因此任何运行 0.1.1-rc.2 到 0.2.x 的 DSH 配置档都应能挂载它,接缝层同时接受两代 API。该范围之外的构建未经测试。

目录

- 你能得到什么
- 快速开始
- Paean Harness
- 安装到 DSH 配置档
- 机器人 token
- 配置
- 聊天名单(谁可以和机器人对话)
- 命令
- 按钮栏
- 卡片
- 智能体工具
- 媒体与附件
- 审批与提问
- 自动压缩与长任务通知
- 安全模型
- 运行时兼容
- 开发
- 故障排查
- 本次构建的本地改动
- 致谢与许可证

你能得到什么

- 与智能体聊天:你发送的任何文本都会成为该聊天所绑定会话的一轮对话。
流式推理和工具调用会出现在同一条消息里,就地编辑。
- 在手机上完全掌控 harness:会话(列出 / 恢复 / 分叉 / 重命名 / 归档)、模型与推理强度、工作区与当前项目文件夹、目标、待办、智能体收件队列、技能、子代理、智能体预设、已安装插件、凭据(仅描述)、主机设置、后台任务、主机文件浏览、会话历史。
- 回合回执与实时状态:每回合结束后给出一行回执(回合数、步数、工具调用数、token、缓存命中率),还有一张状态卡,工作运行时持续刷新。
- 智能体工具:智能体可以通过同一座桥把消息和文件回传给你。

快速开始

1. get the code
git clone https://github.com/SMMURDA/dsh-paean-telegram.git
cd dsh-paean-telegram

2. OPTIONAL rebuild — dist/ is committed, so this is only needed after source edits
npm ci && npm run build

3. install it into your DSH profile (see the next section)
4. create <workspace>/.pi/telegram.json with your chat id (see Configuration)
5. export the bot token, restart the harness, then send /start to your bot

Paean Harness

Paean Harness 是打包好的 DSH 发行版(@paean-ai/harness),由受监管的启动器拉起 Harness 进程,配置档放在 ~/.dsh/profiles/<name> 下——比如提供 Harness Web UI 的 web 配置档。它不带 Telegram 桥,所以维护这个插件,正好补上这个缺口。

上游插件在 Paean 上为什么跑不起来

Paean 运行时打包的是 @deepseek-ai/ 0.2.1-alpha.1,而上游插件是按 0.1.1-rc.2 的接缝写的。由此带来两个具体后果:

1. 插件的 @deepseek-ai/dsh- peer 范围(^0.1.1-rc.2)与运行中的 dsh 版本不匹配,除非授予精确版本豁免,否则安装会被拒绝;
2. 强行装进去之后,会话读取会坏掉——Session.events 在 0.2.x 上是方法,迭代它会抛 session.events is not iterable,于是 Sessions 卡片加载不出来。

这个构建把两道障碍都拆了:peer 范围覆盖 >=0.1.1-rc.2 <0.3.0,会话接缝则按主机暴露的形状来读。

Paean 安装步骤

git clone https://github.com/SMMURDA/dsh-paean-telegram.git
cd dsh-paean-telegram
dist/ is committed, so this is optional unless you changed the source
npm ci && npm run build

1. 装进运行 Paean Harness 进程的那个配置档(默认 Paean 环境里是 web)——见装进 DSH 配置档。
2. 创建 <workspace>/.pi/telegram.json,写上你的 chat id:

{ "security": { "allowedChatIds": [123456789] }, "watch": { "autoStart": true } }

3. 给进程一个 token:在环境变量里设 TELEGRAM_BOT_TOKEN,或者在包旁边放一个 chmod 600 的 .telegram-token。
4. 重启 Harness 进程。Paean 启动器受监管,会自己回来; Web UI 和机器人会有几秒不可用。
5. 向你的机器人发送 /start。

兼容性矩阵

| 环境 | @deepseek-ai/ | 状态 |
| Paean Harness 0.1.0-rc.21 | 0.2.1-alpha.1 | 主要目标 — 已实机验证 |
| 其他 DSH 配置档 | 0.1.1-rc.2 | 支持(旧版接缝) |
| 其他 DSH 配置档 | 0.2.x | 尽力支持 — 接缝与 Paean 相同 |
| DSH 0.3.x 及更高版本 | — | 未测试;可能需要做接缝适配 |

安装到 DSH 配置档

DSH 配置档决定 Harness 进程加载哪些插件。两条路径任选其一。

路径 A — plugin_manager(推荐)

1. 把本仓库克隆到一个固定目录。
2. 可选执行 npm ci && npm run build(仓库里已提交的 dist/ 可直接运行)。
3. 在 DSH 会话中,从绝对目录安装 bundle:

plugin_manager(action: "install_bundle", target: "/abs/path/to/dsh-paean-telegram")

bundle 补丁位于 cordis.patch.yml,它会挂载插件:

- insert:
- id: telegram
name: dsh-telegram

4. 如果你的配置档是启动配置档,重启 harness。

路径 B — 手动接线配置档

本部署用的就是这种方式,想就地改源码时也方便。

1. 让配置档依赖该目录(符号链接安装,改完重启 harness 即生效):

// ~/.dsh/profiles/<profile>/package.json
{
"dependencies": {
"dsh-telegram": "link:/abs/path/to/dsh-paean-telegram"
}
}

DSH 会检查每个 @deepseek-ai/dsh peer 范围与当前运行的 dsh 版本,以此强制插件与运行时兼容。只有当某个 peer 范围不匹配时,它才会在 ~/.dsh/profiles/<profile>/compatibility.json 里记录一条精确版本豁免,例如:

{ "dsh-telegram@0.4.0": ["0.2.1-alpha.1"] }

本分支的 peer 范围(>=0.1.1-rc.2 <0.3.0)同时覆盖 0.1.x 和 0.2.x 两代,所以通常不需要匹配的豁免。早前为旧构建记录的豁免会自动失效;留着或删掉都行。

2. 把插件行加进配置档补丁(~/.dsh/profiles/<profile>/cordis.patch.yml):

- insert:
- id: telegram
name: dsh-telegram

如果你还留着别的 Telegram 桥接,把它禁用掉 —— 同一个 bot token 上跑两个轮询器会争抢 getUpdates。禁用行长这样:

- id: other-telegram-bridge
name: "@local/some-other-bridge"
disabled: true

3. 重启 harness 进程,让 Host 加载插件。

Bot token

用 @BotFather 创建机器人,复制它的 token。插件从不写入 token,只按以下顺序读取:

1. harness 进程环境里的 TELEGRAM_BOT_TOKEN。
2. TELEGRAM_BOT_TOKEN_FILE 指定的文件。
3. 包旁边的 .telegram-token(已被 git 忽略,chmod 600)—— 适合本地检出场景,重启后仍可用,无需 shell 配置。

environment (for a manually started harness)
export TELEGRAM_BOT_TOKEN='<token from BotFather>'

or a checkout-local file
printf '%s' '<token from BotFather>' > /abs/path/to/dsh-paean-telegram/.telegram-token
chmod 600 /abs/path/to/dsh-paean-telegram/.telegram-token

配置

配置放在 <workspace>/.pi/telegram.json(每个工作区根目录一个文件)。所有键都是可选的,缺省时回落到下面的默认值。加载时会校验文件,也可以在聊天里用 /config get <path> 和 /config set <path> <value> 实时修改。

| 键 | 类型 | 默认值 | 含义 |
| security.allowedChatIds | number[] | [] | 入站流量的 chat-id 白名单。为空表示拒绝所有入站聊天。 |
| security.browseRoots | string[] | 无 | 可选的绝对路径白名单,限制主机/工作区浏览(/ls、/mkdir、/open、创建工作区)。缺省 = 不限制。 |
| security.selfAllow | boolean | 启用(缺省) | 自助引导的开关:未授权提示上的「允许此聊天」按钮。设为 false 后,点击该按钮只会返回拒绝文本,绝不改动名单。 |
| watch.autoStart | boolean | false | 插件挂载时自动启动长轮询。 |
| inbound.defaultMode | "auto-handle" \| "queue-only" \| "muted" | "auto-handle" | 入站聊天文本在到达智能体之前的处理方式。 |
| inbound.rules | {chatId?, pattern?, mode}[] | [] | 有序规则;首个匹配生效,否则用 inbound.defaultMode。pattern 是不区分大小写的子串。 |
| outbound.parseMode | "HTML" | "HTML" | 助手输出的 Telegram 解析模式。模型输出的 Markdown 会先规范化为合法的 Telegram HTML;卡片始终是 HTML。 |
| outbound.disableNotification | boolean | false | 静默发送。 |
| outbound.maxRetries | number | 3 | 单条消息在 429 / 网络错误时的重试次数。 |
| outbound.sendRatePerSecond | number | 20 | 全局发送配额(Bot API 的安全上限是 30)。 |
| outbound.maxMessageLength | number | 4096 | 单条载荷的硬上限;更长的文本会拆成多段。 |
| outbound.liveFeed | boolean | true | 一轮流式输出期间原地编辑同一条消息(可见思考过程 + 工具调用)。无需重启即可切换。 |
| compact.threshold | number | 0.8 | 最新请求占用上下文窗口的比例超过该值时触发压缩。 |
| compact.policy | "auto" \| "ask" \| "never" | "ask" | 自动压缩、先询问、或保持安静。 |
| compact.cooldownMs | number | 300000 | 同一会话两次触发之间的最小间隔。 |
| workspace.activePath | string | 缺省(启动目录) | 当前项目文件夹;新会话在它下面创建。在聊天里用 /project 设置。 |
| mode.name | string | "" | 状态卡片上可选的显示标签。 |
| model.provider / model.model | string | 配置档默认值 | Telegram 自己的默认模型,让 bot 跑一个和 web 端不同的模型。 |
| reasoning.effort | "minimal" \| "low" \| "medium" \| "high" \| "max" | medium | 每个聊天的推理强度;会在收到的消息前面加一条指令。 |
| media.transcribe.baseUrl | string | 服务商默认值 | 兼容 OpenAI 的转写端点,用于语音消息。 |
| media.transcribe.apiKey | string | 缺省 | 缺 key 就关闭转写,并给出提示,而不是悄悄丢掉。 |
| media.transcribe.model | string | 包默认值 | 转写模型名。 |
| interactive.userQuestions | "both" \| "telegram" \| "web" \| "auto" | "both" | ask_user_question 和审批卡片归哪个界面管。both 会同时镜像到 Telegram 和 web;哪边先回答,另一边就结束。 |
| interactive.allowByTool | string[] | [] | 点过「Allow forever (by tool)」后永久自动放行的工具名。用 /config set interactive.allowByTool [] 撤销。 |
| notify.onComplete | boolean | true | 目标回合结束时发一张新回执(带声音)。 |
| notify.onLongTask | boolean | true | 每 30 秒编辑一次进度卡片,让已用时间持续走动。 |

最小可用文件:

{
"security": { "allowedChatIds": [123456789] },
"watch": { "autoStart": true }
}

聊天名单(谁可以和 bot 说话)

chat-id 白名单是插件唯一的入站授权边界,白名单为空就拒绝所有人。安全地完成初始配置:

1. 把你自己的 chat id 放进 security.allowedChatIds。不确定 id?给 bot 发 /start —— 拒绝消息里会写出它看到的 chat id。
2. 或者留空白名单,在那条拒绝消息上按 「Allow this chat」:一键完成初始配置,把该聊天追加进名单(用 security.selfAllow: false 关掉它)。
3. telegram_status 智能体工具会报告桥接知道的聊天。

只有白名单里的聊天能收到卡片、命令或待处理的交互输入。其他聊天只回拒绝文案,别的什么都不回。

命令

在聊天里输入 /help 查看这份列表;/start 还会注册 BotFather 命令菜单。

| 命令 | 用途 |
| /start | 欢迎语 + 常驻按钮栏 |
| /menu | 核心菜单卡片 |
| /new | 在工作区里开新会话 |
| /compact | 压缩当前会话 |
| /abort | 中止当前回合 |
| /stop | 关闭这个聊天的会话 |
| /status | 实时状态卡片 |
| /queue | 查看或编辑智能体收件箱 |
| /todo | 显示当前会话的待办列表 |
| /sessions | 会话列表(按项目分组) |
| /history [sessionId] [turns] | 会话轨迹,按轮次分组 |
| /rename | 重命名当前会话 |
| /fork [atSeq] | 分叉当前会话 |
| /use <sessionId> | 切换到某个会话(冷启动时恢复该会话) |
| /archive <sessionId> | 归档会话 |
| /workspaces、/workspacecreate | 工作区列表 / 创建工作区 |
| /project [path]、/pickdir | 选择当前项目文件夹 |
| /models | 浏览服务商和模型 |
| /goals、/goal <objective> [maxRounds]、/goalcreate、/goalclear | 目标 |
| /presets | 智能体预设(会话为空时可选;会话中途切换会分叉) |
| /skills、/subagents、/plugins、/jobs | 清单 |
| /hostsettings、/settingsreplace、/settingsmutate | 主机设置 |
| /credentials | 凭据列表(只显示描述,绝不显示值) |
| /host、/ls [path]、/mkdir <path>、/openpath <path> | 主机详情与文件浏览 |
| /attachment <id> | 把已保存的照片附件发回去 |
| /pluginadd | 安装你自己的动态插件(JSON) |
| /bar | 显示或隐藏按钮栏 |
| /capabilities | 配置档能力矩阵(这个配置档提供哪些接缝) |
| /menucheck | 自检每个菜单数据源 |
| /answer <id> <question-number> <text> | 按 id 回答文本问题;没有选项的问题用这一条命令就能提交,有选项的问题仍需在卡片上点 Submit |
| /config get\|set <path> [value] | 实时读取或修改 bridge 配置 |
| /help | 全部命令 |

不是命令的文本,就是发给所绑定会话的普通智能体提示词。

按钮栏

按钮栏跟着欢迎卡片和每条回复一起出现,所以手机上永远不需要打开命令菜单:☰ Menu、✨ New、🧹 Compact、🧩 Models、🔌 Plugins、🎭 Mode、🧭 Sessions、📊 Status、⌛ Queue · N、🎯 Goal、📋 Todos · N、🧠 Reasoning、🧠 Thinking、🎭 Presets、⏹ Abort、⏹ Stop,另有一对折叠/返回按钮,把按钮栏收进一条小小的承载消息后面。

卡片

卡片是就地编辑的消息;Back/Close 和切换卡片都会自己清理现场。
可用卡片:about、allowed-chats、capabilities、credentials、dynamic plugins、feedback list、goals、history、host、host directory、host settings、jobs、mode、model thinking、models、provider models、providers、new session、presets、preset detail、plugins、project、queue、search、session detail、session projects、sessions、settings、settings namespace、skills、subagent detail、subagents、todos、watch、workspace detail、workspaces。

智能体工具

智能体通过这个 bridge 拿到七个工具:

| 工具 | 用途 |
| telegram_send | 向某个已知聊天发送 HTML 消息 |
| telegram_reply | 回复当前收到的消息(没有待回复消息时会失败) |
| telegram_broadcast | 把同一条消息发给多个聊天 |
| telegram_attach | 发送 1–10 个工作区文件:图片按照片发送,.ogg/.opus 按语音消息发送,其他音频按音频发送,其余一律按文档发送 |
| telegram_send_file | telegram_attach 的别名 |
| telegram_status | 桥接状态:bot 连接情况、智能体状态、队列、已知会话 |
| telegram_mark_no_reply | 把当前收到的消息标记为有意不回复 |

telegram_send、telegram_broadcast 和 telegram_attach 只接受名册上的会话,以及工作区根目录下的文件。

媒体与附件

- 照片/图片会并入本轮对话,供支持视觉的模型使用。
- 语音消息在设置了 media.transcribe.apiKey 时,通过 OpenAI 兼容端点转写;否则保存文件,并告诉智能体文件在哪里。
- 文档/视频保存到同一个附件目录,同时给智能体注入读取提示。
- 出站文件:1–10 个文件,每个 ≤ 50 MB,路径必须解析到工作区根目录内。
- 回答中的图片:回复用 Markdown 引用工作区图片时(light theme),桥接会把该文件作为照片上传,并从正文里删掉这处引用——聊天里出现的是截图,而不是它的路径。流式渲染器和 outbound.liveFeed 关闭时使用的核心转发器都支持这一行为。只有工作区根目录内的 png/jpg/jpeg 符合条件(先解析符号链接,同一个文件无论怎么写都只发送一次)。文件不存在、扩展名不是图片、远程 URL、文件超过 50 MB 上传上限,或者引用位于代码围栏/行内代码中,都原样留在文本里——文档永远不会被改写,也绝不会悄悄丢弃——并且一条回答最多带 10 张图片。
- 智能体的长回答按 Telegram 4096 字符的载荷上限拆分。

审批与提问

ask_user_question 和审批请求渲染为内联卡片,带 Allow once / for this session / forever (by tool)(高风险工具会标注)以及 Deny。设置 interactive.userQuestions: "both" 时,只要挂载了宿主 api-proxy,同一请求会同步到 Web UI,哪一侧先回答就以哪一侧为准。

自动压缩与长任务通知

- 设置 compact.policy: "auto" 时,请求超过上下文窗口的 compact.threshold 就触发压缩;"ask" 则先弹一次性审批卡片。压缩成功会连同摘要一起公告。
- 目标轮次和长时间静默的工具调用会在进度卡片上每 30 秒发一次心跳,目标完成会推送新的回执。两者都可通过 notify.onComplete / notify.onLongTask 开关。

安全模型

- Token:从环境变量或 chmod 600 文件读取;插件从不写入,也从不回显到聊天或日志。
- 入站:只认会话 ID 名册;名册为空则全部拒绝。可选一键引导,
- 用 security.selfAllow: false 禁用。
- 文件系统:/ls、/mkdir、/open 和工作区创建可用 security.browseRoots 限制范围;附件发送限制在工作区根目录内。
- 凭据:只列出描述,绝不列出密钥值。

运行时兼容性

本次构建面向 dsh 0.2.x Host API,同时仍接受旧的 0.1.x 形态,因此同一份构建可同时运行在两者上。发生变动的接口如下:

| 接口 | 0.1.1-rc.2(旧) | 0.2.x(当前) |
| 实时会话日志 | session.events(数组) | session.snapshotEvents()(方法) |
| 事件时间戳 | 事件 .at | 事件 .time |
| 持久化名单 | persistence.list() → { id, cwd } | list() → { header, revision } |
| 读取冷日志 | persistence.readRaw(id) | open(id, "read").read() |

说明:

- 在 0.2.x 主机上,读取 .events 得到的是方法,对它迭代会抛出 session.events is not iterable —— 这正是本分支修复的故障。见故障排查。
- dsh 已将 snapshotEvents() 标记为弃用(「禁止新调用」),这里把它当作唯一的同步访问器使用;长期迁移方向是事件驱动的折叠。
- Peer 范围(每个 @deepseek-ai/dsh peer 均为 >=0.1.1-rc.2 <0.3.0)在两代运行时上都满足 harness 的兼容性门槛,因此在 0.2.x 运行时上安装不再需要精确版本豁免。
- /sessionlog 跟随迁移后的导出接口:先探测 @deepseek-ai/dsh-session-log-export(通过 readSessionLogText 读取根日志),失败则回退到旧的 @deepseek-ai/dsh-host-apiproxy 模块及其 readRaw 读取。
- 按钮标签、卡片、回执和日志行均为英文;从上游继承的中文 UI 字符串已在 src/ 和 test/ 中全部替换。

开发

npm ci # dev dependencies (TypeScript 5.8, @deepseek-ai/* types)
npm run build # tsc -p tsconfig.json -> dist/
npm run typecheck # tsc --noEmit
npm test # build + node --test test/*.test.mjs
npm run check # build + typecheck + full suite

测试套件自包含:不需要真实 Telegram token,也不需要网络访问。test/runtime-compat.test.mjs 固定校验 0.2.x 主机形态(仅快照会话、time 时间戳、基于 open() 的冷读取),旧套件则继续固定校验 0.1.x 形态。

源码布局:

src/
index.ts plugin mount, token resolution, tool registration
config.ts config schema, defaults, validation, token resolution
core/ dispatch, commands, card registry, chat bindings, tools
cards/ one module per card (sessions, models, workspaces, …)
telegram/ transport, keyboards, markdown->HTML, queue, status panel
harness/adapters/ thin adapters over Host services (sessions, goals, llm, …)
extensions/ harness feed, reasoning, openclaw projections

故障排查

| 现象 | 原因与修复 |
| sessions roster load failed session.events is not iterable | 0.2.x 宿主上跑的是旧构建。重新构建(npm run build)并重启 harness——运行中的 Host 会一直持有先前导入的 dist/。本分支已修复。 |
| Telegram is not running: set TELEGRAM_BOT_TOKEN and send /telegram start. | harness 进程看不到 token。导出 TELEGRAM_BOT_TOKEN(或在包目录旁写 .telegram-token),然后重启。 |
| Conflict: terminated by other getUpdates request | 同一个 bot token 上有两个轮询者——另一个 bridge 实例,或本插件出现在两个配置档里。只保留一个启用。 |
| Bot API 返回 401 Unauthorized | token 错误,或已在 BotFather 中吊销。 |
| Bot 有回复,但没有卡片或命令 | 你的会话不在 security.allowedChatIds 里(名单为空会拒绝所有人)。 |
| 改了源码似乎没生效 | Host 导入的是旧模块:重启 harness。只替换 dist/ 不够,它还在缓存里。 |
| 升版本后出现 compatibility 错误 | 配置档里记录的豁免键不再匹配;恢复包版本,或新增一条豁免。 |
| /sessionlog 返回 session log ZIP is served by the web profile … | 找不到适用于该 harness 用户的导出接缝(@deepseek-ai/dsh-session-log-export,或旧的 apiproxy 模块)。确认该包能从 harness 工作目录或 $DSH_HOME 解析,然后重启。 |
| /sessionlog 报告超时 | ZIP 上限 50 MB、120 s;会话日志特别大时,改从 web UI 获取。 |

本构建的本地改动

相对上游 xqicxx/dsh-telegram 的 main:

1. Host API 兼容层,位于 src/harness/adapters/session-read.ts:
sessionEvents()、hasEventLog() 和 eventTime() 按宿主暴露的任一形态读取会话日志,另有 persistedRows() 和 readPersistedEvents() 覆盖两代持久化格式。
2. 所有会话日志读取方都已迁移到这些访问器:状态面板、todos、presets(空白检查、会话中切换、fork 边界)、fork、审批去重、搜索、历史和轨迹。
3. 上下文用量读取改为查看 agent.session,除旧的流式分片外,也接受已定稿的 assistant/message 用量。
4. 新增回归测试套件 test/runtime-compat.test.mjs(9 个测试),锁定 0.2.x 的形态;全套共 738 个测试,全部通过。
5. dist/ 有意提交,这样克隆后无需 TypeScript 工具链即可挂载;npm run build 会刷新它。
6. 上游的内部开发日志(中文的 TESTING.md、PLAN.md、progress.md、task_plan.md、findings.md、README.zh.md 和 docs/)未在此镜像;它们仍可在上游仓库中查看。
7. 仅英文 UI:src/ 和 test/ 下所有中文字符串、标签、日志行和注释被替换成英文,CHANGELOG.md 里引用的中文标签也一并翻译了。
8. 恢复 /sessionlog,供导出接缝已迁到 @deepseek-ai/dsh-session-log-export 的宿主使用:探测时先查当前包,再查旧版 @deepseek-ai/dsh-host-apiproxy 模块,并通过 readSessionLogText 读取根日志,以 readRaw 作为回退。
9. 放宽 dsh peer 版本范围至 >=0.1.1-rc.2 <0.3.0,这样 harness 的兼容性检查在 0.1.x 和 0.2.x 两代上都能通过,无需精确版本豁免。
10. 回答图片(src/media/image-refs.ts):文字回复中引用工作区图片(light theme)时,会把它作为照片上传,并从气泡中移除该引用,流式渲染器和核心转发器都如此处理。代码围栏、行内代码、远程 URL、缺失文件、非图片扩展名以及超过 50 MB 上限的文件保持原样;现在 telegram_attach 和回答图片共用同一个 uploadWorkspaceFiles()。
11. /answer 一步处理纯文本问题:暂存文本和结算 ask_user_question 卡片在同一次调用中完成,因此没有选项的问题不再一直挂起,直到点 ⏹ Abort。带选项的问题仍需点 Submit。

包版本保持 0.4.0,与本 fork 跟踪的上游发布保持一致。

致谢与许可

- 上游项目:xqicxx/dsh-telegram — MIT。
- 本 fork:由 SMMURDA 维护。
- 基于 MIT 许可证发布;原始版权声明保留在 LICENSE 中。重新分发此构建时,请保留该声明和本署名。
预览分享卡片长什么样 ↓SMMURDA/dsh-paean-telegram
分享 · DeepSeek Harness Hub
SMMURDA/dsh-paean-telegram

DeepSeek HarnessDSH的原生 Telegram 桥接,专为 Paean Harness…

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部