neoagent 2.2.1-beta.6 → 2.2.1-beta.8

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 (68) hide show
  1. package/docs/automation.md +2 -2
  2. package/docs/capabilities.md +7 -10
  3. package/docs/hardware.md +4 -7
  4. package/docs/index.md +7 -7
  5. package/docs/integrations.md +1 -1
  6. package/docs/migration.md +238 -0
  7. package/docs/operations.md +1 -1
  8. package/docs/why-neoagent.md +2 -2
  9. package/lib/manager.js +99 -2
  10. package/lib/migrations.js +409 -0
  11. package/package.json +1 -1
  12. package/server/catalog_sources/store-bundles/skills/productivity/migration/SKILL.md +173 -0
  13. package/server/db/database.js +76 -61
  14. package/server/http/routes.js +1 -2
  15. package/server/public/assets/AssetManifest.json +1 -1
  16. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  17. package/server/public/flutter_bootstrap.js +1 -1
  18. package/server/public/main.dart.js +75830 -74189
  19. package/server/routes/auth.js +13 -5
  20. package/server/routes/integrations.js +22 -0
  21. package/server/routes/messaging.js +41 -5
  22. package/server/routes/settings.js +1 -0
  23. package/server/routes/{scheduler.js → tasks.js} +31 -29
  24. package/server/routes/widgets.js +7 -7
  25. package/server/services/ai/capabilityHealth.js +4 -4
  26. package/server/services/ai/engine.js +9 -9
  27. package/server/services/ai/systemPrompt.js +7 -7
  28. package/server/services/ai/taskAnalysis.js +3 -3
  29. package/server/services/ai/toolResult.js +6 -8
  30. package/server/services/ai/tools.js +62 -95
  31. package/server/services/commands/router.js +14 -6
  32. package/server/services/integrations/google/provider.js +20 -2
  33. package/server/services/integrations/manager.js +79 -8
  34. package/server/services/integrations/whatsapp/provider.js +23 -1
  35. package/server/services/manager.js +14 -14
  36. package/server/services/memory/manager.js +7 -7
  37. package/server/services/memory/policy.js +1 -1
  38. package/server/services/messaging/access_policy.js +703 -0
  39. package/server/services/messaging/access_policy.test.js +228 -0
  40. package/server/services/messaging/automation.js +32 -95
  41. package/server/services/messaging/base.js +39 -0
  42. package/server/services/messaging/discord.js +61 -46
  43. package/server/services/messaging/formatting_guides.js +0 -4
  44. package/server/services/messaging/http_platforms.js +178 -15
  45. package/server/services/messaging/manager.js +136 -71
  46. package/server/services/messaging/telegram.js +54 -40
  47. package/server/services/messaging/telnyx.js +43 -14
  48. package/server/services/messaging/whatsapp.js +27 -0
  49. package/server/services/tasks/adapters/gmail_message_received.js +36 -0
  50. package/server/services/tasks/adapters/index.js +10 -0
  51. package/server/services/tasks/adapters/outlook_email_received.js +38 -0
  52. package/server/services/tasks/adapters/schedule.js +57 -0
  53. package/server/services/tasks/adapters/slack_message_received.js +39 -0
  54. package/server/services/tasks/adapters/teams_message_received.js +39 -0
  55. package/server/services/tasks/adapters/whatsapp_personal_message_received.js +42 -0
  56. package/server/services/tasks/integration_runtime.js +260 -0
  57. package/server/services/tasks/runtime.js +539 -0
  58. package/server/services/{scheduler/cron_utils.js → tasks/schedule_utils.js} +2 -0
  59. package/server/services/tasks/security.js +60 -0
  60. package/server/services/tasks/task_repository.js +162 -0
  61. package/server/services/tasks/trigger_registry.js +29 -0
  62. package/server/services/tasks/utils.js +45 -0
  63. package/server/services/websocket.js +1 -1
  64. package/server/services/widgets/service.js +37 -25
  65. package/server/routes/wearable_device.js +0 -147
  66. package/server/services/messaging/waveshare_wearable.js +0 -40
  67. package/server/services/scheduler/cron.js +0 -580
  68. package/server/services/wearables/device_auth.js +0 -228
@@ -332,13 +332,18 @@ db.exec(`
332
332
  user_id INTEGER NOT NULL,
333
333
  agent_id TEXT,
334
334
  name TEXT NOT NULL,
335
+ trigger_type TEXT DEFAULT 'schedule',
336
+ trigger_config TEXT DEFAULT '{}',
335
337
  cron_expression TEXT,
336
338
  run_at TEXT,
337
339
  one_time INTEGER DEFAULT 0,
340
+ execution_mode TEXT DEFAULT 'prompt',
338
341
  task_type TEXT DEFAULT 'agent_prompt',
339
342
  task_config TEXT DEFAULT '{}',
340
343
  enabled INTEGER DEFAULT 1,
341
344
  last_run TEXT,
345
+ last_triggered_at TEXT,
346
+ last_trigger_fingerprint TEXT,
342
347
  created_at TEXT DEFAULT (datetime('now')),
343
348
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
344
349
  FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
@@ -593,62 +598,6 @@ db.exec(`
593
598
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
594
599
  );
595
600
 
596
- CREATE TABLE IF NOT EXISTS wearable_devices (
597
- id TEXT PRIMARY KEY,
598
- user_id INTEGER NOT NULL,
599
- mac_address TEXT,
600
- protocol TEXT NOT NULL,
601
- name TEXT NOT NULL,
602
- status TEXT DEFAULT 'disconnected',
603
- battery_level INTEGER,
604
- last_seen_at TEXT,
605
- created_at TEXT DEFAULT (datetime('now')),
606
- updated_at TEXT DEFAULT (datetime('now')),
607
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
608
- UNIQUE(user_id, mac_address)
609
- );
610
-
611
- CREATE TABLE IF NOT EXISTS wearable_pairing_codes (
612
- id TEXT PRIMARY KEY,
613
- user_id INTEGER NOT NULL,
614
- agent_id TEXT,
615
- code_hash TEXT NOT NULL UNIQUE,
616
- status TEXT DEFAULT 'active',
617
- metadata_json TEXT DEFAULT '{}',
618
- expires_at TEXT NOT NULL,
619
- claimed_at TEXT,
620
- created_at TEXT DEFAULT (datetime('now')),
621
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
622
- FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
623
- );
624
-
625
- CREATE TABLE IF NOT EXISTS wearable_device_tokens (
626
- id TEXT PRIMARY KEY,
627
- user_id INTEGER NOT NULL,
628
- agent_id TEXT,
629
- token_hash TEXT NOT NULL UNIQUE,
630
- device_id TEXT,
631
- device_name TEXT,
632
- mac_address TEXT,
633
- protocol TEXT,
634
- firmware_version TEXT,
635
- status TEXT DEFAULT 'active',
636
- last_seen_at TEXT,
637
- last_connected_at TEXT,
638
- revoked_at TEXT,
639
- metadata_json TEXT DEFAULT '{}',
640
- created_at TEXT DEFAULT (datetime('now')),
641
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
642
- FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
643
- );
644
-
645
- CREATE TABLE IF NOT EXISTS wearable_device_message_cursors (
646
- token_id TEXT PRIMARY KEY,
647
- last_message_id INTEGER DEFAULT 0,
648
- updated_at TEXT DEFAULT (datetime('now')),
649
- FOREIGN KEY (token_id) REFERENCES wearable_device_tokens(id) ON DELETE CASCADE
650
- );
651
-
652
601
  CREATE TABLE IF NOT EXISTS recording_sources (
653
602
  id TEXT PRIMARY KEY,
654
603
  session_id TEXT NOT NULL,
@@ -701,11 +650,6 @@ db.exec(`
701
650
  CREATE INDEX IF NOT EXISTS idx_recording_sources_session ON recording_sources(session_id, source_key);
702
651
  CREATE INDEX IF NOT EXISTS idx_recording_chunks_source ON recording_chunks(source_id, sequence_index);
703
652
  CREATE INDEX IF NOT EXISTS idx_recording_segments_session ON recording_transcript_segments(session_id, start_ms, created_at);
704
- CREATE INDEX IF NOT EXISTS idx_wearable_pairing_codes_user ON wearable_pairing_codes(user_id, status, expires_at);
705
- CREATE INDEX IF NOT EXISTS idx_wearable_pairing_codes_agent ON wearable_pairing_codes(agent_id, status, expires_at);
706
- CREATE INDEX IF NOT EXISTS idx_wearable_device_tokens_user ON wearable_device_tokens(user_id, status, created_at DESC);
707
- CREATE INDEX IF NOT EXISTS idx_wearable_device_tokens_mac ON wearable_device_tokens(user_id, mac_address, status);
708
- CREATE INDEX IF NOT EXISTS idx_wearable_device_cursors_updated ON wearable_device_message_cursors(updated_at);
709
653
 
710
654
  CREATE TABLE IF NOT EXISTS artifacts (
711
655
  id TEXT PRIMARY KEY,
@@ -786,6 +730,22 @@ try {
786
730
  // FTS5 is optional. The app still works with LIKE-based fallbacks if unavailable.
787
731
  }
788
732
 
733
+ try {
734
+ db.exec(`
735
+ DROP INDEX IF EXISTS idx_wearable_pairing_codes_user;
736
+ DROP INDEX IF EXISTS idx_wearable_pairing_codes_agent;
737
+ DROP INDEX IF EXISTS idx_wearable_device_tokens_user;
738
+ DROP INDEX IF EXISTS idx_wearable_device_tokens_mac;
739
+ DROP INDEX IF EXISTS idx_wearable_device_cursors_updated;
740
+ DROP TABLE IF EXISTS wearable_device_message_cursors;
741
+ DROP TABLE IF EXISTS wearable_device_tokens;
742
+ DROP TABLE IF EXISTS wearable_pairing_codes;
743
+ DROP TABLE IF EXISTS wearable_devices;
744
+ `);
745
+ } catch {
746
+ // Ignore cleanup failures for obsolete wearable tables.
747
+ }
748
+
789
749
  // Migrations for existing databases
790
750
  for (const col of [
791
751
  "ALTER TABLE agent_runs ADD COLUMN agent_id TEXT",
@@ -800,12 +760,17 @@ for (const col of [
800
760
  "ALTER TABLE integration_connections ADD COLUMN agent_id TEXT",
801
761
  "ALTER TABLE integration_oauth_states ADD COLUMN agent_id TEXT",
802
762
  "ALTER TABLE scheduled_tasks ADD COLUMN agent_id TEXT",
763
+ "ALTER TABLE scheduled_tasks ADD COLUMN trigger_type TEXT DEFAULT 'schedule'",
764
+ "ALTER TABLE scheduled_tasks ADD COLUMN trigger_config TEXT DEFAULT '{}'",
803
765
  "ALTER TABLE conversations ADD COLUMN agent_id TEXT",
804
766
  "ALTER TABLE conversation_history ADD COLUMN agent_id TEXT",
805
767
  "ALTER TABLE memories ADD COLUMN agent_id TEXT",
806
768
  "ALTER TABLE core_memory ADD COLUMN agent_id TEXT",
807
769
  "ALTER TABLE scheduled_tasks ADD COLUMN run_at TEXT",
808
770
  "ALTER TABLE scheduled_tasks ADD COLUMN one_time INTEGER DEFAULT 0",
771
+ "ALTER TABLE scheduled_tasks ADD COLUMN execution_mode TEXT DEFAULT 'prompt'",
772
+ "ALTER TABLE scheduled_tasks ADD COLUMN last_triggered_at TEXT",
773
+ "ALTER TABLE scheduled_tasks ADD COLUMN last_trigger_fingerprint TEXT",
809
774
  "ALTER TABLE agent_runs ADD COLUMN prompt_metrics TEXT",
810
775
  "ALTER TABLE agent_runs ADD COLUMN metadata_json TEXT",
811
776
  "ALTER TABLE agent_runs ADD COLUMN final_response TEXT",
@@ -1330,8 +1295,58 @@ function backfillVerifiedAccountEmails() {
1330
1295
  }
1331
1296
  }
1332
1297
 
1298
+ function backfillTaskTriggers() {
1299
+ try {
1300
+ db.prepare(
1301
+ `UPDATE scheduled_tasks
1302
+ SET trigger_type = CASE
1303
+ WHEN COALESCE(trigger_type, '') = '' THEN 'schedule'
1304
+ ELSE trigger_type
1305
+ END`
1306
+ ).run();
1307
+ } catch {}
1308
+
1309
+ try {
1310
+ const rows = db
1311
+ .prepare(
1312
+ `SELECT id, cron_expression, run_at, one_time, trigger_type, trigger_config
1313
+ FROM scheduled_tasks`,
1314
+ )
1315
+ .all();
1316
+ const update = db.prepare(
1317
+ `UPDATE scheduled_tasks
1318
+ SET trigger_type = ?, trigger_config = ?, execution_mode = COALESCE(NULLIF(execution_mode, ''), 'prompt')
1319
+ WHERE id = ?`,
1320
+ );
1321
+ const tx = db.transaction(() => {
1322
+ for (const row of rows) {
1323
+ const triggerType = String(row.trigger_type || 'schedule').trim() || 'schedule';
1324
+ let parsedConfig = {};
1325
+ try {
1326
+ parsedConfig = JSON.parse(String(row.trigger_config || '{}')) || {};
1327
+ } catch {
1328
+ parsedConfig = {};
1329
+ }
1330
+ const hasConfig = parsedConfig && typeof parsedConfig === 'object' && !Array.isArray(parsedConfig) && Object.keys(parsedConfig).length > 0;
1331
+ if (triggerType !== 'schedule' && hasConfig) {
1332
+ update.run(triggerType, JSON.stringify(parsedConfig), row.id);
1333
+ continue;
1334
+ }
1335
+
1336
+ const mode = row.one_time ? 'one_time' : 'recurring';
1337
+ const config = row.one_time
1338
+ ? { mode, runAt: row.run_at || null }
1339
+ : { mode, cronExpression: row.cron_expression || null };
1340
+ update.run('schedule', JSON.stringify(config), row.id);
1341
+ }
1342
+ });
1343
+ tx();
1344
+ } catch {}
1345
+ }
1346
+
1333
1347
  backfillAgentIds();
1334
1348
  backfillAgentPolicies();
1349
+ backfillTaskTriggers();
1335
1350
  rebuildPlatformConnectionsForAgents();
1336
1351
  rebuildCoreMemoryForAgents();
1337
1352
  migrateIntegrationConnectionsTable();
@@ -18,7 +18,7 @@ const routeRegistry = [
18
18
  { basePath: '/api/store', modulePath: '../routes/store' },
19
19
  { basePath: '/api/artifacts', modulePath: '../routes/artifacts' },
20
20
  { basePath: '/api/memory', modulePath: '../routes/memory' },
21
- { basePath: '/api/scheduler', modulePath: '../routes/scheduler' },
21
+ { basePath: '/api/tasks', modulePath: '../routes/tasks' },
22
22
  { basePath: '/api/widgets', modulePath: '../routes/widgets' },
23
23
  { basePath: '/api/browser', modulePath: '../routes/browser' },
24
24
  { basePath: '/api/browser-extension', modulePath: '../routes/browser_extension' },
@@ -26,7 +26,6 @@ const routeRegistry = [
26
26
  { basePath: '/api/desktop', modulePath: '../routes/desktop' },
27
27
  { basePath: '/api/recordings', modulePath: '../routes/recordings' },
28
28
  { basePath: '/api/voice-assistant', modulePath: '../routes/voice_assistant' },
29
- { basePath: '/api/wearable-device', modulePath: '../routes/wearable_device' },
30
29
  { basePath: '/api/mobile/health', modulePath: '../routes/mobile-health' }
31
30
  ];
32
31
 
@@ -1 +1 @@
1
- {"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"],"web/icons/Icon-192.png":["web/icons/Icon-192.png"]}
1
+ {"assets/branding/app_icon_256.png":["assets/branding/app_icon_256.png"],"assets/branding/tray_icon_template.png":["assets/branding/tray_icon_template.png"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"],"packages/record_web/assets/js/record.fixwebmduration.js":["packages/record_web/assets/js/record.fixwebmduration.js"],"packages/record_web/assets/js/record.worklet.js":["packages/record_web/assets/js/record.worklet.js"],"web/icons/Icon-192.png":["web/icons/Icon-192.png"]}
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"59aa584fdf100e6c78c785d8a5b565d1de4b48
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "3879536533" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "807831779" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });