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

Telegram 桥接 aleksvega/dsh-tg-bridge

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

用 Telegram 机器人收发文本、语音和照片,远程驱动智能体

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · vision
装得上吗
本站尚未做安装检查
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:api.telegram.org

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

Telegram 桥接 DeepSeek Harness:收发文字、语音、图片,按话题分项目开会话,不用打开桌面应用

README

由 DeepSeek 最新模型翻译生成
dsh-tg-bridge DeepSeek Harness 的 Telegram 桥接:用文本、语音和照片从机器人驱动智能体,无需打开桌面应用。 每个论坛话题都是独立项目,有自己的会话和工作目录。回复会带上进度、「停止」按钮和可复制的代码块。 还没做过机器人?QUICKSTART.md 带你从「没有账号」一步步走到能应答的机器人。 功能 - 文本:普通任务交给智能体,答案回到同一话题。 - 语音:本地 faster-whisper,先显示转写文本,再给答案。 - 照片:本轮自己的模型通过 read_image 读取,文本和 UI 一并处理;不需要第二个模型(视觉叠加层仍为可选)。 - 每个话题一个项目:/cd my-app,之后所有轮次都在该目录下运行——在启用权限的配置档上,沙箱也会收窄到该目录,智能体无法写到项目之外。 - 每个话题的目标和清单:/goal、/tasks;两者都能在重启后保留,并在每轮前附加。 - 实时进度:每轮一条编辑中的消息——步骤、计时器和缓存命中率,外加模型推理,放在可点开的折叠块里。长轮次会再加一个折叠块,列出每次工具调用,整次运行在聊天里始终是一条消息。 - 消息不丢:带确认和重放的日志。
展开完整文档(README 剩余 1 节)
dsh-tg-bridge

DeepSeek Harness 的 Telegram 桥接:用文本、语音和照片从机器人驱动智能体,无需打开桌面应用。

每个论坛话题都是独立项目,有自己的会话和工作目录。回复会带上进度、「停止」按钮和可复制的代码块。

还没做过机器人?QUICKSTART.md 带你从「没有账号」一步步走到能应答的机器人。

功能

- 文本:普通任务交给智能体,答案回到同一话题。
- 语音:本地 faster-whisper,先显示转写文本,再给答案。
- 照片:本轮自己的模型通过 read_image 读取,文本和 UI 一并处理;不需要第二个模型(视觉叠加层仍为可选)。
- 每个话题一个项目:/cd my-app,之后所有轮次都在该目录下运行——在启用权限的配置档上,沙箱也会收窄到该目录,智能体无法写到项目之外。
- 每个话题的目标和清单:/goal、/tasks;两者都能在重启后保留,并在每轮前附加。
- 实时进度:每轮一条编辑中的消息——步骤、计时器和缓存命中率,外加模型推理,放在可点开的折叠块里。长轮次会再加一个折叠块,列出每次工具调用,整次运行在聊天里始终是一条消息。
- 消息不丢:带确认和重放的日志。
- 每个话题的设置:/crew use reviewer 让某个话题拥有自己的模型、effort、权限、智能体预设和语言,其他话题保持配置档;/crew off 恢复。四套内置组合以只读方式提供,可复制。
- 快速失败:配额用完时立刻切换到免费模型。
- dsh-tg check:一条命令完成诊断,不改动系统。
- 语言:菜单和服务消息支持 en、ru、zh;/lang 固定话题语言,不设时新话题取消息本身的语言(西里尔字母 → ru,汉字 → zh),再取 Telegram 的 language_code,最后是 en。
- 「停止」/「重试」按钮、工具确认:直接在消息里,不用敲命令。
- /report:一条命令把「它坏了」变成脱敏文档——版本、配置档、预设、模型、目录、最近一次失败和日志尾部,写文件前移除 token、密钥和主目录路径。

要求

- Node.js ≥ 24(DeepSeek Harness 自带的版本;会话用 zstd 压缩)
- DeepSeek Harness 0.2.1-rc.2 或更新,位于 0.2.x 系列(>=0.2.1-rc.2 <0.3.0)
- 已安装 DeepSeek Harness(~/.dsh/profiles/headless)
- 从 @BotFather 获取的 Telegram 机器人 token

