neoagent 2.3.1-beta.63 → 2.3.1-beta.64
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/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_account_settings.dart +50 -22
- package/flutter_app/lib/main_admin.dart +24 -10
- package/flutter_app/lib/main_app_shell.dart +10 -9
- package/flutter_app/lib/main_chat.dart +433 -309
- package/flutter_app/lib/main_controller.dart +2 -1
- package/flutter_app/lib/main_integrations.dart +15 -7
- package/flutter_app/lib/main_models.dart +116 -7
- package/flutter_app/lib/main_navigation.dart +27 -18
- package/flutter_app/lib/main_operations.dart +162 -91
- package/flutter_app/lib/main_settings.dart +268 -71
- package/flutter_app/lib/main_shared.dart +4 -6
- package/flutter_app/lib/main_unified.dart +388 -0
- package/package.json +1 -1
- package/server/db/database.js +52 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +77499 -76627
- package/server/routes/agents.js +2 -1
- package/server/routes/memory.js +75 -3
- package/server/routes/widgets.js +4 -4
- package/server/services/ai/engine.js +86 -0
- package/server/services/ai/runEvents.js +100 -0
- package/server/services/memory/manager.js +242 -26
- package/server/services/websocket.js +3 -1
- package/server/services/widgets/focus_widget.js +126 -0
- package/server/services/widgets/service.js +130 -2
|
@@ -3778,7 +3778,8 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
3778
3778
|
_desktopFloatingToolbarPopupRequested = false;
|
|
3779
3779
|
unawaited(
|
|
3780
3780
|
_analytics.trackRecordingStopped(
|
|
3781
|
-
kind:
|
|
3781
|
+
kind:
|
|
3782
|
+
recordingRuntime.supportsBackgroundMic &&
|
|
3782
3783
|
!recordingRuntime.supportsScreenAndMic
|
|
3783
3784
|
? 'background'
|
|
3784
3785
|
: 'desktop',
|
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
part of 'main.dart';
|
|
2
2
|
|
|
3
3
|
class IntegrationsPanel extends StatelessWidget {
|
|
4
|
-
const IntegrationsPanel({
|
|
4
|
+
const IntegrationsPanel({
|
|
5
|
+
super.key,
|
|
6
|
+
required this.controller,
|
|
7
|
+
this.embedded = false,
|
|
8
|
+
});
|
|
5
9
|
|
|
6
10
|
final NeoAgentController controller;
|
|
11
|
+
final bool embedded;
|
|
7
12
|
|
|
8
13
|
@override
|
|
9
14
|
Widget build(BuildContext context) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
children: <Widget>[
|
|
15
|
+
final body = Column(
|
|
16
|
+
children: <Widget>[
|
|
17
|
+
if (!embedded) ...<Widget>[
|
|
14
18
|
_PageTitle(
|
|
15
19
|
title: 'Integrations',
|
|
16
20
|
subtitle:
|
|
17
21
|
'Connect and manage official integrations separately from reusable skills.',
|
|
18
22
|
),
|
|
19
23
|
const SizedBox(height: 12),
|
|
20
|
-
Expanded(child: OfficialIntegrationsTab(controller: controller)),
|
|
21
24
|
],
|
|
22
|
-
|
|
25
|
+
Expanded(child: OfficialIntegrationsTab(controller: controller)),
|
|
26
|
+
],
|
|
23
27
|
);
|
|
28
|
+
if (embedded) {
|
|
29
|
+
return body;
|
|
30
|
+
}
|
|
31
|
+
return Padding(padding: _pagePadding(context), child: body);
|
|
24
32
|
}
|
|
25
33
|
}
|
|
26
34
|
|
|
@@ -832,7 +832,7 @@ class MessagingAccessCapabilities {
|
|
|
832
832
|
});
|
|
833
833
|
|
|
834
834
|
factory MessagingAccessCapabilities.fromJson(Map<String, dynamic> json) {
|
|
835
|
-
List<String>
|
|
835
|
+
List<String> stringList(dynamic value) {
|
|
836
836
|
if (value is! List) return const <String>[];
|
|
837
837
|
return value
|
|
838
838
|
.map((item) => item.toString())
|
|
@@ -845,9 +845,9 @@ class MessagingAccessCapabilities {
|
|
|
845
845
|
supportsSharedPolicy: json['supportsSharedPolicy'] != false,
|
|
846
846
|
supportsMentionGate: json['supportsMentionGate'] == true,
|
|
847
847
|
supportsDiscovery: json['supportsDiscovery'] == true,
|
|
848
|
-
directRuleScopes:
|
|
849
|
-
sharedSpaceRuleScopes:
|
|
850
|
-
sharedActorRuleScopes:
|
|
848
|
+
directRuleScopes: stringList(json['directRuleScopes']),
|
|
849
|
+
sharedSpaceRuleScopes: stringList(json['sharedSpaceRuleScopes']),
|
|
850
|
+
sharedActorRuleScopes: stringList(json['sharedActorRuleScopes']),
|
|
851
851
|
manualEntryHint: json['manualEntryHint']?.toString() ?? '',
|
|
852
852
|
);
|
|
853
853
|
}
|
|
@@ -932,7 +932,7 @@ class MessagingAccessCatalog {
|
|
|
932
932
|
String platform,
|
|
933
933
|
Map<String, dynamic> json,
|
|
934
934
|
) {
|
|
935
|
-
List<MessagingAccessTarget>
|
|
935
|
+
List<MessagingAccessTarget> parseTargets(dynamic raw) {
|
|
936
936
|
if (raw is! List) return const <MessagingAccessTarget>[];
|
|
937
937
|
return raw
|
|
938
938
|
.whereType<Map>()
|
|
@@ -950,8 +950,8 @@ class MessagingAccessCatalog {
|
|
|
950
950
|
capabilities: MessagingAccessCapabilities.fromJson(
|
|
951
951
|
_jsonMap(json['capabilities']),
|
|
952
952
|
),
|
|
953
|
-
discoveredTargets:
|
|
954
|
-
suggestedTargets:
|
|
953
|
+
discoveredTargets: parseTargets(json['discoveredTargets']),
|
|
954
|
+
suggestedTargets: parseTargets(json['suggestedTargets']),
|
|
955
955
|
summary: json['summary']?.toString() ?? 'Access policy',
|
|
956
956
|
);
|
|
957
957
|
}
|
|
@@ -1434,6 +1434,7 @@ class RunDetailSnapshot {
|
|
|
1434
1434
|
const RunDetailSnapshot({
|
|
1435
1435
|
required this.run,
|
|
1436
1436
|
required this.steps,
|
|
1437
|
+
required this.events,
|
|
1437
1438
|
required this.response,
|
|
1438
1439
|
});
|
|
1439
1440
|
|
|
@@ -1444,12 +1445,17 @@ class RunDetailSnapshot {
|
|
|
1444
1445
|
json['steps'],
|
|
1445
1446
|
fallbackToMapValues: true,
|
|
1446
1447
|
).map(RunStepItem.fromJson).toList(),
|
|
1448
|
+
events: _jsonMapList(
|
|
1449
|
+
json['events'],
|
|
1450
|
+
fallbackToMapValues: true,
|
|
1451
|
+
).map(RunEventItem.fromJson).toList(),
|
|
1447
1452
|
response: json['response']?.toString() ?? '',
|
|
1448
1453
|
);
|
|
1449
1454
|
}
|
|
1450
1455
|
|
|
1451
1456
|
final RunSummary run;
|
|
1452
1457
|
final List<RunStepItem> steps;
|
|
1458
|
+
final List<RunEventItem> events;
|
|
1453
1459
|
final String response;
|
|
1454
1460
|
|
|
1455
1461
|
int get completedTools => steps
|
|
@@ -1469,6 +1475,95 @@ class RunDetailSnapshot {
|
|
|
1469
1475
|
steps.where((step) => step.isPlanningRelated).length;
|
|
1470
1476
|
}
|
|
1471
1477
|
|
|
1478
|
+
class RunEventItem {
|
|
1479
|
+
const RunEventItem({
|
|
1480
|
+
required this.id,
|
|
1481
|
+
required this.eventType,
|
|
1482
|
+
required this.sequenceIndex,
|
|
1483
|
+
required this.requestId,
|
|
1484
|
+
required this.stepId,
|
|
1485
|
+
required this.payload,
|
|
1486
|
+
required this.createdAt,
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
factory RunEventItem.fromJson(Map<dynamic, dynamic> json) {
|
|
1490
|
+
return RunEventItem(
|
|
1491
|
+
id: _asInt(json['id']),
|
|
1492
|
+
eventType:
|
|
1493
|
+
json['eventType']?.toString().ifEmpty(
|
|
1494
|
+
json['event_type']?.toString() ?? 'event',
|
|
1495
|
+
) ??
|
|
1496
|
+
'event',
|
|
1497
|
+
sequenceIndex: _asInt(json['sequenceIndex'] ?? json['sequence_index']),
|
|
1498
|
+
requestId:
|
|
1499
|
+
json['requestId']?.toString() ?? json['request_id']?.toString(),
|
|
1500
|
+
stepId: json['stepId']?.toString() ?? json['step_id']?.toString(),
|
|
1501
|
+
payload: json['payload'] is Map
|
|
1502
|
+
? Map<String, dynamic>.from(json['payload'] as Map)
|
|
1503
|
+
: (json['payload_json'] is Map
|
|
1504
|
+
? Map<String, dynamic>.from(json['payload_json'] as Map)
|
|
1505
|
+
: const <String, dynamic>{}),
|
|
1506
|
+
createdAt: _parseOptionalTimestamp(
|
|
1507
|
+
json['createdAt']?.toString() ?? json['created_at']?.toString(),
|
|
1508
|
+
),
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
final int id;
|
|
1513
|
+
final String eventType;
|
|
1514
|
+
final int sequenceIndex;
|
|
1515
|
+
final String? requestId;
|
|
1516
|
+
final String? stepId;
|
|
1517
|
+
final Map<String, dynamic> payload;
|
|
1518
|
+
final DateTime? createdAt;
|
|
1519
|
+
|
|
1520
|
+
String get title {
|
|
1521
|
+
switch (eventType) {
|
|
1522
|
+
case 'run_started':
|
|
1523
|
+
return 'Run started';
|
|
1524
|
+
case 'memory_injected':
|
|
1525
|
+
return 'Memory injected';
|
|
1526
|
+
case 'model_turn_started':
|
|
1527
|
+
return 'Model turn started';
|
|
1528
|
+
case 'model_turn_completed':
|
|
1529
|
+
return 'Model turn completed';
|
|
1530
|
+
case 'tool_started':
|
|
1531
|
+
return 'Tool started';
|
|
1532
|
+
case 'tool_completed':
|
|
1533
|
+
return 'Tool completed';
|
|
1534
|
+
case 'tool_failed':
|
|
1535
|
+
return 'Tool failed';
|
|
1536
|
+
case 'run_completed':
|
|
1537
|
+
return 'Run completed';
|
|
1538
|
+
case 'run_failed':
|
|
1539
|
+
return 'Run failed';
|
|
1540
|
+
case 'run_stopped':
|
|
1541
|
+
return 'Run stopped';
|
|
1542
|
+
default:
|
|
1543
|
+
return _titleCase(eventType.replaceAll('_', ' '));
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
String get detail {
|
|
1548
|
+
final toolName = payload['toolName']?.toString() ?? '';
|
|
1549
|
+
if (toolName.trim().isNotEmpty) return toolName;
|
|
1550
|
+
final preview =
|
|
1551
|
+
payload['contentPreview']?.toString() ??
|
|
1552
|
+
payload['recallPreview']?.toString() ??
|
|
1553
|
+
'';
|
|
1554
|
+
if (preview.trim().isNotEmpty) return preview;
|
|
1555
|
+
final error = payload['error']?.toString() ?? '';
|
|
1556
|
+
if (error.trim().isNotEmpty) return error;
|
|
1557
|
+
final titleValue = payload['title']?.toString() ?? '';
|
|
1558
|
+
return titleValue;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
String get createdAtLabel =>
|
|
1562
|
+
createdAt == null ? '' : _formatTimestamp(createdAt!);
|
|
1563
|
+
|
|
1564
|
+
bool get isFailure => eventType == 'tool_failed' || eventType == 'run_failed';
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1472
1567
|
class RunStepItem {
|
|
1473
1568
|
const RunStepItem({
|
|
1474
1569
|
required this.id,
|
|
@@ -2802,6 +2897,9 @@ class AiWidgetItem {
|
|
|
2802
2897
|
required this.userId,
|
|
2803
2898
|
required this.agentId,
|
|
2804
2899
|
required this.name,
|
|
2900
|
+
required this.widgetKind,
|
|
2901
|
+
required this.systemKey,
|
|
2902
|
+
required this.isSystem,
|
|
2805
2903
|
required this.template,
|
|
2806
2904
|
required this.layoutVariant,
|
|
2807
2905
|
required this.definition,
|
|
@@ -2823,6 +2921,14 @@ class AiWidgetItem {
|
|
|
2823
2921
|
userId: _asInt(json['userId'] ?? json['user_id']),
|
|
2824
2922
|
agentId: json['agentId']?.toString() ?? json['agent_id']?.toString(),
|
|
2825
2923
|
name: json['name']?.toString().ifEmpty('Widget') ?? 'Widget',
|
|
2924
|
+
widgetKind:
|
|
2925
|
+
json['widgetKind']?.toString().ifEmpty(
|
|
2926
|
+
json['widget_kind']?.toString() ?? 'custom',
|
|
2927
|
+
) ??
|
|
2928
|
+
'custom',
|
|
2929
|
+
systemKey:
|
|
2930
|
+
json['systemKey']?.toString() ?? json['system_key']?.toString(),
|
|
2931
|
+
isSystem: json['isSystem'] == true || json['is_system'] == true,
|
|
2826
2932
|
template: json['template']?.toString().ifEmpty('summary') ?? 'summary',
|
|
2827
2933
|
layoutVariant:
|
|
2828
2934
|
json['layoutVariant']?.toString().ifEmpty(
|
|
@@ -2876,6 +2982,9 @@ class AiWidgetItem {
|
|
|
2876
2982
|
final int userId;
|
|
2877
2983
|
final String? agentId;
|
|
2878
2984
|
final String name;
|
|
2985
|
+
final String widgetKind;
|
|
2986
|
+
final String? systemKey;
|
|
2987
|
+
final bool isSystem;
|
|
2879
2988
|
final String template;
|
|
2880
2989
|
final String layoutVariant;
|
|
2881
2990
|
final Map<String, dynamic> definition;
|
|
@@ -32,7 +32,7 @@ enum AppSection {
|
|
|
32
32
|
health,
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
enum SidebarGroup { chat, recordings,
|
|
35
|
+
enum SidebarGroup { chat, recordings, automation, settings }
|
|
36
36
|
|
|
37
37
|
extension SidebarGroupX on SidebarGroup {
|
|
38
38
|
String get label {
|
|
@@ -41,8 +41,6 @@ extension SidebarGroupX on SidebarGroup {
|
|
|
41
41
|
return 'Chat';
|
|
42
42
|
case SidebarGroup.recordings:
|
|
43
43
|
return 'Recordings';
|
|
44
|
-
case SidebarGroup.activity:
|
|
45
|
-
return 'Activity';
|
|
46
44
|
case SidebarGroup.automation:
|
|
47
45
|
return 'Automation';
|
|
48
46
|
case SidebarGroup.settings:
|
|
@@ -56,8 +54,6 @@ extension SidebarGroupX on SidebarGroup {
|
|
|
56
54
|
return Icons.chat_bubble_outline;
|
|
57
55
|
case SidebarGroup.recordings:
|
|
58
56
|
return Icons.fiber_smart_record_outlined;
|
|
59
|
-
case SidebarGroup.activity:
|
|
60
|
-
return Icons.insights_outlined;
|
|
61
57
|
case SidebarGroup.automation:
|
|
62
58
|
return Icons.auto_awesome_outlined;
|
|
63
59
|
case SidebarGroup.settings:
|
|
@@ -80,7 +76,7 @@ extension AppSectionX on AppSection {
|
|
|
80
76
|
case AppSection.messaging:
|
|
81
77
|
return 'Messaging';
|
|
82
78
|
case AppSection.runs:
|
|
83
|
-
return 'Runs';
|
|
79
|
+
return 'Runs & Logs';
|
|
84
80
|
case AppSection.settings:
|
|
85
81
|
return 'Settings';
|
|
86
82
|
case AppSection.accountSettings:
|
|
@@ -92,7 +88,7 @@ extension AppSectionX on AppSection {
|
|
|
92
88
|
case AppSection.agents:
|
|
93
89
|
return 'Agents';
|
|
94
90
|
case AppSection.integrations:
|
|
95
|
-
return '
|
|
91
|
+
return 'Tools';
|
|
96
92
|
case AppSection.memory:
|
|
97
93
|
return 'Memory';
|
|
98
94
|
case AppSection.tasks:
|
|
@@ -119,7 +115,7 @@ extension AppSectionX on AppSection {
|
|
|
119
115
|
case AppSection.messaging:
|
|
120
116
|
return Icons.forum_outlined;
|
|
121
117
|
case AppSection.runs:
|
|
122
|
-
return Icons.
|
|
118
|
+
return Icons.monitor_heart_outlined;
|
|
123
119
|
case AppSection.settings:
|
|
124
120
|
return Icons.tune;
|
|
125
121
|
case AppSection.accountSettings:
|
|
@@ -131,7 +127,7 @@ extension AppSectionX on AppSection {
|
|
|
131
127
|
case AppSection.agents:
|
|
132
128
|
return Icons.smart_toy_outlined;
|
|
133
129
|
case AppSection.integrations:
|
|
134
|
-
return Icons.
|
|
130
|
+
return Icons.handyman_outlined;
|
|
135
131
|
case AppSection.memory:
|
|
136
132
|
return Icons.psychology_outlined;
|
|
137
133
|
case AppSection.tasks:
|
|
@@ -152,9 +148,6 @@ extension AppSectionX on AppSection {
|
|
|
152
148
|
return SidebarGroup.chat;
|
|
153
149
|
case AppSection.recordings:
|
|
154
150
|
return SidebarGroup.recordings;
|
|
155
|
-
case AppSection.runs:
|
|
156
|
-
case AppSection.logs:
|
|
157
|
-
return SidebarGroup.activity;
|
|
158
151
|
case AppSection.devices:
|
|
159
152
|
case AppSection.skills:
|
|
160
153
|
case AppSection.integrations:
|
|
@@ -164,6 +157,8 @@ extension AppSectionX on AppSection {
|
|
|
164
157
|
case AppSection.mcp:
|
|
165
158
|
case AppSection.health:
|
|
166
159
|
return SidebarGroup.automation;
|
|
160
|
+
case AppSection.runs:
|
|
161
|
+
case AppSection.logs:
|
|
167
162
|
case AppSection.settings:
|
|
168
163
|
case AppSection.accountSettings:
|
|
169
164
|
case AppSection.messaging:
|
|
@@ -172,17 +167,31 @@ extension AppSectionX on AppSection {
|
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
|
|
170
|
+
AppSection get canonicalSection {
|
|
171
|
+
switch (this) {
|
|
172
|
+
case AppSection.logs:
|
|
173
|
+
return AppSection.runs;
|
|
174
|
+
case AppSection.skills:
|
|
175
|
+
case AppSection.mcp:
|
|
176
|
+
return AppSection.integrations;
|
|
177
|
+
default:
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
175
182
|
String get navigationTitle {
|
|
176
|
-
final
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
final effectiveSection = canonicalSection;
|
|
184
|
+
final groupLabel = effectiveSection.group.label;
|
|
185
|
+
if (effectiveSection == AppSection.voiceAssistant) {
|
|
186
|
+
return effectiveSection.label;
|
|
179
187
|
}
|
|
180
|
-
if (group == SidebarGroup.chat ||
|
|
188
|
+
if (effectiveSection.group == SidebarGroup.chat ||
|
|
189
|
+
effectiveSection.group == SidebarGroup.recordings) {
|
|
181
190
|
return groupLabel;
|
|
182
191
|
}
|
|
183
|
-
if (groupLabel == label) {
|
|
192
|
+
if (groupLabel == effectiveSection.label) {
|
|
184
193
|
return groupLabel;
|
|
185
194
|
}
|
|
186
|
-
return '$groupLabel · $label';
|
|
195
|
+
return '$groupLabel · ${effectiveSection.label}';
|
|
187
196
|
}
|
|
188
197
|
}
|