neoagent 3.2.1-beta.1 → 3.2.1-beta.11
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/extensions/chrome-browser/background.mjs +318 -88
- package/extensions/chrome-browser/http.mjs +136 -0
- package/extensions/chrome-browser/protocol.mjs +654 -90
- package/flutter_app/lib/main_chat.dart +118 -739
- package/flutter_app/lib/main_controller.dart +157 -24
- package/flutter_app/lib/main_integrations.dart +607 -8
- package/flutter_app/lib/main_models.dart +7 -2
- package/flutter_app/lib/main_operations.dart +334 -370
- package/flutter_app/lib/main_security.dart +266 -112
- package/flutter_app/lib/main_settings.dart +342 -3
- package/flutter_app/lib/main_shared.dart +14 -11
- package/flutter_app/lib/src/backend_client.dart +97 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +185 -31
- package/flutter_app/lib/src/desktop_companion_io.dart +319 -86
- package/flutter_app/windows/runner/flutter_window.cpp +143 -32
- package/landing/index.html +3 -1
- package/lib/manager.js +106 -89
- package/lib/schema_migrations.js +115 -13
- package/package.json +30 -15
- package/runtime/paths.js +49 -5
- package/server/db/database.js +2 -2
- package/server/guest-agent.cli.package.json +13 -0
- package/server/guest_agent.js +85 -40
- package/server/http/middleware.js +24 -0
- package/server/http/routes.js +12 -6
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +2 -2
- package/server/public/main.dart.js +81930 -80509
- package/server/routes/admin.js +1 -1
- package/server/routes/android.js +30 -34
- package/server/routes/behavior.js +80 -0
- package/server/routes/browser.js +23 -15
- package/server/routes/desktop.js +18 -1
- package/server/routes/integrations.js +107 -1
- package/server/routes/memory.js +1 -0
- package/server/routes/settings.js +20 -5
- package/server/routes/social_reach.js +12 -3
- package/server/routes/social_video.js +4 -0
- package/server/services/agents/manager.js +1 -1
- package/server/services/ai/capabilityHealth.js +62 -96
- package/server/services/ai/compaction.js +7 -2
- package/server/services/ai/history.js +45 -6
- package/server/services/ai/integrated_tools/http_request.js +8 -0
- package/server/services/ai/loop/agent_engine_core.js +452 -176
- package/server/services/ai/loop/blank_recovery.js +5 -4
- package/server/services/ai/loop/callbacks.js +1 -0
- package/server/services/ai/loop/completion_judge.js +291 -8
- package/server/services/ai/loop/conversation_loop.js +515 -342
- package/server/services/ai/loop/messaging_delivery.js +176 -57
- package/server/services/ai/loop/model_call_guard.js +91 -0
- package/server/services/ai/loop/model_io.js +20 -45
- package/server/services/ai/loop/progress_classification.js +2 -0
- package/server/services/ai/loop/tool_dispatch.js +19 -8
- package/server/services/ai/loopPolicy.js +48 -21
- package/server/services/ai/messagingFallback.js +17 -17
- package/server/services/ai/model_discovery.js +227 -0
- package/server/services/ai/model_failure_cache.js +108 -0
- package/server/services/ai/model_identity.js +71 -0
- package/server/services/ai/models.js +68 -163
- package/server/services/ai/providerRetry.js +17 -59
- package/server/services/ai/provider_selector.js +166 -0
- package/server/services/ai/providers/anthropic.js +2 -2
- package/server/services/ai/providers/claudeCode.js +21 -33
- package/server/services/ai/providers/githubCopilot.js +41 -20
- package/server/services/ai/providers/google.js +135 -97
- package/server/services/ai/providers/grok.js +4 -3
- package/server/services/ai/providers/grokOauth.js +19 -27
- package/server/services/ai/providers/nvidia.js +10 -5
- package/server/services/ai/providers/ollama.js +111 -84
- package/server/services/ai/providers/ollama_stream.js +142 -0
- package/server/services/ai/providers/openai.js +39 -5
- package/server/services/ai/providers/openaiCodex.js +11 -4
- package/server/services/ai/providers/openrouter.js +29 -7
- package/server/services/ai/providers/provider_error.js +36 -0
- package/server/services/ai/settings.js +26 -2
- package/server/services/ai/systemPrompt.js +32 -123
- package/server/services/ai/taskAnalysis.js +104 -11
- package/server/services/ai/toolEvidence.js +256 -29
- package/server/services/ai/tools.js +248 -117
- package/server/services/android/controller.js +770 -237
- package/server/services/android/process.js +140 -0
- package/server/services/android/sdk_download.js +143 -0
- package/server/services/android/uia.js +6 -5
- package/server/services/artifacts/store.js +24 -0
- 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 +48 -0
- package/server/services/behavior/modules/persona_prompt.js +33 -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 +110 -0
- package/server/services/behavior/modules/turn_taking.js +237 -0
- package/server/services/behavior/pipeline.js +285 -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/browser/controller.js +843 -385
- package/server/services/browser/extension/gateway.js +40 -16
- package/server/services/browser/extension/protocol.js +15 -1
- package/server/services/browser/extension/provider.js +71 -47
- package/server/services/browser/extension/registry.js +155 -34
- package/server/services/cli/executor.js +62 -9
- package/server/services/credentials/bitwarden_cli.js +322 -0
- package/server/services/credentials/broker.js +594 -0
- package/server/services/desktop/gateway.js +41 -4
- package/server/services/desktop/protocol.js +3 -0
- package/server/services/desktop/provider.js +39 -42
- package/server/services/desktop/registry.js +137 -52
- package/server/services/integrations/bitwarden/constants.js +14 -0
- package/server/services/integrations/bitwarden/provider.js +197 -0
- package/server/services/integrations/bitwarden/snapshot.js +65 -0
- package/server/services/integrations/figma/provider.js +78 -12
- package/server/services/integrations/github/common.js +11 -6
- package/server/services/integrations/github/provider.js +52 -53
- package/server/services/integrations/google/provider.js +55 -19
- package/server/services/integrations/home_assistant/network.js +17 -20
- package/server/services/integrations/home_assistant/provider.js +7 -5
- package/server/services/integrations/home_assistant/tools.js +17 -5
- package/server/services/integrations/http.js +51 -0
- package/server/services/integrations/manager.js +159 -53
- package/server/services/integrations/microsoft/provider.js +80 -13
- package/server/services/integrations/neoarchive/provider.js +55 -29
- package/server/services/integrations/neorecall/client.js +17 -10
- package/server/services/integrations/neorecall/provider.js +20 -11
- package/server/services/integrations/notion/provider.js +16 -13
- package/server/services/integrations/oauth_provider.js +115 -51
- package/server/services/integrations/registry.js +2 -0
- package/server/services/integrations/slack/provider.js +98 -9
- package/server/services/integrations/spotify/provider.js +67 -71
- package/server/services/integrations/trello/provider.js +21 -7
- package/server/services/integrations/weather/provider.js +18 -12
- package/server/services/integrations/whatsapp/provider.js +76 -16
- package/server/services/manager.js +110 -1
- package/server/services/memory/embedding_index.js +20 -8
- package/server/services/memory/embeddings.js +151 -90
- package/server/services/memory/ingestion.js +50 -9
- package/server/services/memory/ingestion_documents.js +13 -3
- package/server/services/memory/manager.js +66 -52
- package/server/services/messaging/access_policy.js +10 -6
- package/server/services/messaging/automation.js +240 -34
- package/server/services/messaging/discord.js +11 -1
- package/server/services/messaging/formatting_guides.js +5 -4
- package/server/services/messaging/http_platforms.js +37 -16
- package/server/services/messaging/inbound_queue.js +143 -28
- package/server/services/messaging/inbound_store.js +257 -0
- package/server/services/messaging/manager.js +344 -51
- package/server/services/messaging/telegram.js +10 -1
- package/server/services/messaging/typing_keepalive.js +5 -2
- package/server/services/messaging/whatsapp.js +33 -14
- package/server/services/network/http.js +210 -0
- package/server/services/network/safe_request.js +307 -0
- package/server/services/runtime/backends/local-vm.js +227 -67
- package/server/services/runtime/docker-vm-manager.js +9 -0
- package/server/services/runtime/guest_bootstrap.js +30 -4
- package/server/services/runtime/guest_image.js +43 -12
- package/server/services/runtime/manager.js +77 -23
- package/server/services/runtime/validation.js +7 -6
- package/server/services/security/tool_categories.js +6 -0
- package/server/services/social_reach/channels/github.js +10 -4
- package/server/services/social_reach/channels/reddit.js +4 -4
- package/server/services/social_reach/channels/rss.js +2 -2
- package/server/services/social_reach/channels/social_video.js +13 -8
- package/server/services/social_reach/channels/v2ex.js +21 -8
- package/server/services/social_reach/channels/x.js +2 -2
- package/server/services/social_reach/channels/xueqiu.js +5 -5
- package/server/services/social_reach/service.js +9 -6
- package/server/services/social_reach/utils.js +65 -14
- package/server/services/social_video/captions.js +2 -2
- package/server/services/social_video/service.js +343 -68
- package/server/services/tasks/integration_runtime.js +18 -8
- package/server/services/tasks/runtime.js +39 -4
- package/server/services/voice/agentBridge.js +17 -4
- package/server/services/voice/bufferedLiveRelayAdapter.js +5 -0
- package/server/services/voice/liveSession.js +31 -0
- package/server/services/voice/message.js +1 -1
- package/server/services/voice/openaiSpeech.js +33 -8
- package/server/services/voice/providers.js +233 -151
- package/server/services/voice/runtime.js +2 -2
- package/server/services/voice/runtimeManager.js +118 -20
- package/server/services/voice/turnRunner.js +6 -0
- package/server/services/wearable/firmware_manifest.js +51 -13
- package/server/services/wearable/service.js +1 -0
- package/server/utils/abort.js +96 -0
- package/server/utils/cloud-security.js +110 -3
- package/server/utils/files.js +31 -0
- package/server/utils/image_payload.js +95 -0
- package/server/utils/logger.js +19 -0
- package/server/utils/retry.js +107 -0
|
@@ -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
|
}
|
|
@@ -343,10 +412,11 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
343
412
|
onPopInvokedWithResult: (didPop, result) async {
|
|
344
413
|
if (didPop) return;
|
|
345
414
|
final action = await _showLeaveDialog(context);
|
|
346
|
-
if (
|
|
415
|
+
if (!context.mounted) return;
|
|
416
|
+
if (action == _LeaveAction.save) {
|
|
347
417
|
await _doSave();
|
|
348
|
-
if (mounted) Navigator.of(context).pop();
|
|
349
|
-
} else if (action == _LeaveAction.discard
|
|
418
|
+
if (context.mounted) Navigator.of(context).pop();
|
|
419
|
+
} else if (action == _LeaveAction.discard) {
|
|
350
420
|
_hydrate();
|
|
351
421
|
setState(() => _hasUnsavedChanges = false);
|
|
352
422
|
Navigator.of(context).pop();
|
|
@@ -400,6 +470,13 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
400
470
|
_buildSettingsOverview(controller, availableModels.length),
|
|
401
471
|
const SizedBox(height: 16),
|
|
402
472
|
],
|
|
473
|
+
if (_matchesSettingsSection(
|
|
474
|
+
searchQuery,
|
|
475
|
+
_behaviorSettingsSection,
|
|
476
|
+
)) ...<Widget>[
|
|
477
|
+
_buildBehaviorSection(controller, routingModels),
|
|
478
|
+
const SizedBox(height: 16),
|
|
479
|
+
],
|
|
403
480
|
if (_matchesSettingsSection(
|
|
404
481
|
searchQuery,
|
|
405
482
|
_workspaceSettingsSection,
|
|
@@ -521,6 +598,42 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
521
598
|
voiceLiveVoice: _voiceLiveVoice,
|
|
522
599
|
aiProviderConfigs: _buildProviderPayload(),
|
|
523
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
|
+
}
|
|
524
637
|
if (mounted) setState(() => _hasUnsavedChanges = false);
|
|
525
638
|
}
|
|
526
639
|
|
|
@@ -626,6 +739,232 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
626
739
|
);
|
|
627
740
|
}
|
|
628
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
|
+
|
|
629
968
|
Widget _buildWorkspaceSection(NeoAgentController controller) {
|
|
630
969
|
return Card(
|
|
631
970
|
child: Padding(
|
|
@@ -345,7 +345,6 @@ class _EntranceMotionState extends State<_EntranceMotion> {
|
|
|
345
345
|
|
|
346
346
|
class _GlassSurface extends StatelessWidget {
|
|
347
347
|
const _GlassSurface({
|
|
348
|
-
super.key,
|
|
349
348
|
required this.child,
|
|
350
349
|
this.width,
|
|
351
350
|
this.padding,
|
|
@@ -2850,17 +2849,24 @@ String _ensureModelValue(
|
|
|
2850
2849
|
if (allowAuto && value == 'auto') {
|
|
2851
2850
|
return 'auto';
|
|
2852
2851
|
}
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
return value;
|
|
2856
|
-
}
|
|
2857
|
-
}
|
|
2852
|
+
final model = _modelForValue(value, models);
|
|
2853
|
+
if (model != null) return model.id;
|
|
2858
2854
|
if (allowAuto) {
|
|
2859
2855
|
return 'auto';
|
|
2860
2856
|
}
|
|
2861
2857
|
return models.isNotEmpty ? models.first.id : value;
|
|
2862
2858
|
}
|
|
2863
2859
|
|
|
2860
|
+
ModelMeta? _modelForValue(String value, List<ModelMeta> models) {
|
|
2861
|
+
for (final model in models) {
|
|
2862
|
+
if (model.id == value) return model;
|
|
2863
|
+
}
|
|
2864
|
+
for (final model in models) {
|
|
2865
|
+
if (model.modelId == value) return model;
|
|
2866
|
+
}
|
|
2867
|
+
return null;
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2864
2870
|
String _firstAvailableModelId(List<ModelMeta> models) {
|
|
2865
2871
|
for (final model in models) {
|
|
2866
2872
|
if (model.available) {
|
|
@@ -2874,11 +2880,8 @@ String _modelLabelForValue(String value, List<ModelMeta> models) {
|
|
|
2874
2880
|
if (value == 'auto' || value.trim().isEmpty) {
|
|
2875
2881
|
return 'Auto';
|
|
2876
2882
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
return model.label;
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2883
|
+
final model = _modelForValue(value, models);
|
|
2884
|
+
if (model != null) return model.label;
|
|
2882
2885
|
return value;
|
|
2883
2886
|
}
|
|
2884
2887
|
|
|
@@ -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,
|
|
@@ -1359,6 +1378,84 @@ class BackendClient {
|
|
|
1359
1378
|
return _asMap(_decodeJson(response.body));
|
|
1360
1379
|
}
|
|
1361
1380
|
|
|
1381
|
+
Future<Map<String, dynamic>> unlockBitwarden(
|
|
1382
|
+
String baseUrl, {
|
|
1383
|
+
required String masterPassword,
|
|
1384
|
+
required int idleTimeoutMinutes,
|
|
1385
|
+
String? agentId,
|
|
1386
|
+
}) {
|
|
1387
|
+
return postMap(
|
|
1388
|
+
baseUrl,
|
|
1389
|
+
'/api/integrations/bitwarden/unlock',
|
|
1390
|
+
_withAgentId(<String, dynamic>{
|
|
1391
|
+
'masterPassword': masterPassword,
|
|
1392
|
+
'idleTimeoutMinutes': idleTimeoutMinutes,
|
|
1393
|
+
}, agentId),
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
Future<Map<String, dynamic>> lockBitwarden(
|
|
1398
|
+
String baseUrl, {
|
|
1399
|
+
String? agentId,
|
|
1400
|
+
}) {
|
|
1401
|
+
return postMap(
|
|
1402
|
+
baseUrl,
|
|
1403
|
+
'/api/integrations/bitwarden/lock',
|
|
1404
|
+
_withAgentId(<String, dynamic>{}, agentId),
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
Future<Map<String, dynamic>> fetchBitwardenItems(
|
|
1409
|
+
String baseUrl, {
|
|
1410
|
+
String? agentId,
|
|
1411
|
+
}) {
|
|
1412
|
+
return getMap(
|
|
1413
|
+
baseUrl,
|
|
1414
|
+
_withAgentQuery('/api/integrations/bitwarden/items', agentId),
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
Future<Map<String, dynamic>> fetchCredentialBindings(
|
|
1419
|
+
String baseUrl, {
|
|
1420
|
+
String? agentId,
|
|
1421
|
+
}) {
|
|
1422
|
+
return getMap(
|
|
1423
|
+
baseUrl,
|
|
1424
|
+
_withAgentQuery('/api/integrations/bitwarden/bindings', agentId),
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
Future<Map<String, dynamic>> createCredentialBinding(
|
|
1429
|
+
String baseUrl, {
|
|
1430
|
+
required Map<String, dynamic> binding,
|
|
1431
|
+
String? agentId,
|
|
1432
|
+
}) {
|
|
1433
|
+
return postMap(
|
|
1434
|
+
baseUrl,
|
|
1435
|
+
'/api/integrations/bitwarden/bindings',
|
|
1436
|
+
_withAgentId(binding, agentId),
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
Future<Map<String, dynamic>> deleteCredentialBinding(
|
|
1441
|
+
String baseUrl,
|
|
1442
|
+
String bindingId, {
|
|
1443
|
+
String? agentId,
|
|
1444
|
+
}) async {
|
|
1445
|
+
final response = await _httpClient.delete(
|
|
1446
|
+
_resolveUri(
|
|
1447
|
+
baseUrl,
|
|
1448
|
+
_withAgentQuery(
|
|
1449
|
+
'/api/integrations/bitwarden/bindings/${Uri.encodeComponent(bindingId)}',
|
|
1450
|
+
agentId,
|
|
1451
|
+
),
|
|
1452
|
+
),
|
|
1453
|
+
headers: const <String, String>{'Accept': 'application/json'},
|
|
1454
|
+
);
|
|
1455
|
+
_throwIfError(response);
|
|
1456
|
+
return _asMap(_decodeJson(response.body));
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1362
1459
|
Future<Map<String, dynamic>> fetchMessagingStatus(
|
|
1363
1460
|
String baseUrl, {
|
|
1364
1461
|
String? agentId,
|