neoagent 2.3.1-beta.99 → 2.4.1-beta.5
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/.env.example +6 -3
- package/LICENSE +619 -21
- package/README.md +1 -1
- package/extensions/chrome-browser/icons/icon128.png +0 -0
- package/extensions/chrome-browser/icons/icon16.png +0 -0
- package/extensions/chrome-browser/icons/icon48.png +0 -0
- package/extensions/chrome-browser/icons/logo.svg +12 -0
- package/extensions/chrome-browser/manifest.json +11 -1
- package/extensions/chrome-browser/popup.css +5 -0
- package/extensions/chrome-browser/popup.html +2 -4
- package/extensions/chrome-browser/popup.js +1 -5
- package/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_controller.dart +9 -0
- package/flutter_app/lib/main_devices.dart +70 -1
- package/flutter_app/lib/main_integrations.dart +21 -2
- package/flutter_app/lib/main_models.dart +60 -0
- package/flutter_app/lib/main_settings.dart +172 -31
- package/flutter_app/lib/main_theme.dart +31 -2
- package/flutter_app/lib/src/backend_client.dart +12 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +72 -0
- package/flutter_app/lib/src/desktop_companion_io.dart +9 -4
- package/flutter_app/macos/Runner/AppDelegate.swift +23 -2
- package/flutter_app/macos/Runner/DebugProfile.entitlements +4 -0
- package/flutter_app/macos/Runner/Release.entitlements +4 -0
- package/flutter_app/pubspec.lock +5 -5
- package/lib/manager.js +164 -2
- package/package.json +2 -2
- package/server/db/database.js +85 -0
- package/server/guest_agent.js +12 -1
- package/server/http/routes.js +190 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/NOTICES +971 -1066
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/assets/shaders/ink_sparkle.frag +1 -1
- package/server/public/assets/shaders/stretch_effect.frag +1 -1
- package/server/public/canvaskit/canvaskit.js +2 -2
- package/server/public/canvaskit/canvaskit.js.symbols +11796 -11733
- package/server/public/canvaskit/canvaskit.wasm +0 -0
- package/server/public/canvaskit/chromium/canvaskit.js +2 -2
- package/server/public/canvaskit/chromium/canvaskit.js.symbols +10706 -10643
- package/server/public/canvaskit/chromium/canvaskit.wasm +0 -0
- package/server/public/canvaskit/experimental_webparagraph/canvaskit.js +171 -0
- package/server/public/canvaskit/experimental_webparagraph/canvaskit.js.symbols +9134 -0
- package/server/public/canvaskit/experimental_webparagraph/canvaskit.wasm +0 -0
- package/server/public/canvaskit/skwasm.js +14 -14
- package/server/public/canvaskit/skwasm.js.symbols +12787 -12676
- package/server/public/canvaskit/skwasm.wasm +0 -0
- package/server/public/canvaskit/skwasm_heavy.js +14 -14
- package/server/public/canvaskit/skwasm_heavy.js.symbols +14400 -14286
- package/server/public/canvaskit/skwasm_heavy.wasm +0 -0
- package/server/public/canvaskit/wimp.js +94 -95
- package/server/public/canvaskit/wimp.js.symbols +11325 -11177
- package/server/public/canvaskit/wimp.wasm +0 -0
- package/server/public/flutter_bootstrap.js +2 -2
- package/server/public/main.dart.js +84332 -82269
- package/server/routes/integrations.js +2 -2
- package/server/routes/memory.js +73 -0
- package/server/services/ai/engine.js +65 -26
- package/server/services/ai/models.js +21 -0
- package/server/services/ai/preModelCompaction.js +191 -0
- package/server/services/ai/providers/claudeCode.js +273 -0
- package/server/services/ai/providers/openaiCodex.js +212 -40
- package/server/services/ai/settings.js +12 -2
- package/server/services/ai/tools.js +39 -28
- package/server/services/desktop/protocol.js +1 -0
- package/server/services/desktop/provider.js +11 -0
- package/server/services/desktop/registry.js +51 -10
- package/server/services/integrations/google/provider.js +78 -0
- package/server/services/integrations/manager.js +29 -13
- package/server/services/manager.js +25 -0
- package/server/services/memory/ingestion.js +486 -0
- package/server/services/memory/manager.js +422 -0
- package/server/services/memory/openhuman_uplift.test.js +98 -0
- package/server/services/runtime/docker-vm-manager.js +26 -3
- package/server/services/runtime/manager.js +25 -2
- package/server/services/widgets/focus_widget.js +45 -4
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node.js-20+-5fa04e?style=flat-square&logo=node.js&logoColor=white" alt="Node.js"></a>
|
|
7
7
|
<a href="https://sqlite.org"><img src="https://img.shields.io/badge/SQLite-WAL-003b57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite"></a>
|
|
8
8
|
<a href="https://flutter.dev"><img src="https://img.shields.io/badge/Flutter-web%20%2B%20android-02569B?style=flat-square&logo=flutter&logoColor=white" alt="Flutter"></a>
|
|
9
|
-
<a href="LICENSE"><img src="https://img.shields.io/badge/License-
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-AGPL--3.0-a855f7?style=flat-square" alt="License"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">Self-hosted AI agent — runs as a system service, controls Android over ADB, connects to 15+ messaging platforms, all credentials on your server.</p>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#8f6d3e"/>
|
|
5
|
+
<stop offset="100%" stop-color="#2f7d6e"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect x="5.76" y="5.76" width="20.48" height="20.48" rx="6.96" fill="url(#bg)" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1"/>
|
|
9
|
+
<polygon points="16,9.76 9.35,13.12 16,16.48 22.65,13.12" fill="white"/>
|
|
10
|
+
<polyline points="9.35,16.48 16,19.68 22.65,16.48" fill="none" stroke="white" stroke-width="1.44" stroke-linecap="round" stroke-linejoin="round"/>
|
|
11
|
+
<polyline points="9.35,19.68 16,22.72 22.65,19.68" fill="none" stroke="white" stroke-width="1.44" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
+
</svg>
|
|
@@ -6,9 +6,19 @@
|
|
|
6
6
|
"minimum_chrome_version": "118",
|
|
7
7
|
"permissions": ["debugger", "storage", "tabs"],
|
|
8
8
|
"host_permissions": ["http://*/*", "https://*/*"],
|
|
9
|
+
"icons": {
|
|
10
|
+
"16": "icons/icon16.png",
|
|
11
|
+
"48": "icons/icon48.png",
|
|
12
|
+
"128": "icons/icon128.png"
|
|
13
|
+
},
|
|
9
14
|
"action": {
|
|
10
15
|
"default_title": "NeoAgent Browser",
|
|
11
|
-
"default_popup": "popup.html"
|
|
16
|
+
"default_popup": "popup.html",
|
|
17
|
+
"default_icon": {
|
|
18
|
+
"16": "icons/icon16.png",
|
|
19
|
+
"48": "icons/icon48.png",
|
|
20
|
+
"128": "icons/icon128.png"
|
|
21
|
+
}
|
|
12
22
|
},
|
|
13
23
|
"background": {
|
|
14
24
|
"service_worker": "background.mjs",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
<body>
|
|
9
9
|
<main>
|
|
10
10
|
<header>
|
|
11
|
+
<img src="icons/logo.svg" alt="NeoAgent" class="logo">
|
|
11
12
|
<p class="eyebrow">NeoAgent Browser</p>
|
|
12
13
|
<h1>Connect this Chrome</h1>
|
|
13
14
|
<p class="intro">Pair once, then let NeoAgent control this browser when you ask it to.</p>
|
|
@@ -31,8 +32,6 @@
|
|
|
31
32
|
</div>
|
|
32
33
|
</section>
|
|
33
34
|
|
|
34
|
-
<button id="openApp" type="button" class="link-button">Open NeoAgent web page</button>
|
|
35
|
-
|
|
36
35
|
<details id="settings" class="settings">
|
|
37
36
|
<summary>Settings & updates</summary>
|
|
38
37
|
<label>
|
|
@@ -47,8 +46,7 @@
|
|
|
47
46
|
<p class="hint">The server URL is usually filled in by the ZIP downloaded from NeoAgent.</p>
|
|
48
47
|
</details>
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
<p id="message" class="message"></p>
|
|
49
|
+
<p id="message" class="message"></p>
|
|
52
50
|
</main>
|
|
53
51
|
<script src="popup.js" type="module"></script>
|
|
54
52
|
</body>
|
|
@@ -9,7 +9,6 @@ const flowTitleEl = document.querySelector('#flowTitle');
|
|
|
9
9
|
const flowDescriptionEl = document.querySelector('#flowDescription');
|
|
10
10
|
const primaryActionEl = document.querySelector('#primaryAction');
|
|
11
11
|
const secondaryActionEl = document.querySelector('#secondaryAction');
|
|
12
|
-
const openAppEl = document.querySelector('#openApp');
|
|
13
12
|
const disconnectEl = document.querySelector('#disconnect');
|
|
14
13
|
const checkUpdateEl = document.querySelector('#checkUpdate');
|
|
15
14
|
const downloadEl = document.querySelector('#download');
|
|
@@ -59,7 +58,7 @@ function setBusy(isBusy, label = 'Working...') {
|
|
|
59
58
|
}
|
|
60
59
|
const busy = pendingActions > 0;
|
|
61
60
|
|
|
62
|
-
[primaryActionEl, secondaryActionEl,
|
|
61
|
+
[primaryActionEl, secondaryActionEl, disconnectEl, checkUpdateEl, downloadEl].forEach((button) => {
|
|
63
62
|
if (!button || button.hidden) return;
|
|
64
63
|
if (busy) {
|
|
65
64
|
if (!Object.prototype.hasOwnProperty.call(button.dataset, 'wasDisabled')) {
|
|
@@ -99,8 +98,6 @@ function updateFlow() {
|
|
|
99
98
|
const hasToken = Boolean(currentState.token || currentState.tokenId);
|
|
100
99
|
const approvalUrl = currentState.approvalUrl || '';
|
|
101
100
|
|
|
102
|
-
openAppEl.disabled = !hasServerUrl;
|
|
103
|
-
|
|
104
101
|
if (!hasServerUrl) {
|
|
105
102
|
stepLabelEl.textContent = 'Step 1 of 3';
|
|
106
103
|
flowTitleEl.textContent = 'Add your NeoAgent server';
|
|
@@ -243,7 +240,6 @@ serverUrlEl.addEventListener('input', updateFlow);
|
|
|
243
240
|
|
|
244
241
|
bindAsyncClick(primaryActionEl, () => runAction(primaryActionEl.dataset.action));
|
|
245
242
|
bindAsyncClick(secondaryActionEl, () => runAction(secondaryActionEl.dataset.action));
|
|
246
|
-
bindAsyncClick(openAppEl, () => runAction('openApp'));
|
|
247
243
|
bindAsyncClick(disconnectEl, async () => {
|
|
248
244
|
await send('disconnect');
|
|
249
245
|
await refresh();
|
|
@@ -6,6 +6,7 @@ import 'dart:ui' show ImageFilter;
|
|
|
6
6
|
|
|
7
7
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
|
8
8
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
|
9
|
+
import 'package:flutter/cupertino.dart' as cupertino;
|
|
9
10
|
import 'package:flutter/foundation.dart';
|
|
10
11
|
import 'package:flutter/gestures.dart';
|
|
11
12
|
import 'package:flutter/material.dart';
|
|
@@ -1040,6 +1040,15 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
1040
1040
|
}
|
|
1041
1041
|
}
|
|
1042
1042
|
|
|
1043
|
+
Future<Map<String, dynamic>> testCliRuntime() =>
|
|
1044
|
+
_backendClient.testCli(backendUrl);
|
|
1045
|
+
|
|
1046
|
+
Future<Map<String, dynamic>> testBrowserExtension() =>
|
|
1047
|
+
_backendClient.testExtension(backendUrl);
|
|
1048
|
+
|
|
1049
|
+
Future<Map<String, dynamic>> testDesktopCompanion() =>
|
|
1050
|
+
_backendClient.testDesktop(backendUrl);
|
|
1051
|
+
|
|
1043
1052
|
Future<void> openAppUpdate() async {
|
|
1044
1053
|
final release = availableAppUpdate;
|
|
1045
1054
|
if (release == null || isOpeningAppUpdate) {
|
|
@@ -103,8 +103,13 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
103
103
|
_onlineDesktopDevices.length > 1 &&
|
|
104
104
|
(widget.controller.selectedDesktopDeviceId ?? '').isEmpty;
|
|
105
105
|
|
|
106
|
+
bool get _extensionPreferredButOffline =>
|
|
107
|
+
widget.controller.browserBackend == 'extension' &&
|
|
108
|
+
!widget.controller.browserExtensionConnected;
|
|
109
|
+
|
|
106
110
|
String? get _activeScreenshotPath {
|
|
107
111
|
if (_isBrowser) {
|
|
112
|
+
if (_extensionPreferredButOffline) return null;
|
|
108
113
|
return widget.controller.browserScreenshotPath;
|
|
109
114
|
}
|
|
110
115
|
if (_isDesktop) {
|
|
@@ -121,6 +126,7 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
121
126
|
Future<void> _ensurePreview() async {
|
|
122
127
|
final controller = widget.controller;
|
|
123
128
|
if (_isBrowser) {
|
|
129
|
+
if (_extensionPreferredButOffline) return;
|
|
124
130
|
if (controller.browserRuntime['launched'] != true) {
|
|
125
131
|
return;
|
|
126
132
|
}
|
|
@@ -161,6 +167,7 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
161
167
|
return;
|
|
162
168
|
}
|
|
163
169
|
if (_isBrowser) {
|
|
170
|
+
if (_extensionPreferredButOffline) return;
|
|
164
171
|
await widget.controller.refreshBrowserFrameRuntime();
|
|
165
172
|
return;
|
|
166
173
|
}
|
|
@@ -451,6 +458,14 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
451
458
|
browserExtensionActive: usingExtension,
|
|
452
459
|
browserFallbackLabel: browserFallbackLabel,
|
|
453
460
|
),
|
|
461
|
+
if (_isBrowser && prefersExtension) ...<Widget>[
|
|
462
|
+
const SizedBox(height: 14),
|
|
463
|
+
_ExtensionStatusBar(
|
|
464
|
+
connected: extensionConnected,
|
|
465
|
+
onDownload: controller.downloadBrowserExtension,
|
|
466
|
+
onRefresh: controller.refreshBrowserExtensionStatus,
|
|
467
|
+
),
|
|
468
|
+
],
|
|
454
469
|
if (_isDesktop) ...<Widget>[
|
|
455
470
|
const SizedBox(height: 14),
|
|
456
471
|
DropdownButtonFormField<String>(
|
|
@@ -558,7 +573,9 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
558
573
|
busy: _isCurrentSurfaceBusy,
|
|
559
574
|
wakingUp: !_isBrowser && !_isDesktop && _androidStarting,
|
|
560
575
|
enabled: _isBrowser || _isDesktop || _androidOnline,
|
|
561
|
-
connectRequired:
|
|
576
|
+
connectRequired: _isBrowser
|
|
577
|
+
? _extensionPreferredButOffline
|
|
578
|
+
: _desktopRequiresSelection,
|
|
562
579
|
onTapPoint: _handleTap,
|
|
563
580
|
onSwipe: _handleSwipe,
|
|
564
581
|
onWakeRequested: _openPrimary,
|
|
@@ -1701,6 +1718,58 @@ class _RuntimePreview extends StatelessWidget {
|
|
|
1701
1718
|
}
|
|
1702
1719
|
}
|
|
1703
1720
|
|
|
1721
|
+
class _ExtensionStatusBar extends StatelessWidget {
|
|
1722
|
+
const _ExtensionStatusBar({
|
|
1723
|
+
required this.connected,
|
|
1724
|
+
required this.onDownload,
|
|
1725
|
+
required this.onRefresh,
|
|
1726
|
+
});
|
|
1727
|
+
|
|
1728
|
+
final bool connected;
|
|
1729
|
+
final Future<void> Function() onDownload;
|
|
1730
|
+
final Future<void> Function() onRefresh;
|
|
1731
|
+
|
|
1732
|
+
@override
|
|
1733
|
+
Widget build(BuildContext context) {
|
|
1734
|
+
return Container(
|
|
1735
|
+
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
|
|
1736
|
+
decoration: BoxDecoration(
|
|
1737
|
+
color: _bgSecondary,
|
|
1738
|
+
borderRadius: BorderRadius.circular(16),
|
|
1739
|
+
border: Border.all(color: _borderLight),
|
|
1740
|
+
),
|
|
1741
|
+
child: Row(
|
|
1742
|
+
children: <Widget>[
|
|
1743
|
+
_DotStatus(
|
|
1744
|
+
label: connected ? 'Extension connected' : 'Extension not connected',
|
|
1745
|
+
color: connected ? _success : _warning,
|
|
1746
|
+
),
|
|
1747
|
+
const Spacer(),
|
|
1748
|
+
OutlinedButton.icon(
|
|
1749
|
+
onPressed: onDownload,
|
|
1750
|
+
icon: const Icon(Icons.download_outlined, size: 18),
|
|
1751
|
+
label: const Text('Download'),
|
|
1752
|
+
style: OutlinedButton.styleFrom(
|
|
1753
|
+
visualDensity: VisualDensity.compact,
|
|
1754
|
+
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
1755
|
+
),
|
|
1756
|
+
),
|
|
1757
|
+
const SizedBox(width: 8),
|
|
1758
|
+
OutlinedButton.icon(
|
|
1759
|
+
onPressed: onRefresh,
|
|
1760
|
+
icon: const Icon(Icons.sync, size: 18),
|
|
1761
|
+
label: const Text('Refresh'),
|
|
1762
|
+
style: OutlinedButton.styleFrom(
|
|
1763
|
+
visualDensity: VisualDensity.compact,
|
|
1764
|
+
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
1765
|
+
),
|
|
1766
|
+
),
|
|
1767
|
+
],
|
|
1768
|
+
),
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1704
1773
|
class _ResultBlock extends StatelessWidget {
|
|
1705
1774
|
const _ResultBlock({required this.label, required this.value});
|
|
1706
1775
|
|
|
@@ -175,6 +175,12 @@ class OfficialIntegrationsTab extends StatelessWidget {
|
|
|
175
175
|
label: '${item.availableToolCount} tools',
|
|
176
176
|
icon: Icons.build_outlined,
|
|
177
177
|
),
|
|
178
|
+
_MetaPill(
|
|
179
|
+
label: item.memoryCoverage.supported
|
|
180
|
+
? 'Memory ${item.memoryCoverage.statusLabel}'
|
|
181
|
+
: 'No memory sync',
|
|
182
|
+
icon: Icons.psychology_alt_outlined,
|
|
183
|
+
),
|
|
178
184
|
],
|
|
179
185
|
),
|
|
180
186
|
const SizedBox(height: 10),
|
|
@@ -255,6 +261,7 @@ Future<void> _showTrelloSetupDialog(
|
|
|
255
261
|
final apiKeyController = TextEditingController(text: savedApiKey);
|
|
256
262
|
final tokenInputController = TextEditingController();
|
|
257
263
|
|
|
264
|
+
if (!context.mounted) return;
|
|
258
265
|
await showDialog<void>(
|
|
259
266
|
context: context,
|
|
260
267
|
barrierDismissible: false,
|
|
@@ -426,8 +433,7 @@ Future<void> _showTrelloSetupDialog(
|
|
|
426
433
|
}
|
|
427
434
|
final url = authorizeUrl.isNotEmpty
|
|
428
435
|
? authorizeUrl
|
|
429
|
-
: 'https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&key
|
|
430
|
-
Uri.encodeComponent(effectiveApiKey);
|
|
436
|
+
: 'https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&key=${Uri.encodeComponent(effectiveApiKey)}';
|
|
431
437
|
final result = await controller._oauthLauncher
|
|
432
438
|
.openExternal(url: url, label: 'Trello');
|
|
433
439
|
if (!result.launched) {
|
|
@@ -659,6 +665,12 @@ class _OfficialIntegrationAppCard extends StatelessWidget {
|
|
|
659
665
|
label: '${app.availableToolCount} tools',
|
|
660
666
|
icon: Icons.build_circle_outlined,
|
|
661
667
|
),
|
|
668
|
+
_MetaPill(
|
|
669
|
+
label: app.memoryCoverage.supported
|
|
670
|
+
? 'Memory ${app.memoryCoverage.statusLabel}'
|
|
671
|
+
: 'No memory sync',
|
|
672
|
+
icon: Icons.psychology_alt_outlined,
|
|
673
|
+
),
|
|
662
674
|
],
|
|
663
675
|
),
|
|
664
676
|
],
|
|
@@ -715,6 +727,13 @@ class _OfficialIntegrationAppCard extends StatelessWidget {
|
|
|
715
727
|
'Access: ${account.accessModeLabel}',
|
|
716
728
|
style: TextStyle(color: _textSecondary),
|
|
717
729
|
),
|
|
730
|
+
if (account.memoryCoverage.supported) ...<Widget>[
|
|
731
|
+
const SizedBox(height: 4),
|
|
732
|
+
Text(
|
|
733
|
+
'Memory: ${account.memoryCoverage.statusLabel}',
|
|
734
|
+
style: TextStyle(color: _textSecondary),
|
|
735
|
+
),
|
|
736
|
+
],
|
|
718
737
|
const SizedBox(height: 12),
|
|
719
738
|
Wrap(
|
|
720
739
|
spacing: 8,
|
|
@@ -2565,6 +2565,7 @@ class OfficialIntegrationAppItem {
|
|
|
2565
2565
|
),
|
|
2566
2566
|
this.accounts = const <OfficialIntegrationAccountItem>[],
|
|
2567
2567
|
this.availableToolCount = 0,
|
|
2568
|
+
this.memoryCoverage = const OfficialIntegrationMemoryCoverage(),
|
|
2568
2569
|
});
|
|
2569
2570
|
|
|
2570
2571
|
factory OfficialIntegrationAppItem.fromJson(Map<dynamic, dynamic> json) {
|
|
@@ -2583,6 +2584,9 @@ class OfficialIntegrationAppItem {
|
|
|
2583
2584
|
.toList()
|
|
2584
2585
|
: const <OfficialIntegrationAccountItem>[],
|
|
2585
2586
|
availableToolCount: _asInt(json['availableToolCount']),
|
|
2587
|
+
memoryCoverage: OfficialIntegrationMemoryCoverage.fromJson(
|
|
2588
|
+
_jsonMap(json['memoryCoverage']),
|
|
2589
|
+
),
|
|
2586
2590
|
);
|
|
2587
2591
|
}
|
|
2588
2592
|
|
|
@@ -2592,6 +2596,7 @@ class OfficialIntegrationAppItem {
|
|
|
2592
2596
|
final OfficialIntegrationConnectionStatus connection;
|
|
2593
2597
|
final List<OfficialIntegrationAccountItem> accounts;
|
|
2594
2598
|
final int availableToolCount;
|
|
2599
|
+
final OfficialIntegrationMemoryCoverage memoryCoverage;
|
|
2595
2600
|
|
|
2596
2601
|
bool get isConnected => connection.connected;
|
|
2597
2602
|
|
|
@@ -2676,6 +2681,51 @@ class OfficialIntegrationConnectionStatus {
|
|
|
2676
2681
|
}
|
|
2677
2682
|
}
|
|
2678
2683
|
|
|
2684
|
+
class OfficialIntegrationMemoryCoverage {
|
|
2685
|
+
const OfficialIntegrationMemoryCoverage({
|
|
2686
|
+
this.supported = false,
|
|
2687
|
+
this.contributesToMemory = false,
|
|
2688
|
+
this.contributesToTaskExecution = false,
|
|
2689
|
+
this.status = 'not_supported',
|
|
2690
|
+
this.dataDomains = const <String>[],
|
|
2691
|
+
this.documentCount = 0,
|
|
2692
|
+
this.lastRefreshAt,
|
|
2693
|
+
this.nextRefreshAt,
|
|
2694
|
+
this.error,
|
|
2695
|
+
});
|
|
2696
|
+
|
|
2697
|
+
factory OfficialIntegrationMemoryCoverage.fromJson(
|
|
2698
|
+
Map<dynamic, dynamic> json,
|
|
2699
|
+
) {
|
|
2700
|
+
final domainsRaw = json['dataDomains'];
|
|
2701
|
+
return OfficialIntegrationMemoryCoverage(
|
|
2702
|
+
supported: json['supported'] == true,
|
|
2703
|
+
contributesToMemory: json['contributesToMemory'] == true,
|
|
2704
|
+
contributesToTaskExecution: json['contributesToTaskExecution'] == true,
|
|
2705
|
+
status: json['status']?.toString() ?? 'not_supported',
|
|
2706
|
+
dataDomains: domainsRaw is List
|
|
2707
|
+
? domainsRaw.map((item) => item.toString()).toList()
|
|
2708
|
+
: const <String>[],
|
|
2709
|
+
documentCount: _asInt(json['documentCount']),
|
|
2710
|
+
lastRefreshAt: _parseOptionalTimestamp(json['lastRefreshAt']?.toString()),
|
|
2711
|
+
nextRefreshAt: _parseOptionalTimestamp(json['nextRefreshAt']?.toString()),
|
|
2712
|
+
error: json['error']?.toString(),
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
final bool supported;
|
|
2717
|
+
final bool contributesToMemory;
|
|
2718
|
+
final bool contributesToTaskExecution;
|
|
2719
|
+
final String status;
|
|
2720
|
+
final List<String> dataDomains;
|
|
2721
|
+
final int documentCount;
|
|
2722
|
+
final DateTime? lastRefreshAt;
|
|
2723
|
+
final DateTime? nextRefreshAt;
|
|
2724
|
+
final String? error;
|
|
2725
|
+
|
|
2726
|
+
String get statusLabel => _titleCase(status.replaceAll('_', ' '));
|
|
2727
|
+
}
|
|
2728
|
+
|
|
2679
2729
|
class OfficialIntegrationAccountItem {
|
|
2680
2730
|
const OfficialIntegrationAccountItem({
|
|
2681
2731
|
required this.id,
|
|
@@ -2684,6 +2734,7 @@ class OfficialIntegrationAccountItem {
|
|
|
2684
2734
|
this.accountEmail,
|
|
2685
2735
|
this.lastConnectedAt,
|
|
2686
2736
|
this.accessMode = 'read_write',
|
|
2737
|
+
this.memoryCoverage = const OfficialIntegrationMemoryCoverage(),
|
|
2687
2738
|
});
|
|
2688
2739
|
|
|
2689
2740
|
factory OfficialIntegrationAccountItem.fromJson(Map<dynamic, dynamic> json) {
|
|
@@ -2696,6 +2747,9 @@ class OfficialIntegrationAccountItem {
|
|
|
2696
2747
|
json['lastConnectedAt']?.toString(),
|
|
2697
2748
|
),
|
|
2698
2749
|
accessMode: json['accessMode']?.toString() ?? 'read_write',
|
|
2750
|
+
memoryCoverage: OfficialIntegrationMemoryCoverage.fromJson(
|
|
2751
|
+
_jsonMap(json['memoryCoverage']),
|
|
2752
|
+
),
|
|
2699
2753
|
);
|
|
2700
2754
|
}
|
|
2701
2755
|
|
|
@@ -2705,6 +2759,7 @@ class OfficialIntegrationAccountItem {
|
|
|
2705
2759
|
final String? accountEmail;
|
|
2706
2760
|
final DateTime? lastConnectedAt;
|
|
2707
2761
|
final String accessMode;
|
|
2762
|
+
final OfficialIntegrationMemoryCoverage memoryCoverage;
|
|
2708
2763
|
|
|
2709
2764
|
bool get isExpired => status == 'expired';
|
|
2710
2765
|
|
|
@@ -2733,6 +2788,7 @@ class OfficialIntegrationItem {
|
|
|
2733
2788
|
this.connectPrompt,
|
|
2734
2789
|
this.supportsMultipleAccounts = true,
|
|
2735
2790
|
this.connectionMethod = 'oauth',
|
|
2791
|
+
this.memoryCoverage = const OfficialIntegrationMemoryCoverage(),
|
|
2736
2792
|
});
|
|
2737
2793
|
|
|
2738
2794
|
factory OfficialIntegrationItem.fromJson(Map<dynamic, dynamic> json) {
|
|
@@ -2756,6 +2812,9 @@ class OfficialIntegrationItem {
|
|
|
2756
2812
|
connectPrompt: json['connectPrompt']?.toString(),
|
|
2757
2813
|
supportsMultipleAccounts: json['supportsMultipleAccounts'] != false,
|
|
2758
2814
|
connectionMethod: json['connectionMethod']?.toString() ?? 'oauth',
|
|
2815
|
+
memoryCoverage: OfficialIntegrationMemoryCoverage.fromJson(
|
|
2816
|
+
_jsonMap(json['memoryCoverage']),
|
|
2817
|
+
),
|
|
2759
2818
|
);
|
|
2760
2819
|
}
|
|
2761
2820
|
|
|
@@ -2770,6 +2829,7 @@ class OfficialIntegrationItem {
|
|
|
2770
2829
|
final String? connectPrompt;
|
|
2771
2830
|
final bool supportsMultipleAccounts;
|
|
2772
2831
|
final String connectionMethod;
|
|
2832
|
+
final OfficialIntegrationMemoryCoverage memoryCoverage;
|
|
2773
2833
|
|
|
2774
2834
|
bool get isConnected => connection.connected;
|
|
2775
2835
|
|