neoagent 2.4.1-beta.34 → 2.4.1-beta.36

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.
Files changed (30) hide show
  1. package/.env.example +10 -3
  2. package/flutter_app/lib/main_admin.dart +13 -0
  3. package/flutter_app/lib/main_controller.dart +24 -6
  4. package/flutter_app/lib/main_models.dart +14 -0
  5. package/package.json +1 -1
  6. package/server/public/.last_build_id +1 -1
  7. package/server/public/flutter_bootstrap.js +1 -1
  8. package/server/public/main.dart.js +13767 -13696
  9. package/server/routes/mcp.js +29 -13
  10. package/server/routes/memory.js +1 -0
  11. package/server/services/ai/engine.js +35 -6
  12. package/server/services/ai/systemPrompt.js +28 -22
  13. package/server/services/ai/taskAnalysis.js +4 -1
  14. package/server/services/ai/toolSelector.js +8 -1
  15. package/server/services/ai/tools.js +12 -3
  16. package/server/services/desktop/screenRecorder.js +208 -98
  17. package/server/services/desktop/screen_recorder_support.js +46 -0
  18. package/server/services/manager.js +51 -53
  19. package/server/services/mcp/client.js +208 -268
  20. package/server/services/mcp/client_support.js +172 -0
  21. package/server/services/mcp/recovery.js +116 -0
  22. package/server/services/mcp/tool_operations.js +123 -0
  23. package/server/services/memory/ingestion.js +185 -370
  24. package/server/services/memory/ingestion_coverage.js +129 -0
  25. package/server/services/memory/ingestion_documents.js +123 -0
  26. package/server/services/memory/ingestion_support.js +171 -0
  27. package/server/services/messaging/automation.js +71 -134
  28. package/server/services/messaging/inbound_queue.js +111 -0
  29. package/server/services/messaging/typing_keepalive.js +110 -0
  30. package/server/services/tasks/runtime.js +133 -21
package/.env.example CHANGED
@@ -219,9 +219,16 @@ DEEPGRAM_LANGUAGE=multi
219
219
 
220
220
  OLLAMA_URL=http://localhost:11434
221
221
 
222
- # Local screen OCR capture (macOS desktop context recorder).
223
- # Set to false to disable background screen capture/OCR polling.
224
- NEOAGENT_SCREEN_RECORDER_ENABLED=true
222
+ # Connected integration memory refresh cadence in milliseconds.
223
+ NEOAGENT_MEMORY_INGESTION_INTERVAL_MS=600000
224
+
225
+ # Local screen OCR capture. This captures the backend host's macOS desktop,
226
+ # so enable it only when that host is the configured user's desktop.
227
+ NEOAGENT_SCREEN_RECORDER_ENABLED=false
228
+ # Existing NeoAgent user ID that owns all captured screen history. Required when enabled.
229
+ NEOAGENT_SCREEN_RECORDER_USER_ID=
230
+ NEOAGENT_SCREEN_RECORDER_INTERVAL_MS=10000
231
+ NEOAGENT_SCREEN_RECORDER_RETENTION_DAYS=7
225
232
 
226
233
  ########################################
227
234
  # Messaging and voice integrations
@@ -429,6 +429,8 @@ class McpPanel extends StatelessWidget {
429
429
  label: server.status,
430
430
  color: server.status == 'running'
431
431
  ? _success
432
+ : server.hasError
433
+ ? _danger
432
434
  : _textSecondary,
433
435
  ),
434
436
  ],
@@ -465,6 +467,17 @@ class McpPanel extends StatelessWidget {
465
467
  ),
466
468
  ],
467
469
  ),
470
+ if (server.hasError) ...<Widget>[
471
+ const SizedBox(height: 12),
472
+ _InlineError(message: server.error!),
473
+ if (server.retryLabel.isNotEmpty) ...<Widget>[
474
+ const SizedBox(height: 8),
475
+ Text(
476
+ server.retryLabel,
477
+ style: TextStyle(color: _textSecondary),
478
+ ),
479
+ ],
480
+ ],
468
481
  const SizedBox(height: 14),
