@xmoxmo/bncr 0.5.2 → 0.5.4
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
CHANGED
|
@@ -17,6 +17,7 @@ export type BncrStructuredContextFactsInput = {
|
|
|
17
17
|
reply: {
|
|
18
18
|
to: string;
|
|
19
19
|
originatingTo: string;
|
|
20
|
+
rawTo?: string;
|
|
20
21
|
};
|
|
21
22
|
sender: {
|
|
22
23
|
id: string;
|
|
@@ -125,6 +126,7 @@ export function buildBncrStructuredContextFacts(input: BncrStructuredContextFact
|
|
|
125
126
|
reply: {
|
|
126
127
|
to: input.reply.to,
|
|
127
128
|
originatingTo: input.reply.originatingTo,
|
|
129
|
+
...(input.reply.rawTo ? { rawTo: input.reply.rawTo } : {}),
|
|
128
130
|
},
|
|
129
131
|
sender: {
|
|
130
132
|
id: input.sender.id,
|
|
@@ -187,6 +189,7 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
187
189
|
facts: ReturnType<typeof buildBncrStructuredContextFacts>,
|
|
188
190
|
) {
|
|
189
191
|
const result: {
|
|
192
|
+
platform?: string;
|
|
190
193
|
trigger?: {
|
|
191
194
|
botName?: string;
|
|
192
195
|
};
|
|
@@ -199,6 +202,7 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
199
202
|
reply?: {
|
|
200
203
|
to: string;
|
|
201
204
|
originatingTo: string;
|
|
205
|
+
rawTo?: string;
|
|
202
206
|
};
|
|
203
207
|
media?: Array<{
|
|
204
208
|
path?: string;
|
|
@@ -220,6 +224,10 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
220
224
|
}>;
|
|
221
225
|
} = {};
|
|
222
226
|
|
|
227
|
+
if (facts.platform) {
|
|
228
|
+
result.platform = `${facts.channel.id}/${facts.platform}`;
|
|
229
|
+
}
|
|
230
|
+
|
|
223
231
|
if (
|
|
224
232
|
facts.sender.isAdmin === true ||
|
|
225
233
|
facts.sender.isOwner === true ||
|
|
@@ -244,10 +252,11 @@ export function buildBncrPromptVisibleContextFacts(
|
|
|
244
252
|
};
|
|
245
253
|
}
|
|
246
254
|
|
|
247
|
-
if (facts.reply.originatingTo !== facts.reply.to) {
|
|
255
|
+
if (facts.reply.originatingTo !== facts.reply.to || facts.reply.rawTo) {
|
|
248
256
|
result.reply = {
|
|
249
257
|
to: facts.reply.to,
|
|
250
258
|
originatingTo: facts.reply.originatingTo,
|
|
259
|
+
...(facts.reply.rawTo ? { rawTo: facts.reply.rawTo } : {}),
|
|
251
260
|
};
|
|
252
261
|
}
|
|
253
262
|
|
|
@@ -326,6 +335,7 @@ export type BncrStructuredContextFactsFromInboundPartsInput = {
|
|
|
326
335
|
resolution: {
|
|
327
336
|
chatType: string;
|
|
328
337
|
canonicalTo: string;
|
|
338
|
+
rawTo: string;
|
|
329
339
|
originatingTo: string;
|
|
330
340
|
resolvedRoute: {
|
|
331
341
|
agentId?: string;
|
|
@@ -384,6 +394,7 @@ export function buildBncrStructuredContextFactsFromInboundParts(
|
|
|
384
394
|
reply: {
|
|
385
395
|
to: input.resolution.canonicalTo,
|
|
386
396
|
originatingTo: input.resolution.originatingTo,
|
|
397
|
+
rawTo: input.resolution.rawTo,
|
|
387
398
|
},
|
|
388
399
|
sender: {
|
|
389
400
|
id: input.senderIdForContext,
|
|
@@ -48,6 +48,7 @@ export type BncrInboundReplyRouteFact = {
|
|
|
48
48
|
sessionKey: string;
|
|
49
49
|
route: ParsedInbound['route'];
|
|
50
50
|
canonicalTo: string;
|
|
51
|
+
rawTo: string;
|
|
51
52
|
originatingTo: string;
|
|
52
53
|
chatType: 'direct' | 'group';
|
|
53
54
|
};
|
|
@@ -270,7 +271,7 @@ export function resolveBncrInboundConversation(args: {
|
|
|
270
271
|
const dispatchSessionKey = taskSessionKey || baseSessionKey;
|
|
271
272
|
const rawTo = formatRawBncrInboundTarget(route);
|
|
272
273
|
const canonicalTo = formatDisplayScope(route);
|
|
273
|
-
const originatingTo = providedOriginatingTo ||
|
|
274
|
+
const originatingTo = providedOriginatingTo || canonicalTo;
|
|
274
275
|
|
|
275
276
|
return {
|
|
276
277
|
accountId,
|
|
@@ -419,6 +420,7 @@ export function buildBncrInboundReplyRouteFact(
|
|
|
419
420
|
sessionKey: resolution.dispatchSessionKey,
|
|
420
421
|
route: resolution.route,
|
|
421
422
|
canonicalTo: resolution.canonicalTo,
|
|
423
|
+
rawTo: resolution.rawTo,
|
|
422
424
|
originatingTo: resolution.originatingTo,
|
|
423
425
|
chatType: resolution.chatType,
|
|
424
426
|
};
|
|
@@ -52,8 +52,8 @@ const BNCR_HELP_TEXT = [
|
|
|
52
52
|
' • /bncr mode help',
|
|
53
53
|
' • /bncr mode <admin|mention|hybrid|all> [<SceneId>]',
|
|
54
54
|
' • /bncr revoke [<SceneId>]',
|
|
55
|
-
' • /bncr list pending',
|
|
56
|
-
' • /bncr list scenes',
|
|
55
|
+
' • /bncr list pending [filters...]',
|
|
56
|
+
' • /bncr list scenes [filters...]',
|
|
57
57
|
'',
|
|
58
58
|
'📋 Group history',
|
|
59
59
|
' • /bncr history-help',
|
|
@@ -14,7 +14,7 @@ export type BncrSceneAdminCommand =
|
|
|
14
14
|
| { kind: 'mode-help' }
|
|
15
15
|
| { kind: 'mode-get'; sceneKey?: string }
|
|
16
16
|
| { kind: 'mode'; sceneKey: string; mode: BncrGroupReplyMode }
|
|
17
|
-
| { kind: 'list'; scope: 'pending' | 'scenes' }
|
|
17
|
+
| { kind: 'list'; scope: 'pending' | 'scenes'; filters?: string[] }
|
|
18
18
|
| { kind: 'history-limit-get'; sceneKey?: string }
|
|
19
19
|
| { kind: 'history-limit-set'; sceneKey: string; limit: number }
|
|
20
20
|
| { kind: 'history-force-get'; sceneKey?: string }
|
|
@@ -69,6 +69,11 @@ function splitArgs(raw: string): string[] {
|
|
|
69
69
|
.filter(Boolean);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
function normalizeFilters(args: string[]): string[] | undefined {
|
|
73
|
+
const filters = args.map((part) => normalizeToken(part).toLowerCase()).filter(Boolean);
|
|
74
|
+
return filters.length > 0 ? filters : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
72
77
|
function resolveCurrentGroupSceneKey(parsed: ParsedInbound): string | null {
|
|
73
78
|
if (parsed.peer.kind !== 'group') return null;
|
|
74
79
|
const platform = normalizeToken(parsed.platform);
|
|
@@ -151,12 +156,26 @@ export function parseSceneAdminCommand(command: NativeCommand): ParsedSceneAdmin
|
|
|
151
156
|
};
|
|
152
157
|
case 'list':
|
|
153
158
|
if (args[0] === 'pending') {
|
|
154
|
-
|
|
159
|
+
const filters = normalizeFilters(args.slice(1));
|
|
160
|
+
return {
|
|
161
|
+
matched: true,
|
|
162
|
+
valid: true,
|
|
163
|
+
command: { kind: 'list', scope: 'pending', ...(filters ? { filters } : {}) },
|
|
164
|
+
};
|
|
155
165
|
}
|
|
156
166
|
if (args[0] === 'scenes') {
|
|
157
|
-
|
|
167
|
+
const filters = normalizeFilters(args.slice(1));
|
|
168
|
+
return {
|
|
169
|
+
matched: true,
|
|
170
|
+
valid: true,
|
|
171
|
+
command: { kind: 'list', scope: 'scenes', ...(filters ? { filters } : {}) },
|
|
172
|
+
};
|
|
158
173
|
}
|
|
159
|
-
return {
|
|
174
|
+
return {
|
|
175
|
+
matched: true,
|
|
176
|
+
valid: false,
|
|
177
|
+
text: 'Usage: /bncr list <pending|scenes> [filters...]',
|
|
178
|
+
};
|
|
160
179
|
case 'history-limit':
|
|
161
180
|
if (args.length === 0) {
|
|
162
181
|
return { matched: true, valid: true, command: { kind: 'history-limit-get' } };
|
|
@@ -271,6 +290,30 @@ function formatSceneGroups(scenes: BncrSceneRecord[]): string {
|
|
|
271
290
|
.join('\n\n');
|
|
272
291
|
}
|
|
273
292
|
|
|
293
|
+
function buildSceneSearchHaystack(scene: BncrSceneRecord): string[] {
|
|
294
|
+
const parts: string[] = [
|
|
295
|
+
normalizeToken(scene.sceneKey),
|
|
296
|
+
normalizeToken(scene.platform),
|
|
297
|
+
normalizeToken(scene.status),
|
|
298
|
+
normalizeToken(scene.agentId ?? ''),
|
|
299
|
+
normalizeToken(scene.kind),
|
|
300
|
+
normalizeToken(scene.userId ?? ''),
|
|
301
|
+
normalizeToken(scene.userName ?? ''),
|
|
302
|
+
normalizeToken(scene.groupId ?? ''),
|
|
303
|
+
normalizeToken(scene.groupName ?? ''),
|
|
304
|
+
];
|
|
305
|
+
if (scene.kind === 'group') {
|
|
306
|
+
parts.push(scene.groupReplyMode || 'admin');
|
|
307
|
+
}
|
|
308
|
+
return parts.map((part) => part.toLowerCase()).filter(Boolean);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function matchesSceneFilters(scene: BncrSceneRecord, filters: string[] | undefined): boolean {
|
|
312
|
+
if (!filters?.length) return true;
|
|
313
|
+
const haystack = buildSceneSearchHaystack(scene);
|
|
314
|
+
return filters.every((filter) => haystack.some((part) => part.includes(filter)));
|
|
315
|
+
}
|
|
316
|
+
|
|
274
317
|
function applySceneStatus(scene: BncrSceneRecord, status: BncrSceneStatus): BncrSceneRecord {
|
|
275
318
|
return {
|
|
276
319
|
...scene,
|
|
@@ -299,11 +342,19 @@ export function executeSceneAdminCommand(args: {
|
|
|
299
342
|
if (command.kind === 'list') {
|
|
300
343
|
const scenes = Array.from(sceneRegistry.values())
|
|
301
344
|
.filter((scene) => (command.scope === 'pending' ? scene.status === 'pending' : true))
|
|
345
|
+
.filter((scene) => matchesSceneFilters(scene, command.filters))
|
|
302
346
|
.sort((a, b) => a.lastSeenAt - b.lastSeenAt);
|
|
303
347
|
if (scenes.length === 0) {
|
|
304
348
|
return {
|
|
305
349
|
ok: true,
|
|
306
|
-
text:
|
|
350
|
+
text:
|
|
351
|
+
command.scope === 'pending'
|
|
352
|
+
? command.filters?.length
|
|
353
|
+
? `No pending scenes matched: ${command.filters.join(' ')}`
|
|
354
|
+
: 'No pending scenes.'
|
|
355
|
+
: command.filters?.length
|
|
356
|
+
? `No scenes matched: ${command.filters.join(' ')}`
|
|
357
|
+
: 'No scenes recorded.',
|
|
307
358
|
};
|
|
308
359
|
}
|
|
309
360
|
return { ok: true, text: formatSceneGroups(scenes) };
|
|
@@ -220,6 +220,7 @@ export function buildBncrInboundTurnContext(args: {
|
|
|
220
220
|
reply: {
|
|
221
221
|
to: resolution.canonicalTo,
|
|
222
222
|
originatingTo: resolution.originatingTo,
|
|
223
|
+
rawTo: resolution.rawTo,
|
|
223
224
|
},
|
|
224
225
|
message: {
|
|
225
226
|
inboundEventKind: 'user_request',
|
|
@@ -265,6 +266,7 @@ export function buildBncrInboundTurnContext(args: {
|
|
|
265
266
|
},
|
|
266
267
|
extra: {
|
|
267
268
|
OriginatingChannel: channelId,
|
|
269
|
+
...(parsed.isGroup === true && parsed.groupName ? { GroupSubject: parsed.groupName } : {}),
|
|
268
270
|
...(ownerAllowFrom?.length ? { OwnerAllowFrom: ownerAllowFrom } : {}),
|
|
269
271
|
BncrStructuredContextFacts: structuredContextFacts,
|
|
270
272
|
StructuredContextFacts: structuredContextFacts,
|