支持的 harness 范围在 engines.dsh 中声明;该字段单独决定兼容性(存在时 DSH 忽略 peerDependencies)。范围包含显式的预发布分支,因为单纯的 <0.3.0 静默排除 0.2.2- 构建。将来发布 0.3.0 时需要显式提升版本号:桥接依赖 0.2.x 的命令行参数和配置档布局。

生态

中文 DSH 社区维护着最大的插件目录,以及读取这些目录的应用内市场;本桥接遵循它们的打包规则,因此能列在它们旁边:

- awesome-dsh-plugin — 双语(English / 中文)插件列表,以及 dsh-plugin-catalog npm 包
- dsh-market — 中文开发者打造的应用内市场,支持一键安装和主题
- dsh-find-plugin — 在聊天里找插件,不用翻目录

语言

- 菜单(聊天里的 /):三套,默认 ru,另有 en 和 zh;locale 两者都不匹配的客户端会拿到俄语那套。
- 话题语言:/lang en|ru|zh;存进 state.json,重启后仍然有效。
- 新用户的语言取自 Telegram 的 language_code;不是 ru/zh 的一律 → en。
- 目前已翻译:菜单、启动消息、回合状态、错误、/cd、/new、/stop、/lang、对未知命令的回复。长报告(/status、/sessions、/model 之类)仍是俄语,下一轮再处理。

安装

一条命令:你的 bot token 和数字 id。不用手动改任何东西。

Windows、macOS 或 Linux — Node.js 24 或更新。 init 和桥接在哪都能跑;setup(停止、自启动、重启)目前仅限 Windows,所以在 macOS 和 Linux 上用 sh install.sh,它会注册 launchd 或 systemd --user。
node setup.mjs --check 在每个平台都能报告状态。

npx dsh-tg-bridge@latest init --token 123456789:AA... --user 123456789
npx dsh-tg-bridge@latest setup

init 写入 token、你的 id 和工作目录;setup 注册自启动并启动桥接。

作为 DSH 插件(包里带 dsh.bundle;目录条目还在审核中):

dsh plugin --profile desktop add dsh-tg-bridge

DSH 启动时插件会拉起一个桥接,关闭时停掉它;如果桥接已经在跑(比如由计划任务启动),插件就不去动它。先跑 npx dsh-tg-bridge@latest init ...,保证配置存在。

init 做的事:

| 内容 | 位置 |
| bot token | ~/.dsh/.credentials.yaml → refs.DSH_TELEGRAM_BOT_TOKEN;其他键不动 |
| 你的 id 和工作目录 | ~/.dsh/tg-bridge/config.json;已有文件不覆盖 |
| headless 配置档 | 检查是否存在,缺失时提示怎么创建 |

init 参数:--cwd <path>(默认 ~/Projects)、--voice(启用语音转写)、--dry-run(只显示会写入什么,不做任何改动)。

可选的服务商设置放在 config.json 里:

| 键 | 含义 |
| providerKeys | 额外传给回合的环境变量名,从 ~/.dsh/.credentials.yaml 读取;默认 [] |
| pricesUrl | 已废弃:/prices 始终读取 OpenRouter 的公开列表,并把该数字标注为模型的参考值 |
| vision.patch | 为图片轮次启用的覆盖配置档;默认 "",即由该轮次自己的模型读取图片 |
| vision.enabled | 设为 true 后,图片轮次改用 vision.patch 运行,不再使用话题配置档 |
| fallbackModels | 按顺序排列的故障转移链;默认 [],详见下文 |
| fallbackEnabled | 设为 false 可关闭整条链,无需改动列表;/fallback off 会将其设为 false |
| maxParallel | 同时运行的话题数,1–8,默认 3;在聊天中也可用 /jobs 5 |
| replayWindowMs | 重启后,日志中的更新最多可以有多旧仍会被重放;默认 600000(10 分钟) |

fallbackModels 的每一项代表一次尝试,在该轮次自己的模型拒绝后按顺序尝试:

{
"provider": "router-a",
"model": "some-model",
"patch": "~/.dsh/tg-bridge/model-a.yml",
"free": false,
"off": false
}

