@wwlocal/aibot-connector 20260410.9.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/README.md +471 -0
- package/config.example.json +169 -0
- package/dist/cjs/index.js +76 -0
- package/dist/cjs/src/adapters/anthropic-adapter.js +534 -0
- package/dist/cjs/src/adapters/base-adapter.js +176 -0
- package/dist/cjs/src/adapters/deepseek-adapter.js +328 -0
- package/dist/cjs/src/adapters/dify-adapter.js +636 -0
- package/dist/cjs/src/adapters/index.js +131 -0
- package/dist/cjs/src/adapters/openai-adapter.js +361 -0
- package/dist/cjs/src/adapters/webhook-adapter.js +260 -0
- package/dist/cjs/src/agent-forwarder.js +87 -0
- package/dist/cjs/src/ca-cert.js +162 -0
- package/dist/cjs/src/config.js +169 -0
- package/dist/cjs/src/const.js +124 -0
- package/dist/cjs/src/conversation-manager.js +147 -0
- package/dist/cjs/src/dm-policy.js +46 -0
- package/dist/cjs/src/group-policy.js +95 -0
- package/dist/cjs/src/media-handler.js +136 -0
- package/dist/cjs/src/media-loader.js +271 -0
- package/dist/cjs/src/media-storage.js +165 -0
- package/dist/cjs/src/media-uploader.js +203 -0
- package/dist/cjs/src/message-parser.js +133 -0
- package/dist/cjs/src/message-sender.js +87 -0
- package/dist/cjs/src/monitor.js +849 -0
- package/dist/cjs/src/reqid-store.js +87 -0
- package/dist/cjs/src/server.js +72 -0
- package/dist/cjs/src/service-manager.js +135 -0
- package/dist/cjs/src/state-manager.js +143 -0
- package/dist/cjs/src/template-card-parser.js +498 -0
- package/dist/cjs/src/timeout.js +41 -0
- package/dist/cjs/src/version.js +25 -0
- package/dist/esm/index.js +74 -0
- package/dist/esm/src/adapters/anthropic-adapter.js +512 -0
- package/dist/esm/src/adapters/base-adapter.js +174 -0
- package/dist/esm/src/adapters/deepseek-adapter.js +326 -0
- package/dist/esm/src/adapters/dify-adapter.js +634 -0
- package/dist/esm/src/adapters/index.js +123 -0
- package/dist/esm/src/adapters/openai-adapter.js +339 -0
- package/dist/esm/src/adapters/webhook-adapter.js +258 -0
- package/dist/esm/src/agent-forwarder.js +84 -0
- package/dist/esm/src/ca-cert.js +136 -0
- package/dist/esm/src/config.js +145 -0
- package/dist/esm/src/const.js +100 -0
- package/dist/esm/src/conversation-manager.js +144 -0
- package/dist/esm/src/dm-policy.js +44 -0
- package/dist/esm/src/group-policy.js +92 -0
- package/dist/esm/src/media-handler.js +133 -0
- package/dist/esm/src/media-loader.js +246 -0
- package/dist/esm/src/media-storage.js +143 -0
- package/dist/esm/src/media-uploader.js +198 -0
- package/dist/esm/src/message-parser.js +131 -0
- package/dist/esm/src/message-sender.js +83 -0
- package/dist/esm/src/monitor.js +841 -0
- package/dist/esm/src/reqid-store.js +85 -0
- package/dist/esm/src/server.js +69 -0
- package/dist/esm/src/service-manager.js +133 -0
- package/dist/esm/src/state-manager.js +134 -0
- package/dist/esm/src/template-card-parser.js +495 -0
- package/dist/esm/src/timeout.js +38 -0
- package/dist/esm/src/version.js +22 -0
- package/dist/esm/types/index.d.ts +14 -0
- package/dist/esm/types/src/adapters/anthropic-adapter.d.ts +93 -0
- package/dist/esm/types/src/adapters/base-adapter.d.ts +76 -0
- package/dist/esm/types/src/adapters/deepseek-adapter.d.ts +87 -0
- package/dist/esm/types/src/adapters/dify-adapter.d.ts +100 -0
- package/dist/esm/types/src/adapters/index.d.ts +60 -0
- package/dist/esm/types/src/adapters/openai-adapter.d.ts +82 -0
- package/dist/esm/types/src/adapters/types.d.ts +373 -0
- package/dist/esm/types/src/adapters/webhook-adapter.d.ts +54 -0
- package/dist/esm/types/src/agent-forwarder.d.ts +32 -0
- package/dist/esm/types/src/ca-cert.d.ts +53 -0
- package/dist/esm/types/src/config.d.ts +29 -0
- package/dist/esm/types/src/const.d.ts +74 -0
- package/dist/esm/types/src/conversation-manager.d.ts +81 -0
- package/dist/esm/types/src/dm-policy.d.ts +27 -0
- package/dist/esm/types/src/group-policy.d.ts +28 -0
- package/dist/esm/types/src/interface.d.ts +332 -0
- package/dist/esm/types/src/media-handler.d.ts +36 -0
- package/dist/esm/types/src/media-loader.d.ts +47 -0
- package/dist/esm/types/src/media-storage.d.ts +35 -0
- package/dist/esm/types/src/media-uploader.d.ts +65 -0
- package/dist/esm/types/src/message-parser.d.ts +89 -0
- package/dist/esm/types/src/message-sender.d.ts +34 -0
- package/dist/esm/types/src/monitor.d.ts +30 -0
- package/dist/esm/types/src/reqid-store.d.ts +23 -0
- package/dist/esm/types/src/server.d.ts +23 -0
- package/dist/esm/types/src/service-manager.d.ts +52 -0
- package/dist/esm/types/src/state-manager.d.ts +76 -0
- package/dist/esm/types/src/template-card-parser.d.ts +18 -0
- package/dist/esm/types/src/timeout.d.ts +20 -0
- package/dist/esm/types/src/version.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# @wwlocal/aibot-connector
|
|
2
|
+
|
|
3
|
+
企业微信私有化智能机器人连接器(Node.js版),可以通过简单配置将多个智能机器人和大模型/智能体服务建立连接,方便快速、便捷体验智能机器人功能。
|
|
4
|
+
|
|
5
|
+
+-----------------------+ +-------------------+ +-----------------------+
|
|
6
|
+
| 企业微信私有化部署 | | aibot-connector | | 大模型/智能体服务 |
|
|
7
|
+
| (wwlocal) | | (Node.js App) | | (LLM / Agents) |
|
|
8
|
+
+-----------------------+ +-------------------+ +-----------------------+
|
|
9
|
+
| | | | | |
|
|
10
|
+
| [ 个人机器人 ] | | | | [ 大模型服务 (LLM) ] |
|
|
11
|
+
| - 张三的智能机器人 | | +---------+ | | - DeepSeek |
|
|
12
|
+
| - 李四的智能助手 | | | | | | - 腾讯混元 |
|
|
13
|
+
| | <===>| |Routing | | <===>| - 通义千问 |
|
|
14
|
+
| [ 团队共享机器人 ] | | | & | | | - Ollama |
|
|
15
|
+
| - 营销部智能小助手 | | | Adapter | | | |
|
|
16
|
+
| - 人事部小管家 | | | | | | [ 智能体 (Agent) ] |
|
|
17
|
+
| | | +---------+ | | - Dify |
|
|
18
|
+
| [ 业务面向助手 ] | | | | - ADP |
|
|
19
|
+
| - IT客服小助手 | | | | - 等... |
|
|
20
|
+
| - 报销系统小i | | | | |
|
|
21
|
+
+-----------------------+ +-------------------+ +-----------------------+
|
|
22
|
+
^ ^ ^
|
|
23
|
+
| | |
|
|
24
|
+
(内部机器人接口) (独立运行程序) (外部服务接口)
|
|
25
|
+
|
|
26
|
+
## 核心能力
|
|
27
|
+
|
|
28
|
+
| 能力 | 说明 |
|
|
29
|
+
|------|------|
|
|
30
|
+
| **多账号管理** | 支持同时对接多个企微智能机器人和智能体服务 |
|
|
31
|
+
| **多协议适配** | 支持 OpenAI、DeepSeek、Anthropic、Dify、自定义 Webhook 五种适配器 |
|
|
32
|
+
| **思维链展示** | 支持 DeepSeek/Claude 推理模型的 thinking 内容折叠/显示/隐藏 |
|
|
33
|
+
| **多轮对话** | 自动记忆对话历史(可配置轮数) |
|
|
34
|
+
| **媒体处理** | 支持图片/文件的接收和发送 |
|
|
35
|
+
| **模板卡片** | 支持企微模板卡片消息的生成与交互回调 |
|
|
36
|
+
| **访问控制** | 私聊白名单、群组白名单、群内发送者白名单三层策略 |
|
|
37
|
+
|
|
38
|
+
## 技术特性
|
|
39
|
+
|
|
40
|
+
- **可插拔适配器架构**:通过 `provider` 配置字段自动路由到对应适配器,新增 AI 平台只需实现一个适配器类
|
|
41
|
+
- **monitor 层统一节流**:替代各适配器的分散节流,在 monitor 层统一控制中间帧发送频率
|
|
42
|
+
- **流式过期降级**:当企微流式消息超过 6 分钟时自动降级为主动发送
|
|
43
|
+
- **LRU + TTL 内存管理**:消息状态、对话历史、ReqId 存储均有容量限制和自动过期清理
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## 技术栈与依赖
|
|
47
|
+
|
|
48
|
+
### 语言与运行时
|
|
49
|
+
|
|
50
|
+
- **语言**:TypeScript 5.x(strict 模式)
|
|
51
|
+
- **运行时**:Node.js(ESM 模块系统)
|
|
52
|
+
- **模块格式**:ESM 优先,同时输出 CJS
|
|
53
|
+
|
|
54
|
+
### 核心依赖
|
|
55
|
+
|
|
56
|
+
| 包名 | 版本 | 用途 |
|
|
57
|
+
|------|------|------|
|
|
58
|
+
| `@wecom/aibot-node-sdk` | ^1.0.4 | 企微私有部署 WebSocket 连接、消息收发、认证 |
|
|
59
|
+
| `express` | ^4.21.0 | HTTP 健康检查和状态 API |
|
|
60
|
+
| `file-type` | ^21.3.0 | 通过文件 buffer 嗅探 MIME 类型 |
|
|
61
|
+
|
|
62
|
+
### 开发依赖
|
|
63
|
+
|
|
64
|
+
| 包名 | 用途 |
|
|
65
|
+
|------|------|
|
|
66
|
+
| `rollup` + 插件 | 打包构建 |
|
|
67
|
+
| `typescript` | TypeScript 编译 |
|
|
68
|
+
| `rollup-plugin-dts` | 生成 `.d.ts` 类型声明 |
|
|
69
|
+
|
|
70
|
+
## 整体架构图
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
74
|
+
│ @wwlocal/aibot-connector │
|
|
75
|
+
│ │
|
|
76
|
+
│ ┌──────────┐ ┌──────────────┐ ┌─────────────────────────────┐ │
|
|
77
|
+
│ │ index.ts │──→│ ServiceManager│──→│ monitorWeComProvider() │ │
|
|
78
|
+
│ │ (入口) │ │ (多账号管理) │ │ ┌──────────────────────┐ │ │
|
|
79
|
+
│ └──────────┘ └──────────────┘ │ │ WSClient (SDK) │ │ │
|
|
80
|
+
│ │ │ │ - 连接管理 │ │ │
|
|
81
|
+
│ │ ┌──────────────┐ │ │ - 消息监听 │ │ │
|
|
82
|
+
│ └────────→│ Express HTTP │ │ │ - 心跳保活 │ │ │
|
|
83
|
+
│ │ /health │ │ └──────────┬───────────┘ │ │
|
|
84
|
+
│ │ /api/status │ │ │ │ │
|
|
85
|
+
│ └──────────────┘ │ ┌──────────▼───────────┐ │ │
|
|
86
|
+
│ │ │ processWeComMessage()│ │ │
|
|
87
|
+
│ │ │ 1. 解析消息内容 │ │ │
|
|
88
|
+
│ │ │ 2. 策略检查 │ │ │
|
|
89
|
+
│ │ │ 3. 下载媒体 │ │ │
|
|
90
|
+
│ │ │ 4. 初始化状态 │ │ │
|
|
91
|
+
│ │ │ 5. 转发到智能体 │ │ │
|
|
92
|
+
│ │ └──────────┬───────────┘ │ │
|
|
93
|
+
│ │ │ │ │
|
|
94
|
+
│ │ ┌──────────▼───────────┐ │ │
|
|
95
|
+
│ │ │ routeAndDispatchTo │ │ │
|
|
96
|
+
│ │ │ Agent() │ │ │
|
|
97
|
+
│ │ │ - thinking 消息 │ │ │
|
|
98
|
+
│ │ │ - deliver 回调 │ │ │
|
|
99
|
+
│ │ │ - monitor 层节流 │ │ │
|
|
100
|
+
│ │ │ - 流式中间帧 │ │ │
|
|
101
|
+
│ │ └──────────┬───────────┘ │ │
|
|
102
|
+
│ └─────────────┼───────────────┘ │
|
|
103
|
+
│ │ │
|
|
104
|
+
│ ┌────────────────────────────────────────────────▼──────────────┐ │
|
|
105
|
+
│ │ Agent Forwarder │ │
|
|
106
|
+
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
|
|
107
|
+
│ │ │ Adapter Registry (适配器注册表) │ │ │
|
|
108
|
+
│ │ ├──────────┬──────────┬──────────┬─────────┬─────────────┤ │ │
|
|
109
|
+
│ │ │ OpenAI │ DeepSeek │Anthropic │ Dify │ Webhook │ │ │
|
|
110
|
+
│ │ │ Adapter │ Adapter │ Adapter │ Adapter │ Adapter │ │ │
|
|
111
|
+
│ │ └──────────┴──────────┴──────────┴─────────┴─────────────┘ │ │
|
|
112
|
+
│ └──────────────────────────────────────────────────────────────┘ │
|
|
113
|
+
│ │
|
|
114
|
+
│ │ │
|
|
115
|
+
│ ▼ │
|
|
116
|
+
│ ┌─────────────────┐ │
|
|
117
|
+
│ │ 第三方 AI 平台 │ │
|
|
118
|
+
│ │ (OpenAI/DS/...) │ │
|
|
119
|
+
│ └─────────────────┘ │
|
|
120
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## 安装
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# 全局安装
|
|
128
|
+
npm install -g @wwlocal/aibot-connector
|
|
129
|
+
# 会安装到:
|
|
130
|
+
# /usr/local/lib/node_modules/@wwlocal/aibot-connector
|
|
131
|
+
|
|
132
|
+
# 在项目目录中安装
|
|
133
|
+
# 1. 创建项目目录
|
|
134
|
+
mkdir ~/my-wecom-bot
|
|
135
|
+
cd ~/my-wecom-bot
|
|
136
|
+
# 2. 初始化 package.json
|
|
137
|
+
npm init -y
|
|
138
|
+
# 3. 安装依赖(会自动写入 package.json)
|
|
139
|
+
npm install @wwlocal/aibot-connector
|
|
140
|
+
# 包在 ~/my-wecom-bot/node_modules/ 下
|
|
141
|
+
|
|
142
|
+
# 检查安装
|
|
143
|
+
npm list @wwlocal/aibot-connector
|
|
144
|
+
npm list @wecom/aibot-node-sdk
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 配置
|
|
149
|
+
|
|
150
|
+
复制示例配置文件并修改:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cp config.example.json config.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 配置说明
|
|
157
|
+
|
|
158
|
+
```jsonc
|
|
159
|
+
{
|
|
160
|
+
// HTTP 服务端口(默认 3000)
|
|
161
|
+
"port": 3000,
|
|
162
|
+
|
|
163
|
+
// 数据存储目录(媒体文件等)
|
|
164
|
+
"dataDir": "./data",
|
|
165
|
+
|
|
166
|
+
// 智能体端点列表
|
|
167
|
+
"agents": [
|
|
168
|
+
{
|
|
169
|
+
"name": "default", // 端点名称
|
|
170
|
+
"provider": "openai", // 适配器类型:openai / deepseek / anthropic / dify / webhook(默认 openai)
|
|
171
|
+
"url": "https://api.openai.com/v1/chat/completions", // API URL
|
|
172
|
+
"apiKey": "sk-xxx", // API Key
|
|
173
|
+
"model": "gpt-4o", // 模型名称
|
|
174
|
+
"stream": true, // 启用流式(默认 true)
|
|
175
|
+
"systemPrompt": "你是一个有用的助手", // 系统提示词
|
|
176
|
+
"timeoutMs": 300000, // 请求超时(默认 5 分钟)
|
|
177
|
+
"maxHistoryRounds": 20, // 多轮对话最大保留轮数(0=禁用,默认 20)
|
|
178
|
+
"headers": {}, // 自定义请求头(可选)
|
|
179
|
+
"providerOptions": {} // 适配器专属配置(可选,见下方各适配器说明)
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
|
|
183
|
+
// 企微账号列表
|
|
184
|
+
"accounts": [
|
|
185
|
+
{
|
|
186
|
+
"accountId": "bot-1", // 账号标识
|
|
187
|
+
"name": "测试机器人", // 显示名称
|
|
188
|
+
"enabled": true, // 是否启用(默认 true)
|
|
189
|
+
"websocketUrl": "wss://...", // WebSocket 连接地址
|
|
190
|
+
"botId": "xxx", // 机器人 ID
|
|
191
|
+
"secret": "xxx", // 机器人密钥
|
|
192
|
+
"caCert": "cert.pem", // CA 证书文件名(可选)
|
|
193
|
+
"sendThinkingMessage": true, // 是否发送"正在思考…"提示(默认 true)
|
|
194
|
+
|
|
195
|
+
// 访问控制
|
|
196
|
+
"dmPolicy": "open", // 私聊策略:open/allowlist/disabled
|
|
197
|
+
"allowFrom": [], // 私聊白名单 userid 列表
|
|
198
|
+
"groupPolicy": "open", // 群组策略:open/allowlist/disabled
|
|
199
|
+
"groupAllowFrom": [], // 群组白名单 chatid 列表
|
|
200
|
+
"groups": {}, // 群聊专属配置(可为不同群指定不同的 agent)
|
|
201
|
+
|
|
202
|
+
// 媒体与智能体
|
|
203
|
+
"mediaLocalRoots": [], // 本地媒体文件搜索路径
|
|
204
|
+
"agentName": "default" // 使用的智能体端点名称
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 启动
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# 使用默认配置文件(./config.json)
|
|
214
|
+
npm start
|
|
215
|
+
|
|
216
|
+
# 指定配置文件
|
|
217
|
+
npm start -- /path/to/config.json
|
|
218
|
+
|
|
219
|
+
# 通过环境变量指定
|
|
220
|
+
AIBOT_CONFIG=/path/to/config.json npm start
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## API 接口
|
|
224
|
+
|
|
225
|
+
| 方法 | 路径 | 说明 |
|
|
226
|
+
|------|------|------|
|
|
227
|
+
| GET | `/health` | 健康检查 |
|
|
228
|
+
| GET | `/api/status` | 服务状态(各账号连接状态) |
|
|
229
|
+
| POST | `/callback` | 模板卡片事件回调(预留) |
|
|
230
|
+
|
|
231
|
+
### 健康检查
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
curl http://localhost:3000/health
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"status": "ok",
|
|
240
|
+
"version": "1.0.0",
|
|
241
|
+
"uptime": 123.456,
|
|
242
|
+
"timestamp": 1712000000000
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 服务状态
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
curl http://localhost:3000/api/status
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"version": "1.0.0",
|
|
255
|
+
"accounts": [
|
|
256
|
+
{
|
|
257
|
+
"accountId": "bot-1",
|
|
258
|
+
"name": "测试机器人",
|
|
259
|
+
"running": true,
|
|
260
|
+
"lastConnectedAt": 1712000000000
|
|
261
|
+
}
|
|
262
|
+
],
|
|
263
|
+
"timestamp": 1712000000000
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 对接第三方智能体
|
|
268
|
+
|
|
269
|
+
插件内置多种适配器,通过 `provider` 字段选择。OpenAI 适配器同时兼容所有 OpenAI API 兼容服务。
|
|
270
|
+
|
|
271
|
+
### OpenAI(默认)
|
|
272
|
+
|
|
273
|
+
兼容所有 OpenAI Chat Completions API 的服务(包括 Azure OpenAI、Ollama、vLLM 等)。
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"name": "openai",
|
|
278
|
+
"provider": "openai",
|
|
279
|
+
"url": "https://api.openai.com/v1/chat/completions",
|
|
280
|
+
"apiKey": "sk-xxx",
|
|
281
|
+
"model": "gpt-4o"
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Azure OpenAI
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"name": "azure",
|
|
290
|
+
"provider": "openai",
|
|
291
|
+
"url": "https://your-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-08-01-preview",
|
|
292
|
+
"headers": {
|
|
293
|
+
"api-key": "your-azure-key"
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### DeepSeek
|
|
299
|
+
|
|
300
|
+
支持普通对话模型和推理模型(思维链)。
|
|
301
|
+
|
|
302
|
+
```json
|
|
303
|
+
{
|
|
304
|
+
"name": "deepseek-chat",
|
|
305
|
+
"provider": "deepseek",
|
|
306
|
+
"url": "https://api.deepseek.com/chat/completions",
|
|
307
|
+
"apiKey": "sk-xxx",
|
|
308
|
+
"model": "deepseek-chat"
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
推理模型示例(带思维链展示):
|
|
313
|
+
|
|
314
|
+
```json
|
|
315
|
+
{
|
|
316
|
+
"name": "deepseek-reasoner",
|
|
317
|
+
"provider": "deepseek",
|
|
318
|
+
"url": "https://api.deepseek.com/chat/completions",
|
|
319
|
+
"apiKey": "sk-xxx",
|
|
320
|
+
"model": "deepseek-reasoner",
|
|
321
|
+
"providerOptions": {
|
|
322
|
+
"reasoningDisplay": "collapse"
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Anthropic Claude
|
|
328
|
+
|
|
329
|
+
支持 Anthropic 原生 Messages API,以及第三方兼容平台(如 MiniMax)。
|
|
330
|
+
|
|
331
|
+
```json
|
|
332
|
+
{
|
|
333
|
+
"name": "claude-sonnet",
|
|
334
|
+
"provider": "anthropic",
|
|
335
|
+
"url": "https://api.anthropic.com/v1/messages",
|
|
336
|
+
"apiKey": "sk-ant-xxx",
|
|
337
|
+
"model": "claude-sonnet-4-20250514",
|
|
338
|
+
"providerOptions": {
|
|
339
|
+
"maxTokens": 8192,
|
|
340
|
+
"reasoningDisplay": "collapse",
|
|
341
|
+
"useXApiKey": true,
|
|
342
|
+
"anthropicVersion": "2023-06-01"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
第三方兼容平台示例(MiniMax):
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"name": "minimax-anthropic",
|
|
352
|
+
"provider": "anthropic",
|
|
353
|
+
"url": "https://api.minimaxi.com/anthropic",
|
|
354
|
+
"apiKey": "your-minimax-key",
|
|
355
|
+
"model": "MiniMax-M2.7",
|
|
356
|
+
"providerOptions": {
|
|
357
|
+
"maxTokens": 4096,
|
|
358
|
+
"useXApiKey": false
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Dify
|
|
364
|
+
|
|
365
|
+
对接 Dify Chatflow 应用。
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"name": "dify-assistant",
|
|
370
|
+
"provider": "dify",
|
|
371
|
+
"url": "https://api.dify.ai/v1/chat-messages",
|
|
372
|
+
"apiKey": "app-your-dify-app-key",
|
|
373
|
+
"providerOptions": {
|
|
374
|
+
"difyAppType": "chat",
|
|
375
|
+
"difyInputs": {
|
|
376
|
+
"language": "zh-CN"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### 自定义 Webhook
|
|
383
|
+
|
|
384
|
+
通过模板映射对接任意 HTTP API,无需写代码。
|
|
385
|
+
|
|
386
|
+
```json
|
|
387
|
+
{
|
|
388
|
+
"name": "custom-webhook",
|
|
389
|
+
"provider": "webhook",
|
|
390
|
+
"url": "https://your-internal-api.example.com/chat",
|
|
391
|
+
"headers": {
|
|
392
|
+
"X-API-Token": "your-internal-token"
|
|
393
|
+
},
|
|
394
|
+
"providerOptions": {
|
|
395
|
+
"requestTemplate": {
|
|
396
|
+
"message": "{{text}}",
|
|
397
|
+
"userId": "{{user}}",
|
|
398
|
+
"source": "wecom"
|
|
399
|
+
},
|
|
400
|
+
"responseTextField": "data.reply.content"
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### 本地模型(Ollama)
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"name": "ollama",
|
|
410
|
+
"provider": "openai",
|
|
411
|
+
"url": "http://localhost:11434/v1/chat/completions",
|
|
412
|
+
"model": "llama3"
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### providerOptions 参考
|
|
417
|
+
|
|
418
|
+
| 适配器 | 选项 | 说明 |
|
|
419
|
+
|--------|------|------|
|
|
420
|
+
| deepseek | `reasoningDisplay` | 思维链展示模式:`show` / `hide` / `collapse`(默认) |
|
|
421
|
+
| anthropic | `maxTokens` | Anthropic API 必传的 max_tokens(默认 4096) |
|
|
422
|
+
| anthropic | `reasoningDisplay` | 思维链展示模式:`show` / `hide` / `collapse` |
|
|
423
|
+
| anthropic | `useXApiKey` | 是否使用 `x-api-key` 头认证(默认 true)。第三方平台设为 false |
|
|
424
|
+
| anthropic | `anthropicVersion` | API 版本头(默认 `2023-06-01`) |
|
|
425
|
+
| dify | `difyAppType` | Dify 应用类型:`chat` |
|
|
426
|
+
| dify | `difyInputs` | 传递给 Dify 工作流的自定义变量 |
|
|
427
|
+
| webhook | `requestTemplate` | 请求体模板,支持 `{{text}}`、`{{user}}`、`{{chatId}}` 变量 |
|
|
428
|
+
| webhook | `responseTextField` | 响应 JSON 中提取回复文本的字段路径(支持嵌套,如 `data.reply.content`) |
|
|
429
|
+
|
|
430
|
+
## 项目结构
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
aibot-plugin/
|
|
434
|
+
├── index.ts # 服务入口
|
|
435
|
+
├── config.example.json # 配置示例
|
|
436
|
+
├── package.json
|
|
437
|
+
├── tsconfig.json
|
|
438
|
+
├── rollup.config.mjs
|
|
439
|
+
├── src/
|
|
440
|
+
│ ├── config.ts # 配置加载与校验
|
|
441
|
+
│ ├── server.ts # Express HTTP 服务
|
|
442
|
+
│ ├── service-manager.ts # 服务生命周期管理
|
|
443
|
+
│ ├── monitor.ts # 核心消息处理引擎
|
|
444
|
+
│ ├── agent-forwarder.ts # 智能体转发器(适配器调度层)
|
|
445
|
+
│ ├── conversation-manager.ts # 多轮对话历史管理(内存缓存、TTL、LRU)
|
|
446
|
+
│ ├── message-parser.ts # 消息解析
|
|
447
|
+
│ ├── message-sender.ts # 消息发送
|
|
448
|
+
│ ├── template-card-parser.ts # 模板卡片解析
|
|
449
|
+
│ ├── media-handler.ts # 入站媒体下载
|
|
450
|
+
│ ├── media-uploader.ts # 出站媒体上传
|
|
451
|
+
│ ├── media-storage.ts # 本地媒体存储
|
|
452
|
+
│ ├── media-loader.ts # 出站媒体加载
|
|
453
|
+
│ ├── dm-policy.ts # 私聊访问控制
|
|
454
|
+
│ ├── group-policy.ts # 群组访问控制
|
|
455
|
+
│ ├── ca-cert.ts # CA 证书注入
|
|
456
|
+
│ ├── state-manager.ts # 状态管理
|
|
457
|
+
│ ├── reqid-store.ts # ReqId 存储
|
|
458
|
+
│ ├── interface.ts # 类型定义
|
|
459
|
+
│ ├── const.ts # 常量定义
|
|
460
|
+
│ ├── timeout.ts # 超时工具
|
|
461
|
+
│ ├── version.ts # 版本信息
|
|
462
|
+
│ └── adapters/ # 适配器模块
|
|
463
|
+
│ ├── index.ts # 适配器注册与解析
|
|
464
|
+
│ ├── types.ts # 适配器公共类型
|
|
465
|
+
│ ├── base-adapter.ts # 基础适配器(OpenAI 兼容)
|
|
466
|
+
│ ├── openai-adapter.ts # OpenAI 适配器
|
|
467
|
+
│ ├── deepseek-adapter.ts # DeepSeek 适配器(支持思维链)
|
|
468
|
+
│ ├── anthropic-adapter.ts # Anthropic Claude 适配器(原生 API)
|
|
469
|
+
│ ├── dify-adapter.ts # Dify 适配器
|
|
470
|
+
│ └── webhook-adapter.ts # 自定义 Webhook 适配器
|
|
471
|
+
```
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment_port": "HTTP 服务监听端口,用于健康检查 (/health) 和状态查询 (/api/status),不影响消息收发",
|
|
3
|
+
"port": 3000,
|
|
4
|
+
|
|
5
|
+
"_comment_dataDir": "数据存储目录,用于缓存文件等",
|
|
6
|
+
"dataDir": "./data",
|
|
7
|
+
|
|
8
|
+
"_comment_agents": "智能体端点列表。每个端点定义一个 AI 后端的连接方式。accounts 通过 agentName 引用这里的 name",
|
|
9
|
+
"agents": [
|
|
10
|
+
{
|
|
11
|
+
"_comment": "========== OpenAI 适配器示例 ==========",
|
|
12
|
+
"name": "openai-gpt4o",
|
|
13
|
+
"_comment_provider": "适配器类型:openai / deepseek / anthropic / dify / webhook。不配置时默认为 openai",
|
|
14
|
+
"provider": "openai",
|
|
15
|
+
"_comment_url": "API 地址。OpenAI 兼容接口(如 Ollama、vLLM、Azure OpenAI)均可使用 openai 适配器",
|
|
16
|
+
"url": "https://api.openai.com/v1/chat/completions",
|
|
17
|
+
"apiKey": "sk-your-api-key-here",
|
|
18
|
+
"_comment_model": "模型名称,取决于你的 API 提供商支持的模型",
|
|
19
|
+
"model": "gpt-4o",
|
|
20
|
+
"_comment_stream": "是否启用流式响应(SSE),默认 true。流式可实现打字机效果,逐步推送回复",
|
|
21
|
+
"stream": true,
|
|
22
|
+
"_comment_systemPrompt": "系统提示词,设定 AI 的角色和行为",
|
|
23
|
+
"systemPrompt": "你是一个企业微信智能助手。",
|
|
24
|
+
"_comment_timeoutMs": "请求超时时间(毫秒),默认 300000(5分钟)",
|
|
25
|
+
"timeoutMs": 300000,
|
|
26
|
+
"_comment_maxHistoryRounds": "多轮对话最大保留轮数。默认 20 轮(即 AI 能记住最近 20 轮对话)。设为 0 可禁用对话记忆(每次对话都是全新的)",
|
|
27
|
+
"maxHistoryRounds": 20,
|
|
28
|
+
"_comment_headers": "自定义请求头,如需额外认证头可在此添加",
|
|
29
|
+
"headers": {}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"_comment": "========== DeepSeek Chat 示例(普通对话模型,无思维链) ==========",
|
|
33
|
+
"name": "deepseek-chat",
|
|
34
|
+
"provider": "deepseek",
|
|
35
|
+
"url": "https://api.deepseek.com/chat/completions",
|
|
36
|
+
"apiKey": "sk-your-deepseek-key",
|
|
37
|
+
"model": "deepseek-chat",
|
|
38
|
+
"stream": true,
|
|
39
|
+
"systemPrompt": "你是一个企业微信智能助手。"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"_comment": "========== DeepSeek Reasoner 示例(推理模型,有思维链) ==========",
|
|
43
|
+
"name": "deepseek-reasoner",
|
|
44
|
+
"provider": "deepseek",
|
|
45
|
+
"url": "https://api.deepseek.com/chat/completions",
|
|
46
|
+
"apiKey": "sk-your-deepseek-key",
|
|
47
|
+
"_comment_model": "deepseek-reasoner 为推理模型,会返回 reasoning_content(思维链内容)",
|
|
48
|
+
"model": "deepseek-reasoner",
|
|
49
|
+
"stream": true,
|
|
50
|
+
"_comment_providerOptions": "适配器专属配置,不同 provider 有不同的可选项",
|
|
51
|
+
"providerOptions": {
|
|
52
|
+
"_comment_reasoningDisplay": "推理思维链的展示模式(仅 deepseek 适配器有效):hide = 完全隐藏推理过程,只显示最终回答;collapse = 用 <think>...</think> 标签折叠展示;show = 完整展示推理过程和回答",
|
|
53
|
+
"reasoningDisplay": "collapse"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"_comment": "========== Anthropic Claude 示例(原生 API) ==========",
|
|
58
|
+
"name": "claude-sonnet",
|
|
59
|
+
"provider": "anthropic",
|
|
60
|
+
"_comment_url": "Anthropic 原生 Messages API 地址",
|
|
61
|
+
"url": "https://api.anthropic.com/v1/messages",
|
|
62
|
+
"apiKey": "sk-ant-your-anthropic-key",
|
|
63
|
+
"_comment_model": "Claude 模型名称",
|
|
64
|
+
"model": "claude-sonnet-4-20250514",
|
|
65
|
+
"stream": true,
|
|
66
|
+
"systemPrompt": "你是一个企业微信智能助手。",
|
|
67
|
+
"_comment_providerOptions": "Anthropic 适配器专属配置",
|
|
68
|
+
"providerOptions": {
|
|
69
|
+
"_comment_maxTokens": "Anthropic API 要求必传的 max_tokens,默认 4096",
|
|
70
|
+
"maxTokens": 8192,
|
|
71
|
+
"_comment_reasoningDisplay": "思维链展示模式(仅 Claude 推理模型有效):hide / collapse / show",
|
|
72
|
+
"reasoningDisplay": "collapse",
|
|
73
|
+
"_comment_useXApiKey": "是否使用 x-api-key 头认证(默认 true)。Anthropic 原生 API 用 true,第三方兼容平台(如百炼、MiniMax)设为 false",
|
|
74
|
+
"useXApiKey": true,
|
|
75
|
+
"_comment_anthropicVersion": "Anthropic API 版本头,默认 2023-06-01",
|
|
76
|
+
"anthropicVersion": "2023-06-01"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"_comment": "========== MiniMax Anthropic 兼容 API 示例 ==========",
|
|
81
|
+
"name": "minimax-anthropic",
|
|
82
|
+
"provider": "anthropic",
|
|
83
|
+
"_comment_url": "MiniMax 的 Anthropic 兼容接口地址",
|
|
84
|
+
"url": "https://api.minimaxi.com/anthropic",
|
|
85
|
+
"apiKey": "your-minimax-key",
|
|
86
|
+
"model": "MiniMax-M2.7",
|
|
87
|
+
"stream": true,
|
|
88
|
+
"providerOptions": {
|
|
89
|
+
"maxTokens": 4096,
|
|
90
|
+
"_comment_useXApiKey": "MiniMax 使用 Bearer Token 认证,设为 false",
|
|
91
|
+
"useXApiKey": false
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"_comment": "========== Dify 适配器示例 ==========",
|
|
96
|
+
"name": "dify-assistant",
|
|
97
|
+
"provider": "dify",
|
|
98
|
+
"_comment_url": "Dify Chat 应用的 API 地址",
|
|
99
|
+
"url": "https://api.dify.ai/v1/chat-messages",
|
|
100
|
+
"_comment_apiKey": "Dify 应用的 API Key,以 app- 开头",
|
|
101
|
+
"apiKey": "app-your-dify-app-key",
|
|
102
|
+
"stream": true,
|
|
103
|
+
"providerOptions": {
|
|
104
|
+
"_comment_difyAppType": "Dify 应用类型:chat(对话型,支持会话管理)",
|
|
105
|
+
"difyAppType": "chat",
|
|
106
|
+
"_comment_difyInputs": "传递给 Dify 工作流的自定义变量",
|
|
107
|
+
"difyInputs": {
|
|
108
|
+
"language": "zh-CN"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"_comment": "========== 自定义 Webhook 适配器示例 ==========",
|
|
114
|
+
"name": "custom-webhook",
|
|
115
|
+
"_comment_provider": "webhook 适配器:通过模板映射对接任意 HTTP API,无需写代码",
|
|
116
|
+
"provider": "webhook",
|
|
117
|
+
"url": "https://your-internal-api.example.com/chat",
|
|
118
|
+
"headers": {
|
|
119
|
+
"X-API-Token": "your-internal-token"
|
|
120
|
+
},
|
|
121
|
+
"providerOptions": {
|
|
122
|
+
"_comment_requestTemplate": "请求体模板,支持变量替换:{{text}} = 消息文本,{{user}} = 用户ID,{{chatId}} = 聊天ID",
|
|
123
|
+
"requestTemplate": {
|
|
124
|
+
"message": "{{text}}",
|
|
125
|
+
"userId": "{{user}}",
|
|
126
|
+
"source": "wecom"
|
|
127
|
+
},
|
|
128
|
+
"_comment_responseTextField": "从响应 JSON 中提取回复文本的字段路径,支持嵌套(如 data.reply.content)",
|
|
129
|
+
"responseTextField": "data.reply.content"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
|
|
134
|
+
"_comment_accounts": "企微账号列表。支持多个,每个账号对应一个企微机器人的 WebSocket 连接",
|
|
135
|
+
"accounts": [
|
|
136
|
+
{
|
|
137
|
+
"_comment_accountId": "账号唯一标识,用于日志和状态查询",
|
|
138
|
+
"accountId": "bot-1",
|
|
139
|
+
"_comment_name": "账号显示名称,仅用于日志展示",
|
|
140
|
+
"name": "我的机器人",
|
|
141
|
+
"_comment_enabled": "是否启用此账号,设为 false 可临时禁用而无需删除配置",
|
|
142
|
+
"enabled": true,
|
|
143
|
+
"_comment_websocketUrl": "企微机器人 WebSocket 服务地址",
|
|
144
|
+
"websocketUrl": "ws://your-wecom-server:11712",
|
|
145
|
+
"_comment_botId": "企微机器人 ID",
|
|
146
|
+
"botId": "your-bot-id",
|
|
147
|
+
"_comment_secret": "企微机器人密钥",
|
|
148
|
+
"secret": "your-bot-secret",
|
|
149
|
+
"_comment_caCert": "CA 证书路径(可选),用于自签名 HTTPS/WSS 证书",
|
|
150
|
+
"caCert": "",
|
|
151
|
+
"_comment_sendThinkingMessage": "收到用户消息后是否先发送一条「正在思考…」提示消息。注意:这与 DeepSeek 的推理思维链(reasoningDisplay)是两个独立的功能",
|
|
152
|
+
"sendThinkingMessage": true,
|
|
153
|
+
"_comment_dmPolicy": "私聊策略:open = 接受所有人,whitelist = 仅允许 allowFrom 列表中的用户",
|
|
154
|
+
"dmPolicy": "open",
|
|
155
|
+
"_comment_allowFrom": "私聊白名单(仅 dmPolicy 为 whitelist 时生效),填入企微用户 ID",
|
|
156
|
+
"allowFrom": [],
|
|
157
|
+
"_comment_groupPolicy": "群聊策略:open = 接受所有群,whitelist = 仅允许 groupAllowFrom 列表中的群",
|
|
158
|
+
"groupPolicy": "open",
|
|
159
|
+
"_comment_groupAllowFrom": "群聊白名单(仅 groupPolicy 为 whitelist 时生效),填入群聊 ID",
|
|
160
|
+
"groupAllowFrom": [],
|
|
161
|
+
"_comment_groups": "群聊专属配置(可为不同群指定不同的 agent),key 为群聊 ID",
|
|
162
|
+
"groups": {},
|
|
163
|
+
"_comment_mediaLocalRoots": "本地媒体文件搜索路径(用于发送本地图片等)",
|
|
164
|
+
"mediaLocalRoots": [],
|
|
165
|
+
"_comment_agentName": "该账号使用的智能体端点名称,必须对应 agents 列表中某个 name",
|
|
166
|
+
"agentName": "openai-gpt4o"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|