@lijian-ui/dsh-im-gateway 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +183 -0
- package/README.zh-CN.md +207 -0
- package/cordis.patch.yml +24 -0
- package/lib/client.js +1233 -0
- package/lib/index-2mMnMMFx.d.ts +304 -0
- package/lib/index.js +3623 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lijian-ui
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# @lijian-ui/dsh-im-gateway
|
|
2
|
+
|
|
3
|
+
> Multi-channel IM gateway plugin for **DeepSeek Harness (dsh)** — connect DingTalk, QQ and WeChat (iLink) bots to your harness agent, with QR-scan binding and streaming replies.
|
|
4
|
+
>
|
|
5
|
+
> 为 DeepSeek Harness 提供多 IM 通道接入的网关插件:钉钉 / QQ / 个人微信,支持扫码绑定与流式回复。
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@lijian-ui/dsh-im-gateway)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Features / 功能特性
|
|
13
|
+
|
|
14
|
+
- **Unified gateway service** — one plugin, three channels. Every channel routes through a single `ctx.imGateway` core: session management, slash commands, streaming, status broadcast.
|
|
15
|
+
- **DingTalk (钉钉)** — outbound WebSocket stream connection, group + single chats, @-mention filtering, **AI card streaming** (real-time incremental replies), slash commands.
|
|
16
|
+
- **QQ** — WebSocket gateway (official `qqbot-nodejs` SDK), private (c2c) + group chats, **QR-scan bot binding** (no manual console setup), **streaming messages** (c2c).
|
|
17
|
+
- **WeChat (个人微信 / iLink)** — official iLink long-poll protocol, **QR-scan login + pairing code**, single-chat only, media (AES-128-ECB CDN) in/out.
|
|
18
|
+
- **Multi-bot instances** — the same channel type can appear many times (e.g. two DingTalk bots), each with its own credentials.
|
|
19
|
+
- **Built-in slash commands** — `/help`, `/model`, `/status`, `/new`, `/reset`, `/stop` … (see below).
|
|
20
|
+
- **Settings UI** — a full web settings page ("IM 通道") rendered inside the official dsh web UI; QR-scan binding happens right there.
|
|
21
|
+
- **Streaming replies** — DingTalk AI Card, QQ stream_messages; plain-text fallback when a channel doesn't support streaming.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation / 安装
|
|
26
|
+
|
|
27
|
+
Requires DeepSeek Harness (dsh) — the plugin is a standard **dsh bundle** and installs through the official plugin channel.
|
|
28
|
+
|
|
29
|
+
### From npm (recommended) / 从 npm 安装(推荐)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dsh plugin --profile web add @lijian-ui/dsh-im-gateway
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The npm package ships pre-built `lib/` — **no build authorization needed** (`allowBuilds` is not required).
|
|
36
|
+
|
|
37
|
+
### From tarball / 从 tarball 安装
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm pack @lijian-ui/dsh-im-gateway
|
|
41
|
+
dsh plugin --profile web add ./dsh-im-gateway-0.1.0.tgz
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### From GitHub / 从 GitHub 安装
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
dsh plugin --profile web add github:lijian-ui/dsh-im-gateway
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> Git installs fetch **source**, so the first install requires approving the package's `prepare` build script (pnpm ≥ 10). Add the package key to the profile's `pnpm-workspace.yaml` → `allowBuilds` when prompted. Prefer npm/tarball to skip this.
|
|
51
|
+
|
|
52
|
+
### Verify / 验证安装
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
dsh --profile web --dump-config # 应看到 "# == @lijian-ui/dsh-im-gateway" 配置层
|
|
56
|
+
dsh --profile web # 启动后浏览器打开设置 → 「IM 通道」
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Quick Start / 快速上手
|
|
62
|
+
|
|
63
|
+
1. Open the dsh web UI → **Settings → IM 通道**.
|
|
64
|
+
2. Click **添加通道** (Add channel).
|
|
65
|
+
3. Pick a channel type:
|
|
66
|
+
- **QQ**: click **扫码登录** → scan with mobile QQ → credentials auto-fill → save.
|
|
67
|
+
- **个人微信**: click **扫码登录** → scan with mobile WeChat → (enter the pairing code if asked) → credentials auto-fill → save.
|
|
68
|
+
- **钉钉**: fill in AppKey / AppSecret manually (or edit the config file) → save.
|
|
69
|
+
4. Message your bot from the IM client — replies stream back in real time.
|
|
70
|
+
|
|
71
|
+
> Config is stored under `~/.dsh/settings.yaml` (`im-gateway.channels`). Saving from the UI hot-reloads the channels (no restart needed).
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Slash Commands / 斜杠命令
|
|
76
|
+
|
|
77
|
+
Sent to the bot in any IM channel:
|
|
78
|
+
|
|
79
|
+
| Command | Description |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `/help` | List available commands |
|
|
82
|
+
| `/model` | List models with emoji numbers; `/model 1` or `/model <name>` to switch (no session yet → sets default for next conversation) |
|
|
83
|
+
| `/status` | Channel / cwd / current model / agent state |
|
|
84
|
+
| `/new` `/reset` `/clear` | Start a fresh conversation |
|
|
85
|
+
| `/stop` | Abort the current reply |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Configuration / 配置
|
|
90
|
+
|
|
91
|
+
Everything is editable from the settings UI; the underlying schema lives in `~/.dsh/settings.yaml`:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
im-gateway:
|
|
95
|
+
channels:
|
|
96
|
+
- id: dingtalk-main
|
|
97
|
+
type: dingtalk
|
|
98
|
+
name: 主机器人
|
|
99
|
+
enabled: true
|
|
100
|
+
config:
|
|
101
|
+
clientId: "..."
|
|
102
|
+
clientSecret: "..."
|
|
103
|
+
# callbackBaseUrl, appId, botAppId, baseUrl, botId, cdnBaseUrl, pollIntervalMs...
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| Field | Applies to | Meaning |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| `clientId` / `clientSecret` | dingtalk | DingTalk app key / secret (Stream mode) |
|
|
109
|
+
| `appId` / `clientSecret` | qq | QQ Open Platform credentials (QR-bound) |
|
|
110
|
+
| `token` / `botId` / `baseUrl` / `cdnBaseUrl` | weixin | iLink credentials (QR-bound) |
|
|
111
|
+
| `enabled` | all | Whether this instance connects |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Architecture / 架构
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
IM client ──► channel adapter (dingtalk / qq / weixin)
|
|
119
|
+
│ ImInboundMessage
|
|
120
|
+
▼
|
|
121
|
+
ctx.imGateway (core)
|
|
122
|
+
│ ensureSession → agent.followup
|
|
123
|
+
▼
|
|
124
|
+
dsh harness agent (LLM loop)
|
|
125
|
+
│ session events (turn/start, assistant/chunk, tool/call, turn/end)
|
|
126
|
+
▼
|
|
127
|
+
streaming reply → adapter.beginStream/streamText/endStream
|
|
128
|
+
│ (AI Card / stream_messages / plain text fallback)
|
|
129
|
+
▼
|
|
130
|
+
IM client
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **Host half** (node): `src/index.ts` (apply), `src/gateway/` (core + slash commands), `src/channels/` (dingtalk / qq / weixin + protocol helpers), `src/remote.ts` (Typert RPC for the settings UI), `src/sync.ts` (channel reload on config save).
|
|
134
|
+
- **Client half** (browser): `src/client/` — settings page "IM 通道" (add/edit modal + QR-scan login + status dots).
|
|
135
|
+
- **Multi-bot**: `channels` is an array; the same `type` may appear multiple times.
|
|
136
|
+
|
|
137
|
+
### Extension points / 扩展点
|
|
138
|
+
|
|
139
|
+
Third parties can register their own channel without forking:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { ImChannelAdapter } from '@lijian-ui/dsh-im-gateway' // peerDependency on the core
|
|
143
|
+
|
|
144
|
+
class MyChannelAdapter implements ImChannelAdapter { /* ... */ }
|
|
145
|
+
ctx.imGateway.registerChannel(myAdapter)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Development / 开发
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
git clone https://github.com/lijian-ui/dsh-im-gateway.git
|
|
154
|
+
cd dsh-im-gateway
|
|
155
|
+
npm install
|
|
156
|
+
npm run build # tsdown → lib/
|
|
157
|
+
npm run watch # rebuild on save
|
|
158
|
+
npm run typecheck
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Local link into a dsh profile:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
dsh plugin --profile web add ./ # 从本目录安装(link)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
> **Windows note**: the dsh subprocess loads `lib/index.js` from `package.json` `main` — after editing `src/`, always `npm run build` then restart the dsh process (its require cache keeps the old module).
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Troubleshooting / 常见问题
|
|
172
|
+
|
|
173
|
+
- **No logs from the plugin** — cordis buffers `ctx.logger.*` in memory by default. The plugin registers a console exporter on apply, so logs appear in the dsh subprocess stderr (desktop shells prefix them with `[dsh]`).
|
|
174
|
+
- **QQ client shows "连接中" forever** — streaming was opened too early or never closed. This plugin opens the stream on the first assistant text delta and always closes it on `turn/end` (fixed in 0.1.x).
|
|
175
|
+
- **Chat works but replies are not streaming** — the channel fell back to plain text (e.g. QQ group chats don't support `stream_messages`; WeChat has no streaming concept). This is by design.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## License / 许可
|
|
180
|
+
|
|
181
|
+
MIT © lijian-ui
|
|
182
|
+
|
|
183
|
+
Built for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — independent plugin, not affiliated with or endorsed by DeepSeek. 独立插件,与 DeepSeek 无隶属或背书关系。
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# @lijian-ui/dsh-im-gateway — DeepSeek Harness 多 IM 通道网关插件
|
|
2
|
+
|
|
3
|
+
> 把钉钉、QQ、个人微信(iLink)机器人接入 DeepSeek Harness(dsh)的 agent,支持扫码绑定、流式回复、斜杠命令与设置页可视化配置。
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@lijian-ui/dsh-im-gateway)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 一、这是什么
|
|
11
|
+
|
|
12
|
+
`@lijian-ui/dsh-im-gateway` 是 **DeepSeek Harness(dsh)官方插件体系**下的一个组合包(bundle):一个统一的核心网关 + 三个渠道适配器,让你在钉钉 / QQ / 微信上跟 harness agent 对话。
|
|
13
|
+
|
|
14
|
+
- **一个插件,三种渠道**:所有渠道都走同一个 `ctx.imGateway` 核心(会话管理、斜杠命令、流式回复、状态广播)。
|
|
15
|
+
- **扫码绑定,开箱即用**:QQ 和微信不需要去开放平台手动创建机器人——设置页里点「扫码登录」,手机一扫凭据自动填好。
|
|
16
|
+
- **流式回复**:钉钉 AI 卡片实时出字、QQ stream_messages 逐字推送;不支持流式的渠道自动降级为整条文本。
|
|
17
|
+
- **多机器人实例**:同一个渠道类型可以配多个机器人(比如两个钉钉 bot),各自独立凭据。
|
|
18
|
+
- **Web 设置页**:在官方 dsh Web UI 里多出「IM 通道」设置页,扫码、配置、在线状态一目了然。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 二、功能特性
|
|
23
|
+
|
|
24
|
+
### 钉钉(dingtalk)
|
|
25
|
+
- 出站 WebSocket 长连接(官方 Stream 模式),**无需 webhook**
|
|
26
|
+
- 单聊 + 群聊;群聊仅响应 @机器人 的消息(防打扰)
|
|
27
|
+
- **AI 卡片流式输出**:回复像"打字机"一样实时出字,含工具调用提示、完成动画
|
|
28
|
+
- 引用回复 / 图片 / 语音转文字等入站能力
|
|
29
|
+
|
|
30
|
+
### QQ
|
|
31
|
+
- 官方 `@tencent-connect/qqbot-nodejs` WebSocket 网关
|
|
32
|
+
- 私聊(c2c)+ 群聊(仅 @ 响应)
|
|
33
|
+
- **扫码绑定机器人**:`qqbot-connector` 扫码后自动拿到 AppID / AppSecret,免去开放平台手动创建
|
|
34
|
+
- **流式消息**(c2c):`stream_messages` 逐字推送;群聊自动降级为普通文本
|
|
35
|
+
|
|
36
|
+
### 个人微信(weixin / iLink)
|
|
37
|
+
- 微信官方 iLink 协议(`ilinkai.weixin.qq.com`),纯 fetch 长轮询,无额外依赖
|
|
38
|
+
- **扫码登录 + 配对码**:手机微信扫码后按提示输入配对码即完成绑定
|
|
39
|
+
- 仅单聊(一个个人微信号绑一个 bot)
|
|
40
|
+
- 入站图片 AES-128-ECB 解密、出站媒体上传;文本经流式 Markdown 过滤(微信不渲染 MD)
|
|
41
|
+
|
|
42
|
+
### 通用能力
|
|
43
|
+
- **斜杠命令**:`/help` `/model` `/status` `/new` `/reset` `/clear` `/stop`
|
|
44
|
+
- **多实例**:`channels` 是数组,同一类型可配多个
|
|
45
|
+
- **热更新**:设置页保存后立即重建通道,无需重启
|
|
46
|
+
- **状态广播**:设置页每个通道卡片显示在线 / 离线 / 错误状态点
|
|
47
|
+
- **模型切换**:`/model` 列出可用模型(emoji 编号),无会话时可设置全局默认模型
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 三、安装
|
|
52
|
+
|
|
53
|
+
需要已安装 DeepSeek Harness(dsh)。本插件是标准 dsh bundle,走官方插件安装通道。
|
|
54
|
+
|
|
55
|
+
### 3.1 从 npm 安装(推荐)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
dsh plugin --profile web add @lijian-ui/dsh-im-gateway
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
npm 包自带**预构建的 `lib/`**,安装即用——**不需要** `allowBuilds` 构建授权。
|
|
62
|
+
|
|
63
|
+
### 3.2 从 tarball 安装
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm pack @lijian-ui/dsh-im-gateway
|
|
67
|
+
dsh plugin --profile web add ./dsh-im-gateway-0.1.0.tgz
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3.3 从 GitHub 安装
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
dsh plugin --profile web add github:lijian-ui/dsh-im-gateway
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
> git 安装拉取的是**源码**,首次安装需要授权 `prepare` 构建脚本(pnpm ≥ 10 默认拒绝)。按提示把包键加进该 profile 的 `pnpm-workspace.yaml` → `allowBuilds` 即可。想跳过授权就用 npm / tarball 方式。
|
|
77
|
+
|
|
78
|
+
### 3.4 验证安装
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dsh --profile web --dump-config # 输出里应有 "# == @lijian-ui/dsh-im-gateway" 配置层
|
|
82
|
+
dsh --profile web # 启动后浏览器打开设置 → 「IM 通道」
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 四、快速上手
|
|
88
|
+
|
|
89
|
+
1. 启动 dsh,浏览器打开 Web UI → **设置 → IM 通道**。
|
|
90
|
+
2. 点 **添加通道**,选渠道类型:
|
|
91
|
+
- **QQ**:点 **扫码登录** → 手机 QQ 扫码 → 凭据自动填入 → 保存。
|
|
92
|
+
- **个人微信**:点 **扫码登录** → 手机微信扫码 → (如提示)输入配对码 → 凭据自动填入 → 保存。
|
|
93
|
+
- **钉钉**:手动填 AppKey / AppSecret(或直接改配置文件)→ 保存。
|
|
94
|
+
3. 在 IM 客户端给你的机器人发消息——回复实时流式返回。
|
|
95
|
+
|
|
96
|
+
> 配置存于 `~/.dsh/settings.yaml` 的 `im-gateway.channels`。设置页保存后**热重载**,无需重启。
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 五、斜杠命令
|
|
101
|
+
|
|
102
|
+
在任意 IM 渠道给机器人发:
|
|
103
|
+
|
|
104
|
+
| 命令 | 说明 |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| `/help` | 列出可用命令 |
|
|
107
|
+
| `/model` | 列出模型(emoji 编号);`/model 1` 或 `/model <名称>` 切换;无会话时设为下次会话的默认模型 |
|
|
108
|
+
| `/status` | 渠道 / 工作目录 / 当前模型 / agent 状态 |
|
|
109
|
+
| `/new` `/reset` `/clear` | 开启新会话 |
|
|
110
|
+
| `/stop` | 中止当前回复 |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 六、配置
|
|
115
|
+
|
|
116
|
+
优先在设置页编辑;底层存于 `~/.dsh/settings.yaml`:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
im-gateway:
|
|
120
|
+
channels:
|
|
121
|
+
- id: dingtalk-main
|
|
122
|
+
type: dingtalk
|
|
123
|
+
name: 主机器人
|
|
124
|
+
enabled: true
|
|
125
|
+
config:
|
|
126
|
+
clientId: "你的 AppKey"
|
|
127
|
+
clientSecret: "你的 AppSecret"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
| 字段 | 适用渠道 | 含义 |
|
|
131
|
+
| --- | --- | --- |
|
|
132
|
+
| `clientId` / `clientSecret` | dingtalk | 钉钉应用凭据(Stream 模式) |
|
|
133
|
+
| `appId` / `clientSecret` | qq | QQ 开放平台凭据(扫码绑定自动填) |
|
|
134
|
+
| `token` / `botId` / `baseUrl` / `cdnBaseUrl` | weixin | iLink 凭据(扫码绑定自动填) |
|
|
135
|
+
| `enabled` | 全部 | 该实例是否启用连接 |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 七、架构
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
IM 客户端 ──► 渠道适配器(dingtalk / qq / weixin)
|
|
143
|
+
│ ImInboundMessage
|
|
144
|
+
▼
|
|
145
|
+
ctx.imGateway(核心)
|
|
146
|
+
│ ensureSession → agent.followup
|
|
147
|
+
▼
|
|
148
|
+
dsh harness agent(LLM 循环)
|
|
149
|
+
│ 会话事件(turn/start、assistant/chunk、tool/call、turn/end)
|
|
150
|
+
▼
|
|
151
|
+
流式回复 → 适配器 beginStream/streamText/endStream
|
|
152
|
+
│ (AI 卡片 / stream_messages / 纯文本降级)
|
|
153
|
+
▼
|
|
154
|
+
IM 客户端
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **Host 半(node)**:`src/index.ts`(apply)、`src/gateway/`(核心 + 斜杠命令)、`src/channels/`(三渠道 + 协议层)、`src/remote.ts`(Typert RPC,供设置页调用)、`src/sync.ts`(配置保存后重建通道)。
|
|
158
|
+
- **Client 半(浏览器)**:`src/client/`——设置页「IM 通道」(添加/编辑弹窗、扫码登录、状态点)。
|
|
159
|
+
- **多实例**:`channels` 是数组,同一 `type` 可出现多次。
|
|
160
|
+
|
|
161
|
+
### 扩展点
|
|
162
|
+
|
|
163
|
+
第三方无需 fork 即可注册自己的渠道:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { ImChannelAdapter } from '@lijian-ui/dsh-im-gateway' // peerDependency 引用核心
|
|
167
|
+
|
|
168
|
+
class MyChannelAdapter implements ImChannelAdapter { /* ... */ }
|
|
169
|
+
ctx.imGateway.registerChannel(myAdapter)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 八、开发
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
git clone https://github.com/lijian-ui/dsh-im-gateway.git
|
|
178
|
+
cd dsh-im-gateway
|
|
179
|
+
npm install
|
|
180
|
+
npm run build # tsdown → lib/
|
|
181
|
+
npm run watch # 保存即重编译
|
|
182
|
+
npm run typecheck
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
本地 link 进 profile:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
dsh plugin --profile web add ./ # 从本目录安装(link)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
> **Windows 提醒**:dsh 子进程从 `package.json` 的 `main`(`lib/index.js`)加载,**不直接读 src**。改完 `src/` 必须 `npm run build`,然后**重启 dsh 进程**(require 缓存不会自动刷新)。
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 九、常见问题
|
|
196
|
+
|
|
197
|
+
- **看不到插件日志?** cordis 默认把 `ctx.logger.*` 存进内存 buffer 不打印。本插件 apply 时注册了 console exporter,日志会出现在 dsh 子进程 stderr(桌面壳通常带 `[dsh]` 前缀)。
|
|
198
|
+
- **QQ 客户端一直"连接中"?** 流式开得太早或没收尾。本插件在第一个 assistant 文本增量时才开流,`turn/end` 时必关流(0.1.x 已修复)。
|
|
199
|
+
- **能对话但回复不是流式?** 渠道降级为纯文本了(QQ 群聊不支持 `stream_messages`、微信本身无流式概念)——这是设计行为。
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 十、许可
|
|
204
|
+
|
|
205
|
+
MIT © lijian-ui
|
|
206
|
+
|
|
207
|
+
为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 打造的独立插件,与 DeepSeek 官方无隶属或背书关系。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @lijian-ui/dsh-im-gateway bundle patch — SINGLE entry.
|
|
2
|
+
#
|
|
3
|
+
# One plugin (`@lijian-ui/dsh-im-gateway`) provides the core gateway service AND every
|
|
4
|
+
# channel (DingTalk / QQ / 个人维修) as INSTANCES: `channels` is an ARRAY, and
|
|
5
|
+
# the same channel type may appear multiple times (multi-bot support). The
|
|
6
|
+
# bundle ships ZERO instances; a later patch layer (the user's profile
|
|
7
|
+
# cordis.patch.yml or a --patch overlay) replaces the whole array — override
|
|
8
|
+
# by `id` with the SAME shape shown here (see the profile im-dev example).
|
|
9
|
+
#
|
|
10
|
+
# IMPORTANT: the host deep-merge REPLACES arrays wholesale, so any overlay
|
|
11
|
+
# must restate the FULL channels array, not just the instance being added.
|
|
12
|
+
#
|
|
13
|
+
# This entry's package (package.json) also declares dsh.client → the same
|
|
14
|
+
# package carries the browser half (lib/client.js), which client-modules
|
|
15
|
+
# discovers from this entry's name.
|
|
16
|
+
|
|
17
|
+
- insert:
|
|
18
|
+
- id: im-gateway
|
|
19
|
+
name: '@lijian-ui/dsh-im-gateway'
|
|
20
|
+
config:
|
|
21
|
+
cwd: !!js process.cwd()
|
|
22
|
+
streamThrottleMs: 800
|
|
23
|
+
slashCommands: true
|
|
24
|
+
channels: []
|