patch 是一个覆盖文件,其中只有一行 agent-default-model(provider + model);它会作为独立的配置档生成一次,因此该轮次保留其他所有设置,只更换模型。provider 是服务商在配置档中写入时使用的 id,它决定预检探测向谁请求密钥和主机,因此同一个模型 id 在两个路由器上仍算两次尝试。free 只会在切换通知中加上 (free)。off 让条目留在列表中但不参与遍历;patch 文件缺失的条目也会以同样方式跳过,聊天中会说明这一点,而不是将其计入。

这条链可以混合不同公司:一个服务商返回 503 并不能说明另一家的情况,因此繁忙的通道会跳过自己的模型,仍会尝试下一家公司。把不同公司的模型相邻放置——同一个路由器的两条臂是一次故障,不是两次机会——并把 :free 模型放在末尾,作为最后的手段。

什么会触发切换。 服务商自身拒绝的任何情况:400/413/422 拒绝(其自己的校验器拒绝请求)、401/403(密钥被拒)、402 或配额/余额消息(账户为空)、404(不提供该模型 id)、429(速率限制)、5xx 以及 get_channel_failed / “all providers busy”(池不可用)、连接断开或 DNS/TLS 失败,以及空回答。拒绝只会再走一条其他路由,而不是整条链:请求会被完整重放,如果第二个供应商同样拒绝,那么问题出在请求本身,而不是路由,因此回复会建议用 /new 开启新会话。

什么不会触发切换。 轮次时间上限、/stop、会话或目录错误、缺少 dsh 二进制文件:其他供应商不会改变这些,重放会浪费一整轮来得到同样的结果。它们会列在卡片中,让区别可见,而不是靠猜。

/fallback — 从聊天中管理链

/fallback the card: chain state, numbered routes, what starts a switch
/fallback on | off 整条链(按路由:/fallback off 3) /fallback use 3 | skip 3 单条路由的启用或停用 /fallback up 3 | down 3 调整路由在顺序中的位置 /fallback test [3] 用 1-token 请求逐个询问每条路由(或指定一条) /fallback add <provider>/<model> 写入 overlay 并把路由追加到列表 /fallback remove 3 从列表里删掉一条路由(它的 overlay 文件保留)

卡片上每行都有按钮:● n 切换路由,↑ n / ↓ n 移动路由,每次按下后卡片原地重绘。test 只能证明密钥和通道是通的,不能证明服务商接受这段对话,所以一条路由可能回得了 ping,却仍然用 400 拒绝长提示词。卡片上就是这么写的。

id 从 @userinfobot 获取,token 从 @BotFather 获取。

Telegram 里的机器人设置

有三件事不做,机器人要么在群里一声不吭,要么只能半残工作:

1. Privacy mode → Disable(在 BotFather 里用 /setprivacy)。否则机器人只看得到命令,看不到话题里的普通文本。
2. 在群设置里启用 Topics(Edit → Topics)。不启用的话,所有工作都挤进同一个聊天,按话题分的会话建不起来。
3. 给机器人 Pin Messages 权限。只有固定话题第一条消息时才需要;没有这个权限,桥接照常工作,只是不会固定消息。

命令菜单不用手动配:init 和 setup 会一次性装好俄语、英语、中文三种。普通重启桥接不会刷新菜单,所以加完命令要跑 dsh-tg menu。完整设置表、权限、检查和常见错误见 docs/TELEGRAM-SETUP.md。

自启动有两条路。sh install.sh 在 macOS 上写 launchd,在 Linux 上写 systemd --user;dsh-tg setup 在 Windows 上注册 DSH-TG-Bridge 任务,运行带守护的 supervisor(登录时和每五分钟用同一个启动器),这样桥接崩了能自己回来,不会多出第二个轮询进程。在 macOS 和 Linux 上 setup 会拒绝执行并提示用 install.sh,因为它用 taskkill 停旧桥接、用 schtasks 注册自启动。

手动安装(想完全自己掌控时):

npm install -g dsh-tg-bridge
dsh-tg init --token 123456789:AA... --user 123456789
dsh-tg check # report only, changes nothing
dsh-tg setup # stop the old bridge and start the new one

如果桥接已经装好,setup 会用新代码重启它,并重装命令菜单。

故障排查

从零开始,或者帮别人从零开始:QUICKSTART.md 里有同样的答案,还附上他们实际会看到的终端输出。

错误回复末尾带一个代码,告诉你该修什么:

| 代码 | 含义 |
| INSUFFICIENT_QUOTA | 服务商余额为空:充值,或者继续用免费模型(/prices、/model) |
| TG_CONFLICT | 另一个进程正在轮询同一个 bot:执行 /doctor,再执行 /restart |
| MISSING_CREDENTIAL | 配置档里没有服务商密钥:在 DSH 应用里添加 |
| NO_DSH_CLI | 找不到 DeepSeek Harness 命令行:检查应用安装 |
| NETWORK | 连不上服务商网络:重试,检查 VPN/DNS |
| SANDBOX_DENY | DSH 拒绝访问某个文件或目录:检查项目路径和权限 |
| UNKNOWN_MODEL | 配置里的模型不可用:/model 会列出可用的模型 |
| EMPTY_RESPONSE | 模型没有返回内容:重试或切换模型(/model) |
| TURN_TIME_CAP | 本轮达到自身的时间上限:工作已保存,按 Continue |
| TURN_FAILED | 无法识别原因:执行 /doctor 和 /logs errors |

检查

给 bot 发送:

| 命令 | 预期结果 |
| /doctor | 报告:pid、Telegram、磁盘、目录、会话 |
| /update | 哪个 bridge 在运行、npm 上有什么、是否有更新版本(/update confirm 会安装) |
| /thoughts [file\|all\|off] | 把上一轮的推理过程作为消息发出;file/all 把完整日志作为 Markdown 文档发送,off 隐藏该块 |
| /help | 按类别分组的命令 |
| /cd my-app | 话题绑定到该项目,沙箱收窄到该项目 |
| /report | 把脱敏后的打包信息(版本、配置档、预设、模型、cwd、最近一次失败、日志尾部)作为文档发给所有者;在群里只发路径 |
| /prices | 当前模型的费用,以及这是谁的价格:你的服务商的、同一模型在另一网关上的,或者无人公布时的「无公开价格」 |

命令

Work: /cd · /new · /stop · /send · /seed Goals: /goal (plan + checklist) · /goal reopen · /tasks (checklist only) · /tasks done|rm|edit <n> Sessions: /status · /sessions · /sessions <id> · /rewind [n|undo|fork [n]|branches] Agents: /agents · /agents <id> · /agents set model|depth|filter Models: /model · /model <id> · /prices Tuning: /effort · /permissions · /preset · /plan · /jobs · /remind Profiles: /profile · /profile <name> · /profile new <name> from Sets: /crew · /crew use|off|new|copy|rm · /crew model <v> Extensions: /skills · /plugins · /plugins search <word> · /plugins disable|enable <id> · /soul Updates: /update · /update confirm · /update on|off|check|auto · /subscribe on|off Diagnostics: /doctor · /logs [errors|N|text] · /report Service: /app · /restart · /help Settings: /settings — the same switches as buttons, grouped in four tabs Display: /lang · /reasoning on|off · /thoughts

设置卡片

/settings 把命令能设置的开关画在同一条消息里,分四个标签页:bot 说什么、谁来回答以及多努力、新版本、健康检查。每一行显示该设置当前的值,以及点一下会变成什么。点一下等于执行人手动输入的那条命令(/reasoning off、/update on),所以卡片不会和命令打架:它只是命令的视图。改动之后,卡片收成一行普通文字——删掉它,聊天就回到原来的样子。

卡片上的东西没有一样只能在卡片上找到。/settings 是给那些宁愿按带标签的按钮、也不想记住 /effort、/preset、/crew 各自改什么的人用的。

每条命令都在聊天里回应 /help,用你写字的那种语言:用西里尔字母或汉字写的消息会把话题切到俄语或中文,哪怕手机菜单设成了别的语言;/lang 的优先级更高,能固定一个选择。Telegram 菜单显示同一份列表,只是少了 /subscribe:它就一行,关掉它的人不该还得去菜单里再找一遍。

更新

npm 标签 latest 只是个标签,不是更新器:装包会把版本固定在磁盘上,没人动它就不动。两个开关,都只管这次安装(不管话题,因为更新的是安装本身):

| 命令 | 作用 |
| /update | 一行:这里跑的是什么、发布的是什么、设了哪些开关 |
| /update on | 有新版本就告诉我:每个版本一条消息,每天检查一次 |
| /update off | 别再告诉我;不装任何东西,什么都不动 |
| /update auto | 除了告诉我,还自己装新版本(每小时检查一次) |
| /update confirm | 现在手动装新版本 |

上面除了 confirm 和 auto,别的都不安装;就连这两个也只改文件:运行中的进程会一直用旧模块,直到 /restart confirm,所以坏版本永远不会在聊天中途落地。confirm 和 auto 会把被替换的文件复制到 update-backup-<date> 并打印路径;把这个文件夹复制回去就是回滚,没有状态要撤销。

/subscribe on|off 和 /update on|off 说的是同一件事,给那些不想先读 /update 的人用。它故意不在 Telegram 菜单里。

失败不会有通知。桥接没法替你判断什么算失败,而「出错了」这种没人能处理的提示只是噪音;错误留在发生的地方,在 /doctor 和 /logs errors 下面。

工作原理

Telegram → bridge.mjs → dsh --profile headless --json → reply
│
├─ pending/ journal + ack (messages are not lost)
├─ per-topic queue (turns in topics run in parallel)
├─ progress + buttons (you can see the work is going)
└─ fail-fast on quota (free models as a fallback)

桥接是单个进程,用长轮询。每一轮都另起一个命令行进程,答完就退出,所以两轮之间「没有 DSH 进程」是正常的,不是故障。

在一轮进行中插话

如果一轮还在跑的时候你在话题里写字,消息不会排在它后面:桥接把任务丢进 ~/.dsh/tg-bridge/steer/,dsh-steer-inbox 插件会在下一步把它交给正在运行的智能体,智能体随即在聊天里回一句简短的话:现在在做什么,把新增内容放到了哪里。如果智能体 90 秒内没有动静,桥接层会自己写一句中性的话,避免冷场。

附件也是同样的处理方式。语音消息先转写,转写文本回显在聊天里,然后这段文字被引导进正在运行的那一轮;照片或文件会下载到本地路径,再把这个路径引导进去,和空闲轮次的交接方式完全一样。

每种附件在运行中的一轮里会变成什么:

| 发送内容 | 轮次内变成 | 需要 |
| 语音消息、音频文件、以文档形式发送的音频 | 转写文本,在引导前以 🎤 … 回显 | PATH 中有 faster-whisper,并用 init --voice 启用;默认关闭 |
| 小文本文件(.md、.json、.csv、.py、.log 等,最大 60 KB) | 内容本身,放在 <file> 标记之间——无需调用工具 | 无 |
| PDF、压缩包、二进制文件、更大的文件 | 本地路径,位于 ~/.dsh/tg-bridge/inbox/ 下 | 无;智能体用自己的工具打开 |
| 视频、视频消息、动图 | 路径;智能体可以用 ffmpeg 抽帧或提取声音 | 需要 ffmpeg,仅在需要帧或音频时 |
| 照片 | 路径加一句如实说明;轮次用 read_image 读取,读不了就一句话说明 | 支持图片的模型 |

语音是唯一有隐藏前提的一行。没装 faster-whisper 时,语音消息照样会到达——但只是一个智能体读不了的路径——所以桥接层会说明转写已关闭,而不是假装听到了什么。装好转写器后运行 dsh-tg init --voice,其他都不用改。

说明文字不会把附件变成纯文本消息:它会并入同一次交接,所以「为什么失败了」加上一个 .log 文件,会作为一次引导一起到达。

一个相册是一次请求,不是十次。Telegram 会把它作为每个文件一条更新送达,它们共享同一个 media_group_id;桥接层收集整组(最后一项之后静默 1.2 秒,最多 4 秒),然后一次性交接——运行中的轮次收到一次引导,空闲话题则开启一轮。

轮次触到时间上限时

turnTimeoutMs(默认 30 分钟,本安装为 75)是上限,不是目标:轮次一旦触到它,桥接层就用 ⏱ 停下,而不是让一个失控的循环霸占话题几个小时。什么都不会丢——会话和这一轮产出的每个文件都还在——所以消息里带 ⏵ Continue,让智能体检查状态,从停下的地方继续。这刻意不同于 Retry,后者会把整个任务从头重做。

这需要本仓库的插件:

dsh plugin --profile headless add link:<path-to-repository>/plugin/steer-inbox

并在 ~/.dsh/profiles/headless/cordis.patch.yml 里加一行:

- insert:
- id: steer-inbox
name: 'dsh-steer-inbox'
桥接器自己会检查配置档:如果这一行缺失,它就不写任务(写了也只会过期),而是照旧把消息排进队列。

实时思考与推理

有两样东西会落进同一条进度消息,而且各自都不会单独发一条聊天消息。

模型的推理。 命令行提交的每个 thinking 块都会折进一个 Telegram :折叠时只显示一行,点开就是这一轮完整的思考轨迹,而且这一轮结束后它仍然留在那里——和桌面应用里那个可以展开的推理区块一样。这个块只写一次,就在这一轮的最后一次编辑里,之后再也不碰:Telegram 每次编辑消息都会把已展开的块重新折叠,以前这会把聊天从读到一半的段落上拽走。这一轮运行期间,消息里只更新一个计数器(🧠 Размышления · 4821)和最后三步,这样实时编辑的内容能保持简短。内容会做转义;一轮思考得比一条消息装得下还长时,就裁到尾部;面板永远不超过一条消息。被裁掉的块会显示 … · начало скрыто · /thoughts file,发这个命令会把完整日志作为文档发过来。如果 API 拒绝这套标记,同样的内容会改用纯文本重试。

步骤。 三次调用可以内联放下。一轮里动作更多时,完整的步骤列表会移进第二个折叠块,同样在那次最终编辑里加上,这样「它到底跑了什么」点一下就能看到,而不是只看到一个数字。

智能体自己的笔记。 智能体可以留一段简短的决策轨迹:

node ~/.dsh/tg-bridge/say.mjs --thought "checking why the watchdog fired twice"

这条笔记会追加到 ~/.dsh/tg-bridge/thoughts/<chat>_<thread>.jsonl;进度消息里用 💭 行显示最后两条。这个命令不需要 id:它会回退到最新一轮的思考文件,因为工具 shell 不会继承桥接器的环境。--thought 自己从不发 Telegram 消息。

有些决定必须在轮次结束前让人知道——版本发出去了、原因找到了、卡住了——那就改用一行普通消息发到聊天里:

node ~/.dsh/tg-bridge/say.mjs --note "1.10.1 is on npm; restart to load it"

--note 会发一条真实消息,并且和 --thought 一样支持无 id 回退。这个分工是有意的:--thought 是进度消息里的工作轨迹,--note 是改变读者下一步预期的那一行短消息。进度消息本身开头会把请求回显出来(⏳ Принял: «…» · 3 с),所以人发完消息后第一眼看到的是自己的任务,而不是一个通用的转圈。

/reasoning 是 💭 机制的开关。它默认开启:每一轮都会带一条简短指令,要求在每个决策点留一行(任务明确、找到原因、有风险的改动、结果已核对)。/reasoning off 会去掉这条指令和该话题的 💭 行——当你只想要步骤列表时很有用。这个设置按话题存在 state.json 里,所以,闲聊型的研究话题和简洁的部署话题可以不一样。

推理块本身是模型输出;/thoughts 负责把它读回来:

- /thoughts —— 把最后一轮作为消息分片发出来,三分钟后删除;
- /thoughts file —— 把整个最后一轮存成 reasoning-<date>-file.md,以文档形式发送(五小时的一轮有数万字符,任何聊天消息都装不下);
- /thoughts all —— 把会话的每一轮都放进一个文件(长会话有几百 MB);
- /thoughts off / on —— 把推理块从轮次面板里拿掉(面板随后显示 🧠 Размышления · N · /thoughts file),或者放回来。

日志按需从会话文件生成,所以一轮运行期间不会有任何重复内容。
文件落在 ~/.dsh/tg-bridge/thoughts/,旧文件一周后清理。

按话题配置配置档

桌面应用允许你为不同类型的工作建多个配置档,每个都有自己的插件集和模型。同样的切换在话题里也能用:

/profile current profile, available ones, hints
/profile research run this topic's turns on another profile
/profile new research from web
create a profile from a shipped template and bind it
/profile default back to the install default

新配置档由 dsh <name> --from-default-profile --dump-config 写入,所以创建时不会启动任何东西,也不加载任何插件;依赖在配置档的第一轮里安装。绑定按话题生效:之后 /model 改的是该配置档的模型,/plugins 管理的是该配置档的行,/plugins search <word> 列出 npm registry 上带 dsh-plugin 关键字的东西 —— 相当于桌面应用的插件浏览器,只不过在聊天里。每条结果都带一个加号按钮,点了就执行 /plugins add <name>。

话题写入的目录

/cd my-app 做两件事,这两件事值得分开说,因为以前它们是一件事:轮次在那个目录里运行,沙箱止步*于那个目录。后半句只在有权限表的配置档上生效 —— 桥接只在权限表存在时写入那一行,绝不会给选择退出的配置档凭空造一个。

/cd my-app bind the topic: run here, and write only here
/cd ~/Projects/api wide run here, but do not narrow the sandbox
/cd reset unbind; the topic goes back to config.cwd
/cd what this topic is bound to, and how

| 沙箱模式 | 根目录内写入 | 根目录外写入 |
| read-only | 拒绝 | 拒绝 |
| workspace-write | 允许 | 拒绝 |
| danger-full-access | 允许 | 允许 |

workspaceRoot 是边界,即使轮次切换了自己的工作目录,这条边界依然成立:拒绝跟随的是配置的根目录,而不是智能体搬去的目录。这正是关键 —— 模型游荡进另一个项目时,得到的是拒绝,而不是写入。
这张表没有说明三件事,因为实测结果和想当然的读法对不上:

- 只改沙箱那一行,什么都不会变。sandbox-policy 行里写 mode: read-only,权限表里写 defaultPreset: danger-full-access,照样能写到根目录外面。权限表说了算;沙箱那一行只是给没有权限表的配置档用的默认值。
- 所以 danger-full-access 必须按话题逐个手动选(/permissions danger-full-access),它也是唯一能写到根目录外面的模式。
- 带 approval: ask 的预设根本没法在聊天里用:无头回合没有审批通道,升级会失败关闭,回合直接报错。/permissions 列出这类预设时会附上原因,不让人踩坑。

原样安装的版本没有启用权限:cordis.patch.yml 只带 tg-bridge 插件那一行,所以 /cd 照旧绑定目录,/permissions 照旧改整个配置档的预设。按话题生效的行为,要等配置档第一次有了权限表才开始。

目标与任务

每个话题有自己的目标和清单,所以 /new、重启、换会话之后目标都还在:

/goal ship the release set or replace the goal
/goal show the goal and the checklist
/tasks write the migration add a task
/tasks done 2 tick it off
/tasks edit 2 shorter words rewrite it in place, same number
/tasks rm 2 remove it
/goal reopen open a closed goal again
/goal done close the goal (all tasks done)
/goal clear delete the goal and its tasks

桥接器会在每个回合前面加上目标和清单,并附上更新它的确切命令(goal.mjs)。智能体做完一项就勾掉一项,下一回合就能看到新状态。state.json 只有桥接器能写:智能体把任务文件丢进 goal-jobs/,桥接器负责应用,所以不会抢锁,也不会丢更新。

安全

- config.json、state.json、pending/、日志都在 .gitignore 里,永远不会进仓库。
- token 存在 DSH 凭据库里,不在代码或配置里。
- 桥接器只回复 allowedUserIds 里的 id。

文档

- docs/TELEGRAM-SETUP.md:BotFather 设置、群组和机器人权限
- docs/SUPPORT.md:报 bug 时该附什么、永远别附什么,以及「机器人不吭声了」的一句话答案
- docs/ROADMAP.md:接下来做什么
- docs/UX-ANALYSIS.md:交互体验评审
- docs/COST.md:一轮对话花多少成本,以及怎么降低
- docs/CHANGELOG.md:变更记录
- docs/RELEASE-CRITERIA.md:发布就绪标准

许可证

MIT,见 LICENSE。
预览分享卡片长什么样 ↓aleksvega/dsh-tg-bridge
分享 · DeepSeek Harness Hub
aleksvega/dsh-tg-bridge

用 Telegram 机器人收发文本、语音和照片,远程驱动智能体

这是你的仓库?认领条目

回到顶部