@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
|
@@ -20,7 +20,15 @@ import type {
|
|
|
20
20
|
} from './contracts.ts';
|
|
21
21
|
import type { ParsedInbound } from './dispatch-prep.ts';
|
|
22
22
|
import { buildBncrInboundRecordUpdateLastRoute } from './last-route.ts';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
parseBncrNativeCommand,
|
|
25
|
+
parseBncrUnsupportedDirectCommand,
|
|
26
|
+
resolveBncrNativeHelpCommand,
|
|
27
|
+
resolveBncrNativeSessionResetCommand,
|
|
28
|
+
resolveBncrNativeStatusCommand,
|
|
29
|
+
resolveBncrNativeVerboseCommand,
|
|
30
|
+
resolveBncrNativeWhoamiCommand,
|
|
31
|
+
} from './native-command.ts';
|
|
24
32
|
import {
|
|
25
33
|
buildBncrNativeCommandSessionState,
|
|
26
34
|
buildBncrNativeCommandSummary,
|
|
@@ -34,11 +42,13 @@ import {
|
|
|
34
42
|
} from './native-command-runtime.ts';
|
|
35
43
|
import { buildBncrReplyConfig } from './reply-config.ts';
|
|
36
44
|
import { resolveBncrChannelInboundRuntime } from './runtime-compat.ts';
|
|
45
|
+
import { executeSceneAdminCommand, parseSceneAdminCommand } from './scene-admin.ts';
|
|
37
46
|
import {
|
|
38
47
|
buildBncrInboundSessionIdentityPatch,
|
|
39
48
|
recordAndPatchBncrInboundSessionEntry,
|
|
40
49
|
wrapBncrInboundRecordSessionLabelCorrection,
|
|
41
50
|
} from './session-label.ts';
|
|
51
|
+
import { createBncrSessionMetaTaskBarrier } from './session-meta-task.ts';
|
|
42
52
|
|
|
43
53
|
function assertResolvedAgentRoute(resolvedRoute: OpenClawResolvedAgentRoute): {
|
|
44
54
|
sessionKey: string;
|
|
@@ -65,8 +75,9 @@ function buildBncrNativeCommandResolvedRoute(args: {
|
|
|
65
75
|
channelId: string;
|
|
66
76
|
accountId: string;
|
|
67
77
|
peer: ParsedInbound['peer'];
|
|
78
|
+
resolvedAgentId?: string;
|
|
68
79
|
}) {
|
|
69
|
-
|
|
80
|
+
const resolvedRoute = assertResolvedAgentRoute(
|
|
70
81
|
resolveOpenClawAgentRoute(args.api, {
|
|
71
82
|
cfg: args.cfg,
|
|
72
83
|
channel: args.channelId,
|
|
@@ -74,6 +85,14 @@ function buildBncrNativeCommandResolvedRoute(args: {
|
|
|
74
85
|
peer: args.peer,
|
|
75
86
|
}),
|
|
76
87
|
);
|
|
88
|
+
|
|
89
|
+
const agentId = (args.resolvedAgentId || '').trim() || resolvedRoute.agentId;
|
|
90
|
+
if (!agentId || agentId === resolvedRoute.agentId) return resolvedRoute;
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
...resolvedRoute,
|
|
94
|
+
agentId,
|
|
95
|
+
};
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
export { parseBncrNativeCommand } from './native-command.ts';
|
|
@@ -84,6 +103,11 @@ export async function handleBncrNativeCommand(params: {
|
|
|
84
103
|
cfg: BncrInboundConfig;
|
|
85
104
|
parsed: ParsedInbound;
|
|
86
105
|
canonicalAgentId: string;
|
|
106
|
+
resolvedAgentId?: string;
|
|
107
|
+
sceneRegistry: Map<string, import('../../plugin/channel-runtime-types.ts').BncrSceneRecord>;
|
|
108
|
+
defaultAdminAgentId: string;
|
|
109
|
+
defaultPublicAgentId: string;
|
|
110
|
+
now: () => number;
|
|
87
111
|
rememberSessionRoute: BncrRememberSessionRoute;
|
|
88
112
|
enqueueFromReply: BncrEnqueueFromReply;
|
|
89
113
|
logger?: BncrInboundLogger;
|
|
@@ -91,10 +115,65 @@ export async function handleBncrNativeCommand(params: {
|
|
|
91
115
|
| { handled: false }
|
|
92
116
|
| { handled: true; command: string; sessionKey: string; fallbackToAgent?: boolean }
|
|
93
117
|
> {
|
|
94
|
-
const {
|
|
95
|
-
|
|
118
|
+
const {
|
|
119
|
+
api,
|
|
120
|
+
channelId,
|
|
121
|
+
cfg,
|
|
122
|
+
parsed,
|
|
123
|
+
canonicalAgentId,
|
|
124
|
+
resolvedAgentId,
|
|
125
|
+
sceneRegistry,
|
|
126
|
+
defaultAdminAgentId,
|
|
127
|
+
defaultPublicAgentId,
|
|
128
|
+
now,
|
|
129
|
+
rememberSessionRoute,
|
|
130
|
+
enqueueFromReply,
|
|
131
|
+
} = params;
|
|
96
132
|
const { accountId, route, peer, clientId, extracted, msgId } = parsed;
|
|
97
|
-
const command = parseBncrNativeCommand(extracted.text
|
|
133
|
+
const command = parseBncrNativeCommand(extracted.text, {
|
|
134
|
+
allowBareWhoami: parsed.isAdmin !== true,
|
|
135
|
+
allowBareStatus: parsed.isAdmin !== true && parsed.peer.kind === 'direct',
|
|
136
|
+
allowBareSessionReset: parsed.isAdmin !== true && parsed.peer.kind === 'direct',
|
|
137
|
+
});
|
|
138
|
+
if (!command && parsed.peer.kind === 'direct') {
|
|
139
|
+
const unsupportedDirectCommand = parseBncrUnsupportedDirectCommand(extracted.text);
|
|
140
|
+
if (unsupportedDirectCommand) {
|
|
141
|
+
const rejectedRoute = buildBncrNativeCommandResolvedRoute({
|
|
142
|
+
api,
|
|
143
|
+
cfg,
|
|
144
|
+
channelId,
|
|
145
|
+
accountId,
|
|
146
|
+
peer,
|
|
147
|
+
resolvedAgentId,
|
|
148
|
+
});
|
|
149
|
+
const { baseSessionKey, sessionKey } = buildBncrNativeCommandSessionState({
|
|
150
|
+
parsed,
|
|
151
|
+
sessionAgentId: rejectedRoute.agentId || canonicalAgentId,
|
|
152
|
+
resolvedRoute: rejectedRoute,
|
|
153
|
+
});
|
|
154
|
+
const displayTo = formatDisplayScope(route);
|
|
155
|
+
logBncrNativeCommandSummary(
|
|
156
|
+
buildBncrNativeCommandSummary({
|
|
157
|
+
kind: 'unsupported',
|
|
158
|
+
command: unsupportedDirectCommand.command,
|
|
159
|
+
accountId,
|
|
160
|
+
to: displayTo,
|
|
161
|
+
msgId: msgId || null,
|
|
162
|
+
result: 'rejected',
|
|
163
|
+
}),
|
|
164
|
+
);
|
|
165
|
+
await enqueueFromReply({
|
|
166
|
+
accountId,
|
|
167
|
+
sessionKey: baseSessionKey,
|
|
168
|
+
route,
|
|
169
|
+
payload: {
|
|
170
|
+
text: `Unsupported private-chat command: /${unsupportedDirectCommand.command}`,
|
|
171
|
+
replyToId: msgId || undefined,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
return { handled: true, command: unsupportedDirectCommand.command, sessionKey };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
98
177
|
if (!command) return { handled: false };
|
|
99
178
|
const nativeCommandDebugEnabled = resolveNativeCommandDebugEnabled({ cfg, channelId });
|
|
100
179
|
|
|
@@ -115,12 +194,13 @@ export async function handleBncrNativeCommand(params: {
|
|
|
115
194
|
channelId,
|
|
116
195
|
accountId,
|
|
117
196
|
peer,
|
|
197
|
+
resolvedAgentId,
|
|
118
198
|
});
|
|
119
199
|
|
|
120
200
|
const { baseSessionKey, taskSessionKey, sessionKey, displayTo, originatingTo } =
|
|
121
201
|
buildBncrNativeCommandSessionState({
|
|
122
202
|
parsed,
|
|
123
|
-
canonicalAgentId,
|
|
203
|
+
sessionAgentId: resolvedRoute.agentId || canonicalAgentId,
|
|
124
204
|
resolvedRoute,
|
|
125
205
|
});
|
|
126
206
|
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
@@ -133,8 +213,8 @@ export async function handleBncrNativeCommand(params: {
|
|
|
133
213
|
'[bncr] inbound missing clientId for native command identity; using route identity fallback',
|
|
134
214
|
);
|
|
135
215
|
}
|
|
136
|
-
const senderIdForContext = clientId || displayTo;
|
|
137
|
-
const senderDisplayName =
|
|
216
|
+
const senderIdForContext = parsed.userId || clientId || displayTo;
|
|
217
|
+
const senderDisplayName = parsed.userName || displayTo;
|
|
138
218
|
const storePath = resolveBncrInboundSessionStorePath({
|
|
139
219
|
storeConfig: cfg?.session?.store,
|
|
140
220
|
agentId: resolvedRoute.agentId,
|
|
@@ -166,7 +246,217 @@ export async function handleBncrNativeCommand(params: {
|
|
|
166
246
|
});
|
|
167
247
|
|
|
168
248
|
const nativeVerbose = resolveBncrNativeVerboseCommand(command);
|
|
249
|
+
const nativeHelp = resolveBncrNativeHelpCommand(command);
|
|
250
|
+
const nativeWhoami = resolveBncrNativeWhoamiCommand({
|
|
251
|
+
command,
|
|
252
|
+
platform: parsed.platform,
|
|
253
|
+
groupId: parsed.groupId,
|
|
254
|
+
groupName: parsed.groupName,
|
|
255
|
+
userId: parsed.userId,
|
|
256
|
+
userName: parsed.userName,
|
|
257
|
+
isGroup: parsed.isGroup,
|
|
258
|
+
isAdmin: parsed.isAdmin,
|
|
259
|
+
});
|
|
260
|
+
const nativeStatus = resolveBncrNativeStatusCommand({
|
|
261
|
+
command,
|
|
262
|
+
accountId,
|
|
263
|
+
platform: parsed.platform,
|
|
264
|
+
userId: parsed.userId,
|
|
265
|
+
userName: parsed.userName,
|
|
266
|
+
resolvedAgentId: resolvedRoute.agentId || canonicalAgentId,
|
|
267
|
+
sessionKey,
|
|
268
|
+
});
|
|
269
|
+
const nativeSessionReset = resolveBncrNativeSessionResetCommand({ command });
|
|
270
|
+
if (nativeHelp) {
|
|
271
|
+
logBncrNativeCommandSummary(
|
|
272
|
+
buildBncrNativeCommandSummary({
|
|
273
|
+
kind: 'help',
|
|
274
|
+
command: command.command,
|
|
275
|
+
accountId,
|
|
276
|
+
to: displayTo,
|
|
277
|
+
msgId: msgId || null,
|
|
278
|
+
result: 'handled',
|
|
279
|
+
}),
|
|
280
|
+
);
|
|
281
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
282
|
+
storePath,
|
|
283
|
+
sessionKey,
|
|
284
|
+
ctx: ctxPayload,
|
|
285
|
+
patch: sessionIdentityPatch,
|
|
286
|
+
});
|
|
287
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
288
|
+
await enqueueFromReply({
|
|
289
|
+
accountId,
|
|
290
|
+
sessionKey,
|
|
291
|
+
route,
|
|
292
|
+
payload: {
|
|
293
|
+
text: nativeHelp.text,
|
|
294
|
+
replyToId: msgId || undefined,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
return { handled: true, command: command.command, sessionKey };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (nativeWhoami) {
|
|
301
|
+
logBncrNativeCommandSummary(
|
|
302
|
+
buildBncrNativeCommandSummary({
|
|
303
|
+
kind: 'whoami',
|
|
304
|
+
command: command.command,
|
|
305
|
+
accountId,
|
|
306
|
+
to: displayTo,
|
|
307
|
+
msgId: msgId || null,
|
|
308
|
+
result: 'handled',
|
|
309
|
+
}),
|
|
310
|
+
);
|
|
311
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
312
|
+
storePath,
|
|
313
|
+
sessionKey,
|
|
314
|
+
ctx: ctxPayload,
|
|
315
|
+
patch: sessionIdentityPatch,
|
|
316
|
+
});
|
|
317
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
318
|
+
await enqueueFromReply({
|
|
319
|
+
accountId,
|
|
320
|
+
sessionKey,
|
|
321
|
+
route,
|
|
322
|
+
payload: {
|
|
323
|
+
text: nativeWhoami.text,
|
|
324
|
+
replyToId: msgId || undefined,
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
return { handled: true, command: command.command, sessionKey };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (nativeStatus) {
|
|
331
|
+
logBncrNativeCommandSummary(
|
|
332
|
+
buildBncrNativeCommandSummary({
|
|
333
|
+
kind: 'status',
|
|
334
|
+
command: command.command,
|
|
335
|
+
accountId,
|
|
336
|
+
to: displayTo,
|
|
337
|
+
msgId: msgId || null,
|
|
338
|
+
result: 'handled',
|
|
339
|
+
}),
|
|
340
|
+
);
|
|
341
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
342
|
+
storePath,
|
|
343
|
+
sessionKey,
|
|
344
|
+
ctx: ctxPayload,
|
|
345
|
+
patch: sessionIdentityPatch,
|
|
346
|
+
});
|
|
347
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
348
|
+
await enqueueFromReply({
|
|
349
|
+
accountId,
|
|
350
|
+
sessionKey,
|
|
351
|
+
route,
|
|
352
|
+
payload: {
|
|
353
|
+
text: nativeStatus.text,
|
|
354
|
+
replyToId: msgId || undefined,
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
return { handled: true, command: command.command, sessionKey };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (nativeSessionReset) {
|
|
361
|
+
const allowLocalSessionReset = parsed.peer.kind === 'direct';
|
|
362
|
+
if (!allowLocalSessionReset) {
|
|
363
|
+
logBncrNativeCommandSummary(
|
|
364
|
+
buildBncrNativeCommandSummary({
|
|
365
|
+
kind: nativeSessionReset.reason,
|
|
366
|
+
command: command.command,
|
|
367
|
+
accountId,
|
|
368
|
+
to: displayTo,
|
|
369
|
+
msgId: msgId || null,
|
|
370
|
+
result: 'rejected',
|
|
371
|
+
}),
|
|
372
|
+
);
|
|
373
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
374
|
+
storePath,
|
|
375
|
+
sessionKey,
|
|
376
|
+
ctx: ctxPayload,
|
|
377
|
+
patch: sessionIdentityPatch,
|
|
378
|
+
});
|
|
379
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
380
|
+
return { handled: true, command: command.command, sessionKey };
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const requestedAgentId = resolvedRoute.agentId || canonicalAgentId;
|
|
384
|
+
const requestApi = api as BncrInboundApi & {
|
|
385
|
+
request?: (method: string, params: Record<string, unknown>) => Promise<unknown>;
|
|
386
|
+
};
|
|
387
|
+
if (typeof requestApi.request !== 'function') {
|
|
388
|
+
throw new Error('OpenClaw plugin api.request is unavailable for sessions.reset');
|
|
389
|
+
}
|
|
390
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
391
|
+
storePath,
|
|
392
|
+
sessionKey,
|
|
393
|
+
ctx: ctxPayload,
|
|
394
|
+
patch: sessionIdentityPatch,
|
|
395
|
+
});
|
|
396
|
+
const resetResult = (await requestApi.request('sessions.reset', {
|
|
397
|
+
key: baseSessionKey,
|
|
398
|
+
reason: nativeSessionReset.reason,
|
|
399
|
+
...(requestedAgentId ? { agentId: requestedAgentId } : {}),
|
|
400
|
+
})) as { ok?: boolean } | undefined;
|
|
401
|
+
if (resetResult?.ok === false) {
|
|
402
|
+
throw new Error(`sessions.reset failed for ${baseSessionKey}`);
|
|
403
|
+
}
|
|
404
|
+
logBncrNativeCommandSummary(
|
|
405
|
+
buildBncrNativeCommandSummary({
|
|
406
|
+
kind: nativeSessionReset.reason,
|
|
407
|
+
command: command.command,
|
|
408
|
+
accountId,
|
|
409
|
+
to: displayTo,
|
|
410
|
+
msgId: msgId || null,
|
|
411
|
+
result: 'handled',
|
|
412
|
+
}),
|
|
413
|
+
);
|
|
414
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
415
|
+
await enqueueFromReply({
|
|
416
|
+
accountId,
|
|
417
|
+
sessionKey: baseSessionKey,
|
|
418
|
+
route,
|
|
419
|
+
payload: {
|
|
420
|
+
text: nativeSessionReset.text,
|
|
421
|
+
replyToId: msgId || undefined,
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
return { handled: true, command: command.command, sessionKey: baseSessionKey };
|
|
425
|
+
}
|
|
426
|
+
|
|
169
427
|
if (nativeVerbose) {
|
|
428
|
+
if (!parsed.isAdmin) {
|
|
429
|
+
logBncrNativeCommandSummary(
|
|
430
|
+
buildBncrNativeCommandSummary({
|
|
431
|
+
kind: 'verbose',
|
|
432
|
+
command: command.command,
|
|
433
|
+
accountId,
|
|
434
|
+
to: displayTo,
|
|
435
|
+
msgId: msgId || null,
|
|
436
|
+
result: 'rejected',
|
|
437
|
+
}),
|
|
438
|
+
);
|
|
439
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
440
|
+
storePath,
|
|
441
|
+
sessionKey,
|
|
442
|
+
ctx: ctxPayload,
|
|
443
|
+
patch: sessionIdentityPatch,
|
|
444
|
+
});
|
|
445
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
446
|
+
if (parsed.peer.kind !== 'group') {
|
|
447
|
+
await enqueueFromReply({
|
|
448
|
+
accountId,
|
|
449
|
+
sessionKey,
|
|
450
|
+
route,
|
|
451
|
+
payload: {
|
|
452
|
+
text: 'Admin permission required.',
|
|
453
|
+
replyToId: msgId || undefined,
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
return { handled: true, command: command.command, sessionKey };
|
|
458
|
+
}
|
|
459
|
+
|
|
170
460
|
logBncrNativeCommandSummary(
|
|
171
461
|
buildBncrNativeCommandSummary({
|
|
172
462
|
kind: 'verbose',
|
|
@@ -211,6 +501,78 @@ export async function handleBncrNativeCommand(params: {
|
|
|
211
501
|
return { handled: true, command: command.command, sessionKey };
|
|
212
502
|
}
|
|
213
503
|
|
|
504
|
+
const sceneAdmin = parseSceneAdminCommand(command);
|
|
505
|
+
if (sceneAdmin.matched) {
|
|
506
|
+
const silentNonAdminGroupReject = !parsed.isAdmin && parsed.peer.kind === 'group';
|
|
507
|
+
if (!sceneAdmin.valid) {
|
|
508
|
+
logBncrNativeCommandSummary(
|
|
509
|
+
buildBncrNativeCommandSummary({
|
|
510
|
+
kind: 'scene-admin',
|
|
511
|
+
command: command.command,
|
|
512
|
+
accountId,
|
|
513
|
+
to: displayTo,
|
|
514
|
+
msgId: msgId ?? null,
|
|
515
|
+
result: 'rejected',
|
|
516
|
+
}),
|
|
517
|
+
);
|
|
518
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
519
|
+
storePath,
|
|
520
|
+
sessionKey,
|
|
521
|
+
ctx: ctxPayload,
|
|
522
|
+
patch: sessionIdentityPatch,
|
|
523
|
+
});
|
|
524
|
+
if (!silentNonAdminGroupReject) {
|
|
525
|
+
await enqueueFromReply({
|
|
526
|
+
accountId,
|
|
527
|
+
sessionKey,
|
|
528
|
+
route,
|
|
529
|
+
payload: {
|
|
530
|
+
text: sceneAdmin.text,
|
|
531
|
+
replyToId: msgId || undefined,
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
return { handled: true, command: command.command, sessionKey };
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const outcome = executeSceneAdminCommand({
|
|
539
|
+
parsed,
|
|
540
|
+
command: sceneAdmin.command,
|
|
541
|
+
sceneRegistry,
|
|
542
|
+
defaultAdminAgentId,
|
|
543
|
+
defaultPublicAgentId,
|
|
544
|
+
now,
|
|
545
|
+
});
|
|
546
|
+
logBncrNativeCommandSummary(
|
|
547
|
+
buildBncrNativeCommandSummary({
|
|
548
|
+
kind: 'scene-admin',
|
|
549
|
+
command: command.command,
|
|
550
|
+
accountId,
|
|
551
|
+
to: displayTo,
|
|
552
|
+
msgId: msgId ?? null,
|
|
553
|
+
result: outcome.ok ? 'handled' : 'rejected',
|
|
554
|
+
}),
|
|
555
|
+
);
|
|
556
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
557
|
+
storePath,
|
|
558
|
+
sessionKey,
|
|
559
|
+
ctx: ctxPayload,
|
|
560
|
+
patch: sessionIdentityPatch,
|
|
561
|
+
});
|
|
562
|
+
if (!(silentNonAdminGroupReject && !outcome.ok)) {
|
|
563
|
+
await enqueueFromReply({
|
|
564
|
+
accountId,
|
|
565
|
+
sessionKey,
|
|
566
|
+
route,
|
|
567
|
+
payload: {
|
|
568
|
+
text: outcome.text,
|
|
569
|
+
replyToId: msgId || undefined,
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
return { handled: true, command: command.command, sessionKey };
|
|
574
|
+
}
|
|
575
|
+
|
|
214
576
|
await recordAndPatchBncrInboundSessionEntry({
|
|
215
577
|
storePath,
|
|
216
578
|
sessionKey,
|
|
@@ -264,51 +626,59 @@ export async function handleBncrNativeCommand(params: {
|
|
|
264
626
|
textForCommands: ctxPayload.CommandBody,
|
|
265
627
|
raw: parsed,
|
|
266
628
|
}),
|
|
267
|
-
resolveTurn: () =>
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
runDispatch: () =>
|
|
286
|
-
dispatchOpenClawReplyWithBufferedBlockDispatcher(api, {
|
|
287
|
-
ctx: ctxPayload,
|
|
288
|
-
cfg: effectiveReply.replyCfg,
|
|
289
|
-
dispatcherOptions: {
|
|
290
|
-
deliver: createNativeCommandReplyDeliverer({
|
|
291
|
-
command: command.command,
|
|
292
|
-
accountId,
|
|
293
|
-
sessionKey,
|
|
294
|
-
to: displayTo,
|
|
295
|
-
msgId: msgId || undefined,
|
|
296
|
-
effectiveReply,
|
|
297
|
-
route,
|
|
298
|
-
enqueueFromReply,
|
|
299
|
-
nativeCommandDebugEnabled,
|
|
300
|
-
onResponded: () => responded,
|
|
301
|
-
markResponded: () => {
|
|
302
|
-
responded = true;
|
|
303
|
-
},
|
|
304
|
-
}),
|
|
629
|
+
resolveTurn: () => {
|
|
630
|
+
const sessionMetaBarrier = createBncrSessionMetaTaskBarrier();
|
|
631
|
+
return {
|
|
632
|
+
channel: channelId,
|
|
633
|
+
accountId,
|
|
634
|
+
routeSessionKey: resolvedRoute.sessionKey,
|
|
635
|
+
storePath,
|
|
636
|
+
ctxPayload,
|
|
637
|
+
recordInboundSession: wrapBncrInboundRecordSessionLabelCorrection({
|
|
638
|
+
recordInboundSession: recordBncrInboundSession as (
|
|
639
|
+
...args: unknown[]
|
|
640
|
+
) => Promise<unknown> | unknown,
|
|
641
|
+
expectedPatch: sessionIdentityPatch,
|
|
642
|
+
}),
|
|
643
|
+
record: {
|
|
644
|
+
updateLastRoute,
|
|
645
|
+
onRecordError: (err: unknown) => {
|
|
646
|
+
buildNativeCommandRecordErrorLogger(err);
|
|
305
647
|
},
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
shouldEmitToolResult: effectiveReply.allowTool ? () => true : undefined,
|
|
648
|
+
trackSessionMetaTask: (task: Promise<unknown>) => {
|
|
649
|
+
sessionMetaBarrier.track(task);
|
|
309
650
|
},
|
|
310
|
-
}
|
|
311
|
-
|
|
651
|
+
},
|
|
652
|
+
runDispatch: async () => {
|
|
653
|
+
await sessionMetaBarrier.wait();
|
|
654
|
+
return dispatchOpenClawReplyWithBufferedBlockDispatcher(api, {
|
|
655
|
+
ctx: ctxPayload,
|
|
656
|
+
cfg: effectiveReply.replyCfg,
|
|
657
|
+
dispatcherOptions: {
|
|
658
|
+
deliver: createNativeCommandReplyDeliverer({
|
|
659
|
+
command: command.command,
|
|
660
|
+
accountId,
|
|
661
|
+
sessionKey,
|
|
662
|
+
to: displayTo,
|
|
663
|
+
msgId: msgId || undefined,
|
|
664
|
+
effectiveReply,
|
|
665
|
+
route,
|
|
666
|
+
enqueueFromReply,
|
|
667
|
+
nativeCommandDebugEnabled,
|
|
668
|
+
onResponded: () => responded,
|
|
669
|
+
markResponded: () => {
|
|
670
|
+
responded = true;
|
|
671
|
+
},
|
|
672
|
+
}),
|
|
673
|
+
},
|
|
674
|
+
replyOptions: {
|
|
675
|
+
disableBlockStreaming: !effectiveReply.blockStreaming,
|
|
676
|
+
shouldEmitToolResult: effectiveReply.allowTool ? () => true : undefined,
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
},
|
|
680
|
+
};
|
|
681
|
+
},
|
|
312
682
|
},
|
|
313
683
|
});
|
|
314
684
|
|