oh-my-im 0.1.12 → 0.1.13
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 +188 -706
- package/dist/agents/codex-agent.js +25 -3
- package/dist/agents/pi-agent.js +17 -1
- package/dist/bot-app.js +125 -29
- package/dist/bot-worker.js +37 -0
- package/dist/config.js +8 -0
- package/dist/dashboard-worker.js +68 -16
- package/dist/dingtalk-robot.js +17 -0
- package/dist/dingtalk.js +1 -1
- package/dist/dws-client.js +36 -9
- package/dist/dws-dashboard.js +150 -29
- package/dist/dws-history.js +98 -77
- package/dist/{dws-listener.js → group-worker.js} +228 -87
- package/dist/omi.js +8 -7
- package/package.json +3 -3
- package/dist/dws-rule-history.js +0 -96
- package/outputs/session-flowcharts/01-agent-session-create.png +0 -0
- package/outputs/session-flowcharts/02-pi-session-rpc.png +0 -0
- package/outputs/session-flowcharts/03-session-list-switch.png +0 -0
- package/outputs/session-flowcharts/04-private-chat-message-flow.png +0 -0
package/README.md
CHANGED
|
@@ -1,821 +1,303 @@
|
|
|
1
1
|
# oh-my-im
|
|
2
2
|
|
|
3
|
-
`oh-my-im` 是一个运行在本机的钉钉 AI Agent
|
|
3
|
+
`oh-my-im` 是一个运行在本机的钉钉 AI Agent 桥接器。它接收钉钉单聊和配置群中的消息,调用本机的 [Codex CLI](https://github.com/openai/codex) 或 [Pi](https://github.com/badlogic/pi-mono),再通过钉钉文本或互动卡片返回结果。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
项目是一个 TypeScript/Node.js 应用,不使用数据库、Redis 或 Docker。配置、运行状态、日志和回复历史默认保存在当前用户的 `~/.oh-my-im/` 目录。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## 能做什么
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- 单聊机器人:按用户白名单接收钉钉单聊,支持文本、图片、文件、语音等可解析消息。
|
|
10
|
+
- 群消息监听:消费 DWS 全群消息事件,再按“群 + 发送人”规则做本地过滤。
|
|
11
|
+
- Agent 切换:在管理页选择 Codex 或 Pi,也可以在会话中使用已配置的关键词切换。
|
|
12
|
+
- Agent 模型:管理页仅配置 Pi 默认模型;Codex 始终使用系统 Codex CLI 已设置的默认模型。
|
|
13
|
+
- 回复方式:在管理页选择互动卡片或普通文本;该设置同时作用于群聊和私聊。普通文本模式只发送 Agent 最终结果。
|
|
14
|
+
- 互动卡片:显示处理中、工具调用和最终回复;群聊支持 Markdown 或纯文本格式。
|
|
15
|
+
- Session 管理:单聊用户只能查看和切换自己工作目录下的 Session;超级管理员可管理其他工作目录。
|
|
16
|
+
- 本地控制台:配置钉钉凭证、群规则、单聊白名单、Agent、提示词和指令关键词。
|
|
17
|
+
- 进程管理:使用 `omi` 启动、停止、重启、更新和查看 worker 状态。
|
|
10
18
|
|
|
11
|
-
##
|
|
19
|
+
## 工作方式
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
| Session 管理 | 机器人单聊命令 | 查看、选择、清空个人 Session;超级管理员可跨工作目录管理 Session |
|
|
22
|
-
| 本地控制台 | `http://127.0.0.1:12525` | 配置机器人、授权人员、监听规则、指令关键词、Agent 和回复格式,查看最近回复 |
|
|
23
|
-
| 进程管理 | `omi` CLI | 后台启动、停止、重启、更新和状态查看 |
|
|
24
|
-
| 本地记录 | `~/.oh-my-im/replies/` | 按日期保存单聊和群聊的完整问答记录 |
|
|
21
|
+
```text
|
|
22
|
+
钉钉单聊 ── Stream Mode ──> bot-worker ──┐
|
|
23
|
+
├─> Codex CLI / Pi RPC
|
|
24
|
+
DWS 群事件 ── DWS CLI ──> group-worker ──┘
|
|
25
|
+
└─> 钉钉文本 / StandardCard
|
|
26
|
+
|
|
27
|
+
dashboard-worker ──> http://127.0.0.1:12525
|
|
28
|
+
```
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
默认启动会运行三个独立 worker:
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
| Worker | 作用 |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `dashboard-worker` | 提供本地管理页、配置 API、状态和日志查看 |
|
|
35
|
+
| `group-worker` | 监听 `user_im_message_receive_group_all`,处理配置群消息 |
|
|
36
|
+
| `bot-worker` | 通过钉钉 Stream `TOPIC_ROBOT` 处理单聊 |
|
|
37
|
+
|
|
38
|
+
群消息不会因为出现在 DWS 全群事件流中就自动触发 Agent,只有命中管理页配置的群和发送人才会进入处理队列。每个群独立排队,并复用该群对应 Agent 的 Session。
|
|
29
39
|
|
|
30
|
-
|
|
40
|
+
## 前置条件
|
|
31
41
|
|
|
32
42
|
- Node.js `>= 20`
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
- Client Secret(AppSecret)
|
|
39
|
-
- 已开启 Stream Mode 的机器人
|
|
40
|
-
- 卡片机器人 Robot Code
|
|
43
|
+
- 已安装并登录的 Codex CLI;使用 Pi 时还需要已安装并登录 `pi`
|
|
44
|
+
- 已安装并登录的 DWS CLI;只有群监听需要 DWS
|
|
45
|
+
- 一个已开启 Stream Mode 的钉钉企业内部应用机器人
|
|
46
|
+
- 钉钉应用的 Client ID(AppKey)和 Client Secret(AppSecret)
|
|
47
|
+
- 用于群消息发送的机器人配置,以及可选的钉钉机器人 Webhook
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
可先检查本机依赖:
|
|
43
50
|
|
|
44
51
|
```bash
|
|
45
52
|
node --version
|
|
46
53
|
codex --version
|
|
47
54
|
codex login
|
|
48
55
|
dws --version
|
|
56
|
+
dws auth status
|
|
49
57
|
pi --version # 仅使用 Pi 时需要
|
|
50
58
|
```
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
## 安装与启动
|
|
61
|
+
|
|
62
|
+
从源码运行:
|
|
53
63
|
|
|
54
64
|
```bash
|
|
55
65
|
npm install
|
|
56
66
|
npm run build
|
|
57
67
|
npm link
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 3. 启动
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
omi
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
默认会同时启动:
|
|
67
|
-
|
|
68
|
-
1. DWS 群消息监听器;
|
|
69
|
-
2. 钉钉机器人单聊进程;
|
|
70
|
-
3. 本地管理页。
|
|
71
|
-
|
|
72
|
-
首次运行后打开:
|
|
73
|
-
|
|
74
|
-
```text
|
|
75
|
-
http://127.0.0.1:12525
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Web 管理页、DWS 群监听器和钉钉机器人单聊分别运行在独立进程中。即使 DWS 尚未登录、机器人凭证尚未配置或单聊授权人员为空,管理页也可以正常打开。完成机器人凭证、授权人员和监听规则配置,然后点击“保存并生效”。配置修改会被运行中的进程自动读取,一般不需要重启。
|
|
79
|
-
|
|
80
|
-
> 单聊机器人在没有授权人员时会以 deny-all 模式启动,所有单聊消息都会被拒绝;在管理页添加授权人员后即可使用。
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## 二、`omi` 进程管理
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
omi # 默认启动:群监听 + 机器人单聊
|
|
88
|
-
omi start # 同上
|
|
89
|
-
omi listen # omi start 的别名
|
|
90
|
-
omi --no-listen # 只启动机器人单聊,不启动群监听和管理页
|
|
91
|
-
omi status # 查看模式、工作目录、PID、管理页和日志路径
|
|
92
|
-
omi stop # 停止当前进程
|
|
93
|
-
omi restart # 按当前模式停止并重新启动
|
|
94
|
-
omi update # 使用当前已构建代码重启当前模式
|
|
95
|
-
omi -h # 查看帮助
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 启动流程
|
|
99
|
-
|
|
100
|
-
```text
|
|
101
68
|
omi
|
|
102
|
-
├─ 检查 ~/.oh-my-im/omi-state.json
|
|
103
|
-
├─ 检查是否已有未受 omi 管理的群监听进程
|
|
104
|
-
├─ 后台启动 dashboard-worker(本地管理页)
|
|
105
|
-
├─ 后台启动 dws-listener(默认模式)
|
|
106
|
-
├─ 后台启动 bot-worker
|
|
107
|
-
├─ 将 stdout/stderr 写入 ~/.oh-my-im/omi.log
|
|
108
|
-
└─ 保存进程 PID、启动模式和工作目录
|
|
109
69
|
```
|
|
110
70
|
|
|
111
|
-
|
|
71
|
+
也可以不建立全局命令:
|
|
112
72
|
|
|
113
73
|
```bash
|
|
114
74
|
npm run build
|
|
115
|
-
|
|
75
|
+
npm start
|
|
116
76
|
```
|
|
117
77
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
## 三、本地管理控制台
|
|
121
|
-
|
|
122
|
-
默认地址:
|
|
78
|
+
启动后打开管理页:
|
|
123
79
|
|
|
124
80
|
```text
|
|
125
81
|
http://127.0.0.1:12525
|
|
126
82
|
```
|
|
127
83
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
#### Agent 引擎
|
|
131
|
-
|
|
132
|
-
- Codex Agent
|
|
133
|
-
- Pi Agent
|
|
134
|
-
|
|
135
|
-
这是群监听和新单聊会话的默认 Agent。单聊用户可以在自己的会话中临时切换,超级管理员的 Session 切换也只影响当前私聊。
|
|
136
|
-
|
|
137
|
-
#### 机器人设置
|
|
138
|
-
|
|
139
|
-
- 机器人名称
|
|
140
|
-
- 卡片机器人 Robot Code
|
|
141
|
-
- 机器人 `openDingTalkId`
|
|
142
|
-
- 钉钉应用 Client ID
|
|
143
|
-
- 钉钉应用 Client Secret
|
|
144
|
-
- 机器人单聊授权人员
|
|
145
|
-
- Session 超级管理员
|
|
146
|
-
|
|
147
|
-
机器人 ID 可以根据机器人名称调用 DWS 搜索并自动填写。Client Secret 使用密码框且不会回显;已有配置时留空保存会保留原值。
|
|
148
|
-
|
|
149
|
-
#### 提示词前缀
|
|
150
|
-
|
|
151
|
-
“提示词前缀”中的配置内容由用户自由配置,可留空。保存后,新群消息批次会使用:
|
|
152
|
-
|
|
153
|
-
```text
|
|
154
|
-
<用户配置的提示词前缀>
|
|
155
|
-
|
|
156
|
-
DingTalk 消息事件:
|
|
157
|
-
|
|
158
|
-
<事件 JSON>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
程序不再在源码中写死角色、Skill、输出风格或业务安全提示;如有这些要求,应由使用者在 Web 控制台中配置。提示词保存于 `~/.oh-my-im/dws-dashboard.json` 的 `groupPromptPrefix` 字段,并在保存后立即生效。
|
|
162
|
-
|
|
163
|
-
#### 消息指令关键词
|
|
164
|
-
|
|
165
|
-
每类指令支持配置多个关键词,不同关键词使用 `|` 分隔,例如 `打开ai|启动ai|醒醒`:
|
|
166
|
-
|
|
167
|
-
- 暂停当前任务
|
|
168
|
-
- 打开群监听
|
|
169
|
-
- 关闭群监听
|
|
170
|
-
- 切换到 Pi
|
|
171
|
-
- 切换到 Codex
|
|
172
|
-
|
|
173
|
-
#### 钉钉群监控规则
|
|
174
|
-
|
|
175
|
-
一条规则的唯一键为:
|
|
176
|
-
|
|
177
|
-
```text
|
|
178
|
-
groupId + senderId
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
配置流程:
|
|
182
|
-
|
|
183
|
-
1. 输入群名称;
|
|
184
|
-
2. 搜索群并选择精确匹配项;
|
|
185
|
-
3. 根据 `openConversationId` 加载全部真人群成员;
|
|
186
|
-
4. 勾选一个或多个人员;
|
|
187
|
-
5. 保存后展开成多条“群 + 人员”规则。
|
|
188
|
-
|
|
189
|
-
同名群不会自动选择第一个结果,同名人员也需要在对应群成员中明确选择。
|
|
190
|
-
|
|
191
|
-
#### 回复格式
|
|
192
|
-
|
|
193
|
-
- Markdown
|
|
194
|
-
- 纯文本
|
|
195
|
-
|
|
196
|
-
该配置作用于群互动卡片。纯文本模式会转义 Markdown 特殊字符。
|
|
197
|
-
|
|
198
|
-
#### 最近回复
|
|
199
|
-
|
|
200
|
-
控制台每秒刷新,显示最近的处理中、完成和失败记录,包括:
|
|
201
|
-
|
|
202
|
-
- 会话类型和群名;
|
|
203
|
-
- 发送人;
|
|
204
|
-
- 时间;
|
|
205
|
-
- 使用的 Agent;
|
|
206
|
-
- 原始问题;
|
|
207
|
-
- Agent 回复;
|
|
208
|
-
- 当前处理状态和消息数。
|
|
209
|
-
|
|
210
|
-
### 管理页网络边界
|
|
211
|
-
|
|
212
|
-
默认仅绑定 `127.0.0.1`。端口和绑定地址位于:
|
|
213
|
-
|
|
214
|
-
```text
|
|
215
|
-
~/.oh-my-im/dws-dashboard-server.json
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
如果改为 `0.0.0.0` 对外提供服务,必须在前面增加具备身份认证能力的 HTTPS 反向代理或 VPN。管理页自身不提供登录密码。
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## 四、机器人单聊功能与流程
|
|
223
|
-
|
|
224
|
-
单聊入口使用 `dingtalk-stream` 的 `TOPIC_ROBOT` 回调。
|
|
225
|
-
|
|
226
|
-
### 完整流程
|
|
227
|
-
|
|
228
|
-
```text
|
|
229
|
-
用户给机器人发单聊消息
|
|
230
|
-
↓
|
|
231
|
-
钉钉 Stream Mode 推送消息
|
|
232
|
-
↓
|
|
233
|
-
解析 conversationId、conversationType、sender、文本和附件
|
|
234
|
-
↓
|
|
235
|
-
只接受单聊 conversationType
|
|
236
|
-
↓
|
|
237
|
-
检查发送人是否在“机器人单聊授权人员”中
|
|
238
|
-
├─ 否:回复无权限
|
|
239
|
-
└─ 是:继续
|
|
240
|
-
↓
|
|
241
|
-
识别控制关键词或 / 命令
|
|
242
|
-
├─ 是:执行对应控制操作
|
|
243
|
-
└─ 否:构造 Agent prompt
|
|
244
|
-
↓
|
|
245
|
-
在该用户的私有工作区运行 Codex/Pi
|
|
246
|
-
↓
|
|
247
|
-
创建互动卡片并持续更新
|
|
248
|
-
↓
|
|
249
|
-
完成后只展示模型最终回复
|
|
250
|
-
+ 处理详情(消息数、工具调用次数)
|
|
251
|
-
↓
|
|
252
|
-
记录到本地回复历史
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### 1. 单聊鉴权
|
|
256
|
-
|
|
257
|
-
单聊采用默认拒绝策略:只有管理页中“机器人单聊授权人员”里的用户才能使用。
|
|
258
|
-
|
|
259
|
-
鉴权会尝试匹配消息中的:
|
|
260
|
-
|
|
261
|
-
- `senderStaffId`
|
|
262
|
-
- `senderId`
|
|
263
|
-
|
|
264
|
-
未授权用户会收到拒绝消息及本次收到的用户 ID,便于排查配置。
|
|
265
|
-
|
|
266
|
-
### 2. 用户工作区隔离
|
|
267
|
-
|
|
268
|
-
每个授权用户有独立的默认工作目录:
|
|
269
|
-
|
|
270
|
-
```text
|
|
271
|
-
~/.oh-my-im/users/<用户ID>/workspace
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
普通用户通过 `/sessions` 和 `/use` 只能查看、选择该目录下的 Session,不能进入其他用户或其他项目目录。
|
|
275
|
-
|
|
276
|
-
### 3. 支持的消息类型
|
|
277
|
-
|
|
278
|
-
| 消息类型 | 处理方式 |
|
|
279
|
-
| --- | --- |
|
|
280
|
-
| 文本 | 直接作为 prompt |
|
|
281
|
-
| 图片 | 下载到用户工作区的 `.oh-my-im/media/`,把本地路径交给 Agent 分析 |
|
|
282
|
-
| 语音 | 优先使用钉钉消息中的 `recognition` 文本;没有识别结果时提示用户重发或补充文字 |
|
|
283
|
-
| 视频 | 下载到本地,将路径、文件类型和大小写入 prompt |
|
|
284
|
-
| 文件 | 下载到本地,将路径、文件名、Content-Type 和大小写入 prompt |
|
|
285
|
-
| 富文本 | 提取文本,并下载其中可下载的图片或附件 |
|
|
286
|
-
|
|
287
|
-
附件下载目录:
|
|
288
|
-
|
|
289
|
-
```text
|
|
290
|
-
<用户工作区>/.oh-my-im/media/
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
附件下载需要消息中包含有效的 `downloadCode` 和 `robotCode`。
|
|
294
|
-
|
|
295
|
-
### 单聊 Session 流程图
|
|
296
|
-
|
|
297
|
-
下面的流程图展示了从创建 Agent Session、Pi RPC 交互,到 Session 列表选择和单聊消息处理的主要路径:
|
|
298
|
-
|
|
299
|
-
#### 1. Agent Session 创建
|
|
300
|
-
|
|
301
|
-

|
|
302
|
-
|
|
303
|
-
#### 2. Pi Agent RPC 流程
|
|
304
|
-
|
|
305
|
-

|
|
306
|
-
|
|
307
|
-
#### 3. Session 列表与切换
|
|
308
|
-
|
|
309
|
-

|
|
310
|
-
|
|
311
|
-
#### 4. 单聊消息处理流程
|
|
312
|
-
|
|
313
|
-

|
|
314
|
-
|
|
315
|
-
### 4. 单聊并发与后续消息
|
|
316
|
-
|
|
317
|
-
同一个钉钉会话同一时间只运行一个 Agent 任务。
|
|
318
|
-
|
|
319
|
-
- **Pi Agent**:如果 RPC 已提供 steer 能力,后续文本会作为运行中引导发送给当前任务;如果尚不可引导,则进入下一轮队列。
|
|
320
|
-
- **Codex Agent**:`codex exec` 是单轮进程,运行期间的新消息会进入本地队列;当前任务完成后,队列消息合并成下一轮处理。
|
|
321
|
-
- 同一会话不会并行执行两个 Agent 任务。
|
|
322
|
-
|
|
323
|
-
### 5. 单聊卡片回复
|
|
324
|
-
|
|
325
|
-
处理时:
|
|
326
|
-
|
|
327
|
-
```text
|
|
328
|
-
🔵 【Codex Agent】处理中... (N秒)
|
|
329
|
-
Codex Agent 正在处理...
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
完成时:
|
|
84
|
+
首次安装建议按以下顺序配置:
|
|
333
85
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
处理详情 · 1 条消息 · N 次工具调用
|
|
341
|
-
```
|
|
86
|
+
1. 在“钉钉应用”区域填写 Client ID、Client Secret、机器人名称和机器人 ID。
|
|
87
|
+
2. 在 DWS 区域完成登录;管理页可发起 Device Flow 登录并查看状态。
|
|
88
|
+
3. 搜索群并选择群成员,保存群监听规则。每条规则的唯一键是 `groupId + senderId`。
|
|
89
|
+
4. 选择默认 Agent,必要时填写 Agent 模型名和群提示词后缀。
|
|
90
|
+
5. 如需单聊,打开单聊开关并添加单聊授权人员;可另外配置 Session 超级管理员。
|
|
91
|
+
6. 点击“保存并生效”,然后从钉钉发送一条测试消息。
|
|
342
92
|
|
|
343
|
-
|
|
93
|
+
配置保存后由 worker 重新读取,通常不需要重启。新安装默认关闭单聊;没有单聊白名单时,机器人仍可启动,但所有单聊都会被拒绝。
|
|
344
94
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
## 五、单聊命令与 Session 管理
|
|
348
|
-
|
|
349
|
-
### 普通授权用户命令
|
|
350
|
-
|
|
351
|
-
| 命令 | 作用 |
|
|
352
|
-
| --- | --- |
|
|
353
|
-
| `/help` | 查看当前可用命令 |
|
|
354
|
-
| `/status` | 查看 Agent、CLI 路径、工作目录、当前 Session 和会话数 |
|
|
355
|
-
| `/sessions [pi\|codex]` | 查看当前用户私有目录中的最近 Session |
|
|
356
|
-
| `/use <pi\|codex> <编号或sessionId>` | 选择个人目录中的 Session 并继续执行 |
|
|
357
|
-
| `/current` | 查看当前 Agent、Session 和执行路径 |
|
|
358
|
-
| `/new` | 清空当前私聊中的 Agent、Session 和工作路径绑定 |
|
|
95
|
+
### Agent 模型
|
|
359
96
|
|
|
360
|
-
|
|
97
|
+
管理页仅展示 Pi 的模型选择:
|
|
361
98
|
|
|
362
99
|
```text
|
|
363
|
-
|
|
364
|
-
↓
|
|
365
|
-
扫描本机 Codex Session 索引和 rollout 文件
|
|
366
|
-
↓
|
|
367
|
-
只保留 cwd 位于当前用户私有工作区的 Session
|
|
368
|
-
↓
|
|
369
|
-
返回最近 10 条标题、ID 和时间
|
|
370
|
-
↓
|
|
371
|
-
/use codex 1
|
|
372
|
-
↓
|
|
373
|
-
再次校验 Session cwd
|
|
374
|
-
↓
|
|
375
|
-
后续消息使用 codex exec resume
|
|
100
|
+
Pi 默认模型 -> 所有使用 Pi 的群聊和单聊
|
|
376
101
|
```
|
|
377
102
|
|
|
378
|
-
Pi
|
|
379
|
-
|
|
380
|
-
### Session 超级管理员命令
|
|
381
|
-
|
|
382
|
-
只有管理页中勾选为“Session 超级管理员”的授权人员可使用:
|
|
383
|
-
|
|
384
|
-
| 命令 | 作用 |
|
|
385
|
-
| --- | --- |
|
|
386
|
-
| `/admin-sessions` | 汇总本机所有 Pi/Codex Session 工作目录 |
|
|
387
|
-
| `/admin-cd <目录编号>` | 选择一个管理员工作目录 |
|
|
388
|
-
| `/admin-sessions <pi\|codex>` | 查看所选目录下对应 Agent 的 Session |
|
|
389
|
-
| `/admin-use <pi\|codex> <编号或sessionId>` | 选择所选目录中的 Session |
|
|
390
|
-
| `/admin-current` | 查看管理员当前目录、Agent 和 Session |
|
|
391
|
-
| `/admin-reset` | 退出管理员目录并恢复个人私有工作区 |
|
|
392
|
-
|
|
393
|
-
所有管理员切换都会再次校验目录和 Session 的所属关系。管理员选择只影响当前私聊,不会修改其他用户的会话状态,也不会直接改变全局默认 Agent。
|
|
394
|
-
|
|
395
|
-
---
|
|
396
|
-
|
|
397
|
-
## 六、群消息监听功能与流程
|
|
103
|
+
Codex 始终不会传递 `--model`,也不读取 Web 后台或系统变量中的模型值,由 Codex CLI 自己决定默认模型。Pi 的模型列表通过 `pi --list-models` 获取;如果 Pi CLI 暂不可用,可以先完成 CLI 登录或直接保留默认模型。
|
|
398
104
|
|
|
399
|
-
|
|
105
|
+
## `omi` 命令
|
|
400
106
|
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
↓
|
|
412
|
-
DWS 实时事件流接收
|
|
413
|
-
+ 每 2 秒轮询已配置群最近 20 秒消息(只处理当前登录账号发送的关键指令)
|
|
414
|
-
↓
|
|
415
|
-
提取 conversation_id、message_id、sender 和 content
|
|
416
|
-
↓
|
|
417
|
-
过滤机器人自身消息、带 @ 的消息和重复消息
|
|
418
|
-
↓
|
|
419
|
-
优先识别群控制指令
|
|
420
|
-
├─ 打开/关闭监听
|
|
421
|
-
├─ 暂停任务
|
|
422
|
-
└─ 切换 Agent
|
|
423
|
-
↓
|
|
424
|
-
普通消息检查精确的“当前群 + 当前发送人”规则
|
|
425
|
-
├─ 匹配:进入该群队列
|
|
426
|
-
└─ 不匹配:忽略
|
|
427
|
-
↓
|
|
428
|
-
按群合并当前批次消息
|
|
429
|
-
↓
|
|
430
|
-
使用该群对应的 Agent Session 执行
|
|
431
|
-
↓
|
|
432
|
-
实时更新群互动卡片
|
|
433
|
-
↓
|
|
434
|
-
最终只显示模型最终回复
|
|
435
|
-
+ 处理详情(本批消息数、工具调用次数)
|
|
436
|
-
↓
|
|
437
|
-
保存回复历史
|
|
107
|
+
```bash
|
|
108
|
+
omi # 启动群监听、单聊机器人和管理页
|
|
109
|
+
omi start # 同上
|
|
110
|
+
omi listen # start 的别名
|
|
111
|
+
omi --no-listen # 只启动单聊机器人和管理页
|
|
112
|
+
omi status # 查看模式、PID、工作目录、管理页和日志路径
|
|
113
|
+
omi stop # 停止 omi 及其 worker/子进程
|
|
114
|
+
omi restart # 按当前模式重启
|
|
115
|
+
omi update # 使用当前 dist/ 重启
|
|
116
|
+
omi -h # 查看帮助
|
|
438
117
|
```
|
|
439
118
|
|
|
440
|
-
|
|
119
|
+
`omi update` 只重启当前已经构建的代码,不会执行依赖安装或 TypeScript 编译。修改源码后请执行:
|
|
441
120
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
- 配置机器人自身发送的消息;
|
|
446
|
-
- 含 @/mention 元数据或文本 @ 标记的消息;
|
|
447
|
-
- 已处理过的 `message_id` / `event_id`;
|
|
448
|
-
- 当前“群 + 发送人”不在监听规则中。
|
|
449
|
-
|
|
450
|
-
去重集合最多保留最近 1000 个键。实时事件与历史轮询共用同一去重逻辑,因此同一条消息不会重复执行。
|
|
451
|
-
|
|
452
|
-
### 2. 每群独立队列
|
|
453
|
-
|
|
454
|
-
每个群有独立队列,同一群同一时间只运行一个批次;不同群可以独立运行。
|
|
455
|
-
|
|
456
|
-
```text
|
|
457
|
-
群 A:消息 1、2 → 当前批次
|
|
458
|
-
群 A 处理期间又收到消息 3、4 → 下一批合并处理
|
|
459
|
-
群 B 的消息 → 使用群 B 自己的队列
|
|
121
|
+
```bash
|
|
122
|
+
npm run build
|
|
123
|
+
omi update
|
|
460
124
|
```
|
|
461
125
|
|
|
462
|
-
-
|
|
463
|
-
- Pi 运行中收到新消息:优先作为 steer 引导;失败时进入下一批。
|
|
464
|
-
- 关闭监听会清空尚未开始的该群排队消息,但不会强制中断已经完成大部分执行的任务。
|
|
465
|
-
- 暂停指令会清空待处理队列,并调用当前 Agent 的 abort。
|
|
466
|
-
|
|
467
|
-
### 3. 按群复用 Session
|
|
468
|
-
|
|
469
|
-
Session 键为:
|
|
126
|
+
启动 `omi` 时的当前目录会作为默认 Agent 工作目录,也会影响源码运行时读取的本地 `.oh-my-im` 兼容配置。因此应在目标项目目录中启动,例如:
|
|
470
127
|
|
|
471
|
-
```
|
|
472
|
-
|
|
128
|
+
```bash
|
|
129
|
+
cd /path/to/your/workspace
|
|
130
|
+
omi
|
|
473
131
|
```
|
|
474
132
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
- 同一群后续 Codex 消息使用 `codex exec resume`;
|
|
478
|
-
- 同一群后续 Pi 消息使用对应 Pi Session;
|
|
479
|
-
- Pi 和 Codex 的 Session 相互独立;
|
|
480
|
-
- 不同群之间互不共享 Session;
|
|
481
|
-
- 群 Session 当前只保存在监听进程内存中,监听器重启后重新建立。
|
|
133
|
+
## 管理页配置
|
|
482
134
|
|
|
483
|
-
|
|
135
|
+
管理页默认只绑定 `127.0.0.1`,默认端口为 `12525`。可配置内容包括:
|
|
484
136
|
|
|
485
|
-
|
|
137
|
+
- 默认 Agent:Codex 或 Pi,以及可选的模型名。
|
|
138
|
+
- 钉钉应用凭证、机器人名称、机器人发送者 ID。
|
|
139
|
+
- 单聊开关、单聊授权人员和 Session 超级管理员。
|
|
140
|
+
- 群监听规则:群、群成员和每次个人历史消息拉取参数。
|
|
141
|
+
- 群提示词后缀、互动卡片格式、卡片更新间隔和是否显示耗时。
|
|
142
|
+
- 提示词后缀会追加在用户消息事件 JSON 的最下方。
|
|
143
|
+
- Agent 回复方式:互动卡片模式会创建并更新卡片;普通文本模式只在 Agent 完成后发送最终结果。
|
|
144
|
+
- 处理详情:默认不显示,可在卡片设置中开启;开启后展示消息数和工具调用数。
|
|
145
|
+
- 卡片更新间隔设为正数时按间隔更新处理中内容;设为 `0` 或负数时关闭处理中更新,仅在 Agent 完成后发送最终结果。
|
|
146
|
+
- 暂停、开启/关闭监听、切换 Agent 的关键词。多个关键词用 `|` 分隔。
|
|
147
|
+
- 可选的 Webhook,用于 Agent 处理失败时向群发送文本通知。
|
|
486
148
|
|
|
487
|
-
|
|
488
|
-
2. 程序附加的 `DingTalk 消息事件:` 和事件 JSON。
|
|
149
|
+
管理页自身没有登录密码。如果把绑定地址改为 `0.0.0.0` 或 `::`,应在前面增加带身份认证的 HTTPS 反向代理或 VPN,不要直接暴露管理页。
|
|
489
150
|
|
|
490
|
-
|
|
151
|
+
## 单聊命令
|
|
491
152
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
群任务只使用卡片机器人身份回复,不使用 DWS 登录人的个人身份回消息。
|
|
495
|
-
|
|
496
|
-
处理完成后的卡片格式:
|
|
153
|
+
单聊命令必须由已授权用户发送。Session 相关命令在 Agent 任务运行期间不能执行。
|
|
497
154
|
|
|
498
155
|
```text
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
156
|
+
/help
|
|
157
|
+
/status
|
|
158
|
+
/sessions [pi|codex]
|
|
159
|
+
/use <pi|codex> <编号或 sessionId>
|
|
160
|
+
/current
|
|
161
|
+
/new
|
|
505
162
|
```
|
|
506
163
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
- “消息数”是本次合并批次的实际消息数量;
|
|
510
|
-
- “工具调用次数”是本轮所有工具调用的总和;
|
|
511
|
-
- Codex 只展示 `turn.completed.last_agent_message` 或最后一条模型消息,不拼接中间分析消息;
|
|
512
|
-
- Codex 的 `command_execution`、函数调用、MCP、Web 搜索和文件变更事件会计入工具调用;started/completed 事件按稳定 ID 去重;
|
|
513
|
-
- Pi 的 `tool_execution_start` 按 `toolCallId` 去重。
|
|
514
|
-
|
|
515
|
-
群卡片失败时只记录日志,不会回退为 DWS 当前登录人的个人文本消息。
|
|
516
|
-
|
|
517
|
-
---
|
|
518
|
-
|
|
519
|
-
## 七、群内控制指令
|
|
520
|
-
|
|
521
|
-
所有关键词均在管理页配置。关键词会规范化空格和常见标点后匹配;打开/关闭监听要求整条消息命中对应关键词。
|
|
522
|
-
|
|
523
|
-
### 1. 打开群监听
|
|
524
|
-
|
|
525
|
-
触发条件必须同时满足:
|
|
526
|
-
|
|
527
|
-
1. 当前消息来自群聊;
|
|
528
|
-
2. 发送人在“机器人单聊授权人员”名单中;
|
|
529
|
-
3. 管理页配置的机器人已加入当前群;
|
|
530
|
-
4. 消息命中“打开群监听”关键词。
|
|
531
|
-
|
|
532
|
-
处理结果:
|
|
164
|
+
Session 超级管理员额外拥有:
|
|
533
165
|
|
|
534
166
|
```text
|
|
535
|
-
|
|
167
|
+
/admin-sessions [pi|codex]
|
|
168
|
+
/admin-cd <目录编号或路径>
|
|
169
|
+
/admin-use <pi|codex> <编号或 sessionId>
|
|
170
|
+
/admin-current
|
|
171
|
+
/admin-reset
|
|
536
172
|
```
|
|
537
173
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
如果规则已经存在,不会重复添加,但会修正已保存的群名或人员名。机器人随后在当前群发送“已开启某人在本群的AI 能力”提示。
|
|
541
|
-
|
|
542
|
-
当前登录账号自己发送的 `@某人 + 打开/关闭` 指令不会依赖实时事件流,而是每 5 秒扫描当前账号加入的群历史消息进行补偿;其他人员不走这条慢速补偿路径。
|
|
543
|
-
|
|
544
|
-
### 2. 关闭群监听
|
|
545
|
-
|
|
546
|
-
触发条件与打开监听相同,只是关键词来自“关闭群监听”。
|
|
547
|
-
|
|
548
|
-
处理结果:
|
|
549
|
-
|
|
550
|
-
```text
|
|
551
|
-
删除规则:当前 groupId + 当前 senderId
|
|
552
|
-
```
|
|
174
|
+
用户的默认私有工作目录按钉钉用户 ID 隔离。普通 `/sessions` 和 `/use` 不会展示或切换到其他用户目录中的 Session;管理员切换只影响当前私聊。
|
|
553
175
|
|
|
554
|
-
|
|
176
|
+
## 群消息控制
|
|
555
177
|
|
|
556
|
-
|
|
178
|
+
群控制使用管理页配置的关键词。群内开启/关闭监听时,需要在消息中提及目标成员,且命令发送者必须是配置中的授权人员。暂停命令只暂停当前 Agent 任务;Pi 支持运行中引导,Codex 的后续文本会在当前任务结束后合并处理。
|
|
557
179
|
|
|
558
|
-
|
|
180
|
+
群监听依赖 DWS 事件订阅和本地 DWS 登录状态。事件总线连接成功不等于目标群已生效,实际是否处理还取决于管理页中的群成员规则。
|
|
559
181
|
|
|
560
|
-
|
|
182
|
+
## 环境变量
|
|
561
183
|
|
|
562
|
-
|
|
563
|
-
2. 配置的机器人已经加入当前群;
|
|
564
|
-
3. 消息中存在明确的 @目标人员;
|
|
565
|
-
4. 消息内容命中管理页配置的打开或关闭关键词;
|
|
566
|
-
5. 被 @ 人员可以从当前群成员中解析出来;被 @ 人员不要求在“机器人单聊授权人员”名单中。
|
|
184
|
+
环境变量用于覆盖 CLI 路径、工作目录和部分运行参数;钉钉凭证和业务规则应在管理页中配置。
|
|
567
185
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
186
|
+
| 变量 | 默认值 | 用途 |
|
|
187
|
+
| --- | --- | --- |
|
|
188
|
+
| `CODEX_WORK_DIR` | 启动目录 | 群侧 Codex 工作目录 |
|
|
189
|
+
| `AGENT_WORK_DIR` | 启动目录 | 单聊 Agent 工作目录 |
|
|
190
|
+
| `DWS_CLI_PATH` | `dws` | DWS CLI 路径 |
|
|
191
|
+
| `CODEX_CLI_PATH` | `codex` | 群侧 Codex CLI 路径 |
|
|
192
|
+
| `PI_CLI_PATH` | `pi` | Pi CLI 路径 |
|
|
193
|
+
| `DWS_CODEX_MODEL` | 不使用 | 不读取;Codex 使用系统 CLI 默认模型 |
|
|
194
|
+
| `DWS_CODEX_TIMEOUT_MS` | `300000` | 群侧 Codex 超时,单位毫秒 |
|
|
195
|
+
| `CODEX_PROXY` | 未设置 | 传给 Agent 的代理配置 |
|
|
196
|
+
| `CODEX_HOME` | `~/.codex` | Codex Session 根目录 |
|
|
197
|
+
| `PI_CODING_AGENT_SESSION_DIR` | `~/.pi/agent/sessions` | Pi Session 根目录 |
|
|
198
|
+
| `OHMIM_DATA_DIR` | `~/.oh-my-im` | 回复历史目录使用的数据根目录 |
|
|
571
199
|
|
|
572
|
-
|
|
200
|
+
模型来源:Codex 使用系统 CLI 默认模型,Pi 使用 Web 中的 Pi 配置;Pi 未配置模型时使用 Pi CLI 默认模型。
|
|
573
201
|
|
|
574
|
-
|
|
575
|
-
2. 配置的机器人已加入当前群;
|
|
576
|
-
3. 消息命中“切换到 Pi”或“切换到 Codex”关键词。
|
|
202
|
+
当前实现默认以 bypass/full approval 方式运行 Agent。请只在可信的本地工作目录中使用,并确保 Agent 运行账号拥有合适的文件权限。
|
|
577
203
|
|
|
578
|
-
|
|
204
|
+
## 本地数据与日志
|
|
579
205
|
|
|
580
|
-
|
|
206
|
+
默认数据目录为 `~/.oh-my-im/`:
|
|
581
207
|
|
|
582
208
|
```text
|
|
583
|
-
|
|
209
|
+
~/.oh-my-im/
|
|
210
|
+
├── dws-dashboard.json # 管理页配置,包含敏感凭证
|
|
211
|
+
├── dws-dashboard-server.json # 管理页 host/port
|
|
212
|
+
├── omi-state.json # omi 管理的进程状态
|
|
213
|
+
├── omi.log # worker 合并日志
|
|
214
|
+
├── omi-bot.lock # 单聊 worker 锁
|
|
215
|
+
├── group-worker.lock # 群 worker 锁
|
|
216
|
+
├── omi-bot-status.json # 单聊连接状态
|
|
217
|
+
├── dws-cards.json # 群卡片状态
|
|
218
|
+
├── group-sessions.json # 群聊 Agent Session 绑定
|
|
219
|
+
├── private-sessions.json # 私聊 Agent Session 绑定
|
|
220
|
+
├── dws-history-cursor.json # 个人群历史轮询时间游标和消息去重键
|
|
221
|
+
└── replies/YYYY-MM-DD.json # 单聊和群聊回复历史
|
|
584
222
|
```
|
|
585
223
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
### 4. 暂停任务
|
|
589
|
-
|
|
590
|
-
触发条件:当前群和发送人在监控规则中,且消息命中暂停关键词。
|
|
591
|
-
|
|
592
|
-
- 有任务运行:清空待处理消息并中止当前 Agent;
|
|
593
|
-
- 没有任务运行:机器人回复“当前没有正在处理的 Agent 任务”。
|
|
594
|
-
|
|
595
|
-
### 5. 指令防循环与去重
|
|
596
|
-
|
|
597
|
-
- 机器人自己的切换确认消息会被过滤;
|
|
598
|
-
- 相同群、发送人、指令和内容在 15 秒内只执行一次;
|
|
599
|
-
- 打开/关闭指令的轮询补偿与实时流共用防重逻辑;
|
|
600
|
-
- Agent 切换不通过历史搜索补偿,避免机器人确认消息被误判为用户指令。
|
|
224
|
+
`dws-dashboard.json` 含 Client Secret,请限制文件权限,不要提交到 Git 或复制到公开日志。管理页返回状态时会隐藏 Client Secret 和 Webhook 地址,仅显示是否已配置。
|
|
601
225
|
|
|
602
|
-
|
|
226
|
+
## 开发与验证
|
|
603
227
|
|
|
604
|
-
|
|
228
|
+
源码目录为 `src/`,编译产物为 `dist/`,TypeScript 配置启用严格模式:
|
|
605
229
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
codex exec \
|
|
610
|
-
--json \
|
|
611
|
-
--skip-git-repo-check \
|
|
612
|
-
--dangerously-bypass-approvals-and-sandbox \
|
|
613
|
-
--cd <workDir> -
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
### 恢复会话
|
|
617
|
-
|
|
618
|
-
```text
|
|
619
|
-
codex exec resume \
|
|
620
|
-
--json \
|
|
621
|
-
--skip-git-repo-check \
|
|
622
|
-
--dangerously-bypass-approvals-and-sandbox \
|
|
623
|
-
<sessionId> -
|
|
230
|
+
```bash
|
|
231
|
+
npm install
|
|
232
|
+
npm run build
|
|
624
233
|
```
|
|
625
234
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
### JSONL 解析
|
|
629
|
-
|
|
630
|
-
- `thread.started` / `session_meta`:记录 Session ID;
|
|
631
|
-
- `agent_message` / `message`:获取模型消息;
|
|
632
|
-
- `turn.completed.last_agent_message`:作为权威最终回复;
|
|
633
|
-
- `command_execution`:Shell 调用;
|
|
634
|
-
- `function_call` / `custom_tool_call`:函数或自定义工具;
|
|
635
|
-
- `mcp_tool_call`:MCP 工具;
|
|
636
|
-
- `web_search`:Web 搜索;
|
|
637
|
-
- `file_change`:文件修改。
|
|
638
|
-
|
|
639
|
-
处理中只显示最新模型消息;完成卡片不累加以前的 commentary 或工具前消息。
|
|
640
|
-
|
|
641
|
-
---
|
|
642
|
-
|
|
643
|
-
## 九、Pi Agent 执行流程
|
|
235
|
+
开发时可直接运行单个 worker:
|
|
644
236
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
pi --mode rpc --approve [--session <sessionId>]
|
|
237
|
+
```bash
|
|
238
|
+
npm run dev:bot
|
|
239
|
+
npm run dev:dws
|
|
649
240
|
```
|
|
650
241
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
1. 发送 `get_state` 获取当前 Session ID;
|
|
654
|
-
2. 发送 `prompt`;
|
|
655
|
-
3. 聚合 `message_update.text_delta`;
|
|
656
|
-
4. 统计 `tool_execution_start`;
|
|
657
|
-
5. 从 `message_end` 获取权威完整回复;
|
|
658
|
-
6. 收到 `agent_settled` 后结束;
|
|
659
|
-
7. 暂停时发送 RPC `abort`;
|
|
660
|
-
8. 运行中引导通过 RPC `steer` 发送。
|
|
661
|
-
|
|
662
|
-
---
|
|
663
|
-
|
|
664
|
-
## 十、配置和本地数据
|
|
665
|
-
|
|
666
|
-
主要文件位于:
|
|
242
|
+
运行日志:
|
|
667
243
|
|
|
668
|
-
```
|
|
669
|
-
~/.oh-my-im/
|
|
244
|
+
```bash
|
|
245
|
+
tail -f ~/.oh-my-im/omi.log
|
|
670
246
|
```
|
|
671
247
|
|
|
672
|
-
|
|
673
|
-
| --- | --- |
|
|
674
|
-
| `dws-dashboard.json` | 应用凭证、机器人、授权人员、超级管理员、监听规则、群提示词、关键词、Agent、回复格式 |
|
|
675
|
-
| `dws-dashboard-server.json` | 管理页 host 和 port |
|
|
676
|
-
| `dws-cards.json` | 群卡片 ID 和最后状态,用于处理中卡片恢复 |
|
|
677
|
-
| `replies/YYYY-MM-DD.json` | 单聊和群聊回复历史 |
|
|
678
|
-
| `omi-state.json` | `omi` 管理的进程、模式、工作目录和启动时间 |
|
|
679
|
-
| `omi.log` | 后台进程日志 |
|
|
680
|
-
| `dws-listener.lock` | 群监听单实例锁 |
|
|
681
|
-
| `omi-bot.lock` | 单聊机器人单实例锁 |
|
|
682
|
-
| `users/<用户ID>/workspace/` | 单聊用户隔离工作区 |
|
|
683
|
-
|
|
684
|
-
项目会兼容读取部分旧路径和旧回复文件,并执行一次性配置迁移,避免旧配置中的已删除规则在后续启动时复活。
|
|
685
|
-
|
|
686
|
-
### 配置热更新
|
|
687
|
-
|
|
688
|
-
管理页保存配置时:
|
|
689
|
-
|
|
690
|
-
1. 校验规则完整性和重复项;
|
|
691
|
-
2. 校验至少一名机器人单聊授权人员;
|
|
692
|
-
3. 校验超级管理员属于授权人员;
|
|
693
|
-
4. 校验应用凭证、Robot Code、Agent 和回复格式;
|
|
694
|
-
5. 原子写入临时文件后 rename;
|
|
695
|
-
6. 更新运行中卡片客户端的凭证和 Robot Code;
|
|
696
|
-
7. 后续消息立即使用新配置。
|
|
697
|
-
|
|
698
|
-
单聊进程也会在每次权限和指令检查时重新读取配置中的授权人员、超级管理员、关键词和默认 Agent。
|
|
699
|
-
|
|
700
|
-
---
|
|
701
|
-
|
|
702
|
-
## 十一、环境变量
|
|
703
|
-
|
|
704
|
-
| 环境变量 | 作用 | 默认值 |
|
|
705
|
-
| --- | --- | --- |
|
|
706
|
-
| `PI_CLI_PATH` | Pi CLI 路径 | `pi` |
|
|
707
|
-
| `CODEX_CLI_PATH` | 群监听使用的 Codex CLI 路径 | `codex` |
|
|
708
|
-
| `DWS_CLI_PATH` | DWS CLI 路径 | `dws` |
|
|
709
|
-
| `AGENT_WORK_DIR` | 单聊进程基础工作目录配置;用户默认仍使用隔离目录 | 启动目录 |
|
|
710
|
-
| `CODEX_WORK_DIR` | 群 Agent 工作目录 | 启动目录 |
|
|
711
|
-
| `DWS_CODEX_MODEL` | 群 Codex 模型覆盖 | Codex CLI 默认模型 |
|
|
712
|
-
| `CODEX_PROXY` | Codex/Pi 子进程代理 | 未设置 |
|
|
713
|
-
| `DWS_CODEX_TIMEOUT_MS` | 群任务超时 | `300000`(5 分钟) |
|
|
714
|
-
| `DWS_MAX_EVENTS` | DWS 事件消费数量上限,常用于测试 | 不限制 |
|
|
715
|
-
| `LOG_LEVEL` | `debug` / `info` / `warn` / `error` | `info` |
|
|
716
|
-
| `OHMIM_DATA_DIR` | 回复记录根目录覆盖 | `~/.oh-my-im` |
|
|
717
|
-
|
|
718
|
-
单聊 Agent 默认超时为 30 分钟。
|
|
248
|
+
`package.json` 保留了 `npm test` 入口,但当前仓库没有 `tests/*.test.mjs` 文件;因此提交前至少应运行 `npm run build`,并结合实际 DWS、钉钉和 Agent 依赖做端到端验证。构建不会验证外部账号、权限、事件订阅或卡片发送能力。
|
|
719
249
|
|
|
720
|
-
|
|
250
|
+
## 常见问题
|
|
721
251
|
|
|
722
|
-
|
|
252
|
+
### 管理页打不开
|
|
723
253
|
|
|
724
|
-
-
|
|
725
|
-
- 普通用户 Session 被限制在自己的私有工作区;
|
|
726
|
-
- 超级管理员必须同时属于机器人单聊授权人员;
|
|
727
|
-
- 群普通消息、暂停任务和切换 Agent 均必须匹配精确的 `groupId + senderId` 规则;
|
|
728
|
-
- 群打开/关闭监听必须是授权人员,且配置机器人必须在群内;
|
|
729
|
-
- 群切换 Agent 必须已有监控规则,且配置机器人必须在群内;
|
|
730
|
-
- 机器人自身消息被过滤,避免消息循环;
|
|
731
|
-
- 群 prompt 明确禁止群消息绕过 Skill 的确认门禁和生产安全规则;
|
|
732
|
-
- Client Secret 不在管理页回显;
|
|
733
|
-
- 管理页默认只监听本机回环地址;
|
|
734
|
-
- 当前 Codex/Pi 执行使用自动批准/绕过沙箱模式,应只在可信主机和可信工作目录运行;
|
|
735
|
-
- 不应将 `~/.oh-my-im/dws-dashboard.json`、日志或用户工作区提交到 Git。
|
|
254
|
+
确认已经执行 `npm run build`,再运行 `omi status` 查看 dashboard worker 和日志路径。默认地址是 `127.0.0.1:12525`;端口被占用时,修改 `~/.oh-my-im/dws-dashboard-server.json` 后重启。
|
|
736
255
|
|
|
737
|
-
|
|
256
|
+
### 单聊没有响应
|
|
738
257
|
|
|
739
|
-
|
|
258
|
+
确认管理页已打开单聊开关、已添加发送人白名单、Client ID/Secret 正确,并确认钉钉应用已启用 Stream Mode。无白名单时是预期的 deny-all 行为。
|
|
740
259
|
|
|
741
|
-
###
|
|
260
|
+
### 群消息没有触发
|
|
742
261
|
|
|
743
|
-
|
|
744
|
-
- 缺少 `robotCode` 或卡片创建失败时回退 `sessionWebhook` 文本;
|
|
745
|
-
- Agent 失败时更新失败标题和错误摘要;
|
|
746
|
-
- 暂停时保留最后可见内容;
|
|
747
|
-
- `sessionWebhook` 有时效,只能回复最近收到消息的会话。
|
|
262
|
+
依次检查 `dws auth status`、DWS 事件订阅、群监听是否以默认模式启动,以及管理页中是否选择了准确的群和发送人。DWS 事件状态只能证明订阅连接,不能替代本地规则匹配。
|
|
748
263
|
|
|
749
|
-
###
|
|
750
|
-
|
|
751
|
-
- 使用配置的卡片机器人主动创建和更新互动卡片;
|
|
752
|
-
- 卡片被删除或过期时,处理中任务会创建替代卡片;
|
|
753
|
-
- 卡片 API 失败只记录错误,不以 DWS 当前登录人的身份回退发送;
|
|
754
|
-
- 打开、关闭、暂停、排队和切换等控制提示使用配置机器人普通文本发送。
|
|
755
|
-
|
|
756
|
-
---
|
|
757
|
-
|
|
758
|
-
## 十四、开发与构建
|
|
759
|
-
|
|
760
|
-
> 测试文件已从当前发布目录移除;发布前可在源码仓库中执行项目配置的测试命令。
|
|
761
|
-
|
|
762
|
-
### 构建
|
|
264
|
+
### 修改代码后没有生效
|
|
763
265
|
|
|
764
266
|
```bash
|
|
765
267
|
npm run build
|
|
268
|
+
omi update
|
|
269
|
+
omi status
|
|
766
270
|
```
|
|
767
271
|
|
|
768
|
-
###
|
|
769
|
-
|
|
770
|
-
```bash
|
|
771
|
-
LOG_LEVEL=debug npm run dev:dws
|
|
772
|
-
```
|
|
773
|
-
|
|
774
|
-
调试日志会显示:
|
|
775
|
-
|
|
776
|
-
- DWS 群事件分类;
|
|
777
|
-
- 规则命中情况;
|
|
778
|
-
- 消息去重和排队;
|
|
779
|
-
- Agent Session 是否恢复;
|
|
780
|
-
- 工具名称和调用次数;
|
|
781
|
-
- 模型文本更新;
|
|
782
|
-
- 卡片更新错误。
|
|
272
|
+
### 需要停止残留进程
|
|
783
273
|
|
|
784
|
-
|
|
274
|
+
优先执行:
|
|
785
275
|
|
|
786
276
|
```bash
|
|
787
|
-
|
|
277
|
+
omi stop
|
|
788
278
|
```
|
|
789
279
|
|
|
790
|
-
|
|
280
|
+
`omi stop` 会根据状态文件和 worker 进程树停止由本项目启动的 worker 及其 Agent/DWS 子进程。
|
|
791
281
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
##
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
- 单聊运行状态也保存在进程内存中,但可以通过 `/sessions` 重新选择 CLI 已持久化的 Session;
|
|
815
|
-
- 群消息目前忽略所有包含 @ 的消息;
|
|
816
|
-
- 群历史轮询只查询近期窗口,服务长时间停止期间的旧消息不会补执行;
|
|
817
|
-
- 群卡片失败不会降级为个人身份文本回复;
|
|
818
|
-
- 语音完全依赖钉钉提供的识别文本,不在本地执行语音识别;
|
|
819
|
-
- 图片、视频和文件能否被理解取决于当前 Agent 对本地文件的读取能力;
|
|
820
|
-
- 管理页没有内置登录认证;
|
|
821
|
-
- 程序依赖钉钉、DWS、Codex 和 Pi 当前版本的事件及 CLI 输出格式,升级外部组件后应先运行测试和真实消息验证。
|
|
282
|
+
## 项目结构
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
src/
|
|
286
|
+
├── omi.ts # omi CLI、worker 生命周期和进程状态
|
|
287
|
+
├── dashboard-worker.ts # 管理页 worker
|
|
288
|
+
├── dws-dashboard.ts # 管理页 HTTP 服务和配置模型
|
|
289
|
+
├── group-worker.ts # DWS 群消息监听、队列和群卡片
|
|
290
|
+
├── bot-worker.ts # 单聊 worker 生命周期
|
|
291
|
+
├── bot-app.ts # 单聊鉴权、命令和 Agent 会话
|
|
292
|
+
├── dws-client.ts # DWS CLI 调用与 JSON 适配
|
|
293
|
+
├── dws-history.ts # 群消息历史补偿
|
|
294
|
+
├── dingtalk.ts # Stream 单聊消息解析与发送
|
|
295
|
+
├── dingtalk-card.ts # StandardCard 创建和更新
|
|
296
|
+
├── dingtalk-robot.ts # 钉钉机器人 OpenAPI/Webhook
|
|
297
|
+
├── agents/ # Codex/Pi 进程适配
|
|
298
|
+
└── conversation-log.ts # 回复历史持久化
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
[MIT](LICENSE)
|