@anxi78/dsh-yuanbao 0.2.0 → 0.3.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 +103 -36
- package/README_EN.md +15 -15
- package/client.js +3 -3
- package/cordis.patch.yml +1 -1
- package/dist/chat-history.d.ts +116 -10
- package/dist/chat-history.js +217 -13
- package/dist/config.js +3 -0
- package/dist/inbound.js +162 -4
- package/dist/index.js +4 -0
- package/dist/types.d.ts +2 -0
- package/package.json +2 -2
- package/src/chat-history.ts +281 -13
- package/src/config.ts +3 -0
- package/src/inbound.ts +175 -4
- package/src/index.ts +5 -0
- package/src/types.ts +2 -0
package/README.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# dsh-yuanbao
|
|
2
2
|
|
|
3
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
4
|
+
|
|
3
5
|
中文 | [English](./README_EN.md)
|
|
4
6
|
|
|
5
7
|
基于 [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) 的元宝 IM 通道插件,将元宝开放平台 WebSocket 消息接入 dsh agent runtime。
|
|
6
8
|
|
|
9
|
+
npm: [`@anxi78/dsh-yuanbao`](https://www.npmjs.com/package/@anxi78/dsh-yuanbao)
|
|
10
|
+
|
|
7
11
|
> **⚠️ 本仓库是定制分支**
|
|
8
12
|
>
|
|
9
13
|
> 上游:[YuanbaoTeam/dsh-yuanbao](https://github.com/YuanbaoTeam/dsh-yuanbao)
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
## 与上游的差异
|
|
18
22
|
|
|
19
23
|
> 对比基准:上游 `9446ebd`(fix: support yuanbao group replies)
|
|
20
|
-
> 统计:**
|
|
24
|
+
> 统计:**23 个文件,+4012 / -115 行**
|
|
21
25
|
|
|
22
26
|
### 一、新增功能
|
|
23
27
|
|
|
@@ -73,6 +77,73 @@ pinnedSessionId: '' # pinned 模式下的目标会话 ID
|
|
|
73
77
|
|
|
74
78
|
**留空自动回退到 per-peer**,不会因为配置错误把消息塞进空会话。
|
|
75
79
|
|
|
80
|
+
#### 5. 群聊上下文
|
|
81
|
+
|
|
82
|
+
**@bot 时能看到群里刚才聊了什么**,而不只是当前这一条。
|
|
83
|
+
|
|
84
|
+
| 项 | 说明 |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `src/chat-history.ts` | 文本历史(每会话 200 条)+ 媒体历史(50 条)+ 最后一条消息追踪 |
|
|
87
|
+
| `src/inbound.ts` | 在 @bot 检查**之前**先记录,没 @bot 的消息也会进历史 |
|
|
88
|
+
|
|
89
|
+
拼进上下文的格式:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
[群聊最近消息(按时间顺序,最后一条最旧→最新)]
|
|
93
|
+
Alice: 刚才那个方案怎么样
|
|
94
|
+
Bob: 我觉得可以
|
|
95
|
+
[以上是 @bot 之前的消息,下面是本次 @bot 的内容]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
回复完成后按 `historyLimit` 清掉已消费的部分,避免下次重复。
|
|
99
|
+
|
|
100
|
+
配置项:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
historyLimit: 20 # 默认 20 条,0 = 关闭
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**持久化**:历史落盘到 `~/.dsh/.yuanbao-history.json`,重启不再失忆。
|
|
107
|
+
(只存文本,不存媒体 —— 媒体的 url 带签名时效,过期了也用不了。)
|
|
108
|
+
|
|
109
|
+
#### 6. 发图后立刻 @bot,自动带上那张图
|
|
110
|
+
|
|
111
|
+
**场景**:用户先发一张图(这条 @ 不到 bot),紧接着 @bot 问「这张图是什么」。
|
|
112
|
+
|
|
113
|
+
**触发条件(缺一不可):**
|
|
114
|
+
|
|
115
|
+
| 条件 | 说明 |
|
|
116
|
+
|---|---|
|
|
117
|
+
| **同一个人** | 上一条必须是当前发送者发的 |
|
|
118
|
+
| **必须是最后一条** | 中间有任何人的消息都不算,**包括自己发的文字** |
|
|
119
|
+
| **只对图片** | 文件不生效,图+文件混合也不生效 |
|
|
120
|
+
|
|
121
|
+
实现要点:`chatLastMessage` 单独追踪「最后一条消息」——文本历史只记有正文的消息,
|
|
122
|
+
纯图片会被跳过,所以需要独立的记录来判断上一条到底是什么。
|
|
123
|
+
|
|
124
|
+
#### 7. 引用消息(文字 + 媒体)
|
|
125
|
+
|
|
126
|
+
**引用信息不在 `msg_body`,而在消息级的 `cloud_custom_data`:**
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{ "quote": { "desc": "被引用的文字", "type": 2, "id": "msgId" } }
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`type`:1 文字 / 2 图片 / 3 文件 / 4 视频 / 5 语音。
|
|
133
|
+
|
|
134
|
+
| 引用类型 | 处理 |
|
|
135
|
+
|---|---|
|
|
136
|
+
| **文字** | 格式化为 `> [引用消息 from 某人]: 内容` |
|
|
137
|
+
| **媒体** | `desc` 为空,按 `id` 回查媒体历史 → 换取真实 COS 地址 → 下载 → 作为附件 |
|
|
138
|
+
|
|
139
|
+
**关键坑**:入站媒体给的是 `hunyuan.tencent.com/api/resource/download?resourceId=xxx`,
|
|
140
|
+
直接 GET 返回 **401**。必须先调 `/api/resource/v1/download` 换取真正的 COS 地址。
|
|
141
|
+
|
|
142
|
+
#### 8. 设置面板持久化
|
|
143
|
+
|
|
144
|
+
设置存到 `~/.dsh/.yuanbao-settings.json`,重启不丢。
|
|
145
|
+
(为什么不写 `cordis.patch.yml`:那是静态配置,改一次要手写 YAML 再重启。)
|
|
146
|
+
|
|
76
147
|
### 二、修复的问题
|
|
77
148
|
|
|
78
149
|
#### 1. 群消息发送失败(`bot_id is required`)
|
|
@@ -142,34 +213,38 @@ Cordis 插件读取未声明的服务会抛错。新增的 `createServiceReader`
|
|
|
142
213
|
|
|
143
214
|
### 四、文件清单
|
|
144
215
|
|
|
145
|
-
**新增(
|
|
216
|
+
**新增(10 个)**
|
|
146
217
|
|
|
147
218
|
```
|
|
148
219
|
assets/builtin-stickers.json 542 行 内置表情库
|
|
149
|
-
client.js
|
|
150
|
-
src/media.ts
|
|
220
|
+
client.js 327 行 设置面板
|
|
221
|
+
src/media.ts 207 行 入站媒体
|
|
151
222
|
src/outbound-media.ts 363 行 出站媒体
|
|
152
223
|
src/services.ts 59 行 服务读取封装
|
|
153
224
|
src/stickers.ts 131 行 表情包
|
|
154
225
|
src/tools.ts 407 行 Agent 工具
|
|
226
|
+
src/chat-history.ts 363 行 文本/媒体历史、持久化
|
|
227
|
+
src/quote.ts 157 行 引用消息解析
|
|
155
228
|
src/dsh-tools.d.ts 13 行 工具类型声明
|
|
156
229
|
```
|
|
157
230
|
|
|
158
|
-
**修改(
|
|
231
|
+
**修改(13 个)**
|
|
159
232
|
|
|
160
233
|
```
|
|
161
|
-
src/
|
|
162
|
-
src/transport/sender.ts
|
|
163
|
-
src/transport/outbound.ts
|
|
164
|
-
src/session/manager.ts
|
|
165
|
-
src/
|
|
166
|
-
src/index.ts
|
|
167
|
-
src/gateway/index.ts
|
|
168
|
-
src/config.ts +
|
|
169
|
-
src/types.ts +
|
|
170
|
-
package.json
|
|
234
|
+
src/inbound.ts 主要改动 @提及判定、媒体提取、历史、自动附图
|
|
235
|
+
src/transport/sender.ts +265 发送结果传播、身份校验、COS 地址换取
|
|
236
|
+
src/transport/outbound.ts +116 媒体消息支持
|
|
237
|
+
src/session/manager.ts +104 会话路由
|
|
238
|
+
src/bridge.ts +71 复用 gateway account、注册工具
|
|
239
|
+
src/index.ts +91 服务注入、配置、历史恢复
|
|
240
|
+
src/gateway/index.ts +33 account 暴露、httpAuth
|
|
241
|
+
src/config.ts +10 会话路由、historyLimit
|
|
242
|
+
src/types.ts +10 类型定义
|
|
243
|
+
package.json +16 client 入口声明
|
|
171
244
|
```
|
|
172
245
|
|
|
246
|
+
**总计**:`23 files changed, 4012 insertions(+), 115 deletions(-)`
|
|
247
|
+
|
|
173
248
|
### 五、同步上游
|
|
174
249
|
|
|
175
250
|
```bash
|
|
@@ -197,14 +272,14 @@ git merge upstream/main
|
|
|
197
272
|
|
|
198
273
|
## 安装
|
|
199
274
|
|
|
200
|
-
### 方式一:从 npm registry
|
|
275
|
+
### 方式一:从 npm registry 安装(推荐)
|
|
201
276
|
|
|
202
277
|
```bash
|
|
203
|
-
#
|
|
204
|
-
dsh plugin --profile
|
|
278
|
+
# 安装到 web profile
|
|
279
|
+
dsh plugin --profile web add @anxi78/dsh-yuanbao
|
|
205
280
|
|
|
206
281
|
# 启动
|
|
207
|
-
dsh --profile
|
|
282
|
+
dsh --profile web
|
|
208
283
|
```
|
|
209
284
|
|
|
210
285
|
### 方式二:本地路径安装
|
|
@@ -215,19 +290,11 @@ cd /path/to/dsh-yuanbao
|
|
|
215
290
|
pnpm install
|
|
216
291
|
pnpm build
|
|
217
292
|
|
|
218
|
-
# 安装到
|
|
219
|
-
|
|
220
|
-
pnpm dsh plugin --profile yuanbao add /path/to/dsh-yuanbao
|
|
293
|
+
# 安装到 web profile
|
|
294
|
+
dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
221
295
|
|
|
222
296
|
# 启动
|
|
223
|
-
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
如果需要和 Web UI 一起使用,也可以安装到 `web` profile:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
pnpm dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
230
|
-
pnpm dsh --profile web
|
|
297
|
+
dsh --profile web
|
|
231
298
|
```
|
|
232
299
|
|
|
233
300
|
## 环境变量
|
|
@@ -372,7 +439,7 @@ agent-default-model:
|
|
|
372
439
|
```yaml
|
|
373
440
|
- insert:
|
|
374
441
|
- id: dsh-yuanbao
|
|
375
|
-
name: 'dsh-yuanbao'
|
|
442
|
+
name: '@anxi78/dsh-yuanbao'
|
|
376
443
|
config:
|
|
377
444
|
provider: openai
|
|
378
445
|
model: gpt-4o-mini
|
|
@@ -400,6 +467,7 @@ agent-default-model:
|
|
|
400
467
|
| `sessionIdleTimeout` | number | `1800000` | 会话闲置超时,默认 30 分钟 |
|
|
401
468
|
| `sessionMode` | `per-peer` / `pinned` | `per-peer` | **本分支新增**:会话路由模式 |
|
|
402
469
|
| `pinnedSessionId` | string | `''` | **本分支新增**:pinned 模式下的目标会话 ID,留空回退 per-peer |
|
|
470
|
+
| `historyLimit` | number | `20` | **本分支新增**:群聊上下文条数,@bot 时带上最近 N 条;0 = 关闭 |
|
|
403
471
|
| `processingTimeoutMs` | number | `120000` | Agent 处理超时 |
|
|
404
472
|
| `maxReconnectAttempts` | number | `100` | WebSocket 最大重连次数 |
|
|
405
473
|
| `access.c2cMode` | `open` / `allowlist` / `disabled` | `open` | 私聊访问控制 |
|
|
@@ -413,7 +481,7 @@ agent-default-model:
|
|
|
413
481
|
```yaml
|
|
414
482
|
- insert:
|
|
415
483
|
- id: dsh-yuanbao
|
|
416
|
-
name: 'dsh-yuanbao'
|
|
484
|
+
name: '@anxi78/dsh-yuanbao'
|
|
417
485
|
config:
|
|
418
486
|
appKey: !!js process.env.YUANBAO_APP_KEY ?? ''
|
|
419
487
|
appSecret: !!js process.env.YUANBAO_APP_SECRET ?? ''
|
|
@@ -519,10 +587,9 @@ pnpm build
|
|
|
519
587
|
# watch
|
|
520
588
|
pnpm dev
|
|
521
589
|
|
|
522
|
-
# 本地安装到
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
pnpm dsh --profile yuanbao
|
|
590
|
+
# 本地安装到 web profile
|
|
591
|
+
dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
592
|
+
dsh --profile web
|
|
526
593
|
```
|
|
527
594
|
|
|
528
595
|
## License
|
package/README_EN.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-yuanbao
|
|
2
2
|
|
|
3
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
4
|
+
|
|
3
5
|
[中文](./README.md) | English
|
|
4
6
|
|
|
5
7
|
A Yuanbao IM channel plugin for [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh). It connects Yuanbao Open Platform WebSocket messages to the dsh agent runtime.
|
|
@@ -21,14 +23,14 @@ Yuanbao User → Yuanbao WebSocket Gateway → dsh-yuanbao → ctx.agents → ds
|
|
|
21
23
|
|
|
22
24
|
## Installation
|
|
23
25
|
|
|
24
|
-
### Option 1: Install from npm registry
|
|
26
|
+
### Option 1: Install from npm registry (recommended)
|
|
25
27
|
|
|
26
28
|
```bash
|
|
27
|
-
# Install into
|
|
28
|
-
dsh plugin --profile
|
|
29
|
+
# Install into the web profile
|
|
30
|
+
dsh plugin --profile web add @anxi78/dsh-yuanbao
|
|
29
31
|
|
|
30
32
|
# Start
|
|
31
|
-
dsh --profile
|
|
33
|
+
dsh --profile web
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
### Option 2: Install from local path
|
|
@@ -39,15 +41,14 @@ cd /path/to/dsh-yuanbao
|
|
|
39
41
|
pnpm install
|
|
40
42
|
pnpm build
|
|
41
43
|
|
|
42
|
-
# Install into
|
|
43
|
-
|
|
44
|
-
pnpm dsh plugin --profile yuanbao add /path/to/dsh-yuanbao
|
|
44
|
+
# Install into the web profile
|
|
45
|
+
dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
45
46
|
|
|
46
47
|
# Start
|
|
47
|
-
|
|
48
|
+
dsh --profile web
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
The `web` profile is the one used together with the Web UI:
|
|
51
52
|
|
|
52
53
|
```bash
|
|
53
54
|
pnpm dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
@@ -196,7 +197,7 @@ You can also explicitly set the model in `cordis.patch.yml` for `dsh-yuanbao`, o
|
|
|
196
197
|
```yaml
|
|
197
198
|
- insert:
|
|
198
199
|
- id: dsh-yuanbao
|
|
199
|
-
name: 'dsh-yuanbao'
|
|
200
|
+
name: '@anxi78/dsh-yuanbao'
|
|
200
201
|
config:
|
|
201
202
|
provider: openai
|
|
202
203
|
model: gpt-4o-mini
|
|
@@ -235,7 +236,7 @@ Default bundle patch:
|
|
|
235
236
|
```yaml
|
|
236
237
|
- insert:
|
|
237
238
|
- id: dsh-yuanbao
|
|
238
|
-
name: 'dsh-yuanbao'
|
|
239
|
+
name: '@anxi78/dsh-yuanbao'
|
|
239
240
|
config:
|
|
240
241
|
appKey: !!js process.env.YUANBAO_APP_KEY ?? ''
|
|
241
242
|
appSecret: !!js process.env.YUANBAO_APP_SECRET ?? ''
|
|
@@ -326,10 +327,9 @@ pnpm build
|
|
|
326
327
|
# Watch
|
|
327
328
|
pnpm dev
|
|
328
329
|
|
|
329
|
-
# Install locally into
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
pnpm dsh --profile yuanbao
|
|
330
|
+
# Install locally into the web profile
|
|
331
|
+
dsh plugin --profile web add /path/to/dsh-yuanbao
|
|
332
|
+
dsh --profile web
|
|
333
333
|
```
|
|
334
334
|
|
|
335
335
|
## License
|
package/client.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* slots.inject('settings.section', () => slots.register({...}, () => h(Panel)))
|
|
14
14
|
*/
|
|
15
15
|
window.__ModuleLoader__.load({
|
|
16
|
-
id: 'dsh-yuanbao',
|
|
16
|
+
id: '@anxi78/dsh-yuanbao',
|
|
17
17
|
factory: (require) => {
|
|
18
18
|
const React = require('react')
|
|
19
19
|
const h = React.createElement
|
|
@@ -309,10 +309,10 @@ select.yb-input{font-family:inherit;cursor:pointer;appearance:none;background-im
|
|
|
309
309
|
inject: ['slots', 'sessions'],
|
|
310
310
|
apply(ctx) {
|
|
311
311
|
const style = document.createElement('style')
|
|
312
|
-
style.setAttribute('data-plugin-css', 'dsh-yuanbao')
|
|
312
|
+
style.setAttribute('data-plugin-css', '@anxi78/dsh-yuanbao')
|
|
313
313
|
style.textContent = CSS
|
|
314
314
|
document.head.appendChild(style)
|
|
315
|
-
ctx.effect(() => () => style.remove(), 'dsh-yuanbao: 设置页样式')
|
|
315
|
+
ctx.effect(() => () => style.remove(), '@anxi78/dsh-yuanbao: 设置页样式')
|
|
316
316
|
|
|
317
317
|
const slots = (typeof ctx.get === 'function' ? ctx.get('slots') : undefined) || ctx.slots
|
|
318
318
|
if (!slots) return
|
package/cordis.patch.yml
CHANGED
package/dist/chat-history.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* 的 desc 是空的。要还原出真实内容,必须靠本地缓存:
|
|
2
|
+
* 聊天历史
|
|
3
|
+
* =========
|
|
4
|
+
* 两类历史,生命周期不同:
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* 1. 文本历史(chatTextHistories)
|
|
7
|
+
* 群里每条消息都记下来,@bot 时拼进上下文,让 agent 知道刚才在聊什么。
|
|
8
|
+
* 回复完成后按 limit 清空已消费的部分。
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* 2. 媒体历史(chatMediaHistories)
|
|
11
|
+
* 记录消息携带的图片/文件,供「引用消息」按 id 回查。
|
|
12
|
+
* 独立存储:@bot 后文本历史会被清理,但引用随时可能指向更早的图片。
|
|
13
|
+
*
|
|
14
|
+
* 为什么要自己维护文本历史:
|
|
15
|
+
* 元宝只把「@bot 的那条消息」推给插件,群里的其他消息插件根本收不到。
|
|
16
|
+
* 等等——实际上群消息都会推送,只是没有 @ 时被 requireMention 丢掉了。
|
|
17
|
+
* 所以在丢弃之前先记进历史,@bot 时就能带上上下文。
|
|
13
18
|
*/
|
|
14
19
|
import type { InboundMedia } from './media.js';
|
|
15
20
|
/** 一条媒体历史记录 */
|
|
@@ -27,13 +32,80 @@ export type MediaHistoryEntry = {
|
|
|
27
32
|
kind?: 'image' | 'file';
|
|
28
33
|
}>;
|
|
29
34
|
};
|
|
35
|
+
/** 一条文本历史记录 */
|
|
36
|
+
export type TextHistoryEntry = {
|
|
37
|
+
/** 消息 id */
|
|
38
|
+
messageId?: string;
|
|
39
|
+
/** 发送者昵称(优先)或账号 */
|
|
40
|
+
sender: string;
|
|
41
|
+
/** 发送者账号(稳定标识) */
|
|
42
|
+
senderId?: string;
|
|
43
|
+
/** 消息正文(已去除 @bot 的部分) */
|
|
44
|
+
body: string;
|
|
45
|
+
/** 消息时间戳(ms) */
|
|
46
|
+
timestamp: number;
|
|
47
|
+
};
|
|
30
48
|
/** chatKey → 媒体历史 */
|
|
31
49
|
export declare const chatMediaHistories: Map<string, MediaHistoryEntry[]>;
|
|
50
|
+
/** chatKey → 文本历史 */
|
|
51
|
+
export declare const chatTextHistories: Map<string, TextHistoryEntry[]>;
|
|
52
|
+
/**
|
|
53
|
+
* chatKey → 该会话收到的**最后一条消息**的元信息。
|
|
54
|
+
*
|
|
55
|
+
* 和 chatTextHistories 的区别:文本历史只记有正文的消息,
|
|
56
|
+
* 纯图片消息没有正文会被跳过。但「发图后立刻 @bot」需要知道
|
|
57
|
+
* 上一条消息**到底是什么**(哪怕它没有文字),所以单独记一份。
|
|
58
|
+
*/
|
|
59
|
+
export type LastMessageEntry = {
|
|
60
|
+
/** 消息 id */
|
|
61
|
+
messageId?: string;
|
|
62
|
+
/** 发送者账号(稳定标识,用于判断是不是同一个人) */
|
|
63
|
+
senderId?: string;
|
|
64
|
+
/** 发送者昵称 */
|
|
65
|
+
senderNickname?: string;
|
|
66
|
+
/** 这条消息携带的媒体类型(image/file/undefined) */
|
|
67
|
+
mediaKinds: Array<'image' | 'file'>;
|
|
68
|
+
/** 媒体列表(供自动附图使用) */
|
|
69
|
+
medias: Array<{
|
|
70
|
+
url: string;
|
|
71
|
+
name?: string;
|
|
72
|
+
kind?: 'image' | 'file';
|
|
73
|
+
}>;
|
|
74
|
+
/** 记录时间 */
|
|
75
|
+
timestamp: number;
|
|
76
|
+
};
|
|
77
|
+
export declare const chatLastMessage: Map<string, LastMessageEntry>;
|
|
32
78
|
/**
|
|
33
79
|
* 生成会话级缓存键。
|
|
34
80
|
* 群聊用 group:{groupCode},私聊用 direct:{fromAccount}。
|
|
35
81
|
*/
|
|
36
82
|
export declare function deriveChatKey(isGroup: boolean, groupCode?: string, fromAccount?: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* 记录一条群聊文本消息。
|
|
85
|
+
*
|
|
86
|
+
* 空正文(比如纯图片消息)不记 —— 图片走媒体历史,
|
|
87
|
+
* 这里记了也只是空行,反而污染上下文。
|
|
88
|
+
*/
|
|
89
|
+
export declare function rememberText(chatKey: string, entry: {
|
|
90
|
+
messageId?: string;
|
|
91
|
+
sender: string;
|
|
92
|
+
senderId?: string;
|
|
93
|
+
body: string;
|
|
94
|
+
}): void;
|
|
95
|
+
/**
|
|
96
|
+
* 取出最近 limit 条文本历史。
|
|
97
|
+
*
|
|
98
|
+
* 返回的是**当前消息之前**的历史 —— 调用方应在记录当前消息之前调用,
|
|
99
|
+
* 否则当前消息会重复出现(一次在历史里,一次在正文里)。
|
|
100
|
+
*/
|
|
101
|
+
export declare function recentText(chatKey: string, limit: number): TextHistoryEntry[];
|
|
102
|
+
/**
|
|
103
|
+
* 消费掉最近 limit 条历史。
|
|
104
|
+
*
|
|
105
|
+
* 回复完成后调用:这些内容已经进了 agent 的上下文,
|
|
106
|
+
* 下次再拼一遍就是重复。
|
|
107
|
+
*/
|
|
108
|
+
export declare function consumeText(chatKey: string, limit: number): void;
|
|
37
109
|
/**
|
|
38
110
|
* 记录一条消息携带的媒体。
|
|
39
111
|
*
|
|
@@ -50,5 +122,39 @@ export declare function rememberMedia(chatKey: string, entry: {
|
|
|
50
122
|
* 从后往前找 —— 引用通常指向较近的消息。
|
|
51
123
|
*/
|
|
52
124
|
export declare function findMediaByMessageId(chatKey: string, messageId: string | undefined): MediaHistoryEntry | undefined;
|
|
53
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* 记录「这个会话收到的最后一条消息」。
|
|
127
|
+
*
|
|
128
|
+
* 每条消息都要调(包括没有正文的纯图片消息),
|
|
129
|
+
* 这样「发图后立刻 @bot」才能判断上一条到底是什么。
|
|
130
|
+
*/
|
|
131
|
+
export declare function rememberLastMessage(chatKey: string, entry: {
|
|
132
|
+
messageId?: string;
|
|
133
|
+
senderId?: string;
|
|
134
|
+
senderNickname?: string;
|
|
135
|
+
medias: InboundMedia[];
|
|
136
|
+
}): void;
|
|
137
|
+
/** 取这个会话的最后一条消息(没有则 undefined) */
|
|
138
|
+
export declare function lastMessage(chatKey: string): LastMessageEntry | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* 取最近一条媒体记录。
|
|
141
|
+
*
|
|
142
|
+
* 用于「发图后立刻 @bot」的自动附图机制:需要判断上一条消息
|
|
143
|
+
* 是不是同一人发的图片。只看最后一条,不做模糊匹配。
|
|
144
|
+
*/
|
|
145
|
+
export declare function latestMedia(chatKey: string): MediaHistoryEntry | undefined;
|
|
146
|
+
/** 清空某个会话的全部历史(会话结束时调用) */
|
|
54
147
|
export declare function clearChatHistory(chatKey: string): void;
|
|
148
|
+
/** 安排一次防抖写盘(200ms 内的多次改动合并成一次) */
|
|
149
|
+
export declare function schedulePersist(logger?: {
|
|
150
|
+
warn: (m: string) => void;
|
|
151
|
+
}): void;
|
|
152
|
+
/**
|
|
153
|
+
* 启动时从磁盘恢复文本历史。
|
|
154
|
+
*
|
|
155
|
+
* 只恢复最近的条目,过旧的历史带进上下文反而干扰。
|
|
156
|
+
*/
|
|
157
|
+
export declare function loadPersistedHistory(logger?: {
|
|
158
|
+
info: (m: string) => void;
|
|
159
|
+
warn: (m: string) => void;
|
|
160
|
+
}): Promise<void>;
|