neoagent 3.2.1-beta.8 → 3.3.0
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 +59 -4
- package/flutter_app/lib/main_models.dart +171 -22
- package/flutter_app/lib/main_operations.dart +0 -49
- package/flutter_app/lib/main_settings.dart +338 -0
- package/flutter_app/lib/src/backend_client.dart +19 -0
- package/package.json +1 -1
- package/server/db/database.js +2 -2
- package/server/http/routes.js +1 -0
- 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 +85079 -83904
- package/server/routes/behavior.js +80 -0
- package/server/routes/settings.js +4 -0
- package/server/services/agents/manager.js +1 -1
- package/server/services/ai/history.js +1 -1
- package/server/services/ai/loop/agent_engine_core.js +131 -18
- package/server/services/ai/loop/blank_recovery.js +5 -4
- package/server/services/ai/loop/completion_judge.js +280 -18
- package/server/services/ai/loop/conversation_loop.js +92 -34
- package/server/services/ai/loop/messaging_delivery.js +47 -0
- package/server/services/ai/loop/progress_classification.js +2 -0
- package/server/services/ai/loopPolicy.js +24 -2
- package/server/services/ai/messagingFallback.js +17 -17
- package/server/services/ai/model_failure_cache.js +7 -0
- package/server/services/ai/systemPrompt.js +31 -122
- package/server/services/ai/taskAnalysis.js +101 -12
- package/server/services/ai/toolEvidence.js +198 -0
- package/server/services/ai/tools.js +60 -19
- package/server/services/behavior/config.js +251 -0
- package/server/services/behavior/defaults.js +68 -0
- package/server/services/behavior/delivery.js +176 -0
- package/server/services/behavior/index.js +43 -0
- package/server/services/behavior/model_client.js +35 -0
- package/server/services/behavior/modules/agent_identity.js +37 -0
- package/server/services/behavior/modules/channel_style.js +28 -0
- package/server/services/behavior/modules/index.js +29 -0
- package/server/services/behavior/modules/norms.js +101 -0
- package/server/services/behavior/modules/persona.js +172 -0
- package/server/services/behavior/modules/persona_prompt.js +238 -0
- package/server/services/behavior/modules/social_memory.js +86 -0
- package/server/services/behavior/modules/social_observability.js +94 -0
- package/server/services/behavior/modules/social_signals.js +41 -0
- package/server/services/behavior/modules/theory_of_mind.js +118 -0
- package/server/services/behavior/modules/turn_taking.js +238 -0
- package/server/services/behavior/pipeline.js +341 -0
- package/server/services/behavior/registry.js +78 -0
- package/server/services/behavior/signals.js +107 -0
- package/server/services/behavior/state.js +99 -0
- package/server/services/behavior/system_prompt.js +75 -0
- package/server/services/memory/manager.js +14 -33
- package/server/services/messaging/access_policy.js +269 -74
- package/server/services/messaging/automation.js +158 -27
- package/server/services/messaging/discord.js +11 -1
- package/server/services/messaging/formatting_guides.js +5 -4
- package/server/services/messaging/http_platforms.js +73 -28
- package/server/services/messaging/inbound_queue.js +74 -13
- package/server/services/messaging/inbound_store.js +33 -0
- package/server/services/messaging/manager.js +57 -5
- package/server/services/messaging/telegram.js +10 -1
- package/server/services/messaging/whatsapp.js +11 -0
- package/server/services/social_reach/channels/social_video.js +1 -1
- package/server/services/social_video/captions.js +2 -2
- package/server/services/social_video/service.js +194 -29
- package/server/services/voice/message.js +1 -1
- package/server/services/voice/runtime.js +2 -2
- package/server/utils/logger.js +19 -0
- package/server/services/ai/terminal_reply.js +0 -57
|
@@ -132,6 +132,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
132
132
|
const <LinkedAuthProviderItem>[];
|
|
133
133
|
QrLoginChallenge? qrLoginChallenge;
|
|
134
134
|
Map<String, dynamic> settings = const <String, dynamic>{};
|
|
135
|
+
Map<String, dynamic> behaviorConfig = const <String, dynamic>{};
|
|
135
136
|
Map<String, dynamic>? versionInfo;
|
|
136
137
|
Map<String, dynamic>? backendHealthStatus;
|
|
137
138
|
HealthBridgeStatus? deviceHealthStatus;
|
|
@@ -1420,6 +1421,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
1420
1421
|
usageAndLimits = null;
|
|
1421
1422
|
linkedAuthProviders = const <LinkedAuthProviderItem>[];
|
|
1422
1423
|
settings = const <String, dynamic>{};
|
|
1424
|
+
behaviorConfig = const <String, dynamic>{};
|
|
1423
1425
|
chatMessages = const <ChatEntry>[];
|
|
1424
1426
|
_resetChatHistoryPagination();
|
|
1425
1427
|
agentProfiles = const <AgentProfile>[];
|
|
@@ -1764,6 +1766,9 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
1764
1766
|
);
|
|
1765
1767
|
case 'sharedActorRules':
|
|
1766
1768
|
return policy.copyWith(
|
|
1769
|
+
directPolicy: policy.directPolicy == 'disabled'
|
|
1770
|
+
? 'allowlist'
|
|
1771
|
+
: policy.directPolicy,
|
|
1767
1772
|
sharedPolicy: policy.sharedPolicy == 'disabled'
|
|
1768
1773
|
? 'allowlist'
|
|
1769
1774
|
: policy.sharedPolicy,
|
|
@@ -1772,6 +1777,16 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
1772
1777
|
suggestion.rule,
|
|
1773
1778
|
]),
|
|
1774
1779
|
);
|
|
1780
|
+
case 'sharedMemberRules':
|
|
1781
|
+
return policy.copyWith(
|
|
1782
|
+
sharedPolicy: policy.sharedPolicy == 'disabled'
|
|
1783
|
+
? 'allowlist'
|
|
1784
|
+
: policy.sharedPolicy,
|
|
1785
|
+
sharedMemberRules: _dedupeAccessRules(<MessagingAccessRule>[
|
|
1786
|
+
...policy.sharedMemberRules,
|
|
1787
|
+
suggestion.rule,
|
|
1788
|
+
]),
|
|
1789
|
+
);
|
|
1775
1790
|
default:
|
|
1776
1791
|
return policy.copyWith(
|
|
1777
1792
|
sharedPolicy: policy.sharedPolicy == 'disabled'
|
|
@@ -1958,6 +1973,11 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
1958
1973
|
_backendClient.fetchSettings(backendUrl, agentId: agentId),
|
|
1959
1974
|
const <String, dynamic>{},
|
|
1960
1975
|
);
|
|
1976
|
+
final behaviorFuture = _softRefreshLoad<Map<String, dynamic>>(
|
|
1977
|
+
'behavior_config',
|
|
1978
|
+
_backendClient.fetchBehaviorConfig(backendUrl, agentId: agentId),
|
|
1979
|
+
const <String, dynamic>{},
|
|
1980
|
+
);
|
|
1961
1981
|
final runsFuture = _softRefreshLoad<Map<String, dynamic>>(
|
|
1962
1982
|
'runs',
|
|
1963
1983
|
_backendClient.fetchRuns(backendUrl, agentId: agentId),
|
|
@@ -2094,6 +2114,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2094
2114
|
final modelsResponse = await modelsFuture;
|
|
2095
2115
|
final providersResponse = await providersFuture;
|
|
2096
2116
|
final settingsResponse = await settingsFuture;
|
|
2117
|
+
final behaviorResponse = await behaviorFuture;
|
|
2097
2118
|
final runsResponse = await runsFuture;
|
|
2098
2119
|
final timelineResponse = await timelineFuture;
|
|
2099
2120
|
final versionResponse = await versionFuture;
|
|
@@ -2137,6 +2158,9 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2137
2158
|
);
|
|
2138
2159
|
|
|
2139
2160
|
settings = Map<String, dynamic>.from(settingsResponse);
|
|
2161
|
+
behaviorConfig = behaviorResponse['config'] is Map
|
|
2162
|
+
? Map<String, dynamic>.from(behaviorResponse['config'] as Map)
|
|
2163
|
+
: const <String, dynamic>{};
|
|
2140
2164
|
recentRuns = _decodeModelList(
|
|
2141
2165
|
'runs',
|
|
2142
2166
|
runsResponse['runs'],
|
|
@@ -4221,6 +4245,27 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
4221
4245
|
}
|
|
4222
4246
|
}
|
|
4223
4247
|
|
|
4248
|
+
Future<void> saveBehaviorConfig(Map<String, dynamic> config) async {
|
|
4249
|
+
isSavingSettings = true;
|
|
4250
|
+
errorMessage = null;
|
|
4251
|
+
notifyListeners();
|
|
4252
|
+
try {
|
|
4253
|
+
final response = await _backendClient.saveBehaviorConfig(
|
|
4254
|
+
backendUrl,
|
|
4255
|
+
config,
|
|
4256
|
+
agentId: _scopedAgentId,
|
|
4257
|
+
);
|
|
4258
|
+
behaviorConfig = response['config'] is Map
|
|
4259
|
+
? Map<String, dynamic>.from(response['config'] as Map)
|
|
4260
|
+
: Map<String, dynamic>.from(config);
|
|
4261
|
+
} catch (error) {
|
|
4262
|
+
errorMessage = _friendlyErrorMessage(error);
|
|
4263
|
+
} finally {
|
|
4264
|
+
isSavingSettings = false;
|
|
4265
|
+
notifyListeners();
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
|
|
4224
4269
|
void _applyAccountResponse(Map<String, dynamic> response) {
|
|
4225
4270
|
if (response['user'] is Map) {
|
|
4226
4271
|
user = Map<String, dynamic>.from(response['user'] as Map);
|
|
@@ -5338,10 +5383,20 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
5338
5383
|
}
|
|
5339
5384
|
|
|
5340
5385
|
Future<void> updateAssistantBehaviorNotes(String content) async {
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5386
|
+
isSavingSettings = true;
|
|
5387
|
+
errorMessage = null;
|
|
5388
|
+
notifyListeners();
|
|
5389
|
+
try {
|
|
5390
|
+
await _backendClient.saveSettings(backendUrl, <String, dynamic>{
|
|
5391
|
+
'assistant_behavior_notes': content,
|
|
5392
|
+
}, agentId: _scopedAgentId);
|
|
5393
|
+
await refreshMemory();
|
|
5394
|
+
} catch (error) {
|
|
5395
|
+
errorMessage = _friendlyErrorMessage(error);
|
|
5396
|
+
} finally {
|
|
5397
|
+
isSavingSettings = false;
|
|
5398
|
+
notifyListeners();
|
|
5399
|
+
}
|
|
5345
5400
|
}
|
|
5346
5401
|
|
|
5347
5402
|
Future<void> updateCoreMemory(String key, String value) async {
|
|
@@ -719,6 +719,9 @@ class MessagingAccessRule {
|
|
|
719
719
|
required this.scope,
|
|
720
720
|
required this.value,
|
|
721
721
|
this.label,
|
|
722
|
+
this.spaceScope,
|
|
723
|
+
this.spaceValue,
|
|
724
|
+
this.spaceLabel,
|
|
722
725
|
});
|
|
723
726
|
|
|
724
727
|
factory MessagingAccessRule.fromJson(Map<String, dynamic> json) {
|
|
@@ -726,23 +729,38 @@ class MessagingAccessRule {
|
|
|
726
729
|
scope: json['scope']?.toString() ?? 'chat',
|
|
727
730
|
value: json['value']?.toString() ?? '',
|
|
728
731
|
label: json['label']?.toString(),
|
|
732
|
+
spaceScope: json['spaceScope']?.toString(),
|
|
733
|
+
spaceValue: json['spaceValue']?.toString(),
|
|
734
|
+
spaceLabel: json['spaceLabel']?.toString(),
|
|
729
735
|
);
|
|
730
736
|
}
|
|
731
737
|
|
|
732
738
|
final String scope;
|
|
733
739
|
final String value;
|
|
734
740
|
final String? label;
|
|
741
|
+
final String? spaceScope;
|
|
742
|
+
final String? spaceValue;
|
|
743
|
+
final String? spaceLabel;
|
|
735
744
|
|
|
736
745
|
Map<String, dynamic> toJson() => <String, dynamic>{
|
|
737
746
|
'scope': scope,
|
|
738
747
|
'value': value,
|
|
739
748
|
if (label != null && label!.trim().isNotEmpty) 'label': label,
|
|
749
|
+
if (spaceScope != null && spaceScope!.trim().isNotEmpty)
|
|
750
|
+
'spaceScope': spaceScope,
|
|
751
|
+
if (spaceValue != null && spaceValue!.trim().isNotEmpty)
|
|
752
|
+
'spaceValue': spaceValue,
|
|
753
|
+
if (spaceLabel != null && spaceLabel!.trim().isNotEmpty)
|
|
754
|
+
'spaceLabel': spaceLabel,
|
|
740
755
|
};
|
|
741
756
|
|
|
742
|
-
String get id => '$scope:$value';
|
|
757
|
+
String get id => '$scope:$value:${spaceScope ?? ''}:${spaceValue ?? ''}';
|
|
743
758
|
|
|
744
759
|
String get displayLabel => label?.ifEmpty(value) ?? value;
|
|
745
760
|
|
|
761
|
+
String get spaceDisplayLabel =>
|
|
762
|
+
spaceLabel?.ifEmpty(spaceValue ?? '') ?? spaceValue ?? '';
|
|
763
|
+
|
|
746
764
|
String get scopeLabel {
|
|
747
765
|
switch (scope) {
|
|
748
766
|
case 'phone_number':
|
|
@@ -767,23 +785,63 @@ class MessagingAccessRule {
|
|
|
767
785
|
}
|
|
768
786
|
}
|
|
769
787
|
|
|
788
|
+
class MessagingSharedParticipationRule {
|
|
789
|
+
const MessagingSharedParticipationRule({
|
|
790
|
+
required this.scope,
|
|
791
|
+
required this.value,
|
|
792
|
+
required this.allowUntagged,
|
|
793
|
+
this.label,
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
factory MessagingSharedParticipationRule.fromJson(Map<String, dynamic> json) {
|
|
797
|
+
return MessagingSharedParticipationRule(
|
|
798
|
+
scope: json['scope']?.toString() ?? 'chat',
|
|
799
|
+
value: json['value']?.toString() ?? '',
|
|
800
|
+
allowUntagged: json['allowUntagged'] == true,
|
|
801
|
+
label: json['label']?.toString(),
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
final String scope;
|
|
806
|
+
final String value;
|
|
807
|
+
final bool allowUntagged;
|
|
808
|
+
final String? label;
|
|
809
|
+
|
|
810
|
+
String get id => '$scope:$value';
|
|
811
|
+
String get displayLabel => label?.ifEmpty(value) ?? value;
|
|
812
|
+
|
|
813
|
+
Map<String, dynamic> toJson() => <String, dynamic>{
|
|
814
|
+
'scope': scope,
|
|
815
|
+
'value': value,
|
|
816
|
+
'allowUntagged': allowUntagged,
|
|
817
|
+
if (label != null && label!.trim().isNotEmpty) 'label': label,
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
|
|
770
821
|
class MessagingAccessPolicy {
|
|
771
822
|
const MessagingAccessPolicy({
|
|
823
|
+
required this.schemaVersion,
|
|
772
824
|
required this.directPolicy,
|
|
773
825
|
required this.sharedPolicy,
|
|
774
|
-
required this.
|
|
826
|
+
required this.defaultAllowUntaggedInShared,
|
|
775
827
|
required this.directRules,
|
|
776
828
|
required this.sharedSpaceRules,
|
|
777
829
|
required this.sharedActorRules,
|
|
830
|
+
required this.sharedMemberRules,
|
|
831
|
+
required this.sharedParticipationRules,
|
|
778
832
|
});
|
|
779
833
|
|
|
780
834
|
factory MessagingAccessPolicy.fromJson(Map<String, dynamic> json) {
|
|
835
|
+
final schemaVersion = (json['schemaVersion'] as num?)?.toInt() ?? 2;
|
|
781
836
|
return MessagingAccessPolicy(
|
|
837
|
+
schemaVersion: schemaVersion,
|
|
782
838
|
directPolicy:
|
|
783
839
|
json['directPolicy']?.toString().ifEmpty('allowlist') ?? 'allowlist',
|
|
784
840
|
sharedPolicy:
|
|
785
841
|
json['sharedPolicy']?.toString().ifEmpty('allowlist') ?? 'allowlist',
|
|
786
|
-
|
|
842
|
+
defaultAllowUntaggedInShared: schemaVersion < 3
|
|
843
|
+
? json['requireMentionInShared'] != true
|
|
844
|
+
: json['defaultAllowUntaggedInShared'] != false,
|
|
787
845
|
directRules:
|
|
788
846
|
(json['directRules'] is List
|
|
789
847
|
? json['directRules'] as List
|
|
@@ -817,48 +875,85 @@ class MessagingAccessPolicy {
|
|
|
817
875
|
),
|
|
818
876
|
)
|
|
819
877
|
.toList(growable: false),
|
|
878
|
+
sharedMemberRules:
|
|
879
|
+
(json['sharedMemberRules'] is List
|
|
880
|
+
? json['sharedMemberRules'] as List
|
|
881
|
+
: const <dynamic>[])
|
|
882
|
+
.whereType<Map>()
|
|
883
|
+
.map(
|
|
884
|
+
(item) => MessagingAccessRule.fromJson(
|
|
885
|
+
Map<String, dynamic>.from(item),
|
|
886
|
+
),
|
|
887
|
+
)
|
|
888
|
+
.toList(growable: false),
|
|
889
|
+
sharedParticipationRules:
|
|
890
|
+
(json['sharedParticipationRules'] is List
|
|
891
|
+
? json['sharedParticipationRules'] as List
|
|
892
|
+
: const <dynamic>[])
|
|
893
|
+
.whereType<Map>()
|
|
894
|
+
.map(
|
|
895
|
+
(item) => MessagingSharedParticipationRule.fromJson(
|
|
896
|
+
Map<String, dynamic>.from(item),
|
|
897
|
+
),
|
|
898
|
+
)
|
|
899
|
+
.where((item) => item.value.isNotEmpty)
|
|
900
|
+
.toList(growable: false),
|
|
820
901
|
);
|
|
821
902
|
}
|
|
822
903
|
|
|
823
904
|
const MessagingAccessPolicy.defaults({
|
|
905
|
+
this.schemaVersion = 3,
|
|
824
906
|
this.directPolicy = 'allowlist',
|
|
825
907
|
this.sharedPolicy = 'allowlist',
|
|
826
|
-
this.
|
|
908
|
+
this.defaultAllowUntaggedInShared = true,
|
|
827
909
|
this.directRules = const <MessagingAccessRule>[],
|
|
828
910
|
this.sharedSpaceRules = const <MessagingAccessRule>[],
|
|
829
911
|
this.sharedActorRules = const <MessagingAccessRule>[],
|
|
912
|
+
this.sharedMemberRules = const <MessagingAccessRule>[],
|
|
913
|
+
this.sharedParticipationRules = const <MessagingSharedParticipationRule>[],
|
|
830
914
|
});
|
|
831
915
|
|
|
916
|
+
final int schemaVersion;
|
|
832
917
|
final String directPolicy;
|
|
833
918
|
final String sharedPolicy;
|
|
834
|
-
final bool
|
|
919
|
+
final bool defaultAllowUntaggedInShared;
|
|
835
920
|
final List<MessagingAccessRule> directRules;
|
|
836
921
|
final List<MessagingAccessRule> sharedSpaceRules;
|
|
837
922
|
final List<MessagingAccessRule> sharedActorRules;
|
|
923
|
+
final List<MessagingAccessRule> sharedMemberRules;
|
|
924
|
+
final List<MessagingSharedParticipationRule> sharedParticipationRules;
|
|
838
925
|
|
|
839
926
|
MessagingAccessPolicy copyWith({
|
|
927
|
+
int? schemaVersion,
|
|
840
928
|
String? directPolicy,
|
|
841
929
|
String? sharedPolicy,
|
|
842
|
-
bool?
|
|
930
|
+
bool? defaultAllowUntaggedInShared,
|
|
843
931
|
List<MessagingAccessRule>? directRules,
|
|
844
932
|
List<MessagingAccessRule>? sharedSpaceRules,
|
|
845
933
|
List<MessagingAccessRule>? sharedActorRules,
|
|
934
|
+
List<MessagingAccessRule>? sharedMemberRules,
|
|
935
|
+
List<MessagingSharedParticipationRule>? sharedParticipationRules,
|
|
846
936
|
}) {
|
|
847
937
|
return MessagingAccessPolicy(
|
|
938
|
+
schemaVersion: schemaVersion ?? this.schemaVersion,
|
|
848
939
|
directPolicy: directPolicy ?? this.directPolicy,
|
|
849
940
|
sharedPolicy: sharedPolicy ?? this.sharedPolicy,
|
|
850
|
-
|
|
851
|
-
|
|
941
|
+
defaultAllowUntaggedInShared:
|
|
942
|
+
defaultAllowUntaggedInShared ?? this.defaultAllowUntaggedInShared,
|
|
852
943
|
directRules: directRules ?? this.directRules,
|
|
853
944
|
sharedSpaceRules: sharedSpaceRules ?? this.sharedSpaceRules,
|
|
854
945
|
sharedActorRules: sharedActorRules ?? this.sharedActorRules,
|
|
946
|
+
sharedMemberRules: sharedMemberRules ?? this.sharedMemberRules,
|
|
947
|
+
sharedParticipationRules:
|
|
948
|
+
sharedParticipationRules ?? this.sharedParticipationRules,
|
|
855
949
|
);
|
|
856
950
|
}
|
|
857
951
|
|
|
858
952
|
Map<String, dynamic> toJson() => <String, dynamic>{
|
|
953
|
+
'schemaVersion': schemaVersion,
|
|
859
954
|
'directPolicy': directPolicy,
|
|
860
955
|
'sharedPolicy': sharedPolicy,
|
|
861
|
-
'
|
|
956
|
+
'defaultAllowUntaggedInShared': defaultAllowUntaggedInShared,
|
|
862
957
|
'directRules': directRules
|
|
863
958
|
.map((rule) => rule.toJson())
|
|
864
959
|
.toList(growable: false),
|
|
@@ -868,10 +963,19 @@ class MessagingAccessPolicy {
|
|
|
868
963
|
'sharedActorRules': sharedActorRules
|
|
869
964
|
.map((rule) => rule.toJson())
|
|
870
965
|
.toList(growable: false),
|
|
966
|
+
'sharedMemberRules': sharedMemberRules
|
|
967
|
+
.map((rule) => rule.toJson())
|
|
968
|
+
.toList(growable: false),
|
|
969
|
+
'sharedParticipationRules': sharedParticipationRules
|
|
970
|
+
.map((rule) => rule.toJson())
|
|
971
|
+
.toList(growable: false),
|
|
871
972
|
};
|
|
872
973
|
|
|
873
974
|
int get totalRuleCount =>
|
|
874
|
-
directRules.length +
|
|
975
|
+
directRules.length +
|
|
976
|
+
sharedSpaceRules.length +
|
|
977
|
+
sharedActorRules.length +
|
|
978
|
+
sharedMemberRules.length;
|
|
875
979
|
}
|
|
876
980
|
|
|
877
981
|
class MessagingAccessCapabilities {
|
|
@@ -879,6 +983,7 @@ class MessagingAccessCapabilities {
|
|
|
879
983
|
this.supportsDirectPolicy = true,
|
|
880
984
|
this.supportsSharedPolicy = true,
|
|
881
985
|
this.supportsMentionGate = false,
|
|
986
|
+
this.supportsUntaggedGroupToggle = true,
|
|
882
987
|
this.supportsDiscovery = false,
|
|
883
988
|
this.directRuleScopes = const <String>[],
|
|
884
989
|
this.sharedSpaceRuleScopes = const <String>[],
|
|
@@ -899,6 +1004,7 @@ class MessagingAccessCapabilities {
|
|
|
899
1004
|
supportsDirectPolicy: json['supportsDirectPolicy'] != false,
|
|
900
1005
|
supportsSharedPolicy: json['supportsSharedPolicy'] != false,
|
|
901
1006
|
supportsMentionGate: json['supportsMentionGate'] == true,
|
|
1007
|
+
supportsUntaggedGroupToggle: json['supportsUntaggedGroupToggle'] != false,
|
|
902
1008
|
supportsDiscovery: json['supportsDiscovery'] == true,
|
|
903
1009
|
directRuleScopes: stringList(json['directRuleScopes']),
|
|
904
1010
|
sharedSpaceRuleScopes: stringList(json['sharedSpaceRuleScopes']),
|
|
@@ -910,6 +1016,7 @@ class MessagingAccessCapabilities {
|
|
|
910
1016
|
final bool supportsDirectPolicy;
|
|
911
1017
|
final bool supportsSharedPolicy;
|
|
912
1018
|
final bool supportsMentionGate;
|
|
1019
|
+
final bool supportsUntaggedGroupToggle;
|
|
913
1020
|
final bool supportsDiscovery;
|
|
914
1021
|
final List<String> directRuleScopes;
|
|
915
1022
|
final List<String> sharedSpaceRuleScopes;
|
|
@@ -920,6 +1027,7 @@ class MessagingAccessCapabilities {
|
|
|
920
1027
|
'supportsDirectPolicy': supportsDirectPolicy,
|
|
921
1028
|
'supportsSharedPolicy': supportsSharedPolicy,
|
|
922
1029
|
'supportsMentionGate': supportsMentionGate,
|
|
1030
|
+
'supportsUntaggedGroupToggle': supportsUntaggedGroupToggle,
|
|
923
1031
|
'supportsDiscovery': supportsDiscovery,
|
|
924
1032
|
'directRuleScopes': directRuleScopes,
|
|
925
1033
|
'sharedSpaceRuleScopes': sharedSpaceRuleScopes,
|
|
@@ -936,18 +1044,41 @@ class MessagingAccessTarget {
|
|
|
936
1044
|
required this.value,
|
|
937
1045
|
required this.label,
|
|
938
1046
|
required this.subtitle,
|
|
1047
|
+
this.spaceScope,
|
|
1048
|
+
this.spaceValue,
|
|
1049
|
+
this.spaceLabel,
|
|
939
1050
|
});
|
|
940
1051
|
|
|
941
1052
|
factory MessagingAccessTarget.fromJson(Map<String, dynamic> json) {
|
|
1053
|
+
final nestedRule = _jsonMap(json['rule']);
|
|
1054
|
+
final scope =
|
|
1055
|
+
json['scope']?.toString() ?? nestedRule['scope']?.toString() ?? 'chat';
|
|
1056
|
+
final value =
|
|
1057
|
+
json['value']?.toString() ?? nestedRule['value']?.toString() ?? '';
|
|
942
1058
|
return MessagingAccessTarget(
|
|
943
1059
|
source: json['source']?.toString() ?? 'manual',
|
|
944
1060
|
bucket: json['bucket']?.toString() ?? 'sharedSpaceRules',
|
|
945
|
-
scope:
|
|
946
|
-
value:
|
|
1061
|
+
scope: scope,
|
|
1062
|
+
value: value,
|
|
947
1063
|
label:
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1064
|
+
nestedRule['label']?.toString().ifEmpty(
|
|
1065
|
+
json['label']?.toString() ?? value,
|
|
1066
|
+
) ??
|
|
1067
|
+
json['label']?.toString().ifEmpty(value) ??
|
|
1068
|
+
value,
|
|
1069
|
+
subtitle:
|
|
1070
|
+
json['subtitle']?.toString() ??
|
|
1071
|
+
nestedRule['spaceLabel']?.toString() ??
|
|
1072
|
+
'',
|
|
1073
|
+
spaceScope:
|
|
1074
|
+
json['spaceScope']?.toString() ??
|
|
1075
|
+
nestedRule['spaceScope']?.toString(),
|
|
1076
|
+
spaceValue:
|
|
1077
|
+
json['spaceValue']?.toString() ??
|
|
1078
|
+
nestedRule['spaceValue']?.toString(),
|
|
1079
|
+
spaceLabel:
|
|
1080
|
+
json['spaceLabel']?.toString() ??
|
|
1081
|
+
nestedRule['spaceLabel']?.toString(),
|
|
951
1082
|
);
|
|
952
1083
|
}
|
|
953
1084
|
|
|
@@ -957,11 +1088,21 @@ class MessagingAccessTarget {
|
|
|
957
1088
|
final String value;
|
|
958
1089
|
final String label;
|
|
959
1090
|
final String subtitle;
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1091
|
+
final String? spaceScope;
|
|
1092
|
+
final String? spaceValue;
|
|
1093
|
+
final String? spaceLabel;
|
|
1094
|
+
|
|
1095
|
+
MessagingAccessRule get asRule => MessagingAccessRule(
|
|
1096
|
+
scope: scope,
|
|
1097
|
+
value: value,
|
|
1098
|
+
label: label,
|
|
1099
|
+
spaceScope: spaceScope,
|
|
1100
|
+
spaceValue: spaceValue,
|
|
1101
|
+
spaceLabel: spaceLabel,
|
|
1102
|
+
);
|
|
1103
|
+
|
|
1104
|
+
String get id =>
|
|
1105
|
+
'$bucket:$scope:$value:${spaceScope ?? ''}:${spaceValue ?? ''}';
|
|
965
1106
|
|
|
966
1107
|
Map<String, dynamic> toJson() => <String, dynamic>{
|
|
967
1108
|
'source': source,
|
|
@@ -970,6 +1111,12 @@ class MessagingAccessTarget {
|
|
|
970
1111
|
'value': value,
|
|
971
1112
|
'label': label,
|
|
972
1113
|
'subtitle': subtitle,
|
|
1114
|
+
if (spaceScope != null && spaceScope!.trim().isNotEmpty)
|
|
1115
|
+
'spaceScope': spaceScope,
|
|
1116
|
+
if (spaceValue != null && spaceValue!.trim().isNotEmpty)
|
|
1117
|
+
'spaceValue': spaceValue,
|
|
1118
|
+
if (spaceLabel != null && spaceLabel!.trim().isNotEmpty)
|
|
1119
|
+
'spaceLabel': spaceLabel,
|
|
973
1120
|
};
|
|
974
1121
|
}
|
|
975
1122
|
|
|
@@ -2548,7 +2695,8 @@ class OfficialIntegrationAppItem {
|
|
|
2548
2695
|
String get effectiveStatus =>
|
|
2549
2696
|
!isConnected && hasExpiredAccounts ? 'expired' : connection.status;
|
|
2550
2697
|
|
|
2551
|
-
String get statusLabel =>
|
|
2698
|
+
String get statusLabel =>
|
|
2699
|
+
effectiveStatus == 'expired' ? 'Expired' : connection.statusLabel;
|
|
2552
2700
|
}
|
|
2553
2701
|
|
|
2554
2702
|
class OfficialIntegrationEnvStatus {
|
|
@@ -2780,7 +2928,8 @@ class OfficialIntegrationItem {
|
|
|
2780
2928
|
String get effectiveStatus =>
|
|
2781
2929
|
!isConnected && hasExpiredAccounts ? 'expired' : connection.status;
|
|
2782
2930
|
|
|
2783
|
-
String get statusLabel =>
|
|
2931
|
+
String get statusLabel =>
|
|
2932
|
+
effectiveStatus == 'expired' ? 'Expired' : connection.statusLabel;
|
|
2784
2933
|
}
|
|
2785
2934
|
|
|
2786
2935
|
class SkillDocument {
|
|
@@ -1663,11 +1663,6 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1663
1663
|
icon: Icon(Icons.bug_report_outlined),
|
|
1664
1664
|
label: Text('Inspect'),
|
|
1665
1665
|
),
|
|
1666
|
-
OutlinedButton.icon(
|
|
1667
|
-
onPressed: () => _openBehaviorNotesEditor(context, controller),
|
|
1668
|
-
icon: Icon(Icons.edit_outlined),
|
|
1669
|
-
label: Text('Behavior Notes'),
|
|
1670
|
-
),
|
|
1671
1666
|
FilledButton.icon(
|
|
1672
1667
|
onPressed: () => _openMemoryCreator(context, controller),
|
|
1673
1668
|
icon: Icon(Icons.add),
|
|
@@ -2291,50 +2286,6 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2291
2286
|
);
|
|
2292
2287
|
}
|
|
2293
2288
|
|
|
2294
|
-
Future<void> _openBehaviorNotesEditor(
|
|
2295
|
-
BuildContext context,
|
|
2296
|
-
NeoAgentController controller,
|
|
2297
|
-
) async {
|
|
2298
|
-
final contentController = TextEditingController(
|
|
2299
|
-
text: controller.memoryOverview.assistantBehaviorNotes,
|
|
2300
|
-
);
|
|
2301
|
-
await showDialog<void>(
|
|
2302
|
-
context: context,
|
|
2303
|
-
builder: (context) {
|
|
2304
|
-
return AlertDialog(
|
|
2305
|
-
backgroundColor: _bgCard,
|
|
2306
|
-
title: Text('Edit Assistant Behavior Notes'),
|
|
2307
|
-
content: SizedBox(
|
|
2308
|
-
width: 720,
|
|
2309
|
-
child: TextField(
|
|
2310
|
-
controller: contentController,
|
|
2311
|
-
minLines: 16,
|
|
2312
|
-
maxLines: 24,
|
|
2313
|
-
decoration: const InputDecoration(
|
|
2314
|
-
labelText: 'assistant_behavior_notes',
|
|
2315
|
-
),
|
|
2316
|
-
),
|
|
2317
|
-
),
|
|
2318
|
-
actions: <Widget>[
|
|
2319
|
-
TextButton(
|
|
2320
|
-
onPressed: () => Navigator.of(context).pop(),
|
|
2321
|
-
child: Text('Cancel'),
|
|
2322
|
-
),
|
|
2323
|
-
FilledButton(
|
|
2324
|
-
onPressed: () async {
|
|
2325
|
-
await controller.updateAssistantBehaviorNotes(
|
|
2326
|
-
contentController.text,
|
|
2327
|
-
);
|
|
2328
|
-
if (context.mounted) Navigator.of(context).pop();
|
|
2329
|
-
},
|
|
2330
|
-
child: Text('Save'),
|
|
2331
|
-
),
|
|
2332
|
-
],
|
|
2333
|
-
);
|
|
2334
|
-
},
|
|
2335
|
-
);
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
2289
|
Future<void> _openCoreMemoryEditor(
|
|
2339
2290
|
BuildContext context,
|
|
2340
2291
|
NeoAgentController controller, {
|