@xmoxmo/bncr 0.4.6 → 0.4.8
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 +8 -0
- package/package.json +1 -1
- package/src/channel.ts +41 -2
- package/src/core/targets.ts +106 -17
- package/src/messaging/inbound/commands.ts +421 -51
- package/src/messaging/inbound/context-facts.ts +126 -14
- package/src/messaging/inbound/contracts.ts +24 -0
- package/src/messaging/inbound/dispatch-prep.ts +214 -39
- package/src/messaging/inbound/dispatch.ts +71 -5
- package/src/messaging/inbound/gate.ts +56 -86
- package/src/messaging/inbound/group-history.ts +189 -0
- package/src/messaging/inbound/native-command-runtime.ts +77 -61
- package/src/messaging/inbound/native-command.ts +192 -8
- package/src/messaging/inbound/parse.ts +113 -8
- package/src/messaging/inbound/reply-dispatch-serial.ts +62 -0
- package/src/messaging/inbound/reply-dispatch.ts +252 -77
- package/src/messaging/inbound/scene-admin.ts +300 -0
- package/src/messaging/inbound/session-label.ts +122 -13
- package/src/messaging/inbound/session-meta-task.ts +17 -0
- package/src/messaging/inbound/turn-context.ts +184 -71
- package/src/openclaw/channel-runtime-contracts.ts +1 -0
- package/src/plugin/channel-components.ts +35 -1
- package/src/plugin/channel-inbound-helpers.ts +9 -2
- package/src/plugin/channel-runtime-builders-delivery.ts +24 -1
- package/src/plugin/channel-runtime-types.ts +42 -0
- package/src/plugin/file-inbound-init.ts +27 -12
- package/src/plugin/file-inbound-runtime.ts +2 -0
- package/src/plugin/inbound-acceptance.ts +82 -1
- package/src/plugin/inbound-handlers.ts +97 -2
- package/src/plugin/inbound-surface-handlers-group.ts +16 -0
- package/src/plugin/messaging.ts +22 -5
- package/src/plugin/scene-registry.ts +171 -0
- package/src/plugin/state-store.ts +133 -0
- package/src/plugin/state-transient-runtime-group.ts +5 -0
- package/src/plugin/target-runtime.ts +2 -2
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BncrGroupReplyMode,
|
|
3
|
+
BncrSceneKind,
|
|
4
|
+
BncrSceneRecord,
|
|
5
|
+
BncrSceneStatus,
|
|
6
|
+
} from './channel-runtime-types.ts';
|
|
7
|
+
|
|
8
|
+
type ParsedInbound = ReturnType<
|
|
9
|
+
typeof import('../messaging/inbound/parse.ts')['parseBncrInboundParams']
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
export type BncrSceneRegistryDecision =
|
|
13
|
+
| {
|
|
14
|
+
allowed: true;
|
|
15
|
+
scene: BncrSceneRecord;
|
|
16
|
+
agentId: string;
|
|
17
|
+
}
|
|
18
|
+
| {
|
|
19
|
+
allowed: false;
|
|
20
|
+
scene: BncrSceneRecord;
|
|
21
|
+
reason: string;
|
|
22
|
+
replyPolicy: 'silent' | 'pending';
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function asSceneKind(parsed: ParsedInbound): BncrSceneKind {
|
|
26
|
+
return parsed.peer.kind === 'group' ? 'group' : 'direct';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function defaultGroupReplyMode(kind: BncrSceneKind): BncrGroupReplyMode | undefined {
|
|
30
|
+
return kind === 'group' ? 'admin' : undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function buildSceneKey(parsed: ParsedInbound): string {
|
|
34
|
+
return parsed.peer.kind === 'group'
|
|
35
|
+
? `${parsed.platform}:${parsed.groupId}`
|
|
36
|
+
: `${parsed.platform}:${parsed.userId}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function buildSceneRecord(args: {
|
|
40
|
+
parsed: ParsedInbound;
|
|
41
|
+
sceneKey: string;
|
|
42
|
+
kind: BncrSceneKind;
|
|
43
|
+
status: BncrSceneStatus;
|
|
44
|
+
agentId?: string;
|
|
45
|
+
lastSeenAt: number;
|
|
46
|
+
}): BncrSceneRecord {
|
|
47
|
+
const { parsed, sceneKey, kind, status, agentId, lastSeenAt } = args;
|
|
48
|
+
return {
|
|
49
|
+
sceneKey,
|
|
50
|
+
kind,
|
|
51
|
+
status,
|
|
52
|
+
platform: parsed.platform,
|
|
53
|
+
...(parsed.userId ? { userId: parsed.userId } : {}),
|
|
54
|
+
...(parsed.userName ? { userName: parsed.userName } : {}),
|
|
55
|
+
...(kind === 'group' && parsed.groupId ? { groupId: parsed.groupId } : {}),
|
|
56
|
+
...(kind === 'group' && parsed.groupName ? { groupName: parsed.groupName } : {}),
|
|
57
|
+
...(agentId ? { agentId } : {}),
|
|
58
|
+
...(kind === 'group' ? { groupReplyMode: defaultGroupReplyMode(kind) } : {}),
|
|
59
|
+
lastSeenAt,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function decideSceneAdmission(args: {
|
|
64
|
+
parsed: ParsedInbound;
|
|
65
|
+
now: number;
|
|
66
|
+
sceneRegistry: Map<string, BncrSceneRecord>;
|
|
67
|
+
defaultAdminAgentId: string;
|
|
68
|
+
defaultPublicAgentId: string;
|
|
69
|
+
}): BncrSceneRegistryDecision {
|
|
70
|
+
const { parsed, now, sceneRegistry, defaultAdminAgentId, defaultPublicAgentId } = args;
|
|
71
|
+
const sceneKey = buildSceneKey(parsed);
|
|
72
|
+
const kind = asSceneKind(parsed);
|
|
73
|
+
const existing = sceneRegistry.get(sceneKey);
|
|
74
|
+
const shouldForceDirectNonAdminPublic = (agentId?: string) =>
|
|
75
|
+
kind === 'direct' && parsed.isAdmin !== true && (!agentId || agentId === defaultAdminAgentId);
|
|
76
|
+
|
|
77
|
+
if (existing) {
|
|
78
|
+
const forcedAgentId = shouldForceDirectNonAdminPublic(existing.agentId)
|
|
79
|
+
? defaultPublicAgentId
|
|
80
|
+
: existing.agentId;
|
|
81
|
+
const nextScene = {
|
|
82
|
+
...existing,
|
|
83
|
+
...(parsed.userId ? { userId: parsed.userId } : {}),
|
|
84
|
+
...(parsed.userName ? { userName: parsed.userName } : {}),
|
|
85
|
+
...(kind === 'group' && parsed.groupId ? { groupId: parsed.groupId } : {}),
|
|
86
|
+
...(kind === 'group' && parsed.groupName ? { groupName: parsed.groupName } : {}),
|
|
87
|
+
...(forcedAgentId ? { agentId: forcedAgentId } : {}),
|
|
88
|
+
...(kind === 'group' && !existing.groupReplyMode
|
|
89
|
+
? { groupReplyMode: defaultGroupReplyMode(kind) }
|
|
90
|
+
: {}),
|
|
91
|
+
lastSeenAt: now,
|
|
92
|
+
} satisfies BncrSceneRecord;
|
|
93
|
+
|
|
94
|
+
if (kind === 'group' && nextScene.status === 'denied' && parsed.isAdmin) {
|
|
95
|
+
const allowedScene = {
|
|
96
|
+
...nextScene,
|
|
97
|
+
status: 'allowed',
|
|
98
|
+
} satisfies BncrSceneRecord;
|
|
99
|
+
sceneRegistry.set(sceneKey, allowedScene);
|
|
100
|
+
return {
|
|
101
|
+
allowed: true,
|
|
102
|
+
scene: allowedScene,
|
|
103
|
+
agentId: allowedScene.agentId || defaultPublicAgentId,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
sceneRegistry.set(sceneKey, nextScene);
|
|
108
|
+
|
|
109
|
+
if (nextScene.status === 'allowed') {
|
|
110
|
+
const fallbackAgentId =
|
|
111
|
+
kind === 'group'
|
|
112
|
+
? defaultPublicAgentId
|
|
113
|
+
: parsed.isAdmin
|
|
114
|
+
? defaultAdminAgentId
|
|
115
|
+
: defaultPublicAgentId;
|
|
116
|
+
return {
|
|
117
|
+
allowed: true,
|
|
118
|
+
scene: nextScene,
|
|
119
|
+
agentId: nextScene.agentId || fallbackAgentId,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
allowed: false,
|
|
125
|
+
scene: nextScene,
|
|
126
|
+
reason: nextScene.status === 'pending' ? 'scene pending approval' : 'scene denied',
|
|
127
|
+
replyPolicy:
|
|
128
|
+
kind === 'group' ? 'silent' : nextScene.status === 'pending' ? 'pending' : 'silent',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (parsed.isAdmin) {
|
|
133
|
+
const agentId = kind === 'group' ? defaultPublicAgentId : defaultAdminAgentId;
|
|
134
|
+
const scene = buildSceneRecord({
|
|
135
|
+
parsed,
|
|
136
|
+
sceneKey,
|
|
137
|
+
kind,
|
|
138
|
+
status: 'allowed',
|
|
139
|
+
agentId,
|
|
140
|
+
lastSeenAt: now,
|
|
141
|
+
});
|
|
142
|
+
sceneRegistry.set(sceneKey, scene);
|
|
143
|
+
return { allowed: true, scene, agentId };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const directNonAdminAllowed = kind === 'direct';
|
|
147
|
+
const scene = buildSceneRecord({
|
|
148
|
+
parsed,
|
|
149
|
+
sceneKey,
|
|
150
|
+
kind,
|
|
151
|
+
status: directNonAdminAllowed ? 'allowed' : 'denied',
|
|
152
|
+
agentId: directNonAdminAllowed ? defaultPublicAgentId : undefined,
|
|
153
|
+
lastSeenAt: now,
|
|
154
|
+
});
|
|
155
|
+
sceneRegistry.set(sceneKey, scene);
|
|
156
|
+
|
|
157
|
+
if (directNonAdminAllowed) {
|
|
158
|
+
return {
|
|
159
|
+
allowed: true,
|
|
160
|
+
scene,
|
|
161
|
+
agentId: scene.agentId || defaultPublicAgentId,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
allowed: false,
|
|
167
|
+
scene,
|
|
168
|
+
reason: 'scene denied',
|
|
169
|
+
replyPolicy: 'silent',
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -8,16 +8,25 @@ import {
|
|
|
8
8
|
writeOpenClawJsonFileAtomically,
|
|
9
9
|
} from '../openclaw/sdk-helpers.ts';
|
|
10
10
|
import type {
|
|
11
|
+
BncrGroupReplyMode,
|
|
11
12
|
BncrPersistedAccountTimestamp,
|
|
13
|
+
BncrPersistedGroupHistoryBucket,
|
|
14
|
+
BncrPersistedGroupHistoryEntry,
|
|
15
|
+
BncrPersistedGroupHistoryMediaEntry,
|
|
12
16
|
BncrPersistedLastSession,
|
|
13
17
|
BncrPersistedSessionRoute,
|
|
14
18
|
PersistedState as BncrPersistedState,
|
|
19
|
+
BncrSceneRecord,
|
|
15
20
|
} from './channel-runtime-types.ts';
|
|
16
21
|
|
|
22
|
+
const GROUP_REPLY_MODES = new Set<BncrGroupReplyMode>(['admin', 'mention', 'hybrid', 'all']);
|
|
23
|
+
|
|
17
24
|
type BncrPersistedStateStoreInput = {
|
|
18
25
|
outbox?: unknown;
|
|
19
26
|
deadLetter?: unknown;
|
|
20
27
|
sessionRoutes?: unknown;
|
|
28
|
+
sceneRegistry?: unknown;
|
|
29
|
+
groupHistories?: unknown;
|
|
21
30
|
lastSessionByAccount?: unknown;
|
|
22
31
|
lastActivityByAccount?: unknown;
|
|
23
32
|
lastInboundByAccount?: unknown;
|
|
@@ -28,6 +37,9 @@ type BncrPersistedStateStoreInput = {
|
|
|
28
37
|
type PersistedAccountTimestampInput = Partial<BncrPersistedAccountTimestamp>;
|
|
29
38
|
type PersistedLastSessionInput = Partial<BncrPersistedLastSession>;
|
|
30
39
|
type PersistedSessionRouteInput = Partial<BncrPersistedSessionRoute>;
|
|
40
|
+
type PersistedSceneRecordInput = Partial<BncrSceneRecord>;
|
|
41
|
+
type PersistedGroupHistoryBucketInput = Partial<BncrPersistedGroupHistoryBucket>;
|
|
42
|
+
type PersistedGroupHistoryEntryInput = Partial<BncrPersistedGroupHistoryEntry>;
|
|
31
43
|
|
|
32
44
|
export function createBncrStateStore(runtime: {
|
|
33
45
|
getStatePath: () => string | null;
|
|
@@ -50,6 +62,8 @@ export function createBncrStateStore(runtime: {
|
|
|
50
62
|
maxDeadLetterEntries: number;
|
|
51
63
|
maxSessionRouteEntries: number;
|
|
52
64
|
maxAccountActivityEntries: number;
|
|
65
|
+
sceneRegistry: Map<string, BncrSceneRecord>;
|
|
66
|
+
groupHistories: Map<string, BncrPersistedGroupHistoryEntry[]>;
|
|
53
67
|
outbox: Map<string, OutboxEntry>;
|
|
54
68
|
getDeadLetter: () => OutboxEntry[];
|
|
55
69
|
setDeadLetter: (entries: OutboxEntry[]) => void;
|
|
@@ -62,6 +76,117 @@ export function createBncrStateStore(runtime: {
|
|
|
62
76
|
getLastDriftSnapshot: () => BncrPersistedState['lastDriftSnapshot'];
|
|
63
77
|
setLastDriftSnapshot: (value: BncrPersistedState['lastDriftSnapshot']) => void;
|
|
64
78
|
}) {
|
|
79
|
+
function loadPersistedSceneRegistry(persisted: unknown): void {
|
|
80
|
+
runtime.sceneRegistry.clear();
|
|
81
|
+
const items = Array.isArray(persisted) ? (persisted as PersistedSceneRecordInput[]) : [];
|
|
82
|
+
for (const item of items) {
|
|
83
|
+
if (!item || typeof item !== 'object') continue;
|
|
84
|
+
const sceneKey = runtime.asString(item.sceneKey || '').trim();
|
|
85
|
+
const kind = runtime.asString(item.kind || '').trim();
|
|
86
|
+
const status = runtime.asString(item.status || '').trim();
|
|
87
|
+
const platform = runtime.asString(item.platform || '').trim();
|
|
88
|
+
const lastSeenAt = runtime.finiteNumberOr(item.lastSeenAt, 0);
|
|
89
|
+
if (!sceneKey || !platform || lastSeenAt <= 0) continue;
|
|
90
|
+
if (kind !== 'direct' && kind !== 'group') continue;
|
|
91
|
+
if (status !== 'pending' && status !== 'allowed' && status !== 'denied') continue;
|
|
92
|
+
|
|
93
|
+
runtime.sceneRegistry.set(sceneKey, {
|
|
94
|
+
sceneKey,
|
|
95
|
+
kind,
|
|
96
|
+
status,
|
|
97
|
+
platform,
|
|
98
|
+
...(runtime.asString(item.userId || '').trim()
|
|
99
|
+
? { userId: runtime.asString(item.userId || '').trim() }
|
|
100
|
+
: {}),
|
|
101
|
+
...(runtime.asString(item.userName || '').trim()
|
|
102
|
+
? { userName: runtime.asString(item.userName || '').trim() }
|
|
103
|
+
: {}),
|
|
104
|
+
...(runtime.asString(item.groupId || '').trim()
|
|
105
|
+
? { groupId: runtime.asString(item.groupId || '').trim() }
|
|
106
|
+
: {}),
|
|
107
|
+
...(runtime.asString(item.groupName || '').trim()
|
|
108
|
+
? { groupName: runtime.asString(item.groupName || '').trim() }
|
|
109
|
+
: {}),
|
|
110
|
+
...(runtime.asString(item.agentId || '').trim()
|
|
111
|
+
? { agentId: runtime.asString(item.agentId || '').trim() }
|
|
112
|
+
: {}),
|
|
113
|
+
...(kind === 'group' &&
|
|
114
|
+
GROUP_REPLY_MODES.has(
|
|
115
|
+
runtime.asString(item.groupReplyMode || '').trim() as BncrGroupReplyMode,
|
|
116
|
+
)
|
|
117
|
+
? {
|
|
118
|
+
groupReplyMode: runtime
|
|
119
|
+
.asString(item.groupReplyMode || '')
|
|
120
|
+
.trim() as BncrGroupReplyMode,
|
|
121
|
+
}
|
|
122
|
+
: {}),
|
|
123
|
+
lastSeenAt,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function dumpPersistedSceneRegistry() {
|
|
129
|
+
return Array.from(runtime.sceneRegistry.values()).sort((a, b) => a.lastSeenAt - b.lastSeenAt);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function loadPersistedGroupHistories(persisted: unknown): void {
|
|
133
|
+
runtime.groupHistories.clear();
|
|
134
|
+
const buckets = Array.isArray(persisted)
|
|
135
|
+
? (persisted as PersistedGroupHistoryBucketInput[])
|
|
136
|
+
: [];
|
|
137
|
+
for (const bucket of buckets) {
|
|
138
|
+
const key = runtime.asString(bucket?.key || '').trim();
|
|
139
|
+
if (!key) continue;
|
|
140
|
+
const entries: BncrPersistedGroupHistoryEntry[] = [];
|
|
141
|
+
const rawEntries = Array.isArray(bucket?.entries)
|
|
142
|
+
? (bucket.entries as PersistedGroupHistoryEntryInput[])
|
|
143
|
+
: [];
|
|
144
|
+
for (const entry of rawEntries) {
|
|
145
|
+
const sender = runtime.asString(entry?.sender || '').trim();
|
|
146
|
+
const body = runtime.asString(entry?.body || '').trim();
|
|
147
|
+
if (!sender || !body) continue;
|
|
148
|
+
const timestamp = runtime.finiteNumberOr(entry?.timestamp, 0);
|
|
149
|
+
const messageId = runtime.asString(entry?.messageId || '').trim();
|
|
150
|
+
|
|
151
|
+
const media: BncrPersistedGroupHistoryMediaEntry[] = [];
|
|
152
|
+
const rawMedia = Array.isArray(entry?.media)
|
|
153
|
+
? (entry.media as Partial<BncrPersistedGroupHistoryMediaEntry>[])
|
|
154
|
+
: [];
|
|
155
|
+
for (const item of rawMedia) {
|
|
156
|
+
const path = runtime.asString(item?.path || '').trim();
|
|
157
|
+
if (!path) continue;
|
|
158
|
+
const contentType = runtime.asString(item?.contentType || '').trim();
|
|
159
|
+
const kind = runtime.asString(item?.kind || '').trim();
|
|
160
|
+
const mediaMessageId = runtime.asString(item?.messageId || '').trim();
|
|
161
|
+
const normalizedMedia: BncrPersistedGroupHistoryMediaEntry = {
|
|
162
|
+
path,
|
|
163
|
+
...(contentType ? { contentType } : {}),
|
|
164
|
+
...(kind ? { kind: kind as BncrPersistedGroupHistoryMediaEntry['kind'] } : {}),
|
|
165
|
+
...(mediaMessageId ? { messageId: mediaMessageId } : {}),
|
|
166
|
+
};
|
|
167
|
+
media.push(normalizedMedia);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const normalizedEntry: BncrPersistedGroupHistoryEntry = {
|
|
171
|
+
sender,
|
|
172
|
+
body,
|
|
173
|
+
...(timestamp > 0 ? { timestamp } : {}),
|
|
174
|
+
...(messageId ? { messageId } : {}),
|
|
175
|
+
...(media.length > 0 ? { media } : {}),
|
|
176
|
+
};
|
|
177
|
+
entries.push(normalizedEntry);
|
|
178
|
+
}
|
|
179
|
+
if (entries.length > 0) runtime.groupHistories.set(key, entries.slice(-50));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function dumpPersistedGroupHistories() {
|
|
184
|
+
return Array.from(runtime.groupHistories.entries()).map(([key, entries]) => ({
|
|
185
|
+
key,
|
|
186
|
+
entries: entries.slice(-50),
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
|
|
65
190
|
function loadPersistedAccountTimestampMap(target: Map<string, number>, persisted: unknown): void {
|
|
66
191
|
target.clear();
|
|
67
192
|
const items = Array.isArray(persisted)
|
|
@@ -208,6 +333,8 @@ export function createBncrStateStore(runtime: {
|
|
|
208
333
|
runtime.setDeadLetter(deadLetter);
|
|
209
334
|
|
|
210
335
|
loadPersistedSessionRoutes(data.sessionRoutes);
|
|
336
|
+
loadPersistedSceneRegistry(data.sceneRegistry);
|
|
337
|
+
loadPersistedGroupHistories(data.groupHistories);
|
|
211
338
|
loadPersistedLastSessionMap(data.lastSessionByAccount);
|
|
212
339
|
loadPersistedAccountTimestampMap(runtime.lastActivityByAccount, data.lastActivityByAccount);
|
|
213
340
|
loadPersistedAccountTimestampMap(runtime.lastInboundByAccount, data.lastInboundByAccount);
|
|
@@ -225,6 +352,8 @@ export function createBncrStateStore(runtime: {
|
|
|
225
352
|
outbox: Array.from(runtime.outbox.values()),
|
|
226
353
|
deadLetter: runtime.getDeadLetter().slice(-runtime.maxDeadLetterEntries),
|
|
227
354
|
sessionRoutes: dumpPersistedSessionRoutes(),
|
|
355
|
+
sceneRegistry: dumpPersistedSceneRegistry(),
|
|
356
|
+
groupHistories: dumpPersistedGroupHistories(),
|
|
228
357
|
lastSessionByAccount: dumpPersistedLastSessionMap(),
|
|
229
358
|
lastActivityByAccount: dumpPersistedAccountTimestampMap(runtime.lastActivityByAccount),
|
|
230
359
|
lastInboundByAccount: dumpPersistedAccountTimestampMap(runtime.lastInboundByAccount),
|
|
@@ -242,6 +371,10 @@ export function createBncrStateStore(runtime: {
|
|
|
242
371
|
dumpPersistedLastSessionMap,
|
|
243
372
|
loadPersistedSessionRoutes,
|
|
244
373
|
dumpPersistedSessionRoutes,
|
|
374
|
+
loadPersistedSceneRegistry,
|
|
375
|
+
dumpPersistedSceneRegistry,
|
|
376
|
+
loadPersistedGroupHistories,
|
|
377
|
+
dumpPersistedGroupHistories,
|
|
245
378
|
backfillAccountActivityFromSessionRoutes,
|
|
246
379
|
loadState,
|
|
247
380
|
flushState,
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
FileSendTransferState,
|
|
7
7
|
OutboxEntry,
|
|
8
8
|
} from '../core/types.ts';
|
|
9
|
+
import type { BncrPersistedGroupHistoryEntry, BncrSceneRecord } from './channel-runtime-types.ts';
|
|
9
10
|
import { createBncrStateStore } from './state-store.ts';
|
|
10
11
|
import { createBncrTransientStateRuntime } from './transient-state-runtime.ts';
|
|
11
12
|
|
|
@@ -31,6 +32,8 @@ export function createBncrStateTransientRuntimeGroup(runtime: {
|
|
|
31
32
|
maxDeadLetterEntries: number;
|
|
32
33
|
maxSessionRouteEntries: number;
|
|
33
34
|
maxAccountActivityEntries: number;
|
|
35
|
+
sceneRegistry: Map<string, BncrSceneRecord>;
|
|
36
|
+
groupHistories: Map<string, BncrPersistedGroupHistoryEntry[]>;
|
|
34
37
|
outbox: Map<string, OutboxEntry>;
|
|
35
38
|
getDeadLetter: () => OutboxEntry[];
|
|
36
39
|
setDeadLetter: (entries: OutboxEntry[]) => void;
|
|
@@ -69,6 +72,8 @@ export function createBncrStateTransientRuntimeGroup(runtime: {
|
|
|
69
72
|
maxDeadLetterEntries: runtime.maxDeadLetterEntries,
|
|
70
73
|
maxSessionRouteEntries: runtime.maxSessionRouteEntries,
|
|
71
74
|
maxAccountActivityEntries: runtime.maxAccountActivityEntries,
|
|
75
|
+
sceneRegistry: runtime.sceneRegistry,
|
|
76
|
+
groupHistories: runtime.groupHistories,
|
|
72
77
|
outbox: runtime.outbox,
|
|
73
78
|
getDeadLetter: runtime.getDeadLetter,
|
|
74
79
|
setDeadLetter: runtime.setDeadLetter,
|
|
@@ -95,11 +95,11 @@ export function createBncrTargetRuntime(runtime: {
|
|
|
95
95
|
if (!route) {
|
|
96
96
|
runtime.logWarn(
|
|
97
97
|
'target',
|
|
98
|
-
`invalid raw=${raw} accountId=${acc} reason=unparseable-or-unknown
|
|
98
|
+
`invalid raw=${raw} accountId=${acc} reason=unparseable-or-unknown canonicalTo=Bncr:<platform>:0:<userId>|Bncr:<platform>:<groupId>:0 acceptedAliases=Bncr:<platform>:user:<userId>|Bncr:<platform>:group:<groupId> standardSessionKey=agent:<agentId>:bncr:<direct|group>:<hex(scope)>`,
|
|
99
99
|
{ debugOnly: true },
|
|
100
100
|
);
|
|
101
101
|
throw new Error(
|
|
102
|
-
`bncr invalid target(
|
|
102
|
+
`bncr invalid target(canonical: Bncr:<platform>:0:<userId> | Bncr:<platform>:<groupId>:0; aliases: Bncr:<platform>:user:<userId> | Bncr:<platform>:group:<groupId>): ${raw}`,
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
|