neoagent 2.2.1-beta.5 → 2.2.1-beta.7

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 (49) 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 +6 -7
  5. package/docs/integrations.md +1 -1
  6. package/docs/operations.md +1 -1
  7. package/docs/why-neoagent.md +2 -2
  8. package/package.json +1 -1
  9. package/server/db/database.js +76 -61
  10. package/server/http/routes.js +1 -2
  11. package/server/public/assets/AssetManifest.json +1 -1
  12. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  13. package/server/public/flutter_bootstrap.js +1 -1
  14. package/server/public/main.dart.js +65118 -64805
  15. package/server/routes/{scheduler.js → tasks.js} +31 -29
  16. package/server/routes/widgets.js +7 -7
  17. package/server/services/ai/capabilityHealth.js +4 -4
  18. package/server/services/ai/engine.js +31 -12
  19. package/server/services/ai/systemPrompt.js +7 -7
  20. package/server/services/ai/taskAnalysis.js +3 -3
  21. package/server/services/ai/toolResult.js +6 -8
  22. package/server/services/ai/tools.js +62 -95
  23. package/server/services/commands/router.js +14 -6
  24. package/server/services/integrations/whatsapp/provider.js +23 -1
  25. package/server/services/manager.js +14 -14
  26. package/server/services/memory/manager.js +7 -7
  27. package/server/services/memory/policy.js +1 -1
  28. package/server/services/messaging/formatting_guides.js +0 -4
  29. package/server/services/messaging/manager.js +0 -2
  30. package/server/services/tasks/adapters/gmail_message_received.js +36 -0
  31. package/server/services/tasks/adapters/index.js +10 -0
  32. package/server/services/tasks/adapters/outlook_email_received.js +38 -0
  33. package/server/services/tasks/adapters/schedule.js +57 -0
  34. package/server/services/tasks/adapters/slack_message_received.js +39 -0
  35. package/server/services/tasks/adapters/teams_message_received.js +39 -0
  36. package/server/services/tasks/adapters/whatsapp_personal_message_received.js +42 -0
  37. package/server/services/tasks/integration_runtime.js +260 -0
  38. package/server/services/tasks/runtime.js +539 -0
  39. package/server/services/{scheduler/cron_utils.js → tasks/schedule_utils.js} +2 -0
  40. package/server/services/tasks/security.js +60 -0
  41. package/server/services/tasks/task_repository.js +162 -0
  42. package/server/services/tasks/trigger_registry.js +29 -0
  43. package/server/services/tasks/utils.js +45 -0
  44. package/server/services/websocket.js +1 -1
  45. package/server/services/widgets/service.js +38 -25
  46. package/server/routes/wearable_device.js +0 -147
  47. package/server/services/messaging/waveshare_wearable.js +0 -40
  48. package/server/services/scheduler/cron.js +0 -580
  49. package/server/services/wearables/device_auth.js +0 -228
@@ -2,9 +2,9 @@
2
2
 
3
3
  NeoAgent is built for proactive work: tasks that run later, repeat on a schedule, use tools, and notify you when there is something useful to report.
4
4
 
5
- ## Scheduler
5
+ ## Tasks
6
6
 
7
- Use the **Scheduler** section in the UI to create recurring tasks. A scheduled task has:
7
+ Use the **Tasks** section in the UI to create scheduled automations. These tasks use Cron expressions for time-based scheduling. A task has:
8
8
 
9
9
  | Field | Purpose |
10
10
  |---|---|
@@ -9,9 +9,9 @@ The Flutter client exposes the main operator surfaces:
9
9
  | Section | What it is for |
10
10
  |---|---|
11
11
  | Chat | Normal agent runs with tools, memory, integrations, and messaging |
12
- | Runs | Live and historical run steps, including browser, Android, CLI, messaging, scheduler, MCP, and subagent work |
12
+ | Runs | Live and historical run steps, including browser, Android, CLI, messaging, tasks, MCP, and subagent work |
13
13
  | Logs | Service logs and diagnostics from the server you are connected to |
