neoagent 2.3.1-beta.0 → 2.3.1-beta.3

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 (38) hide show
  1. package/README.md +2 -0
  2. package/docs/automation.md +1 -1
  3. package/docs/capabilities.md +2 -2
  4. package/docs/configuration.md +6 -1
  5. package/docs/integrations.md +4 -0
  6. package/package.json +2 -1
  7. package/server/db/database.js +57 -0
  8. package/server/http/routes/screenHistory.js +46 -0
  9. package/server/http/routes/triggers.js +81 -0
  10. package/server/http/routes.js +3 -1
  11. package/server/public/assets/NOTICES +61 -0
  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 +46519 -46294
  15. package/server/routes/integrations.js +11 -8
  16. package/server/services/ai/engine.js +9 -0
  17. package/server/services/ai/systemPrompt.js +1 -1
  18. package/server/services/ai/tools.js +150 -11
  19. package/server/services/browser/controller.js +47 -3
  20. package/server/services/desktop/screenRecorder.js +126 -0
  21. package/server/services/integrations/env.js +5 -0
  22. package/server/services/integrations/registry.js +4 -0
  23. package/server/services/integrations/spotify/provider.js +487 -0
  24. package/server/services/integrations/weather/provider.js +559 -0
  25. package/server/services/integrations/whatsapp/provider.js +6 -2
  26. package/server/services/manager.js +22 -0
  27. package/server/services/messaging/manager.js +29 -7
  28. package/server/services/skills/base_catalog.js +33 -0
  29. package/server/services/tasks/adapters/index.js +2 -0
  30. package/server/services/tasks/adapters/manual.js +12 -0
  31. package/server/services/tasks/adapters/schedule.js +33 -5
  32. package/server/services/tasks/adapters/weather_event.js +84 -0
  33. package/server/services/tasks/integration_runtime.js +85 -0
  34. package/server/services/tasks/runtime.js +2 -2
  35. package/server/services/voice/agentBridge.js +20 -4
  36. package/server/services/voice/message.js +3 -0
  37. package/server/services/voice/runtimeManager.js +136 -1
  38. package/server/services/widgets/service.js +49 -4
package/README.md CHANGED
@@ -22,6 +22,8 @@
22
22
  ```bash
23
23
  npm install -g neoagent
24
24
  neoagent install
25
+
26
+ neoagent migrate
25
27
  ```
26
28
 
27
29
  ## Manage the Service
@@ -4,7 +4,7 @@ NeoAgent is built for proactive work: tasks that run later, repeat on a schedule
4
4
 
5
5
  ## Tasks
6
6
 
7
- Use the **Tasks** section in the UI to create scheduled automations. These tasks use Cron expressions for time-based scheduling. A task has:
7
+ Use the **Tasks** section in the UI to create automations. Tasks can be time-based (Cron) or integration-triggered (for example email, messaging, and weather-event triggers). A task has:
8
8
 
9
9
  | Field | Purpose |
10
10
  |---|---|
@@ -75,10 +75,10 @@ The agent tool `read_health_data` returns summaries and recent samples. It is de
75
75
 
76
76
  NeoAgent has two separate integration layers:
77
77
 
78
- - Official integrations expose structured tools for Google Workspace, Microsoft 365, Notion, Slack, Figma, Home Assistant, and a separate personal WhatsApp connection.
78
+ - Official integrations expose structured tools for Google Workspace, Microsoft 365, Notion, Slack, Figma, Home Assistant, Weather, Spotify, and a separate personal WhatsApp connection.
79
79
  - Messaging platforms let the agent talk through WhatsApp, Telegram, Discord, Slack, Google Chat, Teams, Matrix, Signal, iMessage/BlueBubbles, IRC, Twitch, LINE, Mattermost, configurable webhook bridges, and Telnyx Voice.
80
80
 
81
- Official integration examples include Gmail thread search and send mail, Google Calendar events, Drive upload/download/export/share links, Docs create/append/replace, Sheets read/update/append/create, Microsoft Outlook/Calendar/OneDrive/Teams tools, Notion search/page/block/database tools, Slack conversation/message tools, Figma file/node/comment/image tools, Home Assistant entity/config reads and service calls, and a personal WhatsApp integration with isolated chat read/send tools and per-account read-only versus read/write access.
81
+ Official integration examples include Gmail thread search and send mail, Google Calendar events, Drive upload/download/export/share links, Docs create/append/replace, Sheets read/update/append/create, Microsoft Outlook/Calendar/OneDrive/Teams tools, Notion search/page/block/database tools, Slack conversation/message tools, Figma file/node/comment/image tools, Home Assistant entity/config reads and service calls, Weather current/forecast tools plus weather-event task triggers, Spotify playback/search/control tools, and a personal WhatsApp integration with isolated chat read/send tools and per-account read-only versus read/write access.
82
82
 
83
83
  Messaging examples include Telegram and Discord messages, Slack channel replies, Matrix room messages, Google Chat and Teams webhook delivery, Signal bridge delivery, iMessage/BlueBubbles sends, WhatsApp text and media sends, Telnyx inbound voice, Telnyx outbound calls, and scheduled-task call delivery.
84
84
 
@@ -68,7 +68,7 @@ Recording insight generation is controlled in app AI settings with `auto_recordi
68
68
 
69
69
  ## Official Integrations
70
70
 
71
- Official integrations use OAuth or provider-native account linking and expose structured tools to the agent. The built-in registry currently covers Google Workspace, Notion, Microsoft 365, Slack, Figma, Home Assistant, and personal WhatsApp.
71
+ Official integrations use OAuth or provider-native account linking and expose structured tools to the agent. The built-in registry currently covers Google Workspace, Notion, Microsoft 365, Slack, Figma, Home Assistant, Weather, Spotify, and personal WhatsApp.
72
72
 
73
73
  All OAuth callbacks default to `PUBLIC_URL + /api/integrations/oauth/callback` unless you set a provider-specific redirect URI.
74
74
 
@@ -94,6 +94,11 @@ All OAuth callbacks default to `PUBLIC_URL + /api/integrations/oauth/callback` u
94
94
  | `HOME_ASSISTANT_OAUTH_CLIENT_ID` | Home Assistant OAuth client ID |
95
95
  | `HOME_ASSISTANT_OAUTH_CLIENT_SECRET` | Home Assistant OAuth client secret |
96
96
  | `HOME_ASSISTANT_OAUTH_REDIRECT_URI` | Optional Home Assistant OAuth callback URL |
97
+ | `SPOTIFY_OAUTH_CLIENT_ID` | Spotify OAuth client ID |
98
+ | `SPOTIFY_OAUTH_CLIENT_SECRET` | Spotify OAuth client secret |
99
+ | `SPOTIFY_OAUTH_REDIRECT_URI` | Optional Spotify OAuth callback URL |
100
+
101
+ Weather integration uses Open-Meteo public endpoints and does not require OAuth environment variables.
97
102
 
98
103
  ## Messaging
99
104
 
@@ -14,9 +14,13 @@ The built-in registry includes:
14
14
  | Slack | Conversations, history, posting, search, user info, and Slack Web API requests |
15
15
  | Figma | Current user, files, nodes, rendered images, comments, and Figma REST requests |
16
16
  | Home Assistant | Entity/config reads, service calls, and Home Assistant REST API requests |
17
+ | Weather | Keyless Open-Meteo current weather and forecast tools |
18
+ | Spotify | Playback state, recently played, search, and playback controls |
17
19
 
18
20
  OAuth app credentials are configured through server environment variables. Account connections are created in the Flutter UI under **Integrations**. Connected tools are exposed to the agent as structured tools, so prefer them over browser automation when they can do the job.
19
21
 
22
+ Weather note: the Weather integration uses Open-Meteo public APIs and does not require OAuth client credentials.
23
+
20
24
  ### Per-Account Access Mode
21
25
 
22
26
  Each connected official integration account can be configured per connection as:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.3.1-beta.0",
3
+ "version": "2.3.1-beta.3",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -80,6 +80,7 @@
80
80
  "socket.io": "^4.8.1",
81
81
  "telegraf": "^4.16.3",
82
82
  "telnyx": "^5.51.0",
83
+ "tesseract.js": "^7.0.0",
83
84
  "uuid": "^11.1.0",
84
85
  "ws": "^8.19.0"
85
86
  },
@@ -651,6 +651,40 @@ db.exec(`
651
651
  CREATE INDEX IF NOT EXISTS idx_recording_chunks_source ON recording_chunks(source_id, sequence_index);
652
652
  CREATE INDEX IF NOT EXISTS idx_recording_segments_session ON recording_transcript_segments(session_id, start_ms, created_at);
653
653
 
654
+ CREATE TABLE IF NOT EXISTS screen_history (
655
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
656
+ user_id INTEGER NOT NULL,
657
+ timestamp TEXT DEFAULT (datetime('now')),
658
+ app_name TEXT,
659
+ text_content TEXT,
660
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
661
+ );
662
+
663
+ CREATE TABLE IF NOT EXISTS notification_history (
664
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
665
+ user_id INTEGER NOT NULL,
666
+ app_package TEXT,
667
+ title TEXT,
668
+ body TEXT,
669
+ timestamp TEXT DEFAULT (datetime('now')),
670
+ action_taken TEXT,
671
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
672
+ );
673
+
674
+ CREATE TABLE IF NOT EXISTS geofences (
675
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
676
+ user_id INTEGER NOT NULL,
677
+ label TEXT,
678
+ latitude REAL NOT NULL,
679
+ longitude REAL NOT NULL,
680
+ radius_meters INTEGER NOT NULL,
681
+ trigger_action TEXT,
682
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
683
+ );
684
+
685
+ CREATE INDEX IF NOT EXISTS idx_screen_history_user ON screen_history(user_id, timestamp DESC);
686
+ CREATE INDEX IF NOT EXISTS idx_notification_history_user ON notification_history(user_id, timestamp DESC);
687
+
654
688
  CREATE TABLE IF NOT EXISTS artifacts (
655
689
  id TEXT PRIMARY KEY,
656
690
  user_id INTEGER NOT NULL,
@@ -676,6 +710,29 @@ db.exec(`
676
710
 
677
711
  try {
678
712
  db.exec(`
713
+ CREATE VIRTUAL TABLE IF NOT EXISTS screen_history_fts USING fts5(
714
+ text_content,
715
+ app_name,
716
+ timestamp UNINDEXED,
717
+ user_id UNINDEXED,
718
+ tokenize = 'porter unicode61'
719
+ );
720
+
721
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_ai AFTER INSERT ON screen_history BEGIN
722
+ INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
723
+ VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
724
+ END;
725
+
726
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_ad AFTER DELETE ON screen_history BEGIN
727
+ DELETE FROM screen_history_fts WHERE rowid = old.id;
728
+ END;
729
+
730
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_au AFTER UPDATE ON screen_history BEGIN
731
+ DELETE FROM screen_history_fts WHERE rowid = old.id;
732
+ INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
733
+ VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
734
+ END;
735
+
679
736
  CREATE VIRTUAL TABLE IF NOT EXISTS conversation_history_fts USING fts5(
680
737
  content,
681
738
  role UNINDEXED,
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const express = require('express');
4
+ const db = require('../../db/database');
5
+ const { getErrorMessage } = require('../bootstrap_helpers');
6
+
7
+ const router = express.Router();
8
+
9
+ router.get('/search', (req, res) => {
10
+ const { q, limit = 50, offset = 0 } = req.query;
11
+
12
+ if (!req.user || !req.user.id) {
13
+ return res.status(401).json({ error: 'Unauthorized' });
14
+ }
15
+
16
+ try {
17
+ let results = [];
18
+ if (q) {
19
+ // Full text search
20
+ results = db.prepare(\`
21
+ SELECT s.id, s.timestamp, s.app_name, s.text_content
22
+ FROM screen_history_fts fts
23
+ JOIN screen_history s ON fts.rowid = s.id
24
+ WHERE screen_history_fts MATCH ? AND s.user_id = ?
25
+ ORDER BY s.timestamp DESC
26
+ LIMIT ? OFFSET ?
27
+ \`).all(q, req.user.id, Number(limit), Number(offset));
28
+ } else {
29
+ // Recent history
30
+ results = db.prepare(\`
31
+ SELECT id, timestamp, app_name, text_content
32
+ FROM screen_history
33
+ WHERE user_id = ?
34
+ ORDER BY timestamp DESC
35
+ LIMIT ? OFFSET ?
36
+ \`).all(req.user.id, Number(limit), Number(offset));
37
+ }
38
+
39
+ res.json({ results });
40
+ } catch (err) {
41
+ console.error('[ScreenHistory] Search error:', getErrorMessage(err));
42
+ res.status(500).json({ error: 'Failed to search screen history' });
43
+ }
44
+ });
45
+
46
+ module.exports = router;
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ const express = require('express');
4
+ const db = require('../../db/database');
5
+ const { getErrorMessage } = require('../bootstrap_helpers');
6
+ const { requireAuth } = require('../middleware/auth');
7
+
8
+ const router = express.Router();
9
+
10
+ router.use(requireAuth);
11
+
12
+ router.post('/geofence', async (req, res) => {
13
+ const { label, latitude, longitude, radius_meters, action } = req.body;
14
+
15
+ try {
16
+ const userRow = db.prepare('SELECT id FROM users WHERE id = ?').get(req.user.id);
17
+ if (!userRow) return res.status(401).json({ error: 'Unauthorized' });
18
+
19
+ console.log(`[Triggers] Geofence entered: ${label} by user ${req.user.id}`);
20
+
21
+ // If an agentEngine is running, we can inject a prompt to process this context
22
+ const agentEngine = req.app.locals.agentEngine;
23
+ if (agentEngine) {
24
+ // Find active agent or use default
25
+ const defaultAgentId = db.prepare('SELECT id FROM agents WHERE user_id = ? ORDER BY is_default DESC LIMIT 1').get(req.user.id)?.id;
26
+
27
+ if (defaultAgentId) {
28
+ // Fire and forget a trigger message to the agent
29
+ agentEngine.handleBackgroundTrigger(req.user.id, defaultAgentId, {
30
+ source: 'geofence',
31
+ label,
32
+ action: action || 'User entered a geofenced area. Check if there are any active reminders or tasks related to this location.'
33
+ }).catch(err => console.error('[Triggers] Agent evaluation failed:', err));
34
+ }
35
+ }
36
+
37
+ res.json({ success: true, message: 'Geofence trigger processed' });
38
+ } catch (err) {
39
+ console.error('[Triggers] Geofence error:', getErrorMessage(err));
40
+ res.status(500).json({ error: 'Failed to process geofence trigger' });
41
+ }
42
+ });
43
+
44
+ router.post('/notification', async (req, res) => {
45
+ const { app_package, title, body, action_taken } = req.body;
46
+
47
+ try {
48
+ const userRow = db.prepare('SELECT id FROM users WHERE id = ?').get(req.user.id);
49
+ if (!userRow) return res.status(401).json({ error: 'Unauthorized' });
50
+
51
+ console.log(`[Triggers] Notification received: ${app_package} - ${title}`);
52
+
53
+ db.prepare(\`
54
+ INSERT INTO notification_history (user_id, app_package, title, body, action_taken)
55
+ VALUES (?, ?, ?, ?, ?)
56
+ \`).run(req.user.id, app_package || 'unknown', title || '', body || '', action_taken || 'none');
57
+
58
+ // Notify agent engine to proactively evaluate the notification
59
+ const agentEngine = req.app.locals.agentEngine;
60
+ if (agentEngine) {
61
+ const defaultAgentId = db.prepare('SELECT id FROM agents WHERE user_id = ? ORDER BY is_default DESC LIMIT 1').get(req.user.id)?.id;
62
+
63
+ if (defaultAgentId) {
64
+ agentEngine.handleBackgroundTrigger(req.user.id, defaultAgentId, {
65
+ source: 'notification',
66
+ app_package,
67
+ title,
68
+ body,
69
+ instruction: 'Evaluate this notification. If it is an important reminder, calendar event, or urgent message, inform the user or take appropriate action.'
70
+ }).catch(err => console.error('[Triggers] Agent evaluation failed:', err));
71
+ }
72
+ }
73
+
74
+ res.json({ success: true, message: 'Notification trigger processed and stored' });
75
+ } catch (err) {
76
+ console.error('[Triggers] Notification error:', getErrorMessage(err));
77
+ res.status(500).json({ error: 'Failed to process notification trigger' });
78
+ }
79
+ });
80
+
81
+ module.exports = router;
@@ -26,7 +26,9 @@ 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/mobile/health', modulePath: '../routes/mobile-health' }
29
+ { basePath: '/api/mobile/health', modulePath: '../routes/mobile-health' },
30
+ { basePath: '/api/screen-history', modulePath: '../routes/screenHistory' },
31
+ { basePath: '/api/triggers', modulePath: '../routes/triggers' }
30
32
  ];
31
33
 
32
34
  function registerApiRoutes(app) {
@@ -5535,6 +5535,19 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5535
5535
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5536
5536
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5537
5537
  --------------------------------------------------------------------------------
5538
+ flutter_background_service
5539
+ flutter_background_service_android
5540
+ flutter_background_service_ios
5541
+ flutter_background_service_platform_interface
5542
+
5543
+ Copyright 2022 Eka Setiawan Saputra
5544
+
5545
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5546
+
5547
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5548
+
5549
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5550
+ --------------------------------------------------------------------------------
5538
5551
  flutter_lints
5539
5552
  flutter_markdown
5540
5553
  path_provider
@@ -7093,6 +7106,35 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7093
7106
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
7094
7107
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7095
7108
  --------------------------------------------------------------------------------
7109
+ geolocator
7110
+ geolocator_android
7111
+ geolocator_apple
7112
+ geolocator_platform_interface
7113
+ geolocator_web
7114
+ geolocator_windows
7115
+
7116
+ MIT License
7117
+
7118
+ Copyright (c) 2018 Baseflow
7119
+
7120
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7121
+ of this software and associated documentation files (the "Software"), to deal
7122
+ in the Software without restriction, including without limitation the rights
7123
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7124
+ copies of the Software, and to permit persons to whom the Software is
7125
+ furnished to do so, subject to the following conditions:
7126
+
7127
+ The above copyright notice and this permission notice shall be included in all
7128
+ copies or substantial portions of the Software.
7129
+
7130
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7131
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7132
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7133
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7134
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7135
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
7136
+ SOFTWARE.
7137
+ --------------------------------------------------------------------------------
7096
7138
  glfw
7097
7139
 
7098
7140
 
@@ -24797,6 +24839,25 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24797
24839
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24798
24840
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24799
24841
  --------------------------------------------------------------------------------
24842
+ notification_listener_service
24843
+
24844
+ Copyright (c) 2022 Iheb Briki
24845
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24846
+ of this software and associated documentation files (the "Software"), to deal
24847
+ in the Software without restriction, including without limitation the rights
24848
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24849
+ copies of the Software, and to permit persons to whom the Software is
24850
+ furnished to do so, subject to the following conditions:
24851
+ The above copyright notice and this permission notice shall be included in all
24852
+ copies or substantial portions of the Software.
24853
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24854
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24855
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24856
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24857
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24858
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24859
+ SOFTWARE.
24860
+ --------------------------------------------------------------------------------
24800
24861
  perfetto
24801
24862
 
24802
24863
  Apache License
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"59aa584fdf100e6c78c785d8a5b565d1de4b48
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "714146073" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "1375002290" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });