DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Telegram — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-telegram

Telegram

DeepSeek Harness 的 Telegram 频道——支持丰富的表格和列表、双向真实图片传输、内联键盘提问,以及在聊天中控制模型、预设和模式

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-telegram@0.2.0
README兼容性版本

兼容性与来源证明

Telegram 以 dsh-telegram 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/20

版本

0.1.1stable
2026/8/22
0.2.0stable
2026/8/18
0.1.0stable
2026/8/18

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
195.6 kB
文件数
17
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
251
安全扫描
✓ v0.2.0 扫描通过
最近提交
2026/8/19
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Im@xmanrui/dsh-im将十一种 IM 渠道和一个公网 AI Office 接入本地 DeepSeek Harness。Pocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。

README

dsh-telegram

A Telegram channel for DeepSeek Harness.

Written to fix four concrete failures of the generic channel bridge:

ProblemCauseFix
Bold, links and tables render as literal markdownparse_mode was never setMarkdown is compiled to Telegram's rich blocks — real tables and lists — with an HTML path behind it
The agent cannot send imagesthe reply path only ever passed { text }file references in a reply become real sendPhoto / sendDocument uploads
Questions have no answer buttonsno UserQuestionProvider was registeredquestions render as inline keyboards, with multi-select and free-text answers
No way to change model from chatonly /new existed/model, /preset, /mode, /status, /stop, /compact

Status: early. Verified end-to-end against a live bot on DSH 0.1.0-rc.7, but not yet tested by anyone else or against another DSH release. Expect the rough edges of a 0.1.0.

Install

dsh plugin --profile web add dsh-telegram

dsh plugin forwards to pnpm in the profile directory, so the published package above, a git URL (github:Gum97/dsh-telegram) or a local path (file:../dsh-telegram) all work.

Then add the bundle to the profile's package.json:

{
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-telegram"]
    }
  }
}

Store the bot token — it is never read from plugin config:

# $DSH_HOME/.credentials.yaml
TELEGRAM_BOT_TOKEN: "123456:ABC-DEF..."

Or paste it into Settings → Plugins → Telegram once the profile is running.

Settings page

The plugin registers the telegram settings namespace and ships a browser card keyed on it, so the bot token, the allowed-user list, the working directory and the display switches are editable from Settings → Plugins without touching a file.

Two behaviours are worth knowing:

  • The token is not stored in the settings document. Secrets are stripped from every wire response, so the card can only report whether a token is configured, never show one. It writes through the credentials domain, and a blank field leaves the stored token alone.
  • Not every change applies live. The allowed-user list and the display switches take effect on the next message. The token reference, the working directory and the on/off switch are read when the channel starts, so they apply after DSH restarts — the card says so before you save, and the log repeats it afterwards.

Values pinned in the profile's cordis.patch.yml become the namespace's base layer, so a deployment's choice survives until a user deliberately overrides it, and Reset on a field returns it to that value.

Building from source

The Host half is plain ESM JavaScript and runs as-is. The browser half is the one build step, because DSH's page loader takes a registered CJS factory rather than an ES module:

npm install
npm run build:client   # emits lib/client.js
npm test

prepublishOnly runs both, so a published tarball always carries a bundle that matches its source. React and the DSH client packages stay external require calls resolved by the page — bundling React would give the card a second React instance and break its hooks at runtime.

The upstream clientBundle build preset is not published, so tsdown.client.ts here reproduces its contract. This is a known gap in the out-of-repo plugin story, documented in dsh-client-ui-settings-plugins' own README.

Commands

CommandEffect
/startClaim an unclaimed bot (see below)
/newStart a fresh session for this chat
/modelPick a provider/model from buttons, or /model provider/model
/presetChoose the agent preset used by the next session
/modeSet the sandbox mode (read-only, workspace-write, danger-full-access)
/statusSession id, model, preset, sandbox mode, working directory
/stopCancel the running turn
/compactCompact conversation history
/helpList commands

Who may use the bot

allowedUsers decides, and an empty list means the bot is unclaimed rather than open to everyone.

The first person to send /start to an unclaimed bot is recorded as its owner and the door closes behind them — the way first-run device setup works. Every later stranger is refused and shown their own user id to pass along, and the owner widens access from Settings → Plugins → Telegram.

This matters because a bot's username is discoverable. A bot that accepted anyone would hand whoever found it an agent running shell commands on the owner's machine.

Language

The channel speaks Vietnamese or English, chosen by the language setting and switchable from the settings card. It governs both faces at once — the bot's messages and the card's own labels — because a bot answering in Vietnamese from a card labelled in English is one product speaking two languages at the user.

This is a channel setting rather than the host locale on purpose: DSH ships zh and en only, and its locale schema is a union over exactly those two, so a vi preference is rejected outright. Following the host would have meant hiding Vietnamese behind the Chinese option.

Configuration

KeyDefaultMeaning
enabledtrueTurn the channel off without removing it
tokenRefTELEGRAM_BOT_TOKENCredential name holding the bot token
allowedUsers[]Telegram user ids allowed to talk to the bot; empty means unclaimed
languagevivi or en, for bot messages and the settings card
workspaceRootprocess.cwd()Working directory for channel sessions
routeQuestionstrueAnswer a Telegram session's questions in Telegram, not the browser
streamingtrueEdit one message in place while the answer streams
showToolActivitytrueShow which tool is running inside the preview
richtrueUse real tables and lists (sendRichMessage)
preset—Agent preset for new channel sessions
bindingFile$DSH_HOME/dsh-telegram/bindings.jsonWhere the chat→session map lives

Everything above except preset and bindingFile is also user-editable from the Settings page; those two stay deployment concerns, since pointing the channel at an unwritable binding file would break it with no way back.

Design notes

Escaping happens once. Raw text is HTML-escaped up front; inline patterns then run against the escaped text. Because escaping removes every < and >, no user content can forge a tag. Code spans and fences are lifted out before escaping and restored after, so their contents never see emphasis processing.

Chunking splits the source, not the HTML. Slicing rendered HTML at 4096 bytes would cut a message mid-tag and Telegram would reject the whole send. Splitting markdown and rendering each piece guarantees balanced tags, and a fence spanning a boundary is closed and reopened.

Media never escapes the workspace. A referenced path is resolved against the session's workspace root and rejected if it lands outside; the reference stays as text rather than uploading an arbitrary file.

HTML failure degrades, never drops. If Telegram rejects a rendered payload, the client retries once as plain text. A formatting bug costs formatting, not the message.

Only channel-owned turns are delivered. A session can also be driven from the Web UI. The reply router tracks which turns it opened so those replies are not duplicated into the chat.

Questions in a web profile

The host allows exactly one user-questions provider process-wide, and in a web profile the Web bridge (dsh-host-apiproxy) registers first. Left alone, that means a question raised during a Telegram turn is answered in the browser, and the bot appears to stop mid-turn — the worst outcome for someone holding a phone.

So the channel installs a router over whichever provider holds the slot: sessions bound to a Telegram chat get inline keyboards, and every other session reaches the browser exactly as before. Set routeQuestions: false to switch it off and restore the plain behaviour.

This shares a slot the host models as exclusive, so it is written to fail safe: it checks the field is writable and the incumbent is recognisable before touching anything, hands the incumbent every session it cannot resolve, passes that provider's rejections through untouched, and restores it on disposal. A future DSH that makes the field private costs this feature, not the boot.

Tests

node --test 'test/*.test.js'

Covers the renderer (escaping, emphasis, tables, chunk balance, injection attempts) and media extraction (classification, workspace confinement, deduplication, album grouping) without contacting Telegram.