@zhin.js/adapter-onebot11 5.0.6 → 6.0.1
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/CHANGELOG.md +38 -0
- package/adapters/onebot11.js +1 -1
- package/adapters/onebot11.ts +1 -1
- package/lib/onebot11-endpoint-commands.js +1 -1
- package/lib/onebot11-runtime-state.js +1 -1
- package/lib/protocol.d.ts +3 -2
- package/lib/protocol.js +33 -10
- package/package.json +13 -13
- package/plugin.js +1 -1
- package/src/onebot11-endpoint-commands.ts +1 -1
- package/src/onebot11-runtime-state.ts +1 -1
- package/src/protocol.ts +35 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @zhin.js/adapter-onebot11
|
|
2
2
|
|
|
3
|
+
## 6.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [c8f4d45]
|
|
8
|
+
- @zhin.js/plugin-runtime@1.1.2
|
|
9
|
+
- @zhin.js/host-http@1.0.5
|
|
10
|
+
- @zhin.js/adapter@1.1.4
|
|
11
|
+
- @zhin.js/agent@1.1.1
|
|
12
|
+
- @zhin.js/command@1.0.6
|
|
13
|
+
- @zhin.js/core@1.5.1
|
|
14
|
+
- zhin.js@6.0.1
|
|
15
|
+
|
|
16
|
+
## 6.0.0
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 4fbff5d: feat!: 多模态双向 Segment 一贯制(BREAKING,无兼容层)
|
|
21
|
+
|
|
22
|
+
全框架唯一媒体表达统一为 canonical `Segment` + `MediaRef{kind: url|path|base64|file, value, mime_type?, file_name?, size?}`,新增 audio/video/file 段类型;所有第二形状(legacy `data.url/file/base64` 字段、`mediaRefFromLegacyData`/`mediaRefToLegacyFields` 桥、双写)全部删除。
|
|
23
|
+
|
|
24
|
+
- **core**:`SendContent` 一等支持 `Segment[]`;endpoint 出站载荷只含 canonical 段;`resolveOutboundMediaPolicy` 改为纯声明驱动(adapter definition `segments.outboundMedia`),内置策略表删除,未声明回退 `url-or-text`;`ImageContent` 旧桥删除。
|
|
25
|
+
- **ai**:新增 `MediaContentBlock`/`MediaBlockRef`(Segment 同构)与 `UserMessage.media`(当前 turn 媒体,**不持久化**——存储层自动剥离);`createUserMessage(text, media?)` 签名变更(`ImageContent` 删除);provider 边界序列化器 `filterMediaBlocksForProvider` + 能力表(缺省 image-only,不支持类型降级占位文本);ai-sdk 桥媒体块 → SDK image/file parts。
|
|
26
|
+
- **agent**:入站 turn 注入(`turn/inbound-media.ts`)——commMessage 媒体段 → 当前 turn `UserMessage.media`;图片 path 物化、音频默认 STT(`@zhin.js/speech` 可选,失败降级占位)、视频/文件占位;`publishOutboundElements` 产出 canonical Segment;`transcribeAudioPayload` 导出。
|
|
27
|
+
- **cli**:`bridgeRuntimeMessage` 回复链路媒体段透传,不再压平为文本(`$reply` 直达 normalize → adapter)。
|
|
28
|
+
- **全部 20 个平台适配器**:出站媒体只消费 `data.media`(url 直发 / base64 直发 / 平台上传 / 读盘),入站媒体产出 canonical `data.media`;`segments.outboundMedia` 声明与实际消费逐一核对修正;QQ 入站新增 canonical segments(image/audio/video/file/mention/face/reply),图片/语音/视频不再丢失。
|
|
29
|
+
|
|
30
|
+
迁移:适配器/插件产媒体一律用 `{ type, data: { media: MediaRef } }`;发送 legacy `data.url/file/base64` 形状的段会被 warn 丢弃。
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [7c1e63a]
|
|
33
|
+
- Updated dependencies [4fbff5d]
|
|
34
|
+
- Updated dependencies [5b94d9c]
|
|
35
|
+
- @zhin.js/command@1.0.5
|
|
36
|
+
- @zhin.js/adapter@1.1.3
|
|
37
|
+
- @zhin.js/core@1.5.0
|
|
38
|
+
- @zhin.js/agent@1.1.0
|
|
39
|
+
- zhin.js@6.0.0
|
|
40
|
+
|
|
3
41
|
## 5.0.6
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/adapters/onebot11.js
CHANGED
|
@@ -21,7 +21,7 @@ export default defineAdapter({
|
|
|
21
21
|
create(context) {
|
|
22
22
|
const config = resolveOneBot11Config(context.config);
|
|
23
23
|
const gateway = context.use(messageGatewayToken);
|
|
24
|
-
// 注册到插件运行时状态(onebot11
|
|
24
|
+
// 注册到插件运行时状态(onebot11.endpoint list 的"运行中"数据源)
|
|
25
25
|
context.use(onebot11RuntimeStateToken).endpoints.set(config.name, {
|
|
26
26
|
name: config.name,
|
|
27
27
|
mode: config.connection,
|
package/adapters/onebot11.ts
CHANGED
|
@@ -28,7 +28,7 @@ export default defineAdapter<OneBot11AdapterConfig>({
|
|
|
28
28
|
create(context) {
|
|
29
29
|
const config = resolveOneBot11Config(context.config);
|
|
30
30
|
const gateway = context.use(messageGatewayToken);
|
|
31
|
-
// 注册到插件运行时状态(onebot11
|
|
31
|
+
// 注册到插件运行时状态(onebot11.endpoint list 的"运行中"数据源)
|
|
32
32
|
context.use(onebot11RuntimeStateToken).endpoints.set(config.name, {
|
|
33
33
|
name: config.name,
|
|
34
34
|
mode: config.connection,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `onebot11
|
|
2
|
+
* `onebot11.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
3
|
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
4
|
*/
|
|
5
5
|
import { createEndpointCommands } from '@zhin.js/adapter';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OneBot11 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
-
* 由 plugin.ts setup() provide,adapter create 与 `onebot11
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `onebot11.endpoint` 命令共享(同一 owner generation)。
|
|
4
4
|
*/
|
|
5
5
|
import { defineEndpointRuntimeStateToken } from '@zhin.js/adapter';
|
|
6
6
|
export const onebot11RuntimeStateToken = defineEndpointRuntimeStateToken('onebot11');
|
package/lib/protocol.d.ts
CHANGED
|
@@ -130,13 +130,14 @@ export declare function isOneBot11BotMentioned(input: {
|
|
|
130
130
|
export declare function formatInboundMetadata(ev: OneBot11Event, endpoint: string): Readonly<Record<string, unknown>>;
|
|
131
131
|
/**
|
|
132
132
|
* canonical MediaRef → OneBot `file` 参数:url 直传、base64 → `base64://`、
|
|
133
|
-
* 本地路径 → `file://`(路径在 OneBot
|
|
133
|
+
* 本地路径 → `file://`(路径在 OneBot 实现侧解析)、kind=file 不透明引用原样透传。
|
|
134
134
|
*/
|
|
135
135
|
export declare function mediaRefToOneBotFile(media: MediaRef): string;
|
|
136
136
|
/**
|
|
137
137
|
* Wire-encode an already-rendered outbound payload into OneBot 11 message segments.
|
|
138
138
|
* 入参假定已经 core `normalizeOutboundPayload` 归一为 canonical Segment[];
|
|
139
|
-
*
|
|
139
|
+
* 媒体段只消费 canonical `data.media`(无 MediaRef 的媒体段 warn + 丢弃),
|
|
140
|
+
* 其余 wire 形状段(at / 平台扩展段)原样透传。
|
|
140
141
|
*/
|
|
141
142
|
export declare function formatOutboundSegments(payload: unknown): OneBot11Segment[];
|
|
142
143
|
export declare function buildSendAction(target: string, message: OneBot11Segment[]): {
|
package/lib/protocol.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
4
|
* Spec: https://github.com/botuniverse/onebot-11
|
|
5
5
|
*/
|
|
6
|
-
import { isMediaRef
|
|
6
|
+
import { isMediaRef } from '@zhin.js/core';
|
|
7
|
+
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
8
|
+
const logger = getLogger('onebot11');
|
|
7
9
|
function normalizeConnection(connection, legacyType) {
|
|
8
10
|
if (connection === 'ws' || connection === 'wss')
|
|
9
11
|
return connection;
|
|
@@ -172,7 +174,7 @@ export function formatInboundMetadata(ev, endpoint) {
|
|
|
172
174
|
}
|
|
173
175
|
/**
|
|
174
176
|
* canonical MediaRef → OneBot `file` 参数:url 直传、base64 → `base64://`、
|
|
175
|
-
* 本地路径 → `file://`(路径在 OneBot
|
|
177
|
+
* 本地路径 → `file://`(路径在 OneBot 实现侧解析)、kind=file 不透明引用原样透传。
|
|
176
178
|
*/
|
|
177
179
|
export function mediaRefToOneBotFile(media) {
|
|
178
180
|
if (media.kind === 'base64') {
|
|
@@ -184,25 +186,36 @@ export function mediaRefToOneBotFile(media) {
|
|
|
184
186
|
return media.value;
|
|
185
187
|
}
|
|
186
188
|
/** 媒体段 data 里的 canonical-only 字段,不进 OneBot wire。 */
|
|
187
|
-
const MEDIA_DATA_SKIP_KEYS = new Set(['media', 'alt'
|
|
189
|
+
const MEDIA_DATA_SKIP_KEYS = new Set(['media', 'alt']);
|
|
190
|
+
/**
|
|
191
|
+
* image / record / video 段:只消费 canonical `data.media` MediaRef,
|
|
192
|
+
* 映射为 OneBot `file` 参数;无 MediaRef 时 warn + 丢弃(返回 null)。
|
|
193
|
+
*/
|
|
188
194
|
function oneBotMediaSegment(type, data) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
195
|
+
if (!isMediaRef(data.media)) {
|
|
196
|
+
logger.warn(formatCompact({
|
|
197
|
+
op: 'onebot11_outbound_media_dropped',
|
|
198
|
+
type,
|
|
199
|
+
reason: 'missing_media_ref',
|
|
200
|
+
}));
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
192
203
|
const extra = {};
|
|
193
204
|
for (const [key, value] of Object.entries(data)) {
|
|
194
205
|
if (!MEDIA_DATA_SKIP_KEYS.has(key))
|
|
195
206
|
extra[key] = value;
|
|
196
207
|
}
|
|
197
|
-
return { type, data: { ...extra, file: mediaRefToOneBotFile(media) } };
|
|
208
|
+
return { type, data: { ...extra, file: mediaRefToOneBotFile(data.media) } };
|
|
198
209
|
}
|
|
199
210
|
/**
|
|
200
211
|
* canonical Segment → OneBot 11 数组段:
|
|
201
212
|
* - mention → at(`qq: target`);
|
|
202
213
|
* - reply(`message_id`)→ reply(`id`);
|
|
203
|
-
* - image / audio→record / video 的 MediaRef → `file`(url / base64:// / file
|
|
214
|
+
* - image / audio→record / video 的 MediaRef → `file`(url / base64:// / file:// / 不透明引用);
|
|
215
|
+
* - file 段无 OneBot 11 消息段承载(文件走 upload_*_file API),warn + 丢弃;
|
|
204
216
|
* - face 取 `id`;
|
|
205
217
|
* - 其余(已是 wire 形状的段、平台扩展段)原样透传。
|
|
218
|
+
* 返回 null 表示该段被丢弃。
|
|
206
219
|
*/
|
|
207
220
|
function canonicalToOneBotSegment(segment) {
|
|
208
221
|
const data = segment.data ?? {};
|
|
@@ -230,6 +243,13 @@ function canonicalToOneBotSegment(segment) {
|
|
|
230
243
|
return oneBotMediaSegment(segment.type, data);
|
|
231
244
|
case 'audio':
|
|
232
245
|
return oneBotMediaSegment('record', data);
|
|
246
|
+
case 'file':
|
|
247
|
+
logger.warn(formatCompact({
|
|
248
|
+
op: 'onebot11_outbound_media_dropped',
|
|
249
|
+
type: 'file',
|
|
250
|
+
reason: 'file_segment_not_supported',
|
|
251
|
+
}));
|
|
252
|
+
return null;
|
|
233
253
|
default:
|
|
234
254
|
return { type: segment.type, data };
|
|
235
255
|
}
|
|
@@ -237,7 +257,8 @@ function canonicalToOneBotSegment(segment) {
|
|
|
237
257
|
/**
|
|
238
258
|
* Wire-encode an already-rendered outbound payload into OneBot 11 message segments.
|
|
239
259
|
* 入参假定已经 core `normalizeOutboundPayload` 归一为 canonical Segment[];
|
|
240
|
-
*
|
|
260
|
+
* 媒体段只消费 canonical `data.media`(无 MediaRef 的媒体段 warn + 丢弃),
|
|
261
|
+
* 其余 wire 形状段(at / 平台扩展段)原样透传。
|
|
241
262
|
*/
|
|
242
263
|
export function formatOutboundSegments(payload) {
|
|
243
264
|
if (typeof payload === 'string') {
|
|
@@ -262,7 +283,9 @@ export function formatOutboundSegments(payload) {
|
|
|
262
283
|
segs.push({ type: 'text', data: { text: item } });
|
|
263
284
|
continue;
|
|
264
285
|
}
|
|
265
|
-
|
|
286
|
+
const seg = canonicalToOneBotSegment(item);
|
|
287
|
+
if (seg)
|
|
288
|
+
segs.push(seg);
|
|
266
289
|
}
|
|
267
290
|
return segs.length ? segs : [{ type: 'text', data: { text: '' } }];
|
|
268
291
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-onebot11",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "Zhin.js OneBot 11 adapter for Plugin Runtime (WebSocket client)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"ws": "^8.21.1",
|
|
44
|
-
"@zhin.js/adapter": "1.1.
|
|
45
|
-
"@zhin.js/command": "1.0.
|
|
46
|
-
"@zhin.js/core": "1.
|
|
47
|
-
"@zhin.js/host-http": "1.0.
|
|
44
|
+
"@zhin.js/adapter": "1.1.4",
|
|
45
|
+
"@zhin.js/command": "1.0.6",
|
|
46
|
+
"@zhin.js/core": "1.5.1",
|
|
47
|
+
"@zhin.js/host-http": "1.0.5",
|
|
48
48
|
"@zhin.js/logger": "1.0.75",
|
|
49
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
49
|
+
"@zhin.js/plugin-runtime": "1.1.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^26.1.2",
|
|
@@ -54,16 +54,16 @@
|
|
|
54
54
|
"typescript": "^6.0.3",
|
|
55
55
|
"vitest": "^4.1.10",
|
|
56
56
|
"zod": "^4.4.3",
|
|
57
|
-
"@zhin.js/agent": "1.
|
|
58
|
-
"@zhin.js/host-http": "1.0.
|
|
57
|
+
"@zhin.js/agent": "1.1.1",
|
|
58
|
+
"@zhin.js/host-http": "1.0.5"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"zod": "^4.0.0",
|
|
62
|
-
"@zhin.js/adapter": "1.1.
|
|
63
|
-
"@zhin.js/agent": "1.
|
|
64
|
-
"@zhin.js/core": "1.
|
|
65
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
66
|
-
"zhin.js": "
|
|
62
|
+
"@zhin.js/adapter": "1.1.4",
|
|
63
|
+
"@zhin.js/agent": "1.1.1",
|
|
64
|
+
"@zhin.js/core": "1.5.1",
|
|
65
|
+
"@zhin.js/plugin-runtime": "1.1.2",
|
|
66
|
+
"zhin.js": "6.0.1"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
69
69
|
"zhin.js": {
|
package/plugin.js
CHANGED
|
@@ -9,7 +9,7 @@ export default definePlugin({
|
|
|
9
9
|
displayName: 'OneBot 11 Adapter',
|
|
10
10
|
},
|
|
11
11
|
setup(context) {
|
|
12
|
-
// 运行中 endpoint 注册表(onebot11
|
|
12
|
+
// 运行中 endpoint 注册表(onebot11.endpoint list 的"运行中"数据源)
|
|
13
13
|
context.resources.provide(onebot11RuntimeStateToken, createEndpointRuntimeState());
|
|
14
14
|
// 平台权限门禁:scene_admin / scene_owner 由 sender role 判定(见 ws/wss-endpoint admit metadata)
|
|
15
15
|
return registerDefaultScenePlatformPermitChecker('onebot11');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `onebot11
|
|
2
|
+
* `onebot11.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
3
|
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
4
|
*/
|
|
5
5
|
import { createEndpointCommands } from '@zhin.js/adapter';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OneBot11 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
-
* 由 plugin.ts setup() provide,adapter create 与 `onebot11
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `onebot11.endpoint` 命令共享(同一 owner generation)。
|
|
4
4
|
*/
|
|
5
5
|
import { defineEndpointRuntimeStateToken } from '@zhin.js/adapter';
|
|
6
6
|
|
package/src/protocol.ts
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
4
|
* Spec: https://github.com/botuniverse/onebot-11
|
|
5
5
|
*/
|
|
6
|
-
import { isMediaRef,
|
|
6
|
+
import { isMediaRef, type MediaRef } from '@zhin.js/core';
|
|
7
|
+
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
8
|
+
|
|
9
|
+
const logger = getLogger('onebot11');
|
|
7
10
|
|
|
8
11
|
/** Transitional legacy endpoint row (`endpoints[]` with `context: onebot11`). */
|
|
9
12
|
export interface OneBot11LegacyEndpointRow {
|
|
@@ -295,7 +298,7 @@ export function formatInboundMetadata(
|
|
|
295
298
|
|
|
296
299
|
/**
|
|
297
300
|
* canonical MediaRef → OneBot `file` 参数:url 直传、base64 → `base64://`、
|
|
298
|
-
* 本地路径 → `file://`(路径在 OneBot
|
|
301
|
+
* 本地路径 → `file://`(路径在 OneBot 实现侧解析)、kind=file 不透明引用原样透传。
|
|
299
302
|
*/
|
|
300
303
|
export function mediaRefToOneBotFile(media: MediaRef): string {
|
|
301
304
|
if (media.kind === 'base64') {
|
|
@@ -308,30 +311,42 @@ export function mediaRefToOneBotFile(media: MediaRef): string {
|
|
|
308
311
|
}
|
|
309
312
|
|
|
310
313
|
/** 媒体段 data 里的 canonical-only 字段,不进 OneBot wire。 */
|
|
311
|
-
const MEDIA_DATA_SKIP_KEYS = new Set(['media', 'alt'
|
|
314
|
+
const MEDIA_DATA_SKIP_KEYS = new Set(['media', 'alt']);
|
|
312
315
|
|
|
316
|
+
/**
|
|
317
|
+
* image / record / video 段:只消费 canonical `data.media` MediaRef,
|
|
318
|
+
* 映射为 OneBot `file` 参数;无 MediaRef 时 warn + 丢弃(返回 null)。
|
|
319
|
+
*/
|
|
313
320
|
function oneBotMediaSegment(
|
|
314
321
|
type: 'image' | 'record' | 'video',
|
|
315
322
|
data: Record<string, unknown>,
|
|
316
|
-
): OneBot11Segment {
|
|
317
|
-
|
|
318
|
-
|
|
323
|
+
): OneBot11Segment | null {
|
|
324
|
+
if (!isMediaRef(data.media)) {
|
|
325
|
+
logger.warn(formatCompact({
|
|
326
|
+
op: 'onebot11_outbound_media_dropped',
|
|
327
|
+
type,
|
|
328
|
+
reason: 'missing_media_ref',
|
|
329
|
+
}));
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
319
332
|
const extra: Record<string, unknown> = {};
|
|
320
333
|
for (const [key, value] of Object.entries(data)) {
|
|
321
334
|
if (!MEDIA_DATA_SKIP_KEYS.has(key)) extra[key] = value;
|
|
322
335
|
}
|
|
323
|
-
return { type, data: { ...extra, file: mediaRefToOneBotFile(media) } };
|
|
336
|
+
return { type, data: { ...extra, file: mediaRefToOneBotFile(data.media) } };
|
|
324
337
|
}
|
|
325
338
|
|
|
326
339
|
/**
|
|
327
340
|
* canonical Segment → OneBot 11 数组段:
|
|
328
341
|
* - mention → at(`qq: target`);
|
|
329
342
|
* - reply(`message_id`)→ reply(`id`);
|
|
330
|
-
* - image / audio→record / video 的 MediaRef → `file`(url / base64:// / file
|
|
343
|
+
* - image / audio→record / video 的 MediaRef → `file`(url / base64:// / file:// / 不透明引用);
|
|
344
|
+
* - file 段无 OneBot 11 消息段承载(文件走 upload_*_file API),warn + 丢弃;
|
|
331
345
|
* - face 取 `id`;
|
|
332
346
|
* - 其余(已是 wire 形状的段、平台扩展段)原样透传。
|
|
347
|
+
* 返回 null 表示该段被丢弃。
|
|
333
348
|
*/
|
|
334
|
-
function canonicalToOneBotSegment(segment: OneBot11WireSegment): OneBot11Segment {
|
|
349
|
+
function canonicalToOneBotSegment(segment: OneBot11WireSegment): OneBot11Segment | null {
|
|
335
350
|
const data = segment.data ?? {};
|
|
336
351
|
switch (segment.type) {
|
|
337
352
|
case 'mention': {
|
|
@@ -354,6 +369,13 @@ function canonicalToOneBotSegment(segment: OneBot11WireSegment): OneBot11Segment
|
|
|
354
369
|
return oneBotMediaSegment(segment.type, data);
|
|
355
370
|
case 'audio':
|
|
356
371
|
return oneBotMediaSegment('record', data);
|
|
372
|
+
case 'file':
|
|
373
|
+
logger.warn(formatCompact({
|
|
374
|
+
op: 'onebot11_outbound_media_dropped',
|
|
375
|
+
type: 'file',
|
|
376
|
+
reason: 'file_segment_not_supported',
|
|
377
|
+
}));
|
|
378
|
+
return null;
|
|
357
379
|
default:
|
|
358
380
|
return { type: segment.type, data };
|
|
359
381
|
}
|
|
@@ -362,7 +384,8 @@ function canonicalToOneBotSegment(segment: OneBot11WireSegment): OneBot11Segment
|
|
|
362
384
|
/**
|
|
363
385
|
* Wire-encode an already-rendered outbound payload into OneBot 11 message segments.
|
|
364
386
|
* 入参假定已经 core `normalizeOutboundPayload` 归一为 canonical Segment[];
|
|
365
|
-
*
|
|
387
|
+
* 媒体段只消费 canonical `data.media`(无 MediaRef 的媒体段 warn + 丢弃),
|
|
388
|
+
* 其余 wire 形状段(at / 平台扩展段)原样透传。
|
|
366
389
|
*/
|
|
367
390
|
export function formatOutboundSegments(payload: unknown): OneBot11Segment[] {
|
|
368
391
|
if (typeof payload === 'string') {
|
|
@@ -390,7 +413,8 @@ export function formatOutboundSegments(payload: unknown): OneBot11Segment[] {
|
|
|
390
413
|
segs.push({ type: 'text', data: { text: item } });
|
|
391
414
|
continue;
|
|
392
415
|
}
|
|
393
|
-
|
|
416
|
+
const seg = canonicalToOneBotSegment(item);
|
|
417
|
+
if (seg) segs.push(seg);
|
|
394
418
|
}
|
|
395
419
|
return segs.length ? segs : [{ type: 'text', data: { text: '' } }];
|
|
396
420
|
}
|