469
482
  Wrap(
470
483
  spacing: 10,
@@ -6112,18 +6112,36 @@ class NeoAgentController extends ChangeNotifier {
6112
6112
  }
6113
6113
 
6114
6114
  Future<void> startMcpServer(int id) async {
6115
- await _backendClient.startMcpServer(backendUrl, id);
6116
- await refreshMcp();
6115
+ try {
6116
+ await _backendClient.startMcpServer(backendUrl, id);
6117
+ await refreshMcp();
6118
+ } catch (error) {
6119
+ errorMessage = _friendlyErrorMessage(error);
6120
+ await refreshMcp();
6121
+ notifyListeners();
6122
+ }
6117
6123
  }
6118
6124
 
6119
6125
  Future<void> stopMcpServer(int id) async {
6120
- await _backendClient.stopMcpServer(backendUrl, id);
6121
- await refreshMcp();
6126
+ try {
6127
+ await _backendClient.stopMcpServer(backendUrl, id);
6128
+ await refreshMcp();
6129
+ } catch (error) {
6130
+ errorMessage = _friendlyErrorMessage(error);
6131
+ await refreshMcp();
6132
+ notifyListeners();
6133
+ }
6122
6134
  }
6123
6135
 
6124
6136
  Future<void> deleteMcpServer(int id) async {
6125
- await _backendClient.deleteMcpServer(backendUrl, id);
6126
- await refreshMcp();
6137
+ try {
6138
+ await _backendClient.deleteMcpServer(backendUrl, id);
6139
+ await refreshMcp();
6140
+ } catch (error) {
6141
+ errorMessage = _friendlyErrorMessage(error);
6142
+ await refreshMcp();
6143
+ notifyListeners();
6144
+ }
6127
6145
  }
6128
6146
 
6129
6147
  Future<void> requestHealthPermissions() async {
@@ -3397,6 +3397,9 @@ class McpServerItem {
3397
3397
  required this.enabled,
3398
3398
  required this.status,
3399
3399
  required this.toolCount,
3400
+ required this.error,
3401
+ required this.consecutiveFails,
3402
+ required this.nextRetryAt,
3400
3403
  });
3401
3404
 
3402
3405
  factory McpServerItem.fromJson(Map<dynamic, dynamic> json) {
@@ -3411,6 +3414,9 @@ class McpServerItem {
3411
3414
  enabled: json['enabled'] == true,
3412
3415
  status: json['status']?.toString().ifEmpty('stopped') ?? 'stopped',
3413
3416
  toolCount: _asInt(json['toolCount']),
3417
+ error: json['error']?.toString(),
3418
+ consecutiveFails: _asInt(json['consecutiveFails']),
3419
+ nextRetryAt: _parseOptionalTimestamp(json['nextRetryAt']?.toString()),
3414
3420
  );
3415
3421
  }
3416
3422
 
@@ -3422,6 +3428,14 @@ class McpServerItem {
3422
3428
  final bool enabled;
3423
3429
  final String status;
3424
3430
  final int toolCount;
3431
+ final String? error;
3432
+ final int consecutiveFails;
3433
+ final DateTime? nextRetryAt;
3434
+
3435
+ bool get hasError => (error ?? '').trim().isNotEmpty;
3436
+ String get retryLabel => nextRetryAt == null
3437
+ ? ''
3438
+ : 'Next retry: ${_formatTimestamp(nextRetryAt!)}';
3425
3439
 
3426
3440
  String get authMethodLabel {
3427
3441
  final auth = _jsonMap(config['auth']);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.4.1-beta.34",
3
+ "version": "2.4.1-beta.36",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "server/index.js",
@@ -1 +1 @@
1
- 79f8662ed3c8bed9a624d3d498b9e894
1
+ cd629bebff6e6d3f781e6810f13e3583
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"c416acfeb8126e097f758c664aaa3da929e27d
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "3692681921" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "4109168282" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });