Workflow & Automation

dsh-im-bridge

MHfire/dsh-im-bridge/plugin · ★ 5

MHfire

WeCom intelligent-bot bridge that runs a per-sender DeepSeek Harness agent with a settings card.

License
MIT
Added
2026-10-30
Maintenance
active
Install kind
npm
npm
@mhfire/dsh-im-bridge
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T09:44:28.494Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add '@mhfire/dsh-im-bridge@0.4.4'

从 npm 安装预构建包

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. dsh-im-bridge
  2. Project overview
  3. Features
  4. Architecture
  5. Contents
  6. Compatible DeepSeek Harness versions
  7. Quick start
  8. Prerequisites
  9. 1. WeCom: create an AI Bot (once)
  10. 2. Install the plugin (recommended: npm package)
  11. From source / local development (optional)
  12. 3. Verify
  13. Settings plugin card
  14. Configuration
  15. Persona (persona.md)
  16. Legacy bridge.js
  17. Known limits
  18. Security
  19. License
  20. References

中文 | English

dsh-im-bridge

WeCom AI Bot ⇄ DeepSeek Harness Agent bridge

Connect WeCom (WeChat Work) AI Bot over a long-lived WebSocket, hand messages to a DeepSeek Harness Agent, and stream replies back to WeCom.

license version dsh


Project overview

This repository ships two run modes:

Mode Description Status
plugin/ DSH plugin (recommended): mounts into a dsh profile, creates Agents in-process, one durable session per WeCom chat window, visible in the Web GUI, with a Settings config card Recommended
bridge.js Legacy standalone script: spawns dsh --profile headless per message (stateless) Kept as fallback

Features

  • Direct WebSocket: no public URL, no message crypto, no IP allowlist
  • In-process Agent: no child process spawn; sessions register with the GUI for live view and continue-chat
  • One session per WeCom window: 1:1 = that user; the same group shares one session; a person’s DM and group chats stay separate
  • Channel-prefixed GUI titles: sidebar is 企微·私聊 / 企微·群 plus the first user prompt; leading @bot mentions are stripped on arrival
  • Archive starts a new session: archiving that row in the GUI makes the next message silently open wecom-<hash>-2; the old session is no longer written to
  • Optional WeCom office skills: ships @wecom/cli; when enabled, office 1:1 chats run office commands through the gated wecom_cli tool (requires a non-empty wecomCli.allowFrom; group chats and the GUI never see the tool)
  • Custom persona: zh/en packaged defaults follow Settings language; override with persona.md next to the profile patch
  • Settings card: credentials, allow-list, timeouts, copy, and model overrides are editable in the GUI; live fields apply on the next message, credential changes need a restart to open the WebSocket
  • Streaming animation + completion footer: stage/progress/ETA while running; duration summary when done
  • Workspace PNGs in the reply: ![caption](relative/path.png) in the final reply is uploaded and sent as a separate image after the text
  • Auth / heartbeat / exponential reconnect (built into the SDK)
  • Serial handling per WeCom window to avoid concurrent mix-ups

Architecture

flowchart LR
    U[WeCom user] -- WebSocket --> B[dsh-im-bridge]
    B -->|plugin mode| A1[In-process Agent<br/>agents.create + per-window session]
    B -->|bridge.js mode| A2[dsh --profile headless<br/>one process per message]
    A1 --> S[(Sessions/settings<br/>live in GUI)]
    A2 --> S
    B -- replyStream Markdown --> U

Contents

Compatible DeepSeek Harness versions

DeepSeek Harness is still a developer preview and makes no semver compatibility promise to out-of-tree plugins. Plugin 0.4.4 is aligned to published tags by the APIs it actually calls (details in plugin/README.en.md):

DSH This repo’s plugin
0.2.0-rc.2 Compatible (the line the plugin is developed and verified against)
0.1.2-rc.1 and earlier Not compatible. These versions have no configForms, no plugins.item, and no volatile form of this kind
untagged HEAD Not guaranteed. After upgrading dsh, re-check the Plugins page card and the WeCom connection

Pin dsh to 0.2.0-rc.2, for example npx @deepseek-ai/dsh@0.2.0-rc.2 web. Do not rely on a floating latest. Legacy bridge.js only needs a local dsh CLI and is not bound by the table above.

Quick start

Prerequisites

  • Node.js 18+ (required for legacy bridge.js; the plugin runs with dsh)
  • DeepSeek Harness 0.2.0-rc.2 (see the previous section)

1. WeCom: create an AI Bot (once)

  1. Open the WeCom Admin Console
  2. Apps → AI Bot → Create, set name/avatar
  3. Save credentials (Secret is shown once): BotID and Secret
# 1) Install into the target profile (e.g. web)
dsh plugin --profile web add @mhfire/dsh-im-bridge
# Or pin a version: dsh plugin --profile web add @mhfire/dsh-im-bridge@0.4.4

# 2) In $DSH_HOME/profiles/web/cordis.patch.yml, supply credentials
#    (other fields ship as bundle defaults; override as needed)
# - id: im-bridge
#   config:
#     botId: "<your BotID>"
#     secret: "<your Secret>"
#     # optional: workspace / personaFile / …

# 3) Restart dsh (pin the version, e.g. npx @deepseek-ai/dsh@0.2.0-rc.2 web)
# 4) Or fill botId/secret under Plugins → Official → WeCom Bridge, then restart
# 5) Message the bot in WeCom

From source / local development (optional)

dsh plugin --profile web add <repo-path>/plugin

3. Verify

The bot replies in WeCom, and the session appears in the DSH Web GUI session list (live view and continue-chat).

Settings plugin card

After the plugin is installed and dsh web is running, open Plugins → Official → WeCom Bridge in the sidebar. Save writes this profile’s cordis.patch.yml.

Card control Config key After save
Bot ID / Secret botId / secret Badge becomes “Configured”; a process restart is required to open the WebSocket. A blank save does not clear a stored credential
Allowed sender userids allowFrom Applies on the next message
Task timeout (seconds) agentTimeoutSec Applies on the next message
Placeholder while thinking startHint Applies on the next message
Denied-sender reply / welcome deniedMessage / welcomeMessage Applies on the next message
WeCom-only provider / model provider / model Applies only to later new WeCom-window sessions; both must be set to override

workspace, persona, thinking, and similar fields are not on the card; see the table below or plugin/README.en.md.

Configuration

Copy config.example.json to config.json and fill in values (config.json holds secrets; do not commit):

Field Description
botId / secret WeCom AI Bot credentials
workspace Agent working directory (session cwd)
dshCli Path to the dsh CLI entry (legacy bridge.js only)
agentTimeoutSec Max seconds per task
provider / model WeCom-only model; both required to override the GUI agent-default-model
allowFrom Allowed sender userids; empty [] = allow everyone
startHint Placeholder text when processing starts
thinking Streaming animation: tools / model reasoning vs output / timed fallback (see plugin/README.en.md)
deniedMessage / welcomeMessage Deny text / enter-chat welcome

patch (legacy bridge.js only, optional): path to a workspace --patch overlay (default workspace/headless.patch.yml, local config not in this repo). Add it yourself if needed, e.g. "patch": "headless.patch.yml".

Plugin fields can also be edited under Plugins → Official → WeCom Bridge (previous section) or in the profile patch. Full field list: plugin/README.en.md.

Persona (persona.md)

Precedence: personaFile → persona string → packaged default (zh/en via Host locale.preference; Chinese when unset).

  • Recommended: place persona.md next to cordis.patch.yml under $DSH_HOME/profiles/<name>/, and set personaFile to that absolute path (overrides do not follow language)
  • Defaults: plugin/persona.default.md / plugin/persona.default.en.md; template: plugin/persona.example.md
  • Do not commit secret-bearing persona files
  • Placeholders: {{model}} / {{cwd}} (unknown placeholders fail loudly)

Legacy bridge.js

cd <repo-path>
npm install
node bridge.js

When you see [bridge] 认证成功, 等待消息..., it is ready. Each message spawns a separate dsh --profile headless process (stateless). config.json is read once at startup; changes require a restart.

Known limits

  • v1 inbound is text-only (image/voice/file ignored); outbound can upload workspace PNGs referenced in reply Markdown and send them as separate images (see plugin/README.en.md)
  • Legacy bridge.js may hit spawn EPERM in restricted sandboxes; run normally
  • Legacy mode starts one agent process per message (expensive); the plugin does not
  • Agent output above ~20KB is truncated (WeCom replyStream limit is 20480 bytes)
  • Optional wecom-cli office skills: wecomcli-* and the gated wecom_cli tool register only on the office 1:1 agent; PATH wecom-cli always refuses; group chats do not get the office layer; leftovers in the workspace still leak to GUI; credentials live in workspace .dsh/wecom-cli (gitignore it); there is no GUI confirmation; the WeCom channel forbids ask_user_question (details in plugin/README.en.md)

Security

  • config.json and plugin/persona.md are gitignored — do not force-add or publish them
  • Before publishing, check docs/ and examples for environment-specific secrets

License

MIT

References