@zhin.js/adapter-sandbox 7.0.0 → 7.0.2
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 +25 -0
- package/lib/endpoint.d.ts +2 -5
- package/lib/endpoint.js +27 -27
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/protocol.d.ts +10 -0
- package/lib/protocol.js +17 -0
- package/package.json +14 -13
- package/src/endpoint.ts +28 -37
- package/src/index.ts +1 -0
- package/src/protocol.ts +22 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @zhin.js/adapter-process
|
|
2
2
|
|
|
3
|
+
## 7.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [afc0e66]
|
|
8
|
+
- Updated dependencies [2e41ad5]
|
|
9
|
+
- Updated dependencies [9f57124]
|
|
10
|
+
- @zhin.js/core@1.5.2
|
|
11
|
+
- @zhin.js/adapter@1.1.5
|
|
12
|
+
- @zhin.js/im-contract@1.0.1
|
|
13
|
+
- @zhin.js/plugin-runtime@1.1.3
|
|
14
|
+
- @zhin.js/host-http@1.0.6
|
|
15
|
+
- @zhin.js/page@1.0.6
|
|
16
|
+
|
|
17
|
+
## 7.0.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [c8f4d45]
|
|
22
|
+
- @zhin.js/plugin-runtime@1.1.2
|
|
23
|
+
- @zhin.js/page@1.0.5
|
|
24
|
+
- @zhin.js/host-http@1.0.5
|
|
25
|
+
- @zhin.js/adapter@1.1.4
|
|
26
|
+
- @zhin.js/core@1.5.1
|
|
27
|
+
|
|
3
28
|
## 7.0.0
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EndpointInstance } from '@zhin.js/adapter';
|
|
1
|
+
import type { EndpointInstance, EndpointSendRequest } from '@zhin.js/adapter';
|
|
2
2
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
4
4
|
import type { CapabilityId } from '@zhin.js/plugin-runtime';
|
|
@@ -22,8 +22,5 @@ export declare class SandboxWsEndpoint implements EndpointInstance {
|
|
|
22
22
|
open(): void;
|
|
23
23
|
close(): void;
|
|
24
24
|
stop(): void;
|
|
25
|
-
send({
|
|
26
|
-
readonly target: string;
|
|
27
|
-
readonly payload: unknown;
|
|
28
|
-
}): unknown;
|
|
25
|
+
send({ conversation, payload }: EndpointSendRequest): unknown;
|
|
29
26
|
}
|
package/lib/endpoint.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
6
|
-
import { bindSandboxWsSocket, formatSandboxOutbound, parseSandboxWsPayload, whenWsOpen, } from './protocol.js';
|
|
6
|
+
import { bindSandboxWsSocket, formatSandboxOutbound, parseSandboxWsPayload, sandboxInboundConversation, whenWsOpen, } from './protocol.js';
|
|
7
7
|
const logger = getLogger('sandbox');
|
|
8
8
|
/**
|
|
9
9
|
* 多 sandbox endpoint 共用同一个 HttpHost 时,同 path 的所有 WS listener
|
|
@@ -106,36 +106,39 @@ export class SandboxWsEndpoint {
|
|
|
106
106
|
this.#started = false;
|
|
107
107
|
logger.debug(formatCompact({ op: 'sandbox_stopped' }));
|
|
108
108
|
}
|
|
109
|
-
send({
|
|
109
|
+
send({ conversation, payload }) {
|
|
110
110
|
if (!this.#open)
|
|
111
111
|
return undefined;
|
|
112
|
-
// Reply
|
|
113
|
-
|
|
112
|
+
// Reply targets this endpoint's own live socket (fixed bot name, or the
|
|
113
|
+
// only live random-name connection); conversation carries kind/id stamp.
|
|
114
|
+
const connection = this.#connections.get(this.#options.defaults.name)
|
|
114
115
|
?? this.#findLiveConnection();
|
|
115
116
|
if (!connection) {
|
|
116
|
-
logger.debug(formatCompact({
|
|
117
|
+
logger.debug(formatCompact({
|
|
118
|
+
op: 'sandbox_send_miss',
|
|
119
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
120
|
+
}));
|
|
117
121
|
return undefined;
|
|
118
122
|
}
|
|
119
123
|
if (connection.placeholder) {
|
|
120
|
-
logger.debug(formatCompact({
|
|
124
|
+
logger.debug(formatCompact({
|
|
125
|
+
op: 'sandbox_send_placeholder',
|
|
126
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
127
|
+
}));
|
|
121
128
|
return undefined;
|
|
122
129
|
}
|
|
123
|
-
// Console UI filters by type+id; stamp
|
|
124
|
-
const channel = connection.lastChannel ?? {
|
|
125
|
-
type: 'private',
|
|
126
|
-
id: connection.owner,
|
|
127
|
-
};
|
|
130
|
+
// Console UI filters by type+id; stamp the conversation onto outbound wire.
|
|
128
131
|
connection.socket.send(formatSandboxOutbound(payload, {
|
|
129
|
-
type:
|
|
130
|
-
id:
|
|
132
|
+
type: conversation.kind,
|
|
133
|
+
id: conversation.id,
|
|
131
134
|
bot: this.#options.defaults.name,
|
|
132
135
|
endpoint: connection.target,
|
|
133
136
|
}));
|
|
134
137
|
logger.debug(formatCompact({
|
|
135
138
|
op: 'sandbox_send',
|
|
136
139
|
target: connection.target,
|
|
137
|
-
channelType:
|
|
138
|
-
channelId:
|
|
140
|
+
channelType: conversation.kind,
|
|
141
|
+
channelId: conversation.id,
|
|
139
142
|
}));
|
|
140
143
|
return payload;
|
|
141
144
|
}
|
|
@@ -172,28 +175,25 @@ export class SandboxWsEndpoint {
|
|
|
172
175
|
const release = bindSandboxWsSocket(socket, {
|
|
173
176
|
onMessage: (raw) => {
|
|
174
177
|
const parsed = parseSandboxWsPayload(raw);
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
};
|
|
181
|
-
}
|
|
178
|
+
const sender = parsed.id || owner;
|
|
179
|
+
const conversation = sandboxInboundConversation(String(this.#options.id), {
|
|
180
|
+
type: parsed.type,
|
|
181
|
+
id: sender,
|
|
182
|
+
});
|
|
182
183
|
logger.debug(formatCompact({
|
|
183
184
|
op: 'sandbox_recv',
|
|
184
185
|
target,
|
|
185
|
-
sender
|
|
186
|
+
sender,
|
|
186
187
|
channelType: parsed.type,
|
|
187
|
-
channelId:
|
|
188
|
+
channelId: sender,
|
|
188
189
|
text: parsed.text.slice(0, 80),
|
|
189
190
|
}));
|
|
190
191
|
// Don't gate on #open — inbound must always reach the gateway so
|
|
191
192
|
// Command/AI dispatch and outbound replies work.
|
|
192
193
|
void this.#options.gateway.receive({
|
|
193
|
-
|
|
194
|
-
target,
|
|
194
|
+
conversation,
|
|
195
195
|
content: parsed.text,
|
|
196
|
-
sender
|
|
196
|
+
sender,
|
|
197
197
|
metadata: Object.freeze({
|
|
198
198
|
type: parsed.type,
|
|
199
199
|
channelType: parsed.type,
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { bindSandboxWsSocket, formatSandboxOutbound, normalizeSandboxOutboundSegments, parseSandboxWsPayload, resolveSandboxEndpoint, whenWsOpen, type MessageElement, type MessageType, type ResolvedSandboxBot, type SandboxAdapterConfig, type SandboxWsSocket, } from './protocol.js';
|
|
1
|
+
export { bindSandboxWsSocket, formatSandboxOutbound, normalizeSandboxOutboundSegments, parseSandboxWsPayload, resolveSandboxEndpoint, sandboxInboundConversation, whenWsOpen, type MessageElement, type MessageType, type ResolvedSandboxBot, type SandboxAdapterConfig, type SandboxWsSocket, } from './protocol.js';
|
|
2
2
|
export { SandboxWsEndpoint, type SandboxEndpointOptions, } from './endpoint.js';
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { bindSandboxWsSocket, formatSandboxOutbound, normalizeSandboxOutboundSegments, parseSandboxWsPayload, resolveSandboxEndpoint, whenWsOpen, } from './protocol.js';
|
|
1
|
+
export { bindSandboxWsSocket, formatSandboxOutbound, normalizeSandboxOutboundSegments, parseSandboxWsPayload, resolveSandboxEndpoint, sandboxInboundConversation, whenWsOpen, } from './protocol.js';
|
|
2
2
|
export { SandboxWsEndpoint, } from './endpoint.js';
|
package/lib/protocol.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Sandbox WebSocket wire protocol helpers (no legacy Adapter/Endpoint). */
|
|
2
|
+
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
2
3
|
export type MessageType = 'private' | 'group' | 'guild' | 'direct' | 'channel';
|
|
3
4
|
export interface MessageElement {
|
|
4
5
|
readonly type: string;
|
|
@@ -47,6 +48,15 @@ export declare function parseSandboxWsPayload(raw: string): {
|
|
|
47
48
|
payload: string;
|
|
48
49
|
};
|
|
49
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* 入站归一化 → ConversationRef。sandbox 无平台社交图谱:
|
|
53
|
+
* `private`/`group`/`channel` 直映射;`direct`(私聊)归 'private';
|
|
54
|
+
* `guild`(频道容器语义)归 'channel'。无 guild/temp 容器信息,不产生 parent。
|
|
55
|
+
*/
|
|
56
|
+
export declare function sandboxInboundConversation(endpointId: string, msg: {
|
|
57
|
+
readonly type: MessageType;
|
|
58
|
+
readonly id: string;
|
|
59
|
+
}): ConversationRef;
|
|
50
60
|
export type SandboxOutboundChannel = {
|
|
51
61
|
readonly type?: string;
|
|
52
62
|
readonly id?: string;
|
package/lib/protocol.js
CHANGED
|
@@ -107,6 +107,23 @@ export function parseSandboxWsPayload(raw) {
|
|
|
107
107
|
}
|
|
108
108
|
return { type, id, content, timestamp: payload.timestamp ?? Date.now(), text, action };
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* 入站归一化 → ConversationRef。sandbox 无平台社交图谱:
|
|
112
|
+
* `private`/`group`/`channel` 直映射;`direct`(私聊)归 'private';
|
|
113
|
+
* `guild`(频道容器语义)归 'channel'。无 guild/temp 容器信息,不产生 parent。
|
|
114
|
+
*/
|
|
115
|
+
export function sandboxInboundConversation(endpointId, msg) {
|
|
116
|
+
const kind = msg.type === 'direct'
|
|
117
|
+
? 'private'
|
|
118
|
+
: msg.type === 'guild'
|
|
119
|
+
? 'channel'
|
|
120
|
+
: msg.type;
|
|
121
|
+
return {
|
|
122
|
+
endpoint: { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
|
|
123
|
+
kind,
|
|
124
|
+
id: msg.id,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
110
127
|
const MEDIA_SEGMENT_TYPES = new Set(['image', 'audio', 'video', 'file']);
|
|
111
128
|
/**
|
|
112
129
|
* base64 内联值:Console UI 的 resolveMediaSrc 只识别 data: / base64://
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-sandbox",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.2",
|
|
4
4
|
"description": "Zhin.js Sandbox adapter for Plugin Runtime (WebSocket /sandbox)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -48,14 +48,15 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"lucide-react": "^0.525.0",
|
|
50
50
|
"react": "^19.2.8",
|
|
51
|
-
"@zhin.js/adapter": "1.1.
|
|
51
|
+
"@zhin.js/adapter": "1.1.5",
|
|
52
52
|
"@zhin.js/client": "2.1.4",
|
|
53
53
|
"@zhin.js/console-contract": "1.0.0",
|
|
54
|
-
"@zhin.js/core": "1.5.
|
|
55
|
-
"@zhin.js/host-http": "1.0.
|
|
54
|
+
"@zhin.js/core": "1.5.2",
|
|
55
|
+
"@zhin.js/host-http": "1.0.6",
|
|
56
|
+
"@zhin.js/im-contract": "1.0.1",
|
|
56
57
|
"@zhin.js/logger": "1.0.75",
|
|
57
|
-
"@zhin.js/page": "1.0.
|
|
58
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
58
|
+
"@zhin.js/page": "1.0.6",
|
|
59
|
+
"@zhin.js/plugin-runtime": "1.1.3"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@types/react": "^19.2.18",
|
|
@@ -63,18 +64,18 @@
|
|
|
63
64
|
"typescript": "^6.0.3",
|
|
64
65
|
"vitest": "^4.1.10",
|
|
65
66
|
"ws": "^8.21.1",
|
|
66
|
-
"@zhin.js/pagemanager": "2.0.
|
|
67
|
-
"@zhin.js/runtime": "1.0.
|
|
67
|
+
"@zhin.js/pagemanager": "2.0.12",
|
|
68
|
+
"@zhin.js/runtime": "1.0.7"
|
|
68
69
|
},
|
|
69
70
|
"peerDependencies": {
|
|
70
71
|
"react": "^19.0.0",
|
|
71
|
-
"@zhin.js/adapter": "1.1.
|
|
72
|
+
"@zhin.js/adapter": "1.1.5",
|
|
72
73
|
"@zhin.js/client": "2.1.4",
|
|
73
74
|
"@zhin.js/console-contract": "1.0.0",
|
|
74
|
-
"@zhin.js/core": "1.5.
|
|
75
|
-
"@zhin.js/host-http": "1.0.
|
|
76
|
-
"@zhin.js/page": "1.0.
|
|
77
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
75
|
+
"@zhin.js/core": "1.5.2",
|
|
76
|
+
"@zhin.js/host-http": "1.0.6",
|
|
77
|
+
"@zhin.js/page": "1.0.6",
|
|
78
|
+
"@zhin.js/plugin-runtime": "1.1.3"
|
|
78
79
|
},
|
|
79
80
|
"peerDependenciesMeta": {
|
|
80
81
|
"react": {
|
package/src/endpoint.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* SandboxWsEndpoint — WebSocket lifecycle and MessageGateway bridge for /sandbox.
|
|
3
3
|
*/
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
import type { EndpointInstance } from '@zhin.js/adapter';
|
|
5
|
+
import type { EndpointInstance, EndpointSendRequest } from '@zhin.js/adapter';
|
|
6
6
|
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
7
7
|
import type { HttpHost, WsConnection } from '@zhin.js/host-http';
|
|
8
8
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
bindSandboxWsSocket,
|
|
12
12
|
formatSandboxOutbound,
|
|
13
13
|
parseSandboxWsPayload,
|
|
14
|
+
sandboxInboundConversation,
|
|
14
15
|
whenWsOpen,
|
|
15
16
|
type ResolvedSandboxBot,
|
|
16
17
|
type SandboxWsSocket,
|
|
@@ -58,11 +59,6 @@ function claimSandboxWsPath(
|
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
interface SandboxChannel {
|
|
62
|
-
readonly type: string;
|
|
63
|
-
readonly id: string;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
62
|
interface SandboxConnection {
|
|
67
63
|
readonly target: string;
|
|
68
64
|
readonly owner: string;
|
|
@@ -70,11 +66,6 @@ interface SandboxConnection {
|
|
|
70
66
|
readonly release: () => void;
|
|
71
67
|
/** true = 占位连接(尚无真实 WS 客户端),send 命中时按 miss 处理。 */
|
|
72
68
|
readonly placeholder?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* 最近一条入站频道(Console UI 按 type+id 过滤气泡)。
|
|
75
|
-
* 出站必须带回,否则回复石沉大海。
|
|
76
|
-
*/
|
|
77
|
-
lastChannel?: SandboxChannel;
|
|
78
69
|
}
|
|
79
70
|
|
|
80
71
|
export interface SandboxEndpointOptions {
|
|
@@ -156,35 +147,38 @@ export class SandboxWsEndpoint implements EndpointInstance {
|
|
|
156
147
|
logger.debug(formatCompact({ op: 'sandbox_stopped' }));
|
|
157
148
|
}
|
|
158
149
|
|
|
159
|
-
send({
|
|
150
|
+
send({ conversation, payload }: EndpointSendRequest): unknown {
|
|
160
151
|
if (!this.#open) return undefined;
|
|
161
|
-
// Reply
|
|
162
|
-
|
|
152
|
+
// Reply targets this endpoint's own live socket (fixed bot name, or the
|
|
153
|
+
// only live random-name connection); conversation carries kind/id stamp.
|
|
154
|
+
const connection = this.#connections.get(this.#options.defaults.name)
|
|
163
155
|
?? this.#findLiveConnection();
|
|
164
156
|
if (!connection) {
|
|
165
|
-
logger.debug(formatCompact({
|
|
157
|
+
logger.debug(formatCompact({
|
|
158
|
+
op: 'sandbox_send_miss',
|
|
159
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
160
|
+
}));
|
|
166
161
|
return undefined;
|
|
167
162
|
}
|
|
168
163
|
if (connection.placeholder) {
|
|
169
|
-
logger.debug(formatCompact({
|
|
164
|
+
logger.debug(formatCompact({
|
|
165
|
+
op: 'sandbox_send_placeholder',
|
|
166
|
+
target: `${conversation.kind}:${conversation.id}`,
|
|
167
|
+
}));
|
|
170
168
|
return undefined;
|
|
171
169
|
}
|
|
172
|
-
// Console UI filters by type+id; stamp
|
|
173
|
-
const channel = connection.lastChannel ?? {
|
|
174
|
-
type: 'private',
|
|
175
|
-
id: connection.owner,
|
|
176
|
-
};
|
|
170
|
+
// Console UI filters by type+id; stamp the conversation onto outbound wire.
|
|
177
171
|
connection.socket.send(formatSandboxOutbound(payload, {
|
|
178
|
-
type:
|
|
179
|
-
id:
|
|
172
|
+
type: conversation.kind,
|
|
173
|
+
id: conversation.id,
|
|
180
174
|
bot: this.#options.defaults.name,
|
|
181
175
|
endpoint: connection.target,
|
|
182
176
|
}));
|
|
183
177
|
logger.debug(formatCompact({
|
|
184
178
|
op: 'sandbox_send',
|
|
185
179
|
target: connection.target,
|
|
186
|
-
channelType:
|
|
187
|
-
channelId:
|
|
180
|
+
channelType: conversation.kind,
|
|
181
|
+
channelId: conversation.id,
|
|
188
182
|
}));
|
|
189
183
|
return payload;
|
|
190
184
|
}
|
|
@@ -221,28 +215,25 @@ export class SandboxWsEndpoint implements EndpointInstance {
|
|
|
221
215
|
const release = bindSandboxWsSocket(socket, {
|
|
222
216
|
onMessage: (raw) => {
|
|
223
217
|
const parsed = parseSandboxWsPayload(raw);
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
};
|
|
230
|
-
}
|
|
218
|
+
const sender = parsed.id || owner;
|
|
219
|
+
const conversation = sandboxInboundConversation(String(this.#options.id), {
|
|
220
|
+
type: parsed.type,
|
|
221
|
+
id: sender,
|
|
222
|
+
});
|
|
231
223
|
logger.debug(formatCompact({
|
|
232
224
|
op: 'sandbox_recv',
|
|
233
225
|
target,
|
|
234
|
-
sender
|
|
226
|
+
sender,
|
|
235
227
|
channelType: parsed.type,
|
|
236
|
-
channelId:
|
|
228
|
+
channelId: sender,
|
|
237
229
|
text: parsed.text.slice(0, 80),
|
|
238
230
|
}));
|
|
239
231
|
// Don't gate on #open — inbound must always reach the gateway so
|
|
240
232
|
// Command/AI dispatch and outbound replies work.
|
|
241
233
|
void this.#options.gateway.receive({
|
|
242
|
-
|
|
243
|
-
target,
|
|
234
|
+
conversation,
|
|
244
235
|
content: parsed.text,
|
|
245
|
-
sender
|
|
236
|
+
sender,
|
|
246
237
|
metadata: Object.freeze({
|
|
247
238
|
type: parsed.type,
|
|
248
239
|
channelType: parsed.type,
|
package/src/index.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { readFileSync } from 'node:fs';
|
|
4
4
|
import { isMediaRef } from '@zhin.js/core';
|
|
5
|
+
import type { ConversationKind, ConversationRef } from '@zhin.js/im-contract';
|
|
5
6
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
6
7
|
|
|
7
8
|
const logger = getLogger('sandbox');
|
|
@@ -177,6 +178,27 @@ export function parseSandboxWsPayload(raw: string): {
|
|
|
177
178
|
return { type, id, content, timestamp: payload.timestamp ?? Date.now(), text, action };
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
/**
|
|
182
|
+
* 入站归一化 → ConversationRef。sandbox 无平台社交图谱:
|
|
183
|
+
* `private`/`group`/`channel` 直映射;`direct`(私聊)归 'private';
|
|
184
|
+
* `guild`(频道容器语义)归 'channel'。无 guild/temp 容器信息,不产生 parent。
|
|
185
|
+
*/
|
|
186
|
+
export function sandboxInboundConversation(
|
|
187
|
+
endpointId: string,
|
|
188
|
+
msg: { readonly type: MessageType; readonly id: string },
|
|
189
|
+
): ConversationRef {
|
|
190
|
+
const kind: ConversationKind = msg.type === 'direct'
|
|
191
|
+
? 'private'
|
|
192
|
+
: msg.type === 'guild'
|
|
193
|
+
? 'channel'
|
|
194
|
+
: msg.type;
|
|
195
|
+
return {
|
|
196
|
+
endpoint: { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
|
|
197
|
+
kind,
|
|
198
|
+
id: msg.id,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
180
202
|
export type SandboxOutboundChannel = {
|
|
181
203
|
readonly type?: string;
|
|
182
204
|
readonly id?: string;
|