neoagent 2.4.1-beta.19 → 2.4.1-beta.21
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/README.md +4 -1
- package/docs/getting-started.md +9 -3
- package/flutter_app/assets/branding/app_icon_light_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_64.png +0 -0
- package/flutter_app/assets/branding/tray_icon_light_template.png +0 -0
- package/flutter_app/lib/features/location/location_service.dart +3 -0
- package/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_account_settings.dart +9 -33
- package/flutter_app/lib/main_app_shell.dart +237 -197
- package/flutter_app/lib/main_controller.dart +0 -25
- package/flutter_app/lib/main_devices.dart +2 -0
- package/flutter_app/lib/main_models.dart +144 -0
- package/flutter_app/lib/main_operations.dart +150 -19
- package/flutter_app/lib/main_shared.dart +642 -195
- package/flutter_app/lib/main_theme.dart +2 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +3 -1
- package/flutter_app/lib/src/security/password_strength.dart +84 -0
- package/flutter_app/lib/src/theme/palette.dart +15 -15
- package/flutter_app/pubspec.yaml +3 -0
- package/flutter_app/web/favicon_light.svg +3 -0
- package/flutter_app/web/icons/Icon-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-512-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512-light.png +0 -0
- package/lib/manager.js +282 -81
- package/package.json +17 -3
- package/server/config/origins.js +3 -1
- package/server/db/database.js +73 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/AssetManifest.bin +1 -1
- package/server/public/assets/AssetManifest.bin.json +1 -1
- package/server/public/assets/assets/branding/app_icon_light_256.png +0 -0
- package/server/public/assets/assets/branding/app_icon_light_512.png +0 -0
- package/server/public/assets/assets/branding/tray_icon_light_template.png +0 -0
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/favicon_light.svg +3 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/icons/Icon-192-light.png +0 -0
- package/server/public/icons/Icon-512-light.png +0 -0
- package/server/public/icons/Icon-maskable-192-light.png +0 -0
- package/server/public/icons/Icon-maskable-512-light.png +0 -0
- package/server/public/main.dart.js +68769 -68268
- package/server/routes/agent_profiles.js +3 -0
- package/server/routes/memory.js +22 -1
- package/server/services/account/password_policy.js +6 -1
- package/server/services/memory/intelligence.js +181 -0
- package/server/services/memory/manager.js +475 -25
- package/server/utils/security.js +3 -0
- package/server/services/memory/openhuman_uplift.test.js +0 -98
- package/server/utils/version.test.js +0 -39
|
@@ -2861,6 +2861,10 @@ class MemoryOverview {
|
|
|
2861
2861
|
this.dailyLogs = const <String>[],
|
|
2862
2862
|
this.apiKeys = const <String, String>{},
|
|
2863
2863
|
this.coreEntries = const <String, dynamic>{},
|
|
2864
|
+
this.stats = const MemoryStats(),
|
|
2865
|
+
this.entities = const <MemoryEntity>[],
|
|
2866
|
+
this.knowledgeViews = const <KnowledgeViewItem>[],
|
|
2867
|
+
this.recentKnowledgeChanges = const <KnowledgeChangeItem>[],
|
|
2864
2868
|
});
|
|
2865
2869
|
|
|
2866
2870
|
factory MemoryOverview.fromJson(Map<dynamic, dynamic> json) {
|
|
@@ -2880,6 +2884,16 @@ class MemoryOverview {
|
|
|
2880
2884
|
coreEntries: coreRaw is Map
|
|
2881
2885
|
? Map<String, dynamic>.from(coreRaw)
|
|
2882
2886
|
: const <String, dynamic>{},
|
|
2887
|
+
stats: MemoryStats.fromJson(_jsonMap(json['stats'])),
|
|
2888
|
+
entities: _jsonMapList(
|
|
2889
|
+
json['entities'],
|
|
2890
|
+
).map(MemoryEntity.fromJson).toList(),
|
|
2891
|
+
knowledgeViews: _jsonMapList(
|
|
2892
|
+
json['knowledgeViews'],
|
|
2893
|
+
).map(KnowledgeViewItem.fromJson).toList(),
|
|
2894
|
+
recentKnowledgeChanges: _jsonMapList(
|
|
2895
|
+
json['recentKnowledgeChanges'],
|
|
2896
|
+
).map(KnowledgeChangeItem.fromJson).toList(),
|
|
2883
2897
|
);
|
|
2884
2898
|
}
|
|
2885
2899
|
|
|
@@ -2887,6 +2901,10 @@ class MemoryOverview {
|
|
|
2887
2901
|
final List<String> dailyLogs;
|
|
2888
2902
|
final Map<String, String> apiKeys;
|
|
2889
2903
|
final Map<String, dynamic> coreEntries;
|
|
2904
|
+
final MemoryStats stats;
|
|
2905
|
+
final List<MemoryEntity> entities;
|
|
2906
|
+
final List<KnowledgeViewItem> knowledgeViews;
|
|
2907
|
+
final List<KnowledgeChangeItem> recentKnowledgeChanges;
|
|
2890
2908
|
|
|
2891
2909
|
int get behaviorNotesLength => assistantBehaviorNotes.length;
|
|
2892
2910
|
int get dailyLogCount => dailyLogs.length;
|
|
@@ -2894,6 +2912,112 @@ class MemoryOverview {
|
|
|
2894
2912
|
int get coreCount => coreEntries.length;
|
|
2895
2913
|
}
|
|
2896
2914
|
|
|
2915
|
+
class MemoryStats {
|
|
2916
|
+
const MemoryStats({
|
|
2917
|
+
this.total = 0,
|
|
2918
|
+
this.active = 0,
|
|
2919
|
+
this.archived = 0,
|
|
2920
|
+
this.facts = 0,
|
|
2921
|
+
this.entities = 0,
|
|
2922
|
+
this.knowledgeViews = 0,
|
|
2923
|
+
this.ingestionDocuments = 0,
|
|
2924
|
+
this.averageImportance = 0,
|
|
2925
|
+
this.averageConfidence = 0,
|
|
2926
|
+
});
|
|
2927
|
+
|
|
2928
|
+
factory MemoryStats.fromJson(Map<dynamic, dynamic> json) {
|
|
2929
|
+
return MemoryStats(
|
|
2930
|
+
total: _asInt(json['total']),
|
|
2931
|
+
active: _asInt(json['active']),
|
|
2932
|
+
archived: _asInt(json['archived']),
|
|
2933
|
+
facts: _asInt(json['facts']),
|
|
2934
|
+
entities: _asInt(json['entities']),
|
|
2935
|
+
knowledgeViews: _asInt(json['knowledgeViews']),
|
|
2936
|
+
ingestionDocuments: _asInt(json['ingestionDocuments']),
|
|
2937
|
+
averageImportance: _asDouble(json['averageImportance']),
|
|
2938
|
+
averageConfidence: _asDouble(json['averageConfidence']),
|
|
2939
|
+
);
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2942
|
+
final int total;
|
|
2943
|
+
final int active;
|
|
2944
|
+
final int archived;
|
|
2945
|
+
final int facts;
|
|
2946
|
+
final int entities;
|
|
2947
|
+
final int knowledgeViews;
|
|
2948
|
+
final int ingestionDocuments;
|
|
2949
|
+
final double averageImportance;
|
|
2950
|
+
final double averageConfidence;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
class MemoryEntity {
|
|
2954
|
+
const MemoryEntity({
|
|
2955
|
+
required this.id,
|
|
2956
|
+
required this.key,
|
|
2957
|
+
required this.name,
|
|
2958
|
+
required this.kind,
|
|
2959
|
+
required this.mentionCount,
|
|
2960
|
+
});
|
|
2961
|
+
|
|
2962
|
+
factory MemoryEntity.fromJson(Map<dynamic, dynamic> json) {
|
|
2963
|
+
return MemoryEntity(
|
|
2964
|
+
id: json['id']?.toString() ?? '',
|
|
2965
|
+
key: json['key']?.toString() ?? '',
|
|
2966
|
+
name: json['name']?.toString() ?? '',
|
|
2967
|
+
kind: json['kind']?.toString().ifEmpty('concept') ?? 'concept',
|
|
2968
|
+
mentionCount: _asInt(json['mentionCount']),
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
final String id;
|
|
2973
|
+
final String key;
|
|
2974
|
+
final String name;
|
|
2975
|
+
final String kind;
|
|
2976
|
+
final int mentionCount;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
class KnowledgeViewItem {
|
|
2980
|
+
const KnowledgeViewItem({
|
|
2981
|
+
required this.title,
|
|
2982
|
+
required this.viewType,
|
|
2983
|
+
required this.summary,
|
|
2984
|
+
});
|
|
2985
|
+
|
|
2986
|
+
factory KnowledgeViewItem.fromJson(Map<dynamic, dynamic> json) {
|
|
2987
|
+
return KnowledgeViewItem(
|
|
2988
|
+
title:
|
|
2989
|
+
json['title']?.toString().ifEmpty('Knowledge view') ??
|
|
2990
|
+
'Knowledge view',
|
|
2991
|
+
viewType: json['viewType']?.toString().ifEmpty('view') ?? 'view',
|
|
2992
|
+
summary: json['summary']?.toString() ?? '',
|
|
2993
|
+
);
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
final String title;
|
|
2997
|
+
final String viewType;
|
|
2998
|
+
final String summary;
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
class KnowledgeChangeItem {
|
|
3002
|
+
const KnowledgeChangeItem({
|
|
3003
|
+
required this.title,
|
|
3004
|
+
required this.kind,
|
|
3005
|
+
required this.summary,
|
|
3006
|
+
});
|
|
3007
|
+
|
|
3008
|
+
factory KnowledgeChangeItem.fromJson(Map<dynamic, dynamic> json) {
|
|
3009
|
+
return KnowledgeChangeItem(
|
|
3010
|
+
title: json['title']?.toString().ifEmpty('Change') ?? 'Change',
|
|
3011
|
+
kind: json['kind']?.toString().ifEmpty('change') ?? 'change',
|
|
3012
|
+
summary: json['summary']?.toString() ?? '',
|
|
3013
|
+
);
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
final String title;
|
|
3017
|
+
final String kind;
|
|
3018
|
+
final String summary;
|
|
3019
|
+
}
|
|
3020
|
+
|
|
2897
3021
|
class MemoryItem {
|
|
2898
3022
|
const MemoryItem({
|
|
2899
3023
|
required this.id,
|
|
@@ -2901,25 +3025,45 @@ class MemoryItem {
|
|
|
2901
3025
|
required this.category,
|
|
2902
3026
|
required this.importance,
|
|
2903
3027
|
required this.createdAt,
|
|
3028
|
+
this.summary = '',
|
|
3029
|
+
this.confidence = 0.7,
|
|
3030
|
+
this.entities = const <MemoryEntity>[],
|
|
3031
|
+
this.score,
|
|
2904
3032
|
});
|
|
2905
3033
|
|
|
2906
3034
|
factory MemoryItem.fromJson(Map<dynamic, dynamic> json) {
|
|
2907
3035
|
return MemoryItem(
|
|
2908
3036
|
id: json['id']?.toString() ?? '',
|
|
2909
3037
|
content: json['content']?.toString() ?? '',
|
|
3038
|
+
summary: json['summary']?.toString() ?? '',
|
|
2910
3039
|
category: json['category']?.toString().ifEmpty('memory') ?? 'memory',
|
|
2911
3040
|
importance: _asInt(json['importance']),
|
|
3041
|
+
confidence: _asDouble(json['confidence'], fallback: 0.7),
|
|
2912
3042
|
createdAt: _parseTimestamp(json['created_at']?.toString()),
|
|
3043
|
+
entities: _jsonMapList(
|
|
3044
|
+
json['entities'],
|
|
3045
|
+
).map(MemoryEntity.fromJson).toList(),
|
|
3046
|
+
score: (() {
|
|
3047
|
+
final raw = json['score'];
|
|
3048
|
+
if (raw == null) return null;
|
|
3049
|
+
if (raw is num) return raw.toDouble();
|
|
3050
|
+
return double.tryParse(raw.toString());
|
|
3051
|
+
})(),
|
|
2913
3052
|
);
|
|
2914
3053
|
}
|
|
2915
3054
|
|
|
2916
3055
|
final String id;
|
|
2917
3056
|
final String content;
|
|
3057
|
+
final String summary;
|
|
2918
3058
|
final String category;
|
|
2919
3059
|
final int importance;
|
|
3060
|
+
final double confidence;
|
|
2920
3061
|
final DateTime createdAt;
|
|
3062
|
+
final List<MemoryEntity> entities;
|
|
3063
|
+
final double? score;
|
|
2921
3064
|
|
|
2922
3065
|
String get createdAtLabel => _formatTimestamp(createdAt);
|
|
3066
|
+
int get confidencePercent => (confidence * 100).round().clamp(0, 100);
|
|
2923
3067
|
}
|
|
2924
3068
|
|
|
2925
3069
|
class ConversationItem {
|
|
@@ -1332,9 +1332,7 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1332
1332
|
return AlertDialog(
|
|
1333
1333
|
backgroundColor: _bgCard,
|
|
1334
1334
|
title: Text('Import memory transfer?'),
|
|
1335
|
-
content: Text(
|
|
1336
|
-
'This will import the response into $targetLabel.',
|
|
1337
|
-
),
|
|
1335
|
+
content: Text('This will import the response into $targetLabel.'),
|
|
1338
1336
|
actions: <Widget>[
|
|
1339
1337
|
TextButton(
|
|
1340
1338
|
onPressed: () => Navigator.of(context).pop(false),
|
|
@@ -1381,9 +1379,9 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1381
1379
|
if (!mounted) {
|
|
1382
1380
|
return;
|
|
1383
1381
|
}
|
|
1384
|
-
ScaffoldMessenger.of(
|
|
1385
|
-
|
|
1386
|
-
);
|
|
1382
|
+
ScaffoldMessenger.of(
|
|
1383
|
+
context,
|
|
1384
|
+
).showSnackBar(SnackBar(content: Text('Import failed: $error')));
|
|
1387
1385
|
} finally {
|
|
1388
1386
|
if (mounted) {
|
|
1389
1387
|
setState(() {
|
|
@@ -1519,7 +1517,7 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1519
1517
|
_PageTitle(
|
|
1520
1518
|
title: 'Memory',
|
|
1521
1519
|
subtitle:
|
|
1522
|
-
'
|
|
1520
|
+
'Structured facts, entities, reflections, long-term recall, and behavior notes.',
|
|
1523
1521
|
trailing: Wrap(
|
|
1524
1522
|
spacing: 10,
|
|
1525
1523
|
runSpacing: 10,
|
|
@@ -1541,33 +1539,33 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1541
1539
|
children: <Widget>[
|
|
1542
1540
|
Expanded(
|
|
1543
1541
|
child: _OverviewCard(
|
|
1544
|
-
title: '
|
|
1545
|
-
value: '${controller.memoryOverview.
|
|
1546
|
-
helper: '
|
|
1542
|
+
title: 'Active Memories',
|
|
1543
|
+
value: '${controller.memoryOverview.stats.active}',
|
|
1544
|
+
helper: 'Recallable long-term entries',
|
|
1547
1545
|
),
|
|
1548
1546
|
),
|
|
1549
1547
|
const SizedBox(width: 12),
|
|
1550
1548
|
Expanded(
|
|
1551
1549
|
child: _OverviewCard(
|
|
1552
|
-
title: '
|
|
1553
|
-
value: '${controller.memoryOverview.
|
|
1554
|
-
helper: '
|
|
1550
|
+
title: 'Extracted Facts',
|
|
1551
|
+
value: '${controller.memoryOverview.stats.facts}',
|
|
1552
|
+
helper: 'Structured statements for recall',
|
|
1555
1553
|
),
|
|
1556
1554
|
),
|
|
1557
1555
|
const SizedBox(width: 12),
|
|
1558
1556
|
Expanded(
|
|
1559
1557
|
child: _OverviewCard(
|
|
1560
|
-
title: '
|
|
1561
|
-
value: '${controller.memoryOverview.
|
|
1562
|
-
helper: '
|
|
1558
|
+
title: 'Entities',
|
|
1559
|
+
value: '${controller.memoryOverview.stats.entities}',
|
|
1560
|
+
helper: 'People, projects, files, and concepts',
|
|
1563
1561
|
),
|
|
1564
1562
|
),
|
|
1565
1563
|
const SizedBox(width: 12),
|
|
1566
1564
|
Expanded(
|
|
1567
1565
|
child: _OverviewCard(
|
|
1568
|
-
title: '
|
|
1569
|
-
value: '${controller.memoryOverview.
|
|
1570
|
-
helper: '
|
|
1566
|
+
title: 'Reflections',
|
|
1567
|
+
value: '${controller.memoryOverview.stats.knowledgeViews}',
|
|
1568
|
+
helper: 'Materialized knowledge views',
|
|
1571
1569
|
),
|
|
1572
1570
|
),
|
|
1573
1571
|
],
|
|
@@ -1609,6 +1607,117 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1609
1607
|
),
|
|
1610
1608
|
),
|
|
1611
1609
|
const SizedBox(height: 16),
|
|
1610
|
+
Card(
|
|
1611
|
+
child: Padding(
|
|
1612
|
+
padding: const EdgeInsets.all(18),
|
|
1613
|
+
child: Column(
|
|
1614
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
1615
|
+
children: <Widget>[
|
|
1616
|
+
const _SectionTitle('Memory Intelligence'),
|
|
1617
|
+
const SizedBox(height: 12),
|
|
1618
|
+
Wrap(
|
|
1619
|
+
spacing: 10,
|
|
1620
|
+
runSpacing: 10,
|
|
1621
|
+
children: <Widget>[
|
|
1622
|
+
_MetaPill(
|
|
1623
|
+
label:
|
|
1624
|
+
'Confidence ${(controller.memoryOverview.stats.averageConfidence * 100).round()}%',
|
|
1625
|
+
icon: Icons.verified_outlined,
|
|
1626
|
+
),
|
|
1627
|
+
_MetaPill(
|
|
1628
|
+
label:
|
|
1629
|
+
'Avg importance ${controller.memoryOverview.stats.averageImportance.toStringAsFixed(1)}',
|
|
1630
|
+
icon: Icons.priority_high_outlined,
|
|
1631
|
+
),
|
|
1632
|
+
_MetaPill(
|
|
1633
|
+
label:
|
|
1634
|
+
'${controller.memoryOverview.stats.ingestionDocuments} ingested docs',
|
|
1635
|
+
icon: Icons.source_outlined,
|
|
1636
|
+
),
|
|
1637
|
+
],
|
|
1638
|
+
),
|
|
1639
|
+
const SizedBox(height: 16),
|
|
1640
|
+
if (controller.memoryOverview.entities.isNotEmpty) ...<Widget>[
|
|
1641
|
+
Text(
|
|
1642
|
+
'Top entities',
|
|
1643
|
+
style: TextStyle(fontWeight: FontWeight.w700),
|
|
1644
|
+
),
|
|
1645
|
+
const SizedBox(height: 8),
|
|
1646
|
+
Wrap(
|
|
1647
|
+
spacing: 8,
|
|
1648
|
+
runSpacing: 8,
|
|
1649
|
+
children: controller.memoryOverview.entities.map((entity) {
|
|
1650
|
+
return _MetaPill(
|
|
1651
|
+
label: entity.name,
|
|
1652
|
+
icon: Icons.hub_outlined,
|
|
1653
|
+
);
|
|
1654
|
+
}).toList(),
|
|
1655
|
+
),
|
|
1656
|
+
const SizedBox(height: 16),
|
|
1657
|
+
],
|
|
1658
|
+
if (controller
|
|
1659
|
+
.memoryOverview
|
|
1660
|
+
.knowledgeViews
|
|
1661
|
+
.isNotEmpty) ...<Widget>[
|
|
1662
|
+
Text(
|
|
1663
|
+
'Reflections',
|
|
1664
|
+
style: TextStyle(fontWeight: FontWeight.w700),
|
|
1665
|
+
),
|
|
1666
|
+
const SizedBox(height: 8),
|
|
1667
|
+
...controller.memoryOverview.knowledgeViews.take(5).map((
|
|
1668
|
+
view,
|
|
1669
|
+
) {
|
|
1670
|
+
return Container(
|
|
1671
|
+
width: double.infinity,
|
|
1672
|
+
margin: const EdgeInsets.only(bottom: 10),
|
|
1673
|
+
padding: const EdgeInsets.all(12),
|
|
1674
|
+
decoration: BoxDecoration(
|
|
1675
|
+
color: _bgSecondary,
|
|
1676
|
+
borderRadius: BorderRadius.circular(8),
|
|
1677
|
+
border: Border.all(color: _border),
|
|
1678
|
+
),
|
|
1679
|
+
child: Column(
|
|
1680
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
1681
|
+
children: <Widget>[
|
|
1682
|
+
Row(
|
|
1683
|
+
children: <Widget>[
|
|
1684
|
+
Expanded(
|
|
1685
|
+
child: Text(
|
|
1686
|
+
view.title,
|
|
1687
|
+
style: TextStyle(fontWeight: FontWeight.w700),
|
|
1688
|
+
),
|
|
1689
|
+
),
|
|
1690
|
+
_MetaPill(
|
|
1691
|
+
label: view.viewType,
|
|
1692
|
+
icon: Icons.auto_stories_outlined,
|
|
1693
|
+
),
|
|
1694
|
+
],
|
|
1695
|
+
),
|
|
1696
|
+
if (view.summary.trim().isNotEmpty) ...<Widget>[
|
|
1697
|
+
const SizedBox(height: 8),
|
|
1698
|
+
Text(
|
|
1699
|
+
view.summary,
|
|
1700
|
+
maxLines: 4,
|
|
1701
|
+
overflow: TextOverflow.ellipsis,
|
|
1702
|
+
style: TextStyle(color: _textSecondary),
|
|
1703
|
+
),
|
|
1704
|
+
],
|
|
1705
|
+
],
|
|
1706
|
+
),
|
|
1707
|
+
);
|
|
1708
|
+
}),
|
|
1709
|
+
],
|
|
1710
|
+
if (controller.memoryOverview.entities.isEmpty &&
|
|
1711
|
+
controller.memoryOverview.knowledgeViews.isEmpty)
|
|
1712
|
+
Text(
|
|
1713
|
+
'No structured entities or reflections yet.',
|
|
1714
|
+
style: TextStyle(color: _textSecondary),
|
|
1715
|
+
),
|
|
1716
|
+
],
|
|
1717
|
+
),
|
|
1718
|
+
),
|
|
1719
|
+
),
|
|
1720
|
+
const SizedBox(height: 16),
|
|
1612
1721
|
Card(
|
|
1613
1722
|
child: Theme(
|
|
1614
1723
|
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
|
|
@@ -1938,6 +2047,11 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1938
2047
|
icon: Icons
|
|
1939
2048
|
.priority_high_outlined,
|
|
1940
2049
|
),
|
|
2050
|
+
_MetaPill(
|
|
2051
|
+
label:
|
|
2052
|
+
'Confidence ${memory.confidencePercent}%',
|
|
2053
|
+
icon: Icons.verified_outlined,
|
|
2054
|
+
),
|
|
1941
2055
|
],
|
|
1942
2056
|
),
|
|
1943
2057
|
),
|
|
@@ -1961,6 +2075,23 @@ class _MemoryPanelState extends State<MemoryPanel> {
|
|
|
1961
2075
|
),
|
|
1962
2076
|
const SizedBox(height: 10),
|
|
1963
2077
|
Text(memory.content),
|
|
2078
|
+
if (memory
|
|
2079
|
+
.entities
|
|
2080
|
+
.isNotEmpty) ...<Widget>[
|
|
2081
|
+
const SizedBox(height: 8),
|
|
2082
|
+
Wrap(
|
|
2083
|
+
spacing: 8,
|
|
2084
|
+
runSpacing: 8,
|
|
2085
|
+
children: memory.entities.take(6).map(
|
|
2086
|
+
(entity) {
|
|
2087
|
+
return _MetaPill(
|
|
2088
|
+
label: entity.name,
|
|
2089
|
+
icon: Icons.hub_outlined,
|
|
2090
|
+
);
|
|
2091
|
+
},
|
|
2092
|
+
).toList(),
|
|
2093
|
+
),
|
|
2094
|
+
],
|
|
1964
2095
|
const SizedBox(height: 8),
|
|
1965
2096
|
Text(
|
|
1966
2097
|
memory.createdAtLabel,
|