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
|
@@ -106,6 +106,18 @@ const _workspaceSettingsSection = _SettingsSection('workspace', <String>[
|
|
|
106
106
|
'routing',
|
|
107
107
|
]);
|
|
108
108
|
|
|
109
|
+
const _behaviorSettingsSection = _SettingsSection('behavior', <String>[
|
|
110
|
+
'behavior',
|
|
111
|
+
'persona',
|
|
112
|
+
'social intelligence',
|
|
113
|
+
'turn taking',
|
|
114
|
+
'groups',
|
|
115
|
+
'memory',
|
|
116
|
+
'norms',
|
|
117
|
+
'theory of mind',
|
|
118
|
+
'delivery',
|
|
119
|
+
]);
|
|
120
|
+
|
|
109
121
|
const _modelsSettingsSection = _SettingsSection('models', <String>[
|
|
110
122
|
'models',
|
|
111
123
|
'providers',
|
|
@@ -173,6 +185,7 @@ const _securitySettingsSection = _SettingsSection('security', <String>[
|
|
|
173
185
|
|
|
174
186
|
const List<_SettingsSection> _settingsSearchSections = <_SettingsSection>[
|
|
175
187
|
_overviewSettingsSection,
|
|
188
|
+
_behaviorSettingsSection,
|
|
176
189
|
_workspaceSettingsSection,
|
|
177
190
|
_socialReachSettingsSection,
|
|
178
191
|
_modelsSettingsSection,
|
|
@@ -200,6 +213,17 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
200
213
|
final Map<String, bool> _providerEnabled = <String, bool>{};
|
|
201
214
|
final Map<String, TextEditingController> _providerBaseUrlControllers =
|
|
202
215
|
<String, TextEditingController>{};
|
|
216
|
+
late final TextEditingController _behaviorNotesController;
|
|
217
|
+
late bool _behaviorEnabled;
|
|
218
|
+
late String _behaviorParticipationMode;
|
|
219
|
+
late double _behaviorMinimumNeedScore;
|
|
220
|
+
late double _behaviorBatchWindowMs;
|
|
221
|
+
late String _behaviorDecisionModelId;
|
|
222
|
+
late String _behaviorDeliveryStyle;
|
|
223
|
+
late bool _behaviorTheoryOfMindEnabled;
|
|
224
|
+
late bool _behaviorSocialMemoryEnabled;
|
|
225
|
+
late bool _behaviorNormsEnabled;
|
|
226
|
+
late bool _behaviorObservabilityEnabled;
|
|
203
227
|
|
|
204
228
|
bool _hasUnsavedChanges = false;
|
|
205
229
|
|
|
@@ -218,12 +242,14 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
218
242
|
void initState() {
|
|
219
243
|
super.initState();
|
|
220
244
|
_searchController = TextEditingController();
|
|
245
|
+
_behaviorNotesController = TextEditingController();
|
|
221
246
|
_hydrate();
|
|
222
247
|
}
|
|
223
248
|
|
|
224
249
|
@override
|
|
225
250
|
void dispose() {
|
|
226
251
|
_searchController.dispose();
|
|
252
|
+
_behaviorNotesController.dispose();
|
|
227
253
|
for (final controller in _providerBaseUrlControllers.values) {
|
|
228
254
|
controller.dispose();
|
|
229
255
|
}
|
|
@@ -234,6 +260,10 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
234
260
|
void didUpdateWidget(covariant SettingsPanel oldWidget) {
|
|
235
261
|
super.didUpdateWidget(oldWidget);
|
|
236
262
|
if (oldWidget.controller.settings != widget.controller.settings ||
|
|
263
|
+
oldWidget.controller.behaviorConfig !=
|
|
264
|
+
widget.controller.behaviorConfig ||
|
|
265
|
+
oldWidget.controller.memoryOverview !=
|
|
266
|
+
widget.controller.memoryOverview ||
|
|
237
267
|
oldWidget.controller.aiProviders != widget.controller.aiProviders ||
|
|
238
268
|
oldWidget.controller.supportedModels !=
|
|
239
269
|
widget.controller.supportedModels) {
|
|
@@ -270,6 +300,45 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
270
300
|
_voiceLiveProvider = controller.voiceLiveProvider;
|
|
271
301
|
_voiceLiveModel = controller.voiceLiveModel;
|
|
272
302
|
_voiceLiveVoice = controller.voiceLiveVoice;
|
|
303
|
+
final behavior = controller.behaviorConfig;
|
|
304
|
+
final modules = behavior['modules'] is Map
|
|
305
|
+
? Map<String, dynamic>.from(behavior['modules'] as Map)
|
|
306
|
+
: const <String, dynamic>{};
|
|
307
|
+
bool moduleEnabled(String id) {
|
|
308
|
+
final module = modules[id];
|
|
309
|
+
return module is! Map || module['enabled'] != false;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
_behaviorEnabled = behavior['enabled'] != false;
|
|
313
|
+
_behaviorParticipationMode =
|
|
314
|
+
<String>{
|
|
315
|
+
'automatic',
|
|
316
|
+
'mention_only',
|
|
317
|
+
'always',
|
|
318
|
+
}.contains(behavior['participationMode']?.toString())
|
|
319
|
+
? behavior['participationMode'].toString()
|
|
320
|
+
: 'automatic';
|
|
321
|
+
_behaviorMinimumNeedScore =
|
|
322
|
+
((behavior['minimumNeedScore'] as num?)?.toDouble() ?? 0.72)
|
|
323
|
+
.clamp(0.0, 1.0)
|
|
324
|
+
.toDouble();
|
|
325
|
+
_behaviorBatchWindowMs =
|
|
326
|
+
((behavior['batchWindowMs'] as num?)?.toDouble() ?? 900)
|
|
327
|
+
.clamp(0.0, 5000.0)
|
|
328
|
+
.toDouble();
|
|
329
|
+
_behaviorDecisionModelId =
|
|
330
|
+
behavior['decisionModelId']?.toString().trim() ?? '';
|
|
331
|
+
_behaviorDeliveryStyle = behavior['deliveryStyle'] == 'single'
|
|
332
|
+
? 'single'
|
|
333
|
+
: 'natural_bubbles';
|
|
334
|
+
_behaviorTheoryOfMindEnabled = moduleEnabled('theory_of_mind');
|
|
335
|
+
_behaviorSocialMemoryEnabled = moduleEnabled('social_memory');
|
|
336
|
+
_behaviorNormsEnabled = moduleEnabled('norms');
|
|
337
|
+
_behaviorObservabilityEnabled = moduleEnabled('social_observability');
|
|
338
|
+
final behaviorNotes = controller.memoryOverview.assistantBehaviorNotes;
|
|
339
|
+
if (_behaviorNotesController.text != behaviorNotes) {
|
|
340
|
+
_behaviorNotesController.text = behaviorNotes;
|
|
341
|
+
}
|
|
273
342
|
if (!_voiceLiveModelsByProvider.containsKey(_voiceLiveProvider)) {
|
|
274
343
|
_voiceLiveProvider = 'openai';
|
|
275
344
|
}
|
|
@@ -401,6 +470,13 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
401
470
|
_buildSettingsOverview(controller, availableModels.length),
|
|
402
471
|
const SizedBox(height: 16),
|
|
403
472
|
],
|
|
473
|
+
if (_matchesSettingsSection(
|
|
474
|
+
searchQuery,
|
|
475
|
+
_behaviorSettingsSection,
|
|
476
|
+
)) ...<Widget>[
|
|
477
|
+
_buildBehaviorSection(controller, routingModels),
|
|
478
|
+
const SizedBox(height: 16),
|
|
479
|
+
],
|
|
404
480
|
if (_matchesSettingsSection(
|
|
405
481
|
searchQuery,
|
|
406
482
|
_workspaceSettingsSection,
|
|
@@ -522,6 +598,42 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
522
598
|
voiceLiveVoice: _voiceLiveVoice,
|
|
523
599
|
aiProviderConfigs: _buildProviderPayload(),
|
|
524
600
|
);
|
|
601
|
+
if (controller.errorMessage != null) return;
|
|
602
|
+
final existingModules = controller.behaviorConfig['modules'] is Map
|
|
603
|
+
? Map<String, dynamic>.from(controller.behaviorConfig['modules'] as Map)
|
|
604
|
+
: <String, dynamic>{};
|
|
605
|
+
existingModules.addAll(<String, dynamic>{
|
|
606
|
+
'theory_of_mind': <String, dynamic>{
|
|
607
|
+
'enabled': _behaviorTheoryOfMindEnabled,
|
|
608
|
+
},
|
|
609
|
+
'social_memory': <String, dynamic>{
|
|
610
|
+
'enabled': _behaviorSocialMemoryEnabled,
|
|
611
|
+
},
|
|
612
|
+
'norms': <String, dynamic>{'enabled': _behaviorNormsEnabled},
|
|
613
|
+
'social_observability': <String, dynamic>{
|
|
614
|
+
'enabled': _behaviorObservabilityEnabled,
|
|
615
|
+
},
|
|
616
|
+
});
|
|
617
|
+
await controller.saveBehaviorConfig(<String, dynamic>{
|
|
618
|
+
...controller.behaviorConfig,
|
|
619
|
+
'enabled': _behaviorEnabled,
|
|
620
|
+
'participationMode': _behaviorParticipationMode,
|
|
621
|
+
'minimumNeedScore': _behaviorMinimumNeedScore,
|
|
622
|
+
'batchWindowMs': _behaviorBatchWindowMs.round(),
|
|
623
|
+
'decisionModelId': _behaviorDecisionModelId.isEmpty
|
|
624
|
+
? null
|
|
625
|
+
: _behaviorDecisionModelId,
|
|
626
|
+
'deliveryStyle': _behaviorDeliveryStyle,
|
|
627
|
+
'modules': existingModules,
|
|
628
|
+
});
|
|
629
|
+
if (controller.errorMessage != null) return;
|
|
630
|
+
if (_behaviorNotesController.text !=
|
|
631
|
+
controller.memoryOverview.assistantBehaviorNotes) {
|
|
632
|
+
await controller.updateAssistantBehaviorNotes(
|
|
633
|
+
_behaviorNotesController.text,
|
|
634
|
+
);
|
|
635
|
+
if (controller.errorMessage != null) return;
|
|
636
|
+
}
|
|
525
637
|
if (mounted) setState(() => _hasUnsavedChanges = false);
|
|
526
638
|
}
|
|
527
639
|
|
|
@@ -627,6 +739,232 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
627
739
|
);
|
|
628
740
|
}
|
|
629
741
|
|
|
742
|
+
Widget _buildBehaviorSection(
|
|
743
|
+
NeoAgentController controller,
|
|
744
|
+
List<ModelMeta> routingModels,
|
|
745
|
+
) {
|
|
746
|
+
final modelIds = <String>{
|
|
747
|
+
if (_behaviorDecisionModelId.isNotEmpty) _behaviorDecisionModelId,
|
|
748
|
+
...routingModels.map((model) => model.id),
|
|
749
|
+
}.toList();
|
|
750
|
+
return Card(
|
|
751
|
+
child: Padding(
|
|
752
|
+
padding: const EdgeInsets.all(20),
|
|
753
|
+
child: Column(
|
|
754
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
755
|
+
children: <Widget>[
|
|
756
|
+
const _SectionTitle('Behavior Modules'),
|
|
757
|
+
const SizedBox(height: 10),
|
|
758
|
+
Text(
|
|
759
|
+
'One runtime controls persona, group turn-taking, room memory, norms, Theory of Mind, and delivery.',
|
|
760
|
+
style: TextStyle(color: _textSecondary, height: 1.45),
|
|
761
|
+
),
|
|
762
|
+
const SizedBox(height: 12),
|
|
763
|
+
SwitchListTile.adaptive(
|
|
764
|
+
contentPadding: EdgeInsets.zero,
|
|
765
|
+
title: const Text('Enable behavior modules'),
|
|
766
|
+
subtitle: const Text(
|
|
767
|
+
'Direct messages remain responsive. Allowlisted groups use the participation mode below.',
|
|
768
|
+
),
|
|
769
|
+
value: _behaviorEnabled,
|
|
770
|
+
onChanged: (value) => setState(() {
|
|
771
|
+
_behaviorEnabled = value;
|
|
772
|
+
_hasUnsavedChanges = true;
|
|
773
|
+
}),
|
|
774
|
+
),
|
|
775
|
+
const SizedBox(height: 8),
|
|
776
|
+
DropdownButtonFormField<String>(
|
|
777
|
+
initialValue: _behaviorParticipationMode,
|
|
778
|
+
decoration: const InputDecoration(
|
|
779
|
+
labelText: 'Default group participation',
|
|
780
|
+
helperText:
|
|
781
|
+
'Automatic reads the room and normally holds back. Mention-only makes no decision call until directly addressed.',
|
|
782
|
+
),
|
|
783
|
+
items: const <DropdownMenuItem<String>>[
|
|
784
|
+
DropdownMenuItem(
|
|
785
|
+
value: 'automatic',
|
|
786
|
+
child: Text('Automatic, reserved'),
|
|
787
|
+
),
|
|
788
|
+
DropdownMenuItem(
|
|
789
|
+
value: 'mention_only',
|
|
790
|
+
child: Text('Mention or reply only'),
|
|
791
|
+
),
|
|
792
|
+
DropdownMenuItem(value: 'always', child: Text('Always engage')),
|
|
793
|
+
],
|
|
794
|
+
onChanged: !_behaviorEnabled
|
|
795
|
+
? null
|
|
796
|
+
: (value) {
|
|
797
|
+
if (value == null) return;
|
|
798
|
+
setState(() {
|
|
799
|
+
_behaviorParticipationMode = value;
|
|
800
|
+
_hasUnsavedChanges = true;
|
|
801
|
+
});
|
|
802
|
+
},
|
|
803
|
+
),
|
|
804
|
+
const SizedBox(height: 18),
|
|
805
|
+
Text(
|
|
806
|
+
'Minimum contribution value: ${_behaviorMinimumNeedScore.toStringAsFixed(2)}',
|
|
807
|
+
style: TextStyle(
|
|
808
|
+
color: _textPrimary,
|
|
809
|
+
fontWeight: FontWeight.w600,
|
|
810
|
+
),
|
|
811
|
+
),
|
|
812
|
+
Slider(
|
|
813
|
+
value: _behaviorMinimumNeedScore,
|
|
814
|
+
min: 0,
|
|
815
|
+
max: 1,
|
|
816
|
+
divisions: 20,
|
|
817
|
+
label: _behaviorMinimumNeedScore.toStringAsFixed(2),
|
|
818
|
+
onChanged: !_behaviorEnabled
|
|
819
|
+
? null
|
|
820
|
+
: (value) => setState(() {
|
|
821
|
+
_behaviorMinimumNeedScore = value;
|
|
822
|
+
_hasUnsavedChanges = true;
|
|
823
|
+
}),
|
|
824
|
+
),
|
|
825
|
+
Text(
|
|
826
|
+
'Higher values make NeoAgent more selective in groups.',
|
|
827
|
+
style: TextStyle(color: _textSecondary, fontSize: 12),
|
|
828
|
+
),
|
|
829
|
+
const SizedBox(height: 14),
|
|
830
|
+
Text(
|
|
831
|
+
'Room batch window: ${_behaviorBatchWindowMs.round()} ms',
|
|
832
|
+
style: TextStyle(
|
|
833
|
+
color: _textPrimary,
|
|
834
|
+
fontWeight: FontWeight.w600,
|
|
835
|
+
),
|
|
836
|
+
),
|
|
837
|
+
Slider(
|
|
838
|
+
value: _behaviorBatchWindowMs,
|
|
839
|
+
min: 0,
|
|
840
|
+
max: 5000,
|
|
841
|
+
divisions: 20,
|
|
842
|
+
label: '${_behaviorBatchWindowMs.round()} ms',
|
|
843
|
+
onChanged: !_behaviorEnabled
|
|
844
|
+
? null
|
|
845
|
+
: (value) => setState(() {
|
|
846
|
+
_behaviorBatchWindowMs = value;
|
|
847
|
+
_hasUnsavedChanges = true;
|
|
848
|
+
}),
|
|
849
|
+
),
|
|
850
|
+
const SizedBox(height: 12),
|
|
851
|
+
DropdownButtonFormField<String>(
|
|
852
|
+
initialValue: _behaviorDecisionModelId,
|
|
853
|
+
decoration: const InputDecoration(
|
|
854
|
+
labelText: 'Turn-taking model',
|
|
855
|
+
helperText:
|
|
856
|
+
'Automatic selects a fast model through the normal model catalog.',
|
|
857
|
+
),
|
|
858
|
+
items: <DropdownMenuItem<String>>[
|
|
859
|
+
const DropdownMenuItem(
|
|
860
|
+
value: '',
|
|
861
|
+
child: Text('Automatic (fast)'),
|
|
862
|
+
),
|
|
863
|
+
...modelIds.map(
|
|
864
|
+
(id) => DropdownMenuItem(value: id, child: Text(id)),
|
|
865
|
+
),
|
|
866
|
+
],
|
|
867
|
+
onChanged: !_behaviorEnabled
|
|
868
|
+
? null
|
|
869
|
+
: (value) {
|
|
870
|
+
if (value == null) return;
|
|
871
|
+
setState(() {
|
|
872
|
+
_behaviorDecisionModelId = value;
|
|
873
|
+
_hasUnsavedChanges = true;
|
|
874
|
+
});
|
|
875
|
+
},
|
|
876
|
+
),
|
|
877
|
+
const SizedBox(height: 12),
|
|
878
|
+
DropdownButtonFormField<String>(
|
|
879
|
+
initialValue: _behaviorDeliveryStyle,
|
|
880
|
+
decoration: const InputDecoration(
|
|
881
|
+
labelText: 'Messaging delivery',
|
|
882
|
+
),
|
|
883
|
+
items: const <DropdownMenuItem<String>>[
|
|
884
|
+
DropdownMenuItem(
|
|
885
|
+
value: 'natural_bubbles',
|
|
886
|
+
child: Text('Natural bubbles'),
|
|
887
|
+
),
|
|
888
|
+
DropdownMenuItem(
|
|
889
|
+
value: 'single',
|
|
890
|
+
child: Text('Single message'),
|
|
891
|
+
),
|
|
892
|
+
],
|
|
893
|
+
onChanged: !_behaviorEnabled
|
|
894
|
+
? null
|
|
895
|
+
: (value) {
|
|
896
|
+
if (value == null) return;
|
|
897
|
+
setState(() {
|
|
898
|
+
_behaviorDeliveryStyle = value;
|
|
899
|
+
_hasUnsavedChanges = true;
|
|
900
|
+
});
|
|
901
|
+
},
|
|
902
|
+
),
|
|
903
|
+
const SizedBox(height: 10),
|
|
904
|
+
SwitchListTile.adaptive(
|
|
905
|
+
contentPadding: EdgeInsets.zero,
|
|
906
|
+
title: const Text('Theory of Mind refinement'),
|
|
907
|
+
value: _behaviorTheoryOfMindEnabled,
|
|
908
|
+
onChanged: !_behaviorEnabled
|
|
909
|
+
? null
|
|
910
|
+
: (value) => setState(() {
|
|
911
|
+
_behaviorTheoryOfMindEnabled = value;
|
|
912
|
+
_hasUnsavedChanges = true;
|
|
913
|
+
}),
|
|
914
|
+
),
|
|
915
|
+
SwitchListTile.adaptive(
|
|
916
|
+
contentPadding: EdgeInsets.zero,
|
|
917
|
+
title: const Text('Channel-scoped social memory'),
|
|
918
|
+
value: _behaviorSocialMemoryEnabled,
|
|
919
|
+
onChanged: !_behaviorEnabled
|
|
920
|
+
? null
|
|
921
|
+
: (value) => setState(() {
|
|
922
|
+
_behaviorSocialMemoryEnabled = value;
|
|
923
|
+
_hasUnsavedChanges = true;
|
|
924
|
+
}),
|
|
925
|
+
),
|
|
926
|
+
SwitchListTile.adaptive(
|
|
927
|
+
contentPadding: EdgeInsets.zero,
|
|
928
|
+
title: const Text('Learn room norms'),
|
|
929
|
+
value: _behaviorNormsEnabled,
|
|
930
|
+
onChanged: !_behaviorEnabled
|
|
931
|
+
? null
|
|
932
|
+
: (value) => setState(() {
|
|
933
|
+
_behaviorNormsEnabled = value;
|
|
934
|
+
_hasUnsavedChanges = true;
|
|
935
|
+
}),
|
|
936
|
+
),
|
|
937
|
+
SwitchListTile.adaptive(
|
|
938
|
+
contentPadding: EdgeInsets.zero,
|
|
939
|
+
title: const Text('Social observability'),
|
|
940
|
+
value: _behaviorObservabilityEnabled,
|
|
941
|
+
onChanged: !_behaviorEnabled
|
|
942
|
+
? null
|
|
943
|
+
: (value) => setState(() {
|
|
944
|
+
_behaviorObservabilityEnabled = value;
|
|
945
|
+
_hasUnsavedChanges = true;
|
|
946
|
+
}),
|
|
947
|
+
),
|
|
948
|
+
const SizedBox(height: 12),
|
|
949
|
+
TextField(
|
|
950
|
+
controller: _behaviorNotesController,
|
|
951
|
+
minLines: 4,
|
|
952
|
+
maxLines: 10,
|
|
953
|
+
onChanged: (_) => setState(() {
|
|
954
|
+
_hasUnsavedChanges = true;
|
|
955
|
+
}),
|
|
956
|
+
decoration: const InputDecoration(
|
|
957
|
+
labelText: 'Persona behavior notes',
|
|
958
|
+
helperText:
|
|
959
|
+
'Durable instructions for voice and interaction style. Safety and execution rules still take priority.',
|
|
960
|
+
),
|
|
961
|
+
),
|
|
962
|
+
],
|
|
963
|
+
),
|
|
964
|
+
),
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
|
|
630
968
|
Widget _buildWorkspaceSection(NeoAgentController controller) {
|
|
631
969
|
return Card(
|
|
632
970
|
child: Padding(
|
|
@@ -514,6 +514,25 @@ class BackendClient {
|
|
|
514
514
|
return putMap(baseUrl, '/api/settings', _withAgentId(payload, agentId));
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
+
Future<Map<String, dynamic>> fetchBehaviorConfig(
|
|
518
|
+
String baseUrl, {
|
|
519
|
+
String? agentId,
|
|
520
|
+
}) async {
|
|
521
|
+
return getMap(baseUrl, _withAgentQuery('/api/behavior', agentId));
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
Future<Map<String, dynamic>> saveBehaviorConfig(
|
|
525
|
+
String baseUrl,
|
|
526
|
+
Map<String, dynamic> config, {
|
|
527
|
+
String? agentId,
|
|
528
|
+
}) async {
|
|
529
|
+
return putMap(
|
|
530
|
+
baseUrl,
|
|
531
|
+
'/api/behavior',
|
|
532
|
+
_withAgentId(<String, dynamic>{'config': config}, agentId),
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
|
|
517
536
|
Future<Map<String, dynamic>> fetchTokenUsageSummary(
|
|
518
537
|
String baseUrl, {
|
|
519
538
|
String? agentId,
|
package/package.json
CHANGED
package/server/db/database.js
CHANGED
|
@@ -1311,8 +1311,8 @@ function getMainAgentId(userId) {
|
|
|
1311
1311
|
id, user_id, slug, display_name, description, responsibilities, instructions,
|
|
1312
1312
|
is_default, can_delegate, can_be_delegated_to, delegate_targets_json
|
|
1313
1313
|
)
|
|
1314
|
-
VALUES (?, ?, 'main', 'Main', 'Default personal
|
|
1315
|
-
'Handle general requests and delegate to specialist agents only when there is a clear match.',
|
|
1314
|
+
VALUES (?, ?, 'main', 'Main', 'Default personal AI contact and fallback agent.',
|
|
1315
|
+
'Handle general requests like a proactive favorite contact and delegate to specialist agents only when there is a clear match.',
|
|
1316
1316
|
'', 1, 1, 0, '[]'
|
|
1317
1317
|
)`
|
|
1318
1318
|
).run(id, userId);
|
package/server/http/routes.js
CHANGED
|
@@ -11,6 +11,7 @@ const routeRegistry = [
|
|
|
11
11
|
{ basePath: null, modulePath: '../routes/auth' },
|
|
12
12
|
{ basePath: '/api/account', modulePath: '../routes/account' },
|
|
13
13
|
{ basePath: '/api/settings', modulePath: '../routes/settings' },
|
|
14
|
+
{ basePath: '/api/behavior', modulePath: '../routes/behavior' },
|
|
14
15
|
{ basePath: '/api/agent-profiles', modulePath: '../routes/agent_profiles' },
|
|
15
16
|
{ basePath: '/api/agents', modulePath: '../routes/agents' },
|
|
16
17
|
{ basePath: '/api/messaging', modulePath: '../routes/messaging' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d5e0ef3e2dca2bb1ce478b598336b800
|
|
Binary file
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"0cd610717bde95fd88343c64f81c11ba4e5c00
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "862590908" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|