14
- | Scheduler | Recurring cron tasks and one-time future runs |
14
+ | Tasks | Schedule-triggered and integration-triggered automations |
15
15
  | Skills | Built-in and custom reusable workflows |
16
16
  | Integrations | OAuth account connections for structured app tools |
17
17
  | MCP | Remote MCP server registration and tool discovery |
@@ -19,12 +19,11 @@ The Flutter client exposes the main operator surfaces:
19
19
  | Devices | Server-side browser and Android runtime controls |
20
20
  | Recordings | Recording sessions, transcripts, segments, and playback |
21
21
  | Health | Android Health Connect sync status and synced metrics |
22
- | Wearables | Supported Bluetooth recording devices and audio upload status |
23
22
  | Settings | AI providers, model routing, runtime settings, messaging, and service controls |
24
23
 
25
24
  ## Recordings
26
25
 
27
- NeoAgent records audio as server-side sessions with one or more sources. The web client can record browser microphone and screen audio, the Android app can record phone microphone audio through a foreground service, and the wearable bridge can upload audio chunks from supported Bluetooth devices.
26
+ NeoAgent records audio as server-side sessions with one or more sources. The web client can record browser microphone and screen audio, and the Android app can record phone microphone audio through a foreground service.
28
27
 
29
28
  Recording sessions support:
30
29
 
@@ -55,18 +54,16 @@ Android control supports:
55
54
 
56
55
  These actions run where the NeoAgent backend is running. If NeoAgent is deployed on a remote server, the AI controls the Android runtime attached to that server, not the laptop where you are reading the docs.
57
56
 
58
- ## Android App, Health, And Wearables
57
+ ## Android App And Health
59
58
 
60
- The Flutter Android app is still useful as a client. It can sign in to the same self-hosted backend, run chat and operator UI flows, sync Health Connect data, record audio locally, and bridge supported wearables.
59
+ The Flutter Android app is still useful as a client. It can sign in to the same self-hosted backend, run chat and operator UI flows, sync Health Connect data, and record audio locally.
61
60
 
62
61
  Android app capabilities include:
63
62
 
64
63
  - `NEOAGENT_BACKEND_URL` build/run configuration for real devices.
65
64
  - Health Connect permission flow and background sync.
66
65
  - Microphone recording through an Android foreground service.
67
- - Boot restore hooks for recording and wearable services when Android allows them.
68
- - Bluetooth wearable bridge support for HeyPocket-style devices.
69
- - Upload of wearable chunks and synchronization state to the backend.
66
+ - Boot restore hooks for recording services when Android allows them.
70
67
 
71
68
  ## Health Data
72
69
 
@@ -99,7 +96,7 @@ NeoAgent's agent tool surface includes more than basic chat:
99
96
  | HTTP | Direct HTTP requests |
100
97
  | Memory | Semantic memory, session search, daily logs, API key name reads, and core memory |
101
98
  | Skills | Create, list, update, and delete persistent skills |
102
- | Scheduler | Recurring tasks, one-time runs, model overrides, and optional Telnyx call delivery |
99
+ | Tasks | Schedule-triggered and integration-triggered automations, one-time runs, model overrides, and optional Telnyx call delivery |
103
100
  | MCP | Add, list, and remove MCP servers, plus dynamic MCP tool use |
104
101
  | Subagents | Spawn, list, wait for, and cancel async subagents inside a run |
105
102
  | Output | Generate markdown tables and Mermaid graphs |
package/docs/hardware.md CHANGED
@@ -1,11 +1,8 @@
1
1
  ---
2
- title: Waveshare ESP32-S3 1.8inch AMOLED Setup
3
- sidebar_label: Waveshare 1.8inch AMOLED
2
+ title: Hardware
3
+ sidebar_label: Hardware
4
4
  ---
5
5
 
6
- # Waveshare ESP32-S3 1.8inch AMOLED Setup
7
-
8
- Use this only if you want to build or flash this board:
9
-
10
- Waveshare ESP32-S3 1.8inch AMOLED Touch Display Dev Board
6
+ # Hardware
11
7
 
8
+ There is no dedicated hardware or wearable firmware bundled with NeoAgent.
package/docs/index.md CHANGED
@@ -6,9 +6,9 @@ sidebar_label: Overview
6
6
 
7
7
  # NeoAgent
8
8
 
9
- NeoAgent is a self-hosted proactive AI agent with a bundled Flutter client for web and Android. It runs on your server, keeps credentials server-side, and gives you an operator UI for chat, runs, logs, scheduler tasks, skills, integrations, MCP, memory, Android control, recordings, Health Connect data, wearables, and settings.
9
+ NeoAgent is a self-hosted proactive AI agent with a bundled Flutter client for web and Android. It runs on your server, keeps credentials server-side, and gives you an operator UI for chat, runs, logs, tasks, skills, integrations, MCP, memory, Android control, recordings, Health Connect data, and settings.
10
10
 
11
- It is designed for people who want a focused personal automation server rather than a broad gateway platform. NeoAgent can run scheduled tasks, control a browser, operate a server-attached Android emulator or device, manage files, remember long-term context, connect to hosted AI providers or local Ollama, search recordings, read synced health summaries, and send results through Telegram, Discord, WhatsApp, or Telnyx Voice.
11
+ It is designed for people who want a focused personal automation server rather than a broad gateway platform. NeoAgent can run triggered tasks, control a browser, operate a server-attached Android emulator or device, manage files, remember long-term context, connect to hosted AI providers or local Ollama, search recordings, read synced health summaries, and send results through Telegram, Discord, WhatsApp, or Telnyx Voice.
12
12
 
13
13
  ## Quick Start
14
14
 
@@ -17,17 +17,17 @@ npm install -g neoagent
17
17
  neoagent install
18
18
  ```
19
19
 
20
- Open the server URL, sign in, configure providers and messaging, then create a scheduled task or chat run.
20
+ Open the server URL, sign in, configure providers and messaging, then create a task or chat run.
21
21
 
22
22
  ## What NeoAgent Does
23
23
 
24
24
  | Area | Capability |
25
25
  |---|---|
26
26
  | AI providers | OpenAI, Anthropic, xAI, Google, MiniMax Code, and local Ollama |
27
- | Operator UI | Chat, live runs, logs, scheduler, skills, integrations, MCP, memory, devices, recordings, health, wearables, settings |
28
- | Automation | Recurring scheduled tasks, one-time runs, browser control, file access, CLI skills, subagents, and messaging delivery |
27
+ | Operator UI | Chat, live runs, logs, tasks, skills, integrations, MCP, memory, devices, recordings, health, settings |
28
+ | Automation | Triggered tasks, one-time runs, browser control, file access, CLI skills, subagents, and messaging delivery |
29
29
  | Android control | AI control of a server-attached Android emulator or device: screenshots, UI dumps, taps, typing, intents, APK installs, and ADB shell |
30
- | Recordings | Web, Android, and wearable audio sessions with transcript search and AI insights |
30
+ | Recordings | Web and Android audio sessions with transcript search and AI insights |
31
31
  | Integrations | Google Workspace, Notion, Microsoft 365, Slack, Figma, and remote MCP servers |
32
32
  | Messaging | Telegram, Discord, WhatsApp text/media, and Telnyx Voice calls |
33
33
  | Outputs | Artifacts, Grok image generation, vision analysis, markdown tables, and Mermaid graphs |
@@ -46,5 +46,4 @@ Open the server URL, sign in, configure providers and messaging, then create a s
46
46
  | Skills and MCP | [Skills](skills.md) |
47
47
  | Secrets and runtime settings | [Configuration](configuration.md) |
48
48
  | Logs, updates, and repair | [Operations](operations.md) |
49
- | Want to flash a Waveshare ESP32-S3 1.8inch AMOLED | [Waveshare ESP32-S3 1.8inch AMOLED Setup](hardware.md) |
50
49
  | OpenClaw comparison | [Why NeoAgent](why-neoagent.md) |
@@ -53,7 +53,7 @@ NeoAgent can talk through:
53
53
  | IRC and Twitch | IRC-style channel connections |
54
54
  | LINE and Mattermost | Native send paths with webhook ingestion |
55
55
  | Feishu, Nextcloud Talk, Nostr, Synology Chat, Tlon, Zalo, Zalo Personal, WeChat, and WebChat | Configurable webhook bridges |
56
- | Telnyx Voice | Inbound and outbound calling with text-to-speech; scheduled tasks can call a number |
56
+ | Telnyx Voice | Inbound and outbound calling with text-to-speech; tasks can call a number |
57
57
 
58
58
  Messaging channel credentials are configured through the Flutter app messaging tab (not `.env`) for channel setup and inbound callback routing. The generic inbound callback path is:
59
59
 
@@ -10,7 +10,7 @@ neoagent logs
10
10
  neoagent restart
11
11
  ```
12
12
 
13
- `neoagent status` reports the install root, config path, runtime data paths, release channel, and service state. `neoagent logs` is the first place to look when the service starts but the UI, messaging, OAuth, or scheduled tasks behave unexpectedly.
13
+ `neoagent status` reports the install root, config path, runtime data paths, release channel, and service state. `neoagent logs` is the first place to look when the service starts but the UI, messaging, OAuth, or tasks behave unexpectedly.
14
14
 
15
15
  ## Release Channels
16
16
 
@@ -11,9 +11,9 @@ This comparison is based on the public [OpenClaw README](https://raw.githubuserc
11
11
  | Architecture | Self-hosted Node server, SQLite runtime data, built-in web UI, Android client, server-side credentials. | Gateway control plane with channel connections, optional apps/nodes, and a much wider platform surface. |
12
12
  | Android control | AI control of a server-attached Android emulator or device: screenshots, UI dumps, visible node inspection, app launch, intent launch, taps, long press, typing, swipes, key presses, wait-for-element, APK installs, and `adb shell`. | Broader node/app ecosystem with Android node capabilities documented publicly. |
13
13
  | Messaging breadth | Broad built-in messaging tab coverage: WhatsApp, Telegram, Discord, Slack, Google Chat, Signal, iMessage/BlueBubbles, IRC, Teams, Matrix, LINE, Mattermost, Twitch, and configurable webhook bridges for Feishu, Nextcloud Talk, Nostr, Synology Chat, Tlon, Zalo, WeChat, and WebChat, plus Telnyx Voice. | Still broader as a gateway ecosystem: the public README lists the same major channels plus a larger channel/node/app surface around them. |
14
- | Operator UX | Built-in UI sections for chat, runs, logs, scheduler, skills, integrations, MCP, memory, devices, recordings, health, and settings. | Broader gateway, web, canvas, platform, node, and channel surfaces. |
14
+ | Operator UX | Built-in UI sections for chat, runs, logs, tasks, skills, integrations, MCP, memory, devices, recordings, health, and settings. | Broader gateway, web, canvas, platform, node, and channel surfaces. |
15
15
  | Credentials | AI provider keys and OAuth client secrets are server-side; channel settings are stored through the app where supported. | Public docs describe a broader config and auth surface across gateway, channels, nodes, and apps. |
16
- | Automation | Cron-style scheduled tasks, one-time runs, browser/file/CLI skills, MCP tools, official integrations, subagents, recording search, health summaries, and messaging delivery. | Broader automation platform including cron, webhooks, nodes, and channel-specific actions. |
16
+ | Automation | Trigger-based tasks, one-time runs, browser/file/CLI skills, MCP tools, official integrations, subagents, recording search, health summaries, and messaging delivery. | Broader automation platform including cron, webhooks, nodes, and channel-specific actions. |
17
17
  | Recovery | CLI-first service operations: `neoagent status`, `neoagent logs`, release channels, `neoagent update`, and `neoagent fix`. | Public README highlights onboarding, updating, and doctor-style diagnostics. |
18
18
 
19
19
  Choose NeoAgent when you want the shortest path to a self-hosted proactive agent with a practical operator UI. Choose OpenClaw when you need maximum channel coverage, gateway/node architecture, or the larger companion-app ecosystem.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.2.1-beta.5",
3
+ "version": "2.2.1-beta.7",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -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: "3025620122" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "3421203079" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });