@xmoxmo/bncr 0.4.6 → 0.4.7
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/package.json +1 -1
- package/src/channel.ts +41 -2
- package/src/core/targets.ts +106 -17
- package/src/messaging/inbound/commands.ts +263 -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 +92 -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 +269 -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 +34 -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 +55 -2
- package/src/plugin/inbound-surface-handlers-group.ts +16 -0
- package/src/plugin/messaging.ts +22 -5
- package/src/plugin/scene-registry.ts +155 -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,12 @@ 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
|
+
resolveBncrNativeHelpCommand,
|
|
26
|
+
resolveBncrNativeVerboseCommand,
|
|
27
|
+
resolveBncrNativeWhoamiCommand,
|
|
28
|
+
} from './native-command.ts';
|
|
24
29
|
import {
|
|
25
30
|
buildBncrNativeCommandSessionState,
|
|
26
31
|
buildBncrNativeCommandSummary,
|
|
@@ -34,11 +39,13 @@ import {
|
|
|
34
39
|
} from './native-command-runtime.ts';
|
|
35
40
|
import { buildBncrReplyConfig } from './reply-config.ts';
|
|
36
41
|
import { resolveBncrChannelInboundRuntime } from './runtime-compat.ts';
|
|
42
|
+
import { executeSceneAdminCommand, parseSceneAdminCommand } from './scene-admin.ts';
|
|
37
43
|
import {
|
|
38
44
|
buildBncrInboundSessionIdentityPatch,
|
|
39
45
|
recordAndPatchBncrInboundSessionEntry,
|
|
40
46
|
wrapBncrInboundRecordSessionLabelCorrection,
|
|
41
47
|
} from './session-label.ts';
|
|
48
|
+
import { createBncrSessionMetaTaskBarrier } from './session-meta-task.ts';
|
|
42
49
|
|
|
43
50
|
function assertResolvedAgentRoute(resolvedRoute: OpenClawResolvedAgentRoute): {
|
|
44
51
|
sessionKey: string;
|
|
@@ -65,8 +72,9 @@ function buildBncrNativeCommandResolvedRoute(args: {
|
|
|
65
72
|
channelId: string;
|
|
66
73
|
accountId: string;
|
|
67
74
|
peer: ParsedInbound['peer'];
|
|
75
|
+
resolvedAgentId?: string;
|
|
68
76
|
}) {
|
|
69
|
-
|
|
77
|
+
const resolvedRoute = assertResolvedAgentRoute(
|
|
70
78
|
resolveOpenClawAgentRoute(args.api, {
|
|
71
79
|
cfg: args.cfg,
|
|
72
80
|
channel: args.channelId,
|
|
@@ -74,6 +82,14 @@ function buildBncrNativeCommandResolvedRoute(args: {
|
|
|
74
82
|
peer: args.peer,
|
|
75
83
|
}),
|
|
76
84
|
);
|
|
85
|
+
|
|
86
|
+
const agentId = (args.resolvedAgentId || '').trim() || resolvedRoute.agentId;
|
|
87
|
+
if (!agentId || agentId === resolvedRoute.agentId) return resolvedRoute;
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
...resolvedRoute,
|
|
91
|
+
agentId,
|
|
92
|
+
};
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
export { parseBncrNativeCommand } from './native-command.ts';
|
|
@@ -84,6 +100,11 @@ export async function handleBncrNativeCommand(params: {
|
|
|
84
100
|
cfg: BncrInboundConfig;
|
|
85
101
|
parsed: ParsedInbound;
|
|
86
102
|
canonicalAgentId: string;
|
|
103
|
+
resolvedAgentId?: string;
|
|
104
|
+
sceneRegistry: Map<string, import('../../plugin/channel-runtime-types.ts').BncrSceneRecord>;
|
|
105
|
+
defaultAdminAgentId: string;
|
|
106
|
+
defaultPublicAgentId: string;
|
|
107
|
+
now: () => number;
|
|
87
108
|
rememberSessionRoute: BncrRememberSessionRoute;
|
|
88
109
|
enqueueFromReply: BncrEnqueueFromReply;
|
|
89
110
|
logger?: BncrInboundLogger;
|
|
@@ -91,10 +112,24 @@ export async function handleBncrNativeCommand(params: {
|
|
|
91
112
|
| { handled: false }
|
|
92
113
|
| { handled: true; command: string; sessionKey: string; fallbackToAgent?: boolean }
|
|
93
114
|
> {
|
|
94
|
-
const {
|
|
95
|
-
|
|
115
|
+
const {
|
|
116
|
+
api,
|
|
117
|
+
channelId,
|
|
118
|
+
cfg,
|
|
119
|
+
parsed,
|
|
120
|
+
canonicalAgentId,
|
|
121
|
+
resolvedAgentId,
|
|
122
|
+
sceneRegistry,
|
|
123
|
+
defaultAdminAgentId,
|
|
124
|
+
defaultPublicAgentId,
|
|
125
|
+
now,
|
|
126
|
+
rememberSessionRoute,
|
|
127
|
+
enqueueFromReply,
|
|
128
|
+
} = params;
|
|
96
129
|
const { accountId, route, peer, clientId, extracted, msgId } = parsed;
|
|
97
|
-
const command = parseBncrNativeCommand(extracted.text
|
|
130
|
+
const command = parseBncrNativeCommand(extracted.text, {
|
|
131
|
+
allowBareWhoami: parsed.isAdmin !== true,
|
|
132
|
+
});
|
|
98
133
|
if (!command) return { handled: false };
|
|
99
134
|
const nativeCommandDebugEnabled = resolveNativeCommandDebugEnabled({ cfg, channelId });
|
|
100
135
|
|
|
@@ -115,12 +150,13 @@ export async function handleBncrNativeCommand(params: {
|
|
|
115
150
|
channelId,
|
|
116
151
|
accountId,
|
|
117
152
|
peer,
|
|
153
|
+
resolvedAgentId,
|
|
118
154
|
});
|
|
119
155
|
|
|
120
156
|
const { baseSessionKey, taskSessionKey, sessionKey, displayTo, originatingTo } =
|
|
121
157
|
buildBncrNativeCommandSessionState({
|
|
122
158
|
parsed,
|
|
123
|
-
canonicalAgentId,
|
|
159
|
+
sessionAgentId: resolvedRoute.agentId || canonicalAgentId,
|
|
124
160
|
resolvedRoute,
|
|
125
161
|
});
|
|
126
162
|
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
@@ -133,8 +169,8 @@ export async function handleBncrNativeCommand(params: {
|
|
|
133
169
|
'[bncr] inbound missing clientId for native command identity; using route identity fallback',
|
|
134
170
|
);
|
|
135
171
|
}
|
|
136
|
-
const senderIdForContext = clientId || displayTo;
|
|
137
|
-
const senderDisplayName =
|
|
172
|
+
const senderIdForContext = parsed.userId || clientId || displayTo;
|
|
173
|
+
const senderDisplayName = parsed.userName || displayTo;
|
|
138
174
|
const storePath = resolveBncrInboundSessionStorePath({
|
|
139
175
|
storeConfig: cfg?.session?.store,
|
|
140
176
|
agentId: resolvedRoute.agentId,
|
|
@@ -166,7 +202,108 @@ export async function handleBncrNativeCommand(params: {
|
|
|
166
202
|
});
|
|
167
203
|
|
|
168
204
|
const nativeVerbose = resolveBncrNativeVerboseCommand(command);
|
|
205
|
+
const nativeHelp = resolveBncrNativeHelpCommand(command);
|
|
206
|
+
const nativeWhoami = resolveBncrNativeWhoamiCommand({
|
|
207
|
+
command,
|
|
208
|
+
platform: parsed.platform,
|
|
209
|
+
groupId: parsed.groupId,
|
|
210
|
+
groupName: parsed.groupName,
|
|
211
|
+
userId: parsed.userId,
|
|
212
|
+
userName: parsed.userName,
|
|
213
|
+
isGroup: parsed.isGroup,
|
|
214
|
+
isAdmin: parsed.isAdmin,
|
|
215
|
+
});
|
|
216
|
+
if (nativeHelp) {
|
|
217
|
+
logBncrNativeCommandSummary(
|
|
218
|
+
buildBncrNativeCommandSummary({
|
|
219
|
+
kind: 'help',
|
|
220
|
+
command: command.command,
|
|
221
|
+
accountId,
|
|
222
|
+
to: displayTo,
|
|
223
|
+
msgId: msgId || null,
|
|
224
|
+
result: 'handled',
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
228
|
+
storePath,
|
|
229
|
+
sessionKey,
|
|
230
|
+
ctx: ctxPayload,
|
|
231
|
+
patch: sessionIdentityPatch,
|
|
232
|
+
});
|
|
233
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
234
|
+
await enqueueFromReply({
|
|
235
|
+
accountId,
|
|
236
|
+
sessionKey,
|
|
237
|
+
route,
|
|
238
|
+
payload: {
|
|
239
|
+
text: nativeHelp.text,
|
|
240
|
+
replyToId: msgId || undefined,
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
return { handled: true, command: command.command, sessionKey };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (nativeWhoami) {
|
|
247
|
+
logBncrNativeCommandSummary(
|
|
248
|
+
buildBncrNativeCommandSummary({
|
|
249
|
+
kind: 'whoami',
|
|
250
|
+
command: command.command,
|
|
251
|
+
accountId,
|
|
252
|
+
to: displayTo,
|
|
253
|
+
msgId: msgId || null,
|
|
254
|
+
result: 'handled',
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
258
|
+
storePath,
|
|
259
|
+
sessionKey,
|
|
260
|
+
ctx: ctxPayload,
|
|
261
|
+
patch: sessionIdentityPatch,
|
|
262
|
+
});
|
|
263
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
264
|
+
await enqueueFromReply({
|
|
265
|
+
accountId,
|
|
266
|
+
sessionKey,
|
|
267
|
+
route,
|
|
268
|
+
payload: {
|
|
269
|
+
text: nativeWhoami.text,
|
|
270
|
+
replyToId: msgId || undefined,
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
return { handled: true, command: command.command, sessionKey };
|
|
274
|
+
}
|
|
275
|
+
|
|
169
276
|
if (nativeVerbose) {
|
|
277
|
+
if (!parsed.isAdmin) {
|
|
278
|
+
logBncrNativeCommandSummary(
|
|
279
|
+
buildBncrNativeCommandSummary({
|
|
280
|
+
kind: 'verbose',
|
|
281
|
+
command: command.command,
|
|
282
|
+
accountId,
|
|
283
|
+
to: displayTo,
|
|
284
|
+
msgId: msgId || null,
|
|
285
|
+
result: 'rejected',
|
|
286
|
+
}),
|
|
287
|
+
);
|
|
288
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
289
|
+
storePath,
|
|
290
|
+
sessionKey,
|
|
291
|
+
ctx: ctxPayload,
|
|
292
|
+
patch: sessionIdentityPatch,
|
|
293
|
+
});
|
|
294
|
+
rememberSessionRoute(baseSessionKey, accountId, route);
|
|
295
|
+
await enqueueFromReply({
|
|
296
|
+
accountId,
|
|
297
|
+
sessionKey,
|
|
298
|
+
route,
|
|
299
|
+
payload: {
|
|
300
|
+
text: 'Admin permission required.',
|
|
301
|
+
replyToId: msgId || undefined,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
return { handled: true, command: command.command, sessionKey };
|
|
305
|
+
}
|
|
306
|
+
|
|
170
307
|
logBncrNativeCommandSummary(
|
|
171
308
|
buildBncrNativeCommandSummary({
|
|
172
309
|
kind: 'verbose',
|
|
@@ -211,6 +348,73 @@ export async function handleBncrNativeCommand(params: {
|
|
|
211
348
|
return { handled: true, command: command.command, sessionKey };
|
|
212
349
|
}
|
|
213
350
|
|
|
351
|
+
const sceneAdmin = parseSceneAdminCommand(command);
|
|
352
|
+
if (sceneAdmin.matched) {
|
|
353
|
+
if (!sceneAdmin.valid) {
|
|
354
|
+
logBncrNativeCommandSummary(
|
|
355
|
+
buildBncrNativeCommandSummary({
|
|
356
|
+
kind: 'scene-admin',
|
|
357
|
+
command: command.command,
|
|
358
|
+
accountId,
|
|
359
|
+
to: displayTo,
|
|
360
|
+
msgId: msgId ?? null,
|
|
361
|
+
result: 'rejected',
|
|
362
|
+
}),
|
|
363
|
+
);
|
|
364
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
365
|
+
storePath,
|
|
366
|
+
sessionKey,
|
|
367
|
+
ctx: ctxPayload,
|
|
368
|
+
patch: sessionIdentityPatch,
|
|
369
|
+
});
|
|
370
|
+
await enqueueFromReply({
|
|
371
|
+
accountId,
|
|
372
|
+
sessionKey,
|
|
373
|
+
route,
|
|
374
|
+
payload: {
|
|
375
|
+
text: sceneAdmin.text,
|
|
376
|
+
replyToId: msgId || undefined,
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
return { handled: true, command: command.command, sessionKey };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const outcome = executeSceneAdminCommand({
|
|
383
|
+
parsed,
|
|
384
|
+
command: sceneAdmin.command,
|
|
385
|
+
sceneRegistry,
|
|
386
|
+
defaultAdminAgentId,
|
|
387
|
+
defaultPublicAgentId,
|
|
388
|
+
now,
|
|
389
|
+
});
|
|
390
|
+
logBncrNativeCommandSummary(
|
|
391
|
+
buildBncrNativeCommandSummary({
|
|
392
|
+
kind: 'scene-admin',
|
|
393
|
+
command: command.command,
|
|
394
|
+
accountId,
|
|
395
|
+
to: displayTo,
|
|
396
|
+
msgId: msgId ?? null,
|
|
397
|
+
result: outcome.ok ? 'handled' : 'rejected',
|
|
398
|
+
}),
|
|
399
|
+
);
|
|
400
|
+
await recordAndPatchBncrInboundSessionEntry({
|
|
401
|
+
storePath,
|
|
402
|
+
sessionKey,
|
|
403
|
+
ctx: ctxPayload,
|
|
404
|
+
patch: sessionIdentityPatch,
|
|
405
|
+
});
|
|
406
|
+
await enqueueFromReply({
|
|
407
|
+
accountId,
|
|
408
|
+
sessionKey,
|
|
409
|
+
route,
|
|
410
|
+
payload: {
|
|
411
|
+
text: outcome.text,
|
|
412
|
+
replyToId: msgId || undefined,
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
return { handled: true, command: command.command, sessionKey };
|
|
416
|
+
}
|
|
417
|
+
|
|
214
418
|
await recordAndPatchBncrInboundSessionEntry({
|
|
215
419
|
storePath,
|
|
216
420
|
sessionKey,
|
|
@@ -264,51 +468,59 @@ export async function handleBncrNativeCommand(params: {
|
|
|
264
468
|
textForCommands: ctxPayload.CommandBody,
|
|
265
469
|
raw: parsed,
|
|
266
470
|
}),
|
|
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
|
-
}),
|
|
471
|
+
resolveTurn: () => {
|
|
472
|
+
const sessionMetaBarrier = createBncrSessionMetaTaskBarrier();
|
|
473
|
+
return {
|
|
474
|
+
channel: channelId,
|
|
475
|
+
accountId,
|
|
476
|
+
routeSessionKey: resolvedRoute.sessionKey,
|
|
477
|
+
storePath,
|
|
478
|
+
ctxPayload,
|
|
479
|
+
recordInboundSession: wrapBncrInboundRecordSessionLabelCorrection({
|
|
480
|
+
recordInboundSession: recordBncrInboundSession as (
|
|
481
|
+
...args: unknown[]
|
|
482
|
+
) => Promise<unknown> | unknown,
|
|
483
|
+
expectedPatch: sessionIdentityPatch,
|
|
484
|
+
}),
|
|
485
|
+
record: {
|
|
486
|
+
updateLastRoute,
|
|
487
|
+
onRecordError: (err: unknown) => {
|
|
488
|
+
buildNativeCommandRecordErrorLogger(err);
|
|
305
489
|
},
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
shouldEmitToolResult: effectiveReply.allowTool ? () => true : undefined,
|
|
490
|
+
trackSessionMetaTask: (task: Promise<unknown>) => {
|
|
491
|
+
sessionMetaBarrier.track(task);
|
|
309
492
|
},
|
|
310
|
-
}
|
|
311
|
-
|
|
493
|
+
},
|
|
494
|
+
runDispatch: async () => {
|
|
495
|
+
await sessionMetaBarrier.wait();
|
|
496
|
+
return dispatchOpenClawReplyWithBufferedBlockDispatcher(api, {
|
|
497
|
+
ctx: ctxPayload,
|
|
498
|
+
cfg: effectiveReply.replyCfg,
|
|
499
|
+
dispatcherOptions: {
|
|
500
|
+
deliver: createNativeCommandReplyDeliverer({
|
|
501
|
+
command: command.command,
|
|
502
|
+
accountId,
|
|
503
|
+
sessionKey,
|
|
504
|
+
to: displayTo,
|
|
505
|
+
msgId: msgId || undefined,
|
|
506
|
+
effectiveReply,
|
|
507
|
+
route,
|
|
508
|
+
enqueueFromReply,
|
|
509
|
+
nativeCommandDebugEnabled,
|
|
510
|
+
onResponded: () => responded,
|
|
511
|
+
markResponded: () => {
|
|
512
|
+
responded = true;
|
|
513
|
+
},
|
|
514
|
+
}),
|
|
515
|
+
},
|
|
516
|
+
replyOptions: {
|
|
517
|
+
disableBlockStreaming: !effectiveReply.blockStreaming,
|
|
518
|
+
shouldEmitToolResult: effectiveReply.allowTool ? () => true : undefined,
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
},
|
|
522
|
+
};
|
|
523
|
+
},
|
|
312
524
|
},
|
|
313
525
|
});
|
|
314
526
|
|
|
@@ -19,6 +19,27 @@ export type BncrStructuredContextFactsInput = {
|
|
|
19
19
|
sender: {
|
|
20
20
|
id: string;
|
|
21
21
|
displayName?: string;
|
|
22
|
+
userId?: string;
|
|
23
|
+
userName?: string;
|
|
24
|
+
bridgeId?: string;
|
|
25
|
+
bridgeName?: string;
|
|
26
|
+
isAdmin?: boolean;
|
|
27
|
+
isOwner?: boolean;
|
|
28
|
+
isAuthorizedSender?: boolean;
|
|
29
|
+
role?: 'owner' | 'admin' | 'user';
|
|
30
|
+
};
|
|
31
|
+
platform?: string;
|
|
32
|
+
group?: {
|
|
33
|
+
id?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
isGroup?: boolean;
|
|
36
|
+
};
|
|
37
|
+
trigger?: {
|
|
38
|
+
shouldRespond?: boolean;
|
|
39
|
+
triggerKind?: string;
|
|
40
|
+
botName?: string;
|
|
41
|
+
isBotMentioned?: boolean;
|
|
42
|
+
isReplyToBot?: boolean;
|
|
22
43
|
};
|
|
23
44
|
message: {
|
|
24
45
|
id?: string | null;
|
|
@@ -60,6 +81,27 @@ export function buildBncrStructuredContextFacts(input: BncrStructuredContextFact
|
|
|
60
81
|
sender: {
|
|
61
82
|
id: input.sender.id,
|
|
62
83
|
displayName: input.sender.displayName || input.sender.id,
|
|
84
|
+
userId: input.sender.userId,
|
|
85
|
+
userName: input.sender.userName,
|
|
86
|
+
bridgeId: input.sender.bridgeId,
|
|
87
|
+
bridgeName: input.sender.bridgeName,
|
|
88
|
+
isAdmin: input.sender.isAdmin,
|
|
89
|
+
...(input.sender.isOwner === true ? { isOwner: true } : {}),
|
|
90
|
+
...(input.sender.isAuthorizedSender === true ? { isAuthorizedSender: true } : {}),
|
|
91
|
+
...(input.sender.role !== undefined ? { role: input.sender.role } : {}),
|
|
92
|
+
},
|
|
93
|
+
platform: input.platform,
|
|
94
|
+
group: {
|
|
95
|
+
id: input.group?.id,
|
|
96
|
+
name: input.group?.name,
|
|
97
|
+
isGroup: input.group?.isGroup,
|
|
98
|
+
},
|
|
99
|
+
trigger: {
|
|
100
|
+
shouldRespond: input.trigger?.shouldRespond,
|
|
101
|
+
triggerKind: input.trigger?.triggerKind,
|
|
102
|
+
botName: input.trigger?.botName,
|
|
103
|
+
isBotMentioned: input.trigger?.isBotMentioned,
|
|
104
|
+
isReplyToBot: input.trigger?.isReplyToBot,
|
|
63
105
|
},
|
|
64
106
|
message: {
|
|
65
107
|
id: input.message.id || undefined,
|
|
@@ -85,6 +127,15 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
85
127
|
facts: ReturnType<typeof buildBncrStructuredContextFacts>,
|
|
86
128
|
) {
|
|
87
129
|
const result: {
|
|
130
|
+
trigger?: {
|
|
131
|
+
botName?: string;
|
|
132
|
+
};
|
|
133
|
+
sender?: {
|
|
134
|
+
isAdmin?: boolean;
|
|
135
|
+
isOwner?: boolean;
|
|
136
|
+
isAuthorizedSender?: boolean;
|
|
137
|
+
role?: 'owner' | 'admin' | 'user';
|
|
138
|
+
};
|
|
88
139
|
reply?: {
|
|
89
140
|
to: string;
|
|
90
141
|
originatingTo: string;
|
|
@@ -96,6 +147,30 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
96
147
|
}>;
|
|
97
148
|
} = {};
|
|
98
149
|
|
|
150
|
+
if (
|
|
151
|
+
facts.sender.isAdmin === true ||
|
|
152
|
+
facts.sender.isOwner === true ||
|
|
153
|
+
facts.sender.isAuthorizedSender === true ||
|
|
154
|
+
facts.sender.role === 'owner' ||
|
|
155
|
+
facts.sender.role === 'admin'
|
|
156
|
+
) {
|
|
157
|
+
const sender = {
|
|
158
|
+
...(facts.sender.isAdmin === true ? { isAdmin: true } : {}),
|
|
159
|
+
...(facts.sender.isOwner === true ? { isOwner: true } : {}),
|
|
160
|
+
...(facts.sender.isAuthorizedSender === true ? { isAuthorizedSender: true } : {}),
|
|
161
|
+
...(facts.sender.role === 'owner' || facts.sender.role === 'admin'
|
|
162
|
+
? { role: facts.sender.role }
|
|
163
|
+
: {}),
|
|
164
|
+
};
|
|
165
|
+
if (Object.keys(sender).length > 0) result.sender = sender;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (facts.trigger.botName) {
|
|
169
|
+
result.trigger = {
|
|
170
|
+
botName: facts.trigger.botName,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
99
174
|
if (facts.reply.originatingTo !== facts.reply.to) {
|
|
100
175
|
result.reply = {
|
|
101
176
|
to: facts.reply.to,
|
|
@@ -125,11 +200,25 @@ export type BncrStructuredContextFactsFromInboundPartsInput = {
|
|
|
125
200
|
channelId: string;
|
|
126
201
|
parsed: {
|
|
127
202
|
accountId: string;
|
|
203
|
+
platform?: string;
|
|
128
204
|
peer: {
|
|
129
205
|
kind: string;
|
|
130
206
|
id: string;
|
|
131
207
|
};
|
|
132
208
|
clientId?: string;
|
|
209
|
+
bridgeId?: string;
|
|
210
|
+
bridgeName?: string;
|
|
211
|
+
groupId?: string;
|
|
212
|
+
groupName?: string;
|
|
213
|
+
userId?: string;
|
|
214
|
+
userName?: string;
|
|
215
|
+
isGroup?: boolean;
|
|
216
|
+
isAdmin?: boolean;
|
|
217
|
+
shouldRespond?: boolean;
|
|
218
|
+
triggerKind?: string;
|
|
219
|
+
botName?: string;
|
|
220
|
+
isBotMentioned?: boolean;
|
|
221
|
+
isReplyToBot?: boolean;
|
|
133
222
|
msgId?: string;
|
|
134
223
|
mimeType?: string;
|
|
135
224
|
};
|
|
@@ -147,18 +236,24 @@ export type BncrStructuredContextFactsFromInboundPartsInput = {
|
|
|
147
236
|
prepared: {
|
|
148
237
|
rawBody: string;
|
|
149
238
|
body?: string;
|
|
150
|
-
|
|
151
|
-
|
|
239
|
+
mediaItems?: Array<{
|
|
240
|
+
path: string;
|
|
241
|
+
contentType?: string;
|
|
242
|
+
kind?: string;
|
|
243
|
+
}>;
|
|
152
244
|
};
|
|
153
245
|
senderIdForContext: string;
|
|
154
246
|
senderDisplayName?: string;
|
|
247
|
+
bridgeSenderId?: string;
|
|
248
|
+
bridgeSenderName?: string;
|
|
249
|
+
senderIsOwner?: boolean;
|
|
250
|
+
senderIsAuthorized?: boolean;
|
|
155
251
|
};
|
|
156
252
|
|
|
157
253
|
export function buildBncrStructuredContextFactsFromInboundParts(
|
|
158
254
|
input: BncrStructuredContextFactsFromInboundPartsInput,
|
|
159
255
|
) {
|
|
160
|
-
const
|
|
161
|
-
const mediaContentType = input.prepared.mediaContentType || input.parsed.mimeType;
|
|
256
|
+
const mediaItems = Array.isArray(input.prepared.mediaItems) ? input.prepared.mediaItems : [];
|
|
162
257
|
return buildBncrStructuredContextFacts({
|
|
163
258
|
channelId: input.channelId,
|
|
164
259
|
accountId: input.parsed.accountId,
|
|
@@ -180,6 +275,27 @@ export function buildBncrStructuredContextFactsFromInboundParts(
|
|
|
180
275
|
sender: {
|
|
181
276
|
id: input.senderIdForContext,
|
|
182
277
|
displayName: input.senderDisplayName,
|
|
278
|
+
userId: input.parsed.userId,
|
|
279
|
+
userName: input.parsed.userName,
|
|
280
|
+
bridgeId: input.bridgeSenderId || input.parsed.bridgeId || input.parsed.clientId,
|
|
281
|
+
bridgeName: input.bridgeSenderName || input.parsed.bridgeName,
|
|
282
|
+
isAdmin: input.parsed.isAdmin,
|
|
283
|
+
isOwner: input.senderIsOwner === true ? true : undefined,
|
|
284
|
+
isAuthorizedSender: input.senderIsAuthorized === true ? true : undefined,
|
|
285
|
+
role: input.senderIsOwner ? 'owner' : input.parsed.isAdmin ? 'admin' : undefined,
|
|
286
|
+
},
|
|
287
|
+
platform: input.parsed.platform,
|
|
288
|
+
group: {
|
|
289
|
+
id: input.parsed.groupId,
|
|
290
|
+
name: input.parsed.groupName,
|
|
291
|
+
isGroup: input.parsed.isGroup,
|
|
292
|
+
},
|
|
293
|
+
trigger: {
|
|
294
|
+
shouldRespond: input.parsed.shouldRespond,
|
|
295
|
+
triggerKind: input.parsed.triggerKind,
|
|
296
|
+
botName: input.parsed.botName,
|
|
297
|
+
isBotMentioned: input.parsed.isBotMentioned,
|
|
298
|
+
isReplyToBot: input.parsed.isReplyToBot,
|
|
183
299
|
},
|
|
184
300
|
message: {
|
|
185
301
|
id: input.parsed.msgId,
|
|
@@ -188,15 +304,11 @@ export function buildBncrStructuredContextFactsFromInboundParts(
|
|
|
188
304
|
commandBody: input.prepared.rawBody,
|
|
189
305
|
envelopeBody: input.prepared.body,
|
|
190
306
|
},
|
|
191
|
-
media:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
messageId: input.parsed.msgId,
|
|
198
|
-
},
|
|
199
|
-
]
|
|
200
|
-
: [],
|
|
307
|
+
media: mediaItems.map((item) => ({
|
|
308
|
+
path: item.path,
|
|
309
|
+
contentType: item.contentType,
|
|
310
|
+
kind: item.kind || inferBncrStructuredMediaKind(item.contentType),
|
|
311
|
+
messageId: input.parsed.msgId,
|
|
312
|
+
})),
|
|
201
313
|
});
|
|
202
314
|
}
|
|
@@ -15,21 +15,45 @@ export type BncrInboundParsedPeer = OpenClawChannelPeer;
|
|
|
15
15
|
|
|
16
16
|
export type BncrInboundParamsInput = {
|
|
17
17
|
accountId?: unknown;
|
|
18
|
+
protocolVersion?: unknown;
|
|
19
|
+
capabilities?: unknown;
|
|
18
20
|
platform?: unknown;
|
|
19
21
|
groupId?: unknown;
|
|
22
|
+
groupName?: unknown;
|
|
20
23
|
userId?: unknown;
|
|
24
|
+
userName?: unknown;
|
|
21
25
|
sessionKey?: unknown;
|
|
22
26
|
originatingTo?: unknown;
|
|
23
27
|
providedOriginatingTo?: unknown;
|
|
24
28
|
to?: unknown;
|
|
25
29
|
clientId?: unknown;
|
|
30
|
+
bridgeId?: unknown;
|
|
31
|
+
bridgeName?: unknown;
|
|
32
|
+
isGroup?: unknown;
|
|
33
|
+
isAdmin?: unknown;
|
|
26
34
|
msg?: unknown;
|
|
27
35
|
type?: unknown;
|
|
28
36
|
base64?: unknown;
|
|
29
37
|
path?: unknown;
|
|
38
|
+
paths?: unknown;
|
|
39
|
+
mediaList?: unknown;
|
|
30
40
|
mimeType?: unknown;
|
|
31
41
|
fileName?: unknown;
|
|
32
42
|
msgId?: unknown;
|
|
43
|
+
shouldRespond?: unknown;
|
|
44
|
+
triggerKind?: unknown;
|
|
45
|
+
botName?: unknown;
|
|
46
|
+
isBotMentioned?: unknown;
|
|
47
|
+
isReplyToBot?: unknown;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type BncrInboundMediaItem = {
|
|
51
|
+
path?: string;
|
|
52
|
+
base64?: string;
|
|
53
|
+
mimeType?: string;
|
|
54
|
+
fileName?: string;
|
|
55
|
+
type?: string;
|
|
56
|
+
transferId?: string;
|
|
33
57
|
};
|
|
34
58
|
|
|
35
59
|
export type BncrRememberSessionRoute = (
|