neoagent 3.2.1-beta.12 → 3.2.1-beta.13
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/flutter_app/lib/main_app_shell.dart +178 -34
- package/flutter_app/lib/main_chat.dart +542 -80
- package/flutter_app/lib/main_controller.dart +13 -0
- package/flutter_app/lib/main_models.dart +167 -20
- package/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +76649 -76021
- package/server/services/behavior/modules/turn_taking.js +15 -14
- package/server/services/behavior/pipeline.js +24 -7
- package/server/services/messaging/access_policy.js +264 -73
- package/server/services/messaging/automation.js +1 -1
- package/server/services/messaging/http_platforms.js +69 -25
- package/server/services/messaging/manager.js +39 -5
|
@@ -131,6 +131,12 @@ function genericMessageFromWebhook(platform, config, req) {
|
|
|
131
131
|
const senderTag = jsonPath(body, config.senderTagPath || 'senderTag')
|
|
132
132
|
|| senderUsername
|
|
133
133
|
|| null;
|
|
134
|
+
const wasMentioned = config.mentionedPath
|
|
135
|
+
? jsonPath(body, config.mentionedPath) === true
|
|
136
|
+
: body.wasMentioned === true;
|
|
137
|
+
const repliedToAgent = config.repliedToAgentPath
|
|
138
|
+
? jsonPath(body, config.repliedToAgentPath) === true
|
|
139
|
+
: body.repliedToAgent === true;
|
|
134
140
|
|
|
135
141
|
if (!String(content || '').trim()) return null;
|
|
136
142
|
return {
|
|
@@ -143,6 +149,8 @@ function genericMessageFromWebhook(platform, config, req) {
|
|
|
143
149
|
content: String(content),
|
|
144
150
|
mediaType: null,
|
|
145
151
|
isGroup: Boolean(config.groupByDefault) || String(chatId) !== String(sender),
|
|
152
|
+
wasMentioned,
|
|
153
|
+
repliedToAgent,
|
|
146
154
|
messageId: jsonPath(body, config.messageIdPath || 'messageId') || crypto.randomUUID(),
|
|
147
155
|
timestamp: new Date().toISOString(),
|
|
148
156
|
rawMessage: body,
|
|
@@ -241,7 +249,7 @@ class ConfigurableHttpPlatform extends BasePlatform {
|
|
|
241
249
|
roomId: msg.isGroup ? String(msg.chatId || '') : '',
|
|
242
250
|
roleIds: [],
|
|
243
251
|
phoneNumber: '',
|
|
244
|
-
wasMentioned:
|
|
252
|
+
wasMentioned: msg.wasMentioned === true,
|
|
245
253
|
}, {
|
|
246
254
|
senderName: msg.senderName || null,
|
|
247
255
|
meta: msg.isGroup ? `Chat: ${msg.chatId}` : '',
|
|
@@ -403,7 +411,10 @@ class GoogleChatPlatform extends ConfigurableHttpPlatform {
|
|
|
403
411
|
const body = req.body || {};
|
|
404
412
|
const incoming = body.message || body;
|
|
405
413
|
const content = incoming.argumentText || incoming.text || body.text;
|
|
414
|
+
const wasMentioned = Boolean(String(incoming.argumentText || '').trim());
|
|
406
415
|
if (!content) return { handled: true, status: 202, body: 'ignored' };
|
|
416
|
+
const spaceType = String(incoming.space?.type || body.space?.type || '').toUpperCase();
|
|
417
|
+
const isGroup = spaceType !== 'DIRECT_MESSAGE';
|
|
407
418
|
const message = {
|
|
408
419
|
platform: 'google_chat',
|
|
409
420
|
chatId: String(incoming.space?.name || body.space?.name || this.config.defaultTo || 'google_chat'),
|
|
@@ -413,7 +424,8 @@ class GoogleChatPlatform extends ConfigurableHttpPlatform {
|
|
|
413
424
|
senderTag: body.user?.name || incoming.sender?.name || null,
|
|
414
425
|
content: String(content),
|
|
415
426
|
mediaType: null,
|
|
416
|
-
isGroup
|
|
427
|
+
isGroup,
|
|
428
|
+
wasMentioned,
|
|
417
429
|
messageId: String(incoming.name || crypto.randomUUID()),
|
|
418
430
|
timestamp: new Date().toISOString(),
|
|
419
431
|
rawMessage: body,
|
|
@@ -422,15 +434,15 @@ class GoogleChatPlatform extends ConfigurableHttpPlatform {
|
|
|
422
434
|
platform: 'google_chat',
|
|
423
435
|
senderId: message.sender,
|
|
424
436
|
chatId: message.chatId,
|
|
425
|
-
isDirect:
|
|
426
|
-
isShared:
|
|
437
|
+
isDirect: !isGroup,
|
|
438
|
+
isShared: isGroup,
|
|
427
439
|
groupId: '',
|
|
428
440
|
channelId: '',
|
|
429
441
|
serverId: '',
|
|
430
|
-
roomId: message.chatId,
|
|
442
|
+
roomId: isGroup ? message.chatId : '',
|
|
431
443
|
roleIds: [],
|
|
432
444
|
phoneNumber: '',
|
|
433
|
-
wasMentioned
|
|
445
|
+
wasMentioned,
|
|
434
446
|
}, {
|
|
435
447
|
senderName: message.senderName,
|
|
436
448
|
meta: `Space: ${message.chatId}`,
|
|
@@ -452,6 +464,14 @@ class TeamsPlatform extends ConfigurableHttpPlatform {
|
|
|
452
464
|
const body = req.body || {};
|
|
453
465
|
const content = body.text || body.message?.text || body.value?.text;
|
|
454
466
|
if (!content) return { handled: true, status: 202, body: 'ignored' };
|
|
467
|
+
const recipientId = String(body.recipient?.id || '').trim();
|
|
468
|
+
const wasMentioned = recipientId
|
|
469
|
+
? (Array.isArray(body.entities) ? body.entities : [])
|
|
470
|
+
.some((entity) => entity?.type === 'mention' && String(entity.mentioned?.id || '') === recipientId)
|
|
471
|
+
: false;
|
|
472
|
+
const isGroup = typeof body.conversation?.isGroup === 'boolean'
|
|
473
|
+
? body.conversation.isGroup
|
|
474
|
+
: true;
|
|
455
475
|
const message = {
|
|
456
476
|
platform: 'teams',
|
|
457
477
|
chatId: String(body.conversation?.id || body.channelData?.channel?.id || this.config.defaultTo || 'teams'),
|
|
@@ -461,7 +481,8 @@ class TeamsPlatform extends ConfigurableHttpPlatform {
|
|
|
461
481
|
senderTag: body.from?.id || null,
|
|
462
482
|
content: String(content).replace(/<[^>]+>/g, '').trim(),
|
|
463
483
|
mediaType: null,
|
|
464
|
-
isGroup
|
|
484
|
+
isGroup,
|
|
485
|
+
wasMentioned,
|
|
465
486
|
messageId: String(body.id || crypto.randomUUID()),
|
|
466
487
|
timestamp: body.timestamp || new Date().toISOString(),
|
|
467
488
|
rawMessage: body,
|
|
@@ -470,15 +491,15 @@ class TeamsPlatform extends ConfigurableHttpPlatform {
|
|
|
470
491
|
platform: 'teams',
|
|
471
492
|
senderId: message.sender,
|
|
472
493
|
chatId: message.chatId,
|
|
473
|
-
isDirect:
|
|
474
|
-
isShared:
|
|
494
|
+
isDirect: !isGroup,
|
|
495
|
+
isShared: isGroup,
|
|
475
496
|
groupId: '',
|
|
476
|
-
channelId: message.chatId,
|
|
497
|
+
channelId: isGroup ? message.chatId : '',
|
|
477
498
|
serverId: '',
|
|
478
499
|
roomId: '',
|
|
479
500
|
roleIds: [],
|
|
480
501
|
phoneNumber: '',
|
|
481
|
-
wasMentioned
|
|
502
|
+
wasMentioned,
|
|
482
503
|
}, {
|
|
483
504
|
senderName: message.senderName,
|
|
484
505
|
meta: `Conversation: ${message.chatId}`,
|
|
@@ -564,8 +585,8 @@ class MatrixPlatform extends BasePlatform {
|
|
|
564
585
|
if (event.sender && this.userId && event.sender === this.userId) continue;
|
|
565
586
|
const content = event.content?.body || '';
|
|
566
587
|
if (!content) continue;
|
|
567
|
-
|
|
568
|
-
const cleanContent =
|
|
588
|
+
const wasMentioned = this.userId ? String(content).includes(this.userId) : false;
|
|
589
|
+
const cleanContent = wasMentioned
|
|
569
590
|
? String(content).replaceAll(this.userId, '').trim()
|
|
570
591
|
: String(content);
|
|
571
592
|
if (!cleanContent) continue;
|
|
@@ -579,6 +600,7 @@ class MatrixPlatform extends BasePlatform {
|
|
|
579
600
|
content: cleanContent,
|
|
580
601
|
mediaType: null,
|
|
581
602
|
isGroup: true,
|
|
603
|
+
wasMentioned,
|
|
582
604
|
messageId: String(event.event_id || crypto.randomUUID()),
|
|
583
605
|
timestamp: event.origin_server_ts ? new Date(event.origin_server_ts).toISOString() : new Date().toISOString(),
|
|
584
606
|
rawMessage: event,
|
|
@@ -595,7 +617,7 @@ class MatrixPlatform extends BasePlatform {
|
|
|
595
617
|
roomId: roomId,
|
|
596
618
|
roleIds: [],
|
|
597
619
|
phoneNumber: '',
|
|
598
|
-
wasMentioned
|
|
620
|
+
wasMentioned,
|
|
599
621
|
}, {
|
|
600
622
|
senderName: message.senderName,
|
|
601
623
|
meta: `Room: ${roomId}`,
|
|
@@ -692,16 +714,37 @@ class SignalPlatform extends ConfigurableHttpPlatform {
|
|
|
692
714
|
const dataMessage = envelope.dataMessage || {};
|
|
693
715
|
const content = dataMessage.message || '';
|
|
694
716
|
if (!content) continue;
|
|
717
|
+
const groupId = String(
|
|
718
|
+
dataMessage.groupInfo?.groupId
|
|
719
|
+
|| dataMessage.groupInfo?.groupIdV2
|
|
720
|
+
|| dataMessage.groupInfo?.id
|
|
721
|
+
|| '',
|
|
722
|
+
);
|
|
723
|
+
const isGroup = Boolean(dataMessage.groupInfo);
|
|
724
|
+
const senderId = String(envelope.sourceNumber || envelope.source || 'signal');
|
|
725
|
+
const mentionedSelf = (Array.isArray(dataMessage.mentions) ? dataMessage.mentions : [])
|
|
726
|
+
.some((mention) => [
|
|
727
|
+
mention?.number,
|
|
728
|
+
mention?.uuid,
|
|
729
|
+
mention?.aci,
|
|
730
|
+
].map(String).includes(String(this.account)));
|
|
731
|
+
const repliedToAgent = [
|
|
732
|
+
dataMessage.quote?.authorNumber,
|
|
733
|
+
dataMessage.quote?.author,
|
|
734
|
+
dataMessage.quote?.authorUuid,
|
|
735
|
+
].map(String).includes(String(this.account));
|
|
695
736
|
const message = {
|
|
696
737
|
platform: 'signal',
|
|
697
|
-
chatId:
|
|
698
|
-
sender:
|
|
738
|
+
chatId: groupId || senderId,
|
|
739
|
+
sender: senderId,
|
|
699
740
|
senderName: envelope.sourceName || null,
|
|
700
741
|
senderDisplayName: envelope.sourceName || null,
|
|
701
742
|
senderTag: envelope.sourceNumber || envelope.source || null,
|
|
702
743
|
content: String(content),
|
|
703
744
|
mediaType: null,
|
|
704
|
-
isGroup
|
|
745
|
+
isGroup,
|
|
746
|
+
wasMentioned: Boolean(mentionedSelf),
|
|
747
|
+
repliedToAgent: Boolean(repliedToAgent),
|
|
705
748
|
messageId: String(envelope.timestamp || crypto.randomUUID()),
|
|
706
749
|
timestamp: envelope.timestamp ? new Date(Number(envelope.timestamp)).toISOString() : new Date().toISOString(),
|
|
707
750
|
rawMessage: item,
|
|
@@ -712,13 +755,13 @@ class SignalPlatform extends ConfigurableHttpPlatform {
|
|
|
712
755
|
chatId: message.chatId,
|
|
713
756
|
isDirect: !message.isGroup,
|
|
714
757
|
isShared: message.isGroup,
|
|
715
|
-
groupId: message.isGroup ? message.chatId : '',
|
|
758
|
+
groupId: message.isGroup ? (groupId || message.chatId) : '',
|
|
716
759
|
channelId: '',
|
|
717
760
|
serverId: '',
|
|
718
761
|
roomId: '',
|
|
719
762
|
roleIds: [],
|
|
720
763
|
phoneNumber: message.sender,
|
|
721
|
-
wasMentioned:
|
|
764
|
+
wasMentioned: message.wasMentioned,
|
|
722
765
|
}, {
|
|
723
766
|
senderName: message.senderName,
|
|
724
767
|
meta: message.isGroup ? `Group: ${message.chatId}` : '',
|
|
@@ -789,6 +832,7 @@ class LinePlatform extends ConfigurableHttpPlatform {
|
|
|
789
832
|
content: String(content),
|
|
790
833
|
mediaType: null,
|
|
791
834
|
isGroup: Boolean(event.source?.groupId || event.source?.roomId),
|
|
835
|
+
wasMentioned: false,
|
|
792
836
|
messageId: String(event.message?.id || event.webhookEventId || crypto.randomUUID()),
|
|
793
837
|
timestamp: event.timestamp ? new Date(Number(event.timestamp)).toISOString() : new Date().toISOString(),
|
|
794
838
|
rawMessage: event,
|
|
@@ -951,11 +995,10 @@ class IrcPlatform extends BasePlatform {
|
|
|
951
995
|
const [, nick, target, content] = match;
|
|
952
996
|
if (nick === this.nick) continue;
|
|
953
997
|
const isGroup = target.startsWith('#');
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
const cleanContent = isGroup
|
|
998
|
+
const escapedNick = this.nick.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
999
|
+
const wasMentioned = isGroup
|
|
1000
|
+
&& new RegExp(`(^|\\s)${escapedNick}[:,]?\\b`, 'i').test(content);
|
|
1001
|
+
const cleanContent = wasMentioned
|
|
959
1002
|
? content.replace(new RegExp(`(^|\\s)${this.nick.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[:,]?\\s*`, 'i'), ' ').trim()
|
|
960
1003
|
: content;
|
|
961
1004
|
if (!cleanContent) continue;
|
|
@@ -969,6 +1012,7 @@ class IrcPlatform extends BasePlatform {
|
|
|
969
1012
|
content: cleanContent,
|
|
970
1013
|
mediaType: null,
|
|
971
1014
|
isGroup,
|
|
1015
|
+
wasMentioned,
|
|
972
1016
|
messageId: crypto.randomUUID(),
|
|
973
1017
|
timestamp: new Date().toISOString(),
|
|
974
1018
|
};
|
|
@@ -984,7 +1028,7 @@ class IrcPlatform extends BasePlatform {
|
|
|
984
1028
|
roomId: '',
|
|
985
1029
|
roleIds: [],
|
|
986
1030
|
phoneNumber: '',
|
|
987
|
-
wasMentioned
|
|
1031
|
+
wasMentioned,
|
|
988
1032
|
}, {
|
|
989
1033
|
senderName: nick,
|
|
990
1034
|
meta: isGroup ? `Channel: ${target}` : '',
|
|
@@ -190,9 +190,13 @@ class MessagingManager extends EventEmitter {
|
|
|
190
190
|
wasMentioned: msg.wasMentioned === true,
|
|
191
191
|
repliedToAgent: msg.repliedToAgent === true,
|
|
192
192
|
groupId: msg.groupId || null,
|
|
193
|
+
groupName: msg.groupName || null,
|
|
193
194
|
channelId: msg.channelId || null,
|
|
195
|
+
channelName: msg.channelName || null,
|
|
194
196
|
serverId: msg.serverId || msg.guildId || null,
|
|
197
|
+
serverName: msg.serverName || msg.guildName || null,
|
|
195
198
|
roomId: msg.roomId || null,
|
|
199
|
+
roomName: msg.roomName || null,
|
|
196
200
|
roleIds: Array.isArray(msg.roleIds) ? msg.roleIds.map(String) : [],
|
|
197
201
|
mediaType: msg.mediaType,
|
|
198
202
|
localMediaPath: msg.localMediaPath || null,
|
|
@@ -409,7 +413,13 @@ class MessagingManager extends EventEmitter {
|
|
|
409
413
|
const unique = [];
|
|
410
414
|
const seen = new Set();
|
|
411
415
|
for (const item of merged) {
|
|
412
|
-
const id =
|
|
416
|
+
const id = [
|
|
417
|
+
item.bucket,
|
|
418
|
+
item.rule.scope,
|
|
419
|
+
item.rule.value,
|
|
420
|
+
item.rule.spaceScope || '',
|
|
421
|
+
item.rule.spaceValue || '',
|
|
422
|
+
].join(':');
|
|
413
423
|
if (seen.has(id)) continue;
|
|
414
424
|
seen.add(id);
|
|
415
425
|
unique.push(item);
|
|
@@ -1123,7 +1133,22 @@ class MessagingManager extends EventEmitter {
|
|
|
1123
1133
|
|
|
1124
1134
|
async getAccessCatalog(userId, platformName, options = {}) {
|
|
1125
1135
|
const agentId = this._agentId(userId, options);
|
|
1126
|
-
const
|
|
1136
|
+
const capabilities = getPlatformAccessCapabilities(platformName);
|
|
1137
|
+
const normalizeTargetBucket = (target) => (
|
|
1138
|
+
target?.bucket === 'directRules'
|
|
1139
|
+
&& capabilities.supportsSharedPolicy
|
|
1140
|
+
&& capabilities.sharedActorRuleScopes.includes(target.scope)
|
|
1141
|
+
? { ...target, bucket: 'sharedActorRules' }
|
|
1142
|
+
: target
|
|
1143
|
+
);
|
|
1144
|
+
const listedTargets = await this.listAccessTargets(
|
|
1145
|
+
userId,
|
|
1146
|
+
platformName,
|
|
1147
|
+
{ agentId },
|
|
1148
|
+
);
|
|
1149
|
+
const discoveredTargets = (
|
|
1150
|
+
Array.isArray(listedTargets) ? listedTargets : []
|
|
1151
|
+
).map(normalizeTargetBucket);
|
|
1127
1152
|
|
|
1128
1153
|
const recentRows = db.prepare(
|
|
1129
1154
|
`SELECT platform_chat_id, metadata
|
|
@@ -1140,20 +1165,29 @@ class MessagingManager extends EventEmitter {
|
|
|
1140
1165
|
} catch {
|
|
1141
1166
|
metadata = {};
|
|
1142
1167
|
}
|
|
1143
|
-
return
|
|
1168
|
+
return normalizeTargetBucket(
|
|
1169
|
+
classifyRecentTarget(platformName, { ...row, metadata }),
|
|
1170
|
+
);
|
|
1144
1171
|
})
|
|
1145
1172
|
.filter(Boolean);
|
|
1146
1173
|
|
|
1147
1174
|
const seen = new Set();
|
|
1148
1175
|
const unique = (items) => items.filter((item) => {
|
|
1149
|
-
const
|
|
1176
|
+
const rule = item?.rule || item || {};
|
|
1177
|
+
const keyValue = [
|
|
1178
|
+
item?.bucket,
|
|
1179
|
+
rule.scope,
|
|
1180
|
+
rule.value,
|
|
1181
|
+
rule.spaceScope || '',
|
|
1182
|
+
rule.spaceValue || '',
|
|
1183
|
+
].join(':');
|
|
1150
1184
|
if (seen.has(keyValue)) return false;
|
|
1151
1185
|
seen.add(keyValue);
|
|
1152
1186
|
return true;
|
|
1153
1187
|
});
|
|
1154
1188
|
|
|
1155
1189
|
return {
|
|
1156
|
-
capabilities
|
|
1190
|
+
capabilities,
|
|
1157
1191
|
discoveredTargets: unique([...(Array.isArray(discoveredTargets) ? discoveredTargets : []), ...recentTargets]),
|
|
1158
1192
|
suggestedTargets: unique(this.accessSuggestions.get(this._accessSuggestionKey(userId, agentId, platformName)) || []),
|
|
1159
1193
|
policy: this._loadAccessPolicy(userId, agentId, platformName),
|