neoagent 3.2.1-beta.1 → 3.2.1-beta.11
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/extensions/chrome-browser/background.mjs +318 -88
- package/extensions/chrome-browser/http.mjs +136 -0
- package/extensions/chrome-browser/protocol.mjs +654 -90
- package/flutter_app/lib/main_chat.dart +118 -739
- package/flutter_app/lib/main_controller.dart +157 -24
- package/flutter_app/lib/main_integrations.dart +607 -8
- package/flutter_app/lib/main_models.dart +7 -2
- package/flutter_app/lib/main_operations.dart +334 -370
- package/flutter_app/lib/main_security.dart +266 -112
- package/flutter_app/lib/main_settings.dart +342 -3
- package/flutter_app/lib/main_shared.dart +14 -11
- package/flutter_app/lib/src/backend_client.dart +97 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +185 -31
- package/flutter_app/lib/src/desktop_companion_io.dart +319 -86
- package/flutter_app/windows/runner/flutter_window.cpp +143 -32
- package/landing/index.html +3 -1
- package/lib/manager.js +106 -89
- package/lib/schema_migrations.js +115 -13
- package/package.json +30 -15
- package/runtime/paths.js +49 -5
- package/server/db/database.js +2 -2
- package/server/guest-agent.cli.package.json +13 -0
- package/server/guest_agent.js +85 -40
- package/server/http/middleware.js +24 -0
- package/server/http/routes.js +12 -6
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +2 -2
- package/server/public/main.dart.js +81930 -80509
- package/server/routes/admin.js +1 -1
- package/server/routes/android.js +30 -34
- package/server/routes/behavior.js +80 -0
- package/server/routes/browser.js +23 -15
- package/server/routes/desktop.js +18 -1
- package/server/routes/integrations.js +107 -1
- package/server/routes/memory.js +1 -0
- package/server/routes/settings.js +20 -5
- package/server/routes/social_reach.js +12 -3
- package/server/routes/social_video.js +4 -0
- package/server/services/agents/manager.js +1 -1
- package/server/services/ai/capabilityHealth.js +62 -96
- package/server/services/ai/compaction.js +7 -2
- package/server/services/ai/history.js +45 -6
- package/server/services/ai/integrated_tools/http_request.js +8 -0
- package/server/services/ai/loop/agent_engine_core.js +452 -176
- package/server/services/ai/loop/blank_recovery.js +5 -4
- package/server/services/ai/loop/callbacks.js +1 -0
- package/server/services/ai/loop/completion_judge.js +291 -8
- package/server/services/ai/loop/conversation_loop.js +515 -342
- package/server/services/ai/loop/messaging_delivery.js +176 -57
- package/server/services/ai/loop/model_call_guard.js +91 -0
- package/server/services/ai/loop/model_io.js +20 -45
- package/server/services/ai/loop/progress_classification.js +2 -0
- package/server/services/ai/loop/tool_dispatch.js +19 -8
- package/server/services/ai/loopPolicy.js +48 -21
- package/server/services/ai/messagingFallback.js +17 -17
- package/server/services/ai/model_discovery.js +227 -0
- package/server/services/ai/model_failure_cache.js +108 -0
- package/server/services/ai/model_identity.js +71 -0
- package/server/services/ai/models.js +68 -163
- package/server/services/ai/providerRetry.js +17 -59
- package/server/services/ai/provider_selector.js +166 -0
- package/server/services/ai/providers/anthropic.js +2 -2
- package/server/services/ai/providers/claudeCode.js +21 -33
- package/server/services/ai/providers/githubCopilot.js +41 -20
- package/server/services/ai/providers/google.js +135 -97
- package/server/services/ai/providers/grok.js +4 -3
- package/server/services/ai/providers/grokOauth.js +19 -27
- package/server/services/ai/providers/nvidia.js +10 -5
- package/server/services/ai/providers/ollama.js +111 -84
- package/server/services/ai/providers/ollama_stream.js +142 -0
- package/server/services/ai/providers/openai.js +39 -5
- package/server/services/ai/providers/openaiCodex.js +11 -4
- package/server/services/ai/providers/openrouter.js +29 -7
- package/server/services/ai/providers/provider_error.js +36 -0
- package/server/services/ai/settings.js +26 -2
- package/server/services/ai/systemPrompt.js +32 -123
- package/server/services/ai/taskAnalysis.js +104 -11
- package/server/services/ai/toolEvidence.js +256 -29
- package/server/services/ai/tools.js +248 -117
- package/server/services/android/controller.js +770 -237
- package/server/services/android/process.js +140 -0
- package/server/services/android/sdk_download.js +143 -0
- package/server/services/android/uia.js +6 -5
- package/server/services/artifacts/store.js +24 -0
- package/server/services/behavior/config.js +251 -0
- package/server/services/behavior/defaults.js +68 -0
- package/server/services/behavior/delivery.js +176 -0
- package/server/services/behavior/index.js +43 -0
- package/server/services/behavior/model_client.js +35 -0
- package/server/services/behavior/modules/agent_identity.js +37 -0
- package/server/services/behavior/modules/channel_style.js +28 -0
- package/server/services/behavior/modules/index.js +29 -0
- package/server/services/behavior/modules/norms.js +101 -0
- package/server/services/behavior/modules/persona.js +48 -0
- package/server/services/behavior/modules/persona_prompt.js +33 -0
- package/server/services/behavior/modules/social_memory.js +86 -0
- package/server/services/behavior/modules/social_observability.js +94 -0
- package/server/services/behavior/modules/social_signals.js +41 -0
- package/server/services/behavior/modules/theory_of_mind.js +110 -0
- package/server/services/behavior/modules/turn_taking.js +237 -0
- package/server/services/behavior/pipeline.js +285 -0
- package/server/services/behavior/registry.js +78 -0
- package/server/services/behavior/signals.js +107 -0
- package/server/services/behavior/state.js +99 -0
- package/server/services/behavior/system_prompt.js +75 -0
- package/server/services/browser/controller.js +843 -385
- package/server/services/browser/extension/gateway.js +40 -16
- package/server/services/browser/extension/protocol.js +15 -1
- package/server/services/browser/extension/provider.js +71 -47
- package/server/services/browser/extension/registry.js +155 -34
- package/server/services/cli/executor.js +62 -9
- package/server/services/credentials/bitwarden_cli.js +322 -0
- package/server/services/credentials/broker.js +594 -0
- package/server/services/desktop/gateway.js +41 -4
- package/server/services/desktop/protocol.js +3 -0
- package/server/services/desktop/provider.js +39 -42
- package/server/services/desktop/registry.js +137 -52
- package/server/services/integrations/bitwarden/constants.js +14 -0
- package/server/services/integrations/bitwarden/provider.js +197 -0
- package/server/services/integrations/bitwarden/snapshot.js +65 -0
- package/server/services/integrations/figma/provider.js +78 -12
- package/server/services/integrations/github/common.js +11 -6
- package/server/services/integrations/github/provider.js +52 -53
- package/server/services/integrations/google/provider.js +55 -19
- package/server/services/integrations/home_assistant/network.js +17 -20
- package/server/services/integrations/home_assistant/provider.js +7 -5
- package/server/services/integrations/home_assistant/tools.js +17 -5
- package/server/services/integrations/http.js +51 -0
- package/server/services/integrations/manager.js +159 -53
- package/server/services/integrations/microsoft/provider.js +80 -13
- package/server/services/integrations/neoarchive/provider.js +55 -29
- package/server/services/integrations/neorecall/client.js +17 -10
- package/server/services/integrations/neorecall/provider.js +20 -11
- package/server/services/integrations/notion/provider.js +16 -13
- package/server/services/integrations/oauth_provider.js +115 -51
- package/server/services/integrations/registry.js +2 -0
- package/server/services/integrations/slack/provider.js +98 -9
- package/server/services/integrations/spotify/provider.js +67 -71
- package/server/services/integrations/trello/provider.js +21 -7
- package/server/services/integrations/weather/provider.js +18 -12
- package/server/services/integrations/whatsapp/provider.js +76 -16
- package/server/services/manager.js +110 -1
- package/server/services/memory/embedding_index.js +20 -8
- package/server/services/memory/embeddings.js +151 -90
- package/server/services/memory/ingestion.js +50 -9
- package/server/services/memory/ingestion_documents.js +13 -3
- package/server/services/memory/manager.js +66 -52
- package/server/services/messaging/access_policy.js +10 -6
- package/server/services/messaging/automation.js +240 -34
- package/server/services/messaging/discord.js +11 -1
- package/server/services/messaging/formatting_guides.js +5 -4
- package/server/services/messaging/http_platforms.js +37 -16
- package/server/services/messaging/inbound_queue.js +143 -28
- package/server/services/messaging/inbound_store.js +257 -0
- package/server/services/messaging/manager.js +344 -51
- package/server/services/messaging/telegram.js +10 -1
- package/server/services/messaging/typing_keepalive.js +5 -2
- package/server/services/messaging/whatsapp.js +33 -14
- package/server/services/network/http.js +210 -0
- package/server/services/network/safe_request.js +307 -0
- package/server/services/runtime/backends/local-vm.js +227 -67
- package/server/services/runtime/docker-vm-manager.js +9 -0
- package/server/services/runtime/guest_bootstrap.js +30 -4
- package/server/services/runtime/guest_image.js +43 -12
- package/server/services/runtime/manager.js +77 -23
- package/server/services/runtime/validation.js +7 -6
- package/server/services/security/tool_categories.js +6 -0
- package/server/services/social_reach/channels/github.js +10 -4
- package/server/services/social_reach/channels/reddit.js +4 -4
- package/server/services/social_reach/channels/rss.js +2 -2
- package/server/services/social_reach/channels/social_video.js +13 -8
- package/server/services/social_reach/channels/v2ex.js +21 -8
- package/server/services/social_reach/channels/x.js +2 -2
- package/server/services/social_reach/channels/xueqiu.js +5 -5
- package/server/services/social_reach/service.js +9 -6
- package/server/services/social_reach/utils.js +65 -14
- package/server/services/social_video/captions.js +2 -2
- package/server/services/social_video/service.js +343 -68
- package/server/services/tasks/integration_runtime.js +18 -8
- package/server/services/tasks/runtime.js +39 -4
- package/server/services/voice/agentBridge.js +17 -4
- package/server/services/voice/bufferedLiveRelayAdapter.js +5 -0
- package/server/services/voice/liveSession.js +31 -0
- package/server/services/voice/message.js +1 -1
- package/server/services/voice/openaiSpeech.js +33 -8
- package/server/services/voice/providers.js +233 -151
- package/server/services/voice/runtime.js +2 -2
- package/server/services/voice/runtimeManager.js +118 -20
- package/server/services/voice/turnRunner.js +6 -0
- package/server/services/wearable/firmware_manifest.js +51 -13
- package/server/services/wearable/service.js +1 -0
- package/server/utils/abort.js +96 -0
- package/server/utils/cloud-security.js +110 -3
- package/server/utils/files.js +31 -0
- package/server/utils/image_payload.js +95 -0
- package/server/utils/logger.js +19 -0
- package/server/utils/retry.js +107 -0
|
@@ -505,8 +505,10 @@ class _SkillsPanelState extends State<SkillsPanel>
|
|
|
505
505
|
|
|
506
506
|
// Installed tab search & filter state
|
|
507
507
|
String _installedQuery = '';
|
|
508
|
-
String _installedStatusFilter =
|
|
509
|
-
|
|
508
|
+
String _installedStatusFilter =
|
|
509
|
+
'all'; // 'all' | 'active' | 'draft' | 'disabled'
|
|
510
|
+
String _installedSourceFilter =
|
|
511
|
+
'all'; // 'all' | 'built-in' | 'learned' | 'user' | 'store'
|
|
510
512
|
late final TextEditingController _installedSearchController;
|
|
511
513
|
|
|
512
514
|
@override
|
|
@@ -645,18 +647,36 @@ class _SkillsPanelState extends State<SkillsPanel>
|
|
|
645
647
|
final q = _installedQuery;
|
|
646
648
|
if (q.isNotEmpty &&
|
|
647
649
|
!skill.name.toLowerCase().contains(q) &&
|
|
648
|
-
!skill.description.toLowerCase().contains(q))
|
|
650
|
+
!skill.description.toLowerCase().contains(q)) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
649
653
|
if (_installedStatusFilter != 'all') {
|
|
650
|
-
if (_installedStatusFilter == 'active' &&
|
|
651
|
-
|
|
652
|
-
|
|
654
|
+
if (_installedStatusFilter == 'active' &&
|
|
655
|
+
(!skill.enabled || skill.draft)) {
|
|
656
|
+
return false;
|
|
657
|
+
}
|
|
658
|
+
if (_installedStatusFilter == 'draft' && !skill.draft) {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
if (_installedStatusFilter == 'disabled' && skill.enabled) {
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (_installedSourceFilter != 'all' &&
|
|
666
|
+
skill.source != _installedSourceFilter) {
|
|
667
|
+
return false;
|
|
653
668
|
}
|
|
654
|
-
if (_installedSourceFilter != 'all' && skill.source != _installedSourceFilter) return false;
|
|
655
669
|
return true;
|
|
656
670
|
}).toList();
|
|
657
671
|
|
|
658
672
|
final statusFilters = <String>['all', 'active', 'draft', 'disabled'];
|
|
659
|
-
final sourceFilters = <String>[
|
|
673
|
+
final sourceFilters = <String>[
|
|
674
|
+
'all',
|
|
675
|
+
'built-in',
|
|
676
|
+
'learned',
|
|
677
|
+
'user',
|
|
678
|
+
'store',
|
|
679
|
+
];
|
|
660
680
|
|
|
661
681
|
return Card(
|
|
662
682
|
child: Column(
|
|
@@ -757,157 +777,174 @@ class _SkillsPanelState extends State<SkillsPanel>
|
|
|
757
777
|
separatorBuilder: (_, __) => const SizedBox(height: 10),
|
|
758
778
|
itemBuilder: (context, index) {
|
|
759
779
|
final skill = filteredSkills[index];
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
780
|
+
return LayoutBuilder(
|
|
781
|
+
builder: (context, constraints) {
|
|
782
|
+
final compact = constraints.maxWidth < 760;
|
|
783
|
+
return Container(
|
|
784
|
+
padding: const EdgeInsets.all(14),
|
|
785
|
+
decoration: BoxDecoration(
|
|
786
|
+
color: _bgSecondary,
|
|
787
|
+
borderRadius: BorderRadius.circular(14),
|
|
788
|
+
border: Border.all(color: _border),
|
|
789
|
+
),
|
|
790
|
+
child: compact
|
|
791
|
+
? Column(
|
|
792
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
793
|
+
children: <Widget>[
|
|
794
|
+
Row(
|
|
795
|
+
children: <Widget>[
|
|
796
|
+
Expanded(
|
|
797
|
+
child: Text(
|
|
798
|
+
skill.name,
|
|
799
|
+
style: TextStyle(
|
|
800
|
+
fontWeight: FontWeight.w700,
|
|
801
|
+
),
|
|
802
|
+
),
|
|
803
|
+
),
|
|
804
|
+
Switch(
|
|
805
|
+
value: skill.enabled,
|
|
806
|
+
onChanged: (value) => controller
|
|
807
|
+
.setSkillEnabled(skill.name, value),
|
|
808
|
+
),
|
|
809
|
+
],
|
|
810
|
+
),
|
|
811
|
+
Text(
|
|
812
|
+
skill.description.ifEmpty('No description'),
|
|
813
|
+
style: TextStyle(color: _textSecondary),
|
|
814
|
+
),
|
|
815
|
+
const SizedBox(height: 10),
|
|
816
|
+
Wrap(
|
|
817
|
+
spacing: 8,
|
|
818
|
+
runSpacing: 8,
|
|
819
|
+
children: <Widget>[
|
|
820
|
+
_MetaPill(
|
|
821
|
+
label: skill.category,
|
|
822
|
+
icon: Icons.folder_outlined,
|
|
823
|
+
),
|
|
824
|
+
_MetaPill(
|
|
825
|
+
label: skill.source,
|
|
826
|
+
icon: Icons.source_outlined,
|
|
827
|
+
),
|
|
828
|
+
if (skill.draft)
|
|
829
|
+
const _MetaPill(
|
|
830
|
+
label: 'Draft',
|
|
831
|
+
icon: Icons.edit_note_outlined,
|
|
832
|
+
),
|
|
833
|
+
],
|
|
834
|
+
),
|
|
835
|
+
const SizedBox(height: 10),
|
|
836
|
+
Row(
|
|
837
|
+
children: <Widget>[
|
|
838
|
+
const Spacer(),
|
|
839
|
+
OutlinedButton(
|
|
840
|
+
onPressed: () => _openSkillEditor(
|
|
841
|
+
context,
|
|
842
|
+
skill.name,
|
|
843
|
+
),
|
|
844
|
+
child: Text('Open'),
|
|
845
|
+
),
|
|
846
|
+
const SizedBox(width: 8),
|
|
847
|
+
TextButton.icon(
|
|
848
|
+
onPressed: () => _confirmDeleteSkill(
|
|
849
|
+
context,
|
|
850
|
+
skill.name,
|
|
851
|
+
),
|
|
852
|
+
icon: Icon(Icons.delete_outline),
|
|
853
|
+
style: TextButton.styleFrom(
|
|
854
|
+
foregroundColor: _danger,
|
|
855
|
+
),
|
|
856
|
+
label: Text('Delete'),
|
|
857
|
+
),
|
|
858
|
+
],
|
|
859
|
+
),
|
|
860
|
+
],
|
|
861
|
+
)
|
|
862
|
+
: Row(
|
|
863
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
864
|
+
children: <Widget>[
|
|
865
|
+
Expanded(
|
|
866
|
+
child: Column(
|
|
867
|
+
crossAxisAlignment:
|
|
868
|
+
CrossAxisAlignment.start,
|
|
869
|
+
children: <Widget>[
|
|
870
|
+
Text(
|
|
871
|
+
skill.name,
|
|
872
|
+
style: TextStyle(
|
|
873
|
+
fontWeight: FontWeight.w700,
|
|
874
|
+
),
|
|
875
|
+
),
|
|
876
|
+
const SizedBox(height: 6),
|
|
877
|
+
Text(
|
|
878
|
+
skill.description.ifEmpty(
|
|
879
|
+
'No description',
|
|
880
|
+
),
|
|
881
|
+
style: TextStyle(
|
|
882
|
+
color: _textSecondary,
|
|
883
|
+
),
|
|
884
|
+
),
|
|
885
|
+
const SizedBox(height: 10),
|
|
886
|
+
Wrap(
|
|
887
|
+
spacing: 8,
|
|
888
|
+
runSpacing: 8,
|
|
889
|
+
children: <Widget>[
|
|
890
|
+
_MetaPill(
|
|
891
|
+
label: skill.category,
|
|
892
|
+
icon: Icons.folder_outlined,
|
|
893
|
+
),
|
|
894
|
+
_MetaPill(
|
|
895
|
+
label: skill.source,
|
|
896
|
+
icon: Icons.source_outlined,
|
|
897
|
+
),
|
|
898
|
+
if (skill.draft)
|
|
899
|
+
const _MetaPill(
|
|
900
|
+
label: 'Draft',
|
|
901
|
+
icon: Icons.edit_note_outlined,
|
|
902
|
+
),
|
|
903
|
+
],
|
|
904
|
+
),
|
|
905
|
+
],
|
|
864
906
|
),
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
907
|
+
),
|
|
908
|
+
const SizedBox(width: 10),
|
|
909
|
+
Column(
|
|
910
|
+
children: <Widget>[
|
|
911
|
+
Switch(
|
|
912
|
+
value: skill.enabled,
|
|
913
|
+
onChanged: (value) => controller
|
|
914
|
+
.setSkillEnabled(skill.name, value),
|
|
869
915
|
),
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
icon: Icon(Icons.delete_outline),
|
|
893
|
-
style: TextButton.styleFrom(
|
|
894
|
-
foregroundColor: _danger,
|
|
895
|
-
),
|
|
896
|
-
label: Text('Delete'),
|
|
916
|
+
OutlinedButton(
|
|
917
|
+
onPressed: () => _openSkillEditor(
|
|
918
|
+
context,
|
|
919
|
+
skill.name,
|
|
920
|
+
),
|
|
921
|
+
child: Text('Open'),
|
|
922
|
+
),
|
|
923
|
+
const SizedBox(height: 6),
|
|
924
|
+
TextButton.icon(
|
|
925
|
+
onPressed: () => _confirmDeleteSkill(
|
|
926
|
+
context,
|
|
927
|
+
skill.name,
|
|
928
|
+
),
|
|
929
|
+
icon: Icon(Icons.delete_outline),
|
|
930
|
+
style: TextButton.styleFrom(
|
|
931
|
+
foregroundColor: _danger,
|
|
932
|
+
),
|
|
933
|
+
label: Text('Delete'),
|
|
934
|
+
),
|
|
935
|
+
],
|
|
936
|
+
),
|
|
937
|
+
],
|
|
897
938
|
),
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
),
|
|
902
|
-
);
|
|
903
|
-
},
|
|
904
|
-
);
|
|
939
|
+
);
|
|
940
|
+
},
|
|
941
|
+
);
|
|
905
942
|
},
|
|
906
943
|
),
|
|
907
944
|
),
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
945
|
+
],
|
|
946
|
+
),
|
|
947
|
+
);
|
|
911
948
|
}
|
|
912
949
|
|
|
913
950
|
Widget _buildStoreTab(
|
|
@@ -1465,8 +1502,9 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1465
1502
|
);
|
|
1466
1503
|
if (!mounted) return;
|
|
1467
1504
|
_llmImportController.clear();
|
|
1468
|
-
final warningText =
|
|
1469
|
-
|
|
1505
|
+
final warningText = result.warnings.isEmpty
|
|
1506
|
+
? ''
|
|
1507
|
+
: ' ${result.warnings.join(' ')}';
|
|
1470
1508
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
1471
1509
|
SnackBar(
|
|
1472
1510
|
content: Text(
|
|
@@ -1494,9 +1532,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1494
1532
|
: controller.memories;
|
|
1495
1533
|
if (_entityFilter == null) return base;
|
|
1496
1534
|
return base
|
|
1497
|
-
.where(
|
|
1498
|
-
(m) => m.entities.any((e) => e.name == _entityFilter),
|
|
1499
|
-
)
|
|
1535
|
+
.where((m) => m.entities.any((e) => e.name == _entityFilter))
|
|
1500
1536
|
.toList();
|
|
1501
1537
|
}
|
|
1502
1538
|
|
|
@@ -1588,7 +1624,10 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1588
1624
|
});
|
|
1589
1625
|
}
|
|
1590
1626
|
|
|
1591
|
-
void _openRetrievalInspector(
|
|
1627
|
+
void _openRetrievalInspector(
|
|
1628
|
+
BuildContext context,
|
|
1629
|
+
NeoAgentController controller,
|
|
1630
|
+
) {
|
|
1592
1631
|
Navigator.of(context).push(
|
|
1593
1632
|
MaterialPageRoute(
|
|
1594
1633
|
builder: (context) => RetrievalInspectorView(controller: controller),
|
|
@@ -1603,7 +1642,8 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1603
1642
|
final memoriesToShow = _visibleMemories;
|
|
1604
1643
|
final selectedIds = _selectedVisibleMemoryIds.toSet();
|
|
1605
1644
|
final selectedCount = selectedIds.length;
|
|
1606
|
-
final allVisibleSelected =
|
|
1645
|
+
final allVisibleSelected =
|
|
1646
|
+
memoriesToShow.isNotEmpty &&
|
|
1607
1647
|
memoriesToShow.every((m) => selectedIds.contains(m.id));
|
|
1608
1648
|
final showingSearchResults = controller.memoryRecallResults.isNotEmpty;
|
|
1609
1649
|
final compact = MediaQuery.sizeOf(context).width < 760;
|
|
@@ -1623,11 +1663,6 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1623
1663
|
icon: Icon(Icons.bug_report_outlined),
|
|
1624
1664
|
label: Text('Inspect'),
|
|
1625
1665
|
),
|
|
1626
|
-
OutlinedButton.icon(
|
|
1627
|
-
onPressed: () => _openBehaviorNotesEditor(context, controller),
|
|
1628
|
-
icon: Icon(Icons.edit_outlined),
|
|
1629
|
-
label: Text('Behavior Notes'),
|
|
1630
|
-
),
|
|
1631
1666
|
FilledButton.icon(
|
|
1632
1667
|
onPressed: () => _openMemoryCreator(context, controller),
|
|
1633
1668
|
icon: Icon(Icons.add),
|
|
@@ -1644,9 +1679,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1644
1679
|
padding: const EdgeInsets.all(18),
|
|
1645
1680
|
child: Row(
|
|
1646
1681
|
children: <Widget>[
|
|
1647
|
-
_MemoryConfidenceGauge(
|
|
1648
|
-
confidence: stats.averageConfidence,
|
|
1649
|
-
),
|
|
1682
|
+
_MemoryConfidenceGauge(confidence: stats.averageConfidence),
|
|
1650
1683
|
const SizedBox(width: 18),
|
|
1651
1684
|
Expanded(
|
|
1652
1685
|
child: Wrap(
|
|
@@ -1705,9 +1738,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1705
1738
|
children: <Widget>[
|
|
1706
1739
|
Row(
|
|
1707
1740
|
children: <Widget>[
|
|
1708
|
-
Expanded(
|
|
1709
|
-
child: const _SectionTitle('Knowledge Graph'),
|
|
1710
|
-
),
|
|
1741
|
+
Expanded(child: const _SectionTitle('Knowledge Graph')),
|
|
1711
1742
|
if (_entityFilter != null)
|
|
1712
1743
|
TextButton.icon(
|
|
1713
1744
|
onPressed: () =>
|
|
@@ -1720,10 +1751,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1720
1751
|
const SizedBox(height: 4),
|
|
1721
1752
|
Text(
|
|
1722
1753
|
'Tap an entity to filter memories by it.',
|
|
1723
|
-
style: TextStyle(
|
|
1724
|
-
color: _textSecondary,
|
|
1725
|
-
fontSize: 12,
|
|
1726
|
-
),
|
|
1754
|
+
style: TextStyle(color: _textSecondary, fontSize: 12),
|
|
1727
1755
|
),
|
|
1728
1756
|
const SizedBox(height: 14),
|
|
1729
1757
|
SizedBox(
|
|
@@ -1857,15 +1885,16 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1857
1885
|
Wrap(
|
|
1858
1886
|
spacing: 8,
|
|
1859
1887
|
runSpacing: 8,
|
|
1860
|
-
crossAxisAlignment:
|
|
1861
|
-
WrapCrossAlignment.center,
|
|
1888
|
+
crossAxisAlignment: WrapCrossAlignment.center,
|
|
1862
1889
|
children: <Widget>[
|
|
1863
1890
|
OutlinedButton.icon(
|
|
1864
|
-
onPressed:
|
|
1891
|
+
onPressed:
|
|
1892
|
+
allVisibleSelected ||
|
|
1865
1893
|
_bulkActionInFlight
|
|
1866
1894
|
? null
|
|
1867
1895
|
: () => _selectAllVisibleMemories(
|
|
1868
|
-
memoriesToShow
|
|
1896
|
+
memoriesToShow,
|
|
1897
|
+
),
|
|
1869
1898
|
icon: Icon(
|
|
1870
1899
|
Icons.done_all_outlined,
|
|
1871
1900
|
size: 16,
|
|
@@ -1903,9 +1932,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1903
1932
|
Icons.archive_outlined,
|
|
1904
1933
|
size: 16,
|
|
1905
1934
|
),
|
|
1906
|
-
label: Text(
|
|
1907
|
-
'Archive ($selectedCount)',
|
|
1908
|
-
),
|
|
1935
|
+
label: Text('Archive ($selectedCount)'),
|
|
1909
1936
|
),
|
|
1910
1937
|
OutlinedButton.icon(
|
|
1911
1938
|
onPressed: _bulkActionInFlight
|
|
@@ -1923,9 +1950,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1923
1950
|
Icons.delete_sweep_outlined,
|
|
1924
1951
|
size: 16,
|
|
1925
1952
|
),
|
|
1926
|
-
label: Text(
|
|
1927
|
-
'Delete ($selectedCount)',
|
|
1928
|
-
),
|
|
1953
|
+
label: Text('Delete ($selectedCount)'),
|
|
1929
1954
|
),
|
|
1930
1955
|
],
|
|
1931
1956
|
],
|
|
@@ -1941,8 +1966,9 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1941
1966
|
)
|
|
1942
1967
|
else
|
|
1943
1968
|
...memoriesToShow.map((memory) {
|
|
1944
|
-
final isSelected =
|
|
1945
|
-
|
|
1969
|
+
final isSelected = selectedIds.contains(
|
|
1970
|
+
memory.id,
|
|
1971
|
+
);
|
|
1946
1972
|
return _MemoryRow(
|
|
1947
1973
|
memory: memory,
|
|
1948
1974
|
isSelected: isSelected,
|
|
@@ -1950,8 +1976,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1950
1976
|
memory.id,
|
|
1951
1977
|
!isSelected,
|
|
1952
1978
|
),
|
|
1953
|
-
onCheck: (value) =>
|
|
1954
|
-
_toggleMemorySelection(
|
|
1979
|
+
onCheck: (value) => _toggleMemorySelection(
|
|
1955
1980
|
memory.id,
|
|
1956
1981
|
value ?? false,
|
|
1957
1982
|
),
|
|
@@ -1964,9 +1989,9 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1964
1989
|
'This memory will be removed permanently.',
|
|
1965
1990
|
onConfirm: () =>
|
|
1966
1991
|
_deleteSingleMemory(
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1992
|
+
controller,
|
|
1993
|
+
memory.id,
|
|
1994
|
+
),
|
|
1970
1995
|
),
|
|
1971
1996
|
);
|
|
1972
1997
|
}),
|
|
@@ -1985,9 +2010,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
1985
2010
|
Expanded(
|
|
1986
2011
|
child: Text(
|
|
1987
2012
|
'Key-value pairs that persist across conversations.',
|
|
1988
|
-
style: TextStyle(
|
|
1989
|
-
color: _textSecondary,
|
|
1990
|
-
),
|
|
2013
|
+
style: TextStyle(color: _textSecondary),
|
|
1991
2014
|
),
|
|
1992
2015
|
),
|
|
1993
2016
|
TextButton.icon(
|
|
@@ -2001,75 +2024,75 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2001
2024
|
],
|
|
2002
2025
|
),
|
|
2003
2026
|
const SizedBox(height: 10),
|
|
2004
|
-
if (controller
|
|
2005
|
-
.memoryOverview.coreEntries.isEmpty)
|
|
2027
|
+
if (controller.memoryOverview.coreEntries.isEmpty)
|
|
2006
2028
|
Text(
|
|
2007
2029
|
'No core memory entries yet.',
|
|
2008
2030
|
style: TextStyle(color: _textSecondary),
|
|
2009
2031
|
)
|
|
2010
2032
|
else
|
|
2011
|
-
...controller.memoryOverview.coreEntries
|
|
2012
|
-
.entries
|
|
2033
|
+
...controller.memoryOverview.coreEntries.entries
|
|
2013
2034
|
.map((entry) {
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
decoration: BoxDecoration(
|
|
2019
|
-
color: _bgSecondary,
|
|
2020
|
-
borderRadius:
|
|
2021
|
-
BorderRadius.circular(12),
|
|
2022
|
-
border: Border.all(color: _border),
|
|
2023
|
-
),
|
|
2024
|
-
child: Row(
|
|
2025
|
-
crossAxisAlignment:
|
|
2026
|
-
CrossAxisAlignment.start,
|
|
2027
|
-
children: <Widget>[
|
|
2028
|
-
Expanded(
|
|
2029
|
-
child: Column(
|
|
2030
|
-
crossAxisAlignment:
|
|
2031
|
-
CrossAxisAlignment.start,
|
|
2032
|
-
children: <Widget>[
|
|
2033
|
-
Text(
|
|
2034
|
-
entry.key,
|
|
2035
|
-
style: TextStyle(
|
|
2036
|
-
fontWeight: FontWeight.w700,
|
|
2037
|
-
),
|
|
2038
|
-
),
|
|
2039
|
-
const SizedBox(height: 6),
|
|
2040
|
-
Text(
|
|
2041
|
-
entry.value.toString(),
|
|
2042
|
-
),
|
|
2043
|
-
],
|
|
2044
|
-
),
|
|
2035
|
+
return Container(
|
|
2036
|
+
width: double.infinity,
|
|
2037
|
+
margin: const EdgeInsets.only(
|
|
2038
|
+
bottom: 10,
|
|
2045
2039
|
),
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
keyValue: entry,
|
|
2040
|
+
padding: const EdgeInsets.all(12),
|
|
2041
|
+
decoration: BoxDecoration(
|
|
2042
|
+
color: _bgSecondary,
|
|
2043
|
+
borderRadius: BorderRadius.circular(
|
|
2044
|
+
12,
|
|
2052
2045
|
),
|
|
2053
|
-
|
|
2046
|
+
border: Border.all(color: _border),
|
|
2054
2047
|
),
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2048
|
+
child: Row(
|
|
2049
|
+
crossAxisAlignment:
|
|
2050
|
+
CrossAxisAlignment.start,
|
|
2051
|
+
children: <Widget>[
|
|
2052
|
+
Expanded(
|
|
2053
|
+
child: Column(
|
|
2054
|
+
crossAxisAlignment:
|
|
2055
|
+
CrossAxisAlignment.start,
|
|
2056
|
+
children: <Widget>[
|
|
2057
|
+
Text(
|
|
2058
|
+
entry.key,
|
|
2059
|
+
style: TextStyle(
|
|
2060
|
+
fontWeight:
|
|
2061
|
+
FontWeight.w700,
|
|
2062
|
+
),
|
|
2063
|
+
),
|
|
2064
|
+
const SizedBox(height: 6),
|
|
2065
|
+
Text(entry.value.toString()),
|
|
2066
|
+
],
|
|
2067
|
+
),
|
|
2065
2068
|
),
|
|
2066
|
-
|
|
2067
|
-
|
|
2069
|
+
IconButton(
|
|
2070
|
+
onPressed: () =>
|
|
2071
|
+
_openCoreMemoryEditor(
|
|
2072
|
+
context,
|
|
2073
|
+
controller,
|
|
2074
|
+
keyValue: entry,
|
|
2075
|
+
),
|
|
2076
|
+
icon: Icon(Icons.edit_outlined),
|
|
2077
|
+
),
|
|
2078
|
+
IconButton(
|
|
2079
|
+
onPressed: () => _confirmDelete(
|
|
2080
|
+
context,
|
|
2081
|
+
title:
|
|
2082
|
+
'Delete core memory entry?',
|
|
2083
|
+
message:
|
|
2084
|
+
'Remove "${entry.key}" from core memory.',
|
|
2085
|
+
onConfirm: () =>
|
|
2086
|
+
controller.deleteCoreMemory(
|
|
2087
|
+
entry.key,
|
|
2088
|
+
),
|
|
2089
|
+
),
|
|
2090
|
+
icon: Icon(Icons.delete_outline),
|
|
2091
|
+
),
|
|
2092
|
+
],
|
|
2068
2093
|
),
|
|
2069
|
-
|
|
2070
|
-
),
|
|
2071
|
-
);
|
|
2072
|
-
}),
|
|
2094
|
+
);
|
|
2095
|
+
}),
|
|
2073
2096
|
],
|
|
2074
2097
|
),
|
|
2075
2098
|
),
|
|
@@ -2092,11 +2115,8 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2092
2115
|
FilledButton.icon(
|
|
2093
2116
|
onPressed: _llmPromptLoading
|
|
2094
2117
|
? null
|
|
2095
|
-
: () =>
|
|
2096
|
-
|
|
2097
|
-
icon: Icon(
|
|
2098
|
-
Icons.auto_awesome_outlined,
|
|
2099
|
-
),
|
|
2118
|
+
: () => _loadLlmPrompt(controller),
|
|
2119
|
+
icon: Icon(Icons.auto_awesome_outlined),
|
|
2100
2120
|
label: Text(
|
|
2101
2121
|
_llmPromptLoading
|
|
2102
2122
|
? 'Generating...'
|
|
@@ -2105,11 +2125,9 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2105
2125
|
),
|
|
2106
2126
|
OutlinedButton.icon(
|
|
2107
2127
|
onPressed:
|
|
2108
|
-
_llmPromptController.text
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
? null
|
|
2112
|
-
: _copyLlmPrompt,
|
|
2128
|
+
_llmPromptController.text.trim().isEmpty
|
|
2129
|
+
? null
|
|
2130
|
+
: _copyLlmPrompt,
|
|
2113
2131
|
icon: Icon(Icons.copy_all_outlined),
|
|
2114
2132
|
label: Text('Copy Prompt'),
|
|
2115
2133
|
),
|
|
@@ -2122,8 +2140,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2122
2140
|
maxLines: 8,
|
|
2123
2141
|
readOnly: true,
|
|
2124
2142
|
decoration: const InputDecoration(
|
|
2125
|
-
labelText:
|
|
2126
|
-
'Prompt to paste into another AI',
|
|
2143
|
+
labelText: 'Prompt to paste into another AI',
|
|
2127
2144
|
),
|
|
2128
2145
|
),
|
|
2129
2146
|
const SizedBox(height: 16),
|
|
@@ -2133,8 +2150,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2133
2150
|
onChanged: _llmImporting
|
|
2134
2151
|
? null
|
|
2135
2152
|
: (value) => setState(
|
|
2136
|
-
() =>
|
|
2137
|
-
_llmApplyBehaviorNotes = value,
|
|
2153
|
+
() => _llmApplyBehaviorNotes = value,
|
|
2138
2154
|
),
|
|
2139
2155
|
title: Text('Apply behavior notes'),
|
|
2140
2156
|
subtitle: Text(
|
|
@@ -2147,8 +2163,7 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2147
2163
|
onChanged: _llmImporting
|
|
2148
2164
|
? null
|
|
2149
2165
|
: (value) => setState(
|
|
2150
|
-
() =>
|
|
2151
|
-
_llmApplyCoreMemory = value,
|
|
2166
|
+
() => _llmApplyCoreMemory = value,
|
|
2152
2167
|
),
|
|
2153
2168
|
title: Text('Apply core memory'),
|
|
2154
2169
|
subtitle: Text(
|
|
@@ -2168,13 +2183,10 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2168
2183
|
FilledButton.icon(
|
|
2169
2184
|
onPressed: _llmImporting
|
|
2170
2185
|
? null
|
|
2171
|
-
: () =>
|
|
2172
|
-
_importLlmMemories(controller),
|
|
2186
|
+
: () => _importLlmMemories(controller),
|
|
2173
2187
|
icon: Icon(Icons.file_download_outlined),
|
|
2174
2188
|
label: Text(
|
|
2175
|
-
_llmImporting
|
|
2176
|
-
? 'Importing...'
|
|
2177
|
-
: 'Import',
|
|
2189
|
+
_llmImporting ? 'Importing...' : 'Import',
|
|
2178
2190
|
),
|
|
2179
2191
|
),
|
|
2180
2192
|
],
|
|
@@ -2274,50 +2286,6 @@ class _MemoryPanelState extends State<MemoryPanel>
|
|
|
2274
2286
|
);
|
|
2275
2287
|
}
|
|
2276
2288
|
|
|
2277
|
-
Future<void> _openBehaviorNotesEditor(
|
|
2278
|
-
BuildContext context,
|
|
2279
|
-
NeoAgentController controller,
|
|
2280
|
-
) async {
|
|
2281
|
-
final contentController = TextEditingController(
|
|
2282
|
-
text: controller.memoryOverview.assistantBehaviorNotes,
|
|
2283
|
-
);
|
|
2284
|
-
await showDialog<void>(
|
|
2285
|
-
context: context,
|
|
2286
|
-
builder: (context) {
|
|
2287
|
-
return AlertDialog(
|
|
2288
|
-
backgroundColor: _bgCard,
|
|
2289
|
-
title: Text('Edit Assistant Behavior Notes'),
|
|
2290
|
-
content: SizedBox(
|
|
2291
|
-
width: 720,
|
|
2292
|
-
child: TextField(
|
|
2293
|
-
controller: contentController,
|
|
2294
|
-
minLines: 16,
|
|
2295
|
-
maxLines: 24,
|
|
2296
|
-
decoration: const InputDecoration(
|
|
2297
|
-
labelText: 'assistant_behavior_notes',
|
|
2298
|
-
),
|
|
2299
|
-
),
|
|
2300
|
-
),
|
|
2301
|
-
actions: <Widget>[
|
|
2302
|
-
TextButton(
|
|
2303
|
-
onPressed: () => Navigator.of(context).pop(),
|
|
2304
|
-
child: Text('Cancel'),
|
|
2305
|
-
),
|
|
2306
|
-
FilledButton(
|
|
2307
|
-
onPressed: () async {
|
|
2308
|
-
await controller.updateAssistantBehaviorNotes(
|
|
2309
|
-
contentController.text,
|
|
2310
|
-
);
|
|
2311
|
-
if (context.mounted) Navigator.of(context).pop();
|
|
2312
|
-
},
|
|
2313
|
-
child: Text('Save'),
|
|
2314
|
-
),
|
|
2315
|
-
],
|
|
2316
|
-
);
|
|
2317
|
-
},
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2321
2289
|
Future<void> _openCoreMemoryEditor(
|
|
2322
2290
|
BuildContext context,
|
|
2323
2291
|
NeoAgentController controller, {
|
|
@@ -2453,9 +2421,10 @@ class _MemoryConfidenceGaugeState extends State<_MemoryConfidenceGauge>
|
|
|
2453
2421
|
vsync: this,
|
|
2454
2422
|
duration: const Duration(milliseconds: 1200),
|
|
2455
2423
|
);
|
|
2456
|
-
_progress = Tween<double>(
|
|
2457
|
-
|
|
2458
|
-
|
|
2424
|
+
_progress = Tween<double>(
|
|
2425
|
+
begin: 0,
|
|
2426
|
+
end: widget.confidence,
|
|
2427
|
+
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic));
|
|
2459
2428
|
_controller.forward();
|
|
2460
2429
|
}
|
|
2461
2430
|
|
|
@@ -2463,12 +2432,10 @@ class _MemoryConfidenceGaugeState extends State<_MemoryConfidenceGauge>
|
|
|
2463
2432
|
void didUpdateWidget(_MemoryConfidenceGauge oldWidget) {
|
|
2464
2433
|
super.didUpdateWidget(oldWidget);
|
|
2465
2434
|
if (oldWidget.confidence != widget.confidence) {
|
|
2466
|
-
_progress = Tween<double>(
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic),
|
|
2471
|
-
);
|
|
2435
|
+
_progress = Tween<double>(begin: _progress.value, end: widget.confidence)
|
|
2436
|
+
.animate(
|
|
2437
|
+
CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic),
|
|
2438
|
+
);
|
|
2472
2439
|
_controller
|
|
2473
2440
|
..reset()
|
|
2474
2441
|
..forward();
|
|
@@ -2658,10 +2625,7 @@ class _MemoryRow extends StatelessWidget {
|
|
|
2658
2625
|
if (onDelete != null)
|
|
2659
2626
|
IconButton(
|
|
2660
2627
|
onPressed: onDelete,
|
|
2661
|
-
icon: Icon(
|
|
2662
|
-
Icons.delete_outline,
|
|
2663
|
-
size: 18,
|
|
2664
|
-
),
|
|
2628
|
+
icon: Icon(Icons.delete_outline, size: 18),
|
|
2665
2629
|
),
|
|
2666
2630
|
],
|
|
2667
2631
|
),
|
|
@@ -2686,10 +2650,7 @@ class _MemoryRow extends StatelessWidget {
|
|
|
2686
2650
|
const SizedBox(height: 6),
|
|
2687
2651
|
Text(
|
|
2688
2652
|
memory.createdAtLabel,
|
|
2689
|
-
style: TextStyle(
|
|
2690
|
-
fontSize: 11,
|
|
2691
|
-
color: _textMuted,
|
|
2692
|
-
),
|
|
2653
|
+
style: TextStyle(fontSize: 11, color: _textMuted),
|
|
2693
2654
|
),
|
|
2694
2655
|
],
|
|
2695
2656
|
),
|
|
@@ -2778,27 +2739,31 @@ class _EntityGraphViewState extends State<_EntityGraphView>
|
|
|
2778
2739
|
for (int i = 0; i < entities.length; i++) {
|
|
2779
2740
|
final entity = entities[i];
|
|
2780
2741
|
final sizeFactor = 0.4 + 0.6 * (entity.mentionCount / maxMention);
|
|
2781
|
-
_nodes.add(
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2742
|
+
_nodes.add(
|
|
2743
|
+
_GraphNode(
|
|
2744
|
+
id: entity.name,
|
|
2745
|
+
label: entity.name,
|
|
2746
|
+
radius: 18 + 20 * sizeFactor,
|
|
2747
|
+
color: _kindColors[entity.kind] ?? _kindColors['concept']!,
|
|
2748
|
+
kind: entity.kind,
|
|
2749
|
+
isReflection: false,
|
|
2750
|
+
offsetPhase: i * 0.7,
|
|
2751
|
+
),
|
|
2752
|
+
);
|
|
2790
2753
|
}
|
|
2791
2754
|
|
|
2792
2755
|
for (int i = 0; i < views.length && i < 6; i++) {
|
|
2793
|
-
_nodes.add(
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2756
|
+
_nodes.add(
|
|
2757
|
+
_GraphNode(
|
|
2758
|
+
id: 'kv_${views[i].title}',
|
|
2759
|
+
label: views[i].title,
|
|
2760
|
+
radius: 14,
|
|
2761
|
+
color: const Color(0xFF8B7EC8),
|
|
2762
|
+
kind: views[i].viewType,
|
|
2763
|
+
isReflection: true,
|
|
2764
|
+
offsetPhase: (entities.length + i) * 0.9,
|
|
2765
|
+
),
|
|
2766
|
+
);
|
|
2802
2767
|
}
|
|
2803
2768
|
|
|
2804
2769
|
_layoutDone = false;
|
|
@@ -2939,10 +2904,12 @@ class _EntityGraphPainter extends CustomPainter {
|
|
|
2939
2904
|
void paint(Canvas canvas, Size size) {
|
|
2940
2905
|
if (nodes.isEmpty) return;
|
|
2941
2906
|
|
|
2942
|
-
final entityNodes =
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2907
|
+
final entityNodes = nodes
|
|
2908
|
+
.where((n) => !n.isReflection)
|
|
2909
|
+
.toList(growable: false);
|
|
2910
|
+
final reflectionNodes = nodes
|
|
2911
|
+
.where((n) => n.isReflection)
|
|
2912
|
+
.toList(growable: false);
|
|
2946
2913
|
|
|
2947
2914
|
// Draw connections between entity nodes (subtle web)
|
|
2948
2915
|
final linePaint = Paint()
|
|
@@ -2974,8 +2941,8 @@ class _EntityGraphPainter extends CustomPainter {
|
|
|
2974
2941
|
var closest = entityNodes.first;
|
|
2975
2942
|
var minDist = double.infinity;
|
|
2976
2943
|
for (final en in entityNodes) {
|
|
2977
|
-
final d =
|
|
2978
|
-
(en.y - rn.y) * (en.y - rn.y);
|
|
2944
|
+
final d =
|
|
2945
|
+
(en.x - rn.x) * (en.x - rn.x) + (en.y - rn.y) * (en.y - rn.y);
|
|
2979
2946
|
if (d < minDist) {
|
|
2980
2947
|
minDist = d;
|
|
2981
2948
|
closest = en;
|
|
@@ -3002,8 +2969,9 @@ class _EntityGraphPainter extends CustomPainter {
|
|
|
3002
2969
|
// Glow
|
|
3003
2970
|
if (isSelected || isHovered) {
|
|
3004
2971
|
final glowPaint = Paint()
|
|
3005
|
-
..color = (isSelected ? accentColor : node.color)
|
|
3006
|
-
|
|
2972
|
+
..color = (isSelected ? accentColor : node.color).withValues(
|
|
2973
|
+
alpha: 0.22,
|
|
2974
|
+
)
|
|
3007
2975
|
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 12);
|
|
3008
2976
|
canvas.drawCircle(Offset(cx, cy), r + 6, glowPaint);
|
|
3009
2977
|
}
|
|
@@ -3023,8 +2991,8 @@ class _EntityGraphPainter extends CustomPainter {
|
|
|
3023
2991
|
..color = isSelected
|
|
3024
2992
|
? accentColor
|
|
3025
2993
|
: (isHovered
|
|
3026
|
-
|
|
3027
|
-
|
|
2994
|
+
? node.color.withValues(alpha: 0.8)
|
|
2995
|
+
: node.color.withValues(alpha: 0.35))
|
|
3028
2996
|
..style = PaintingStyle.stroke
|
|
3029
2997
|
..strokeWidth = isSelected ? 2.5 : 1.5;
|
|
3030
2998
|
canvas.drawCircle(Offset(cx, cy), r, borderPaint);
|
|
@@ -3041,10 +3009,7 @@ class _EntityGraphPainter extends CustomPainter {
|
|
|
3041
3009
|
maxLines: 1,
|
|
3042
3010
|
ellipsis: '…',
|
|
3043
3011
|
)..layout(maxWidth: r * 3);
|
|
3044
|
-
tp.paint(
|
|
3045
|
-
canvas,
|
|
3046
|
-
Offset(cx - tp.width / 2, cy + r + 5),
|
|
3047
|
-
);
|
|
3012
|
+
tp.paint(canvas, Offset(cx - tp.width / 2, cy + r + 5));
|
|
3048
3013
|
}
|
|
3049
3014
|
}
|
|
3050
3015
|
|
|
@@ -5365,6 +5330,7 @@ String _formatTaskWeekdays(Set<int> weekdays) {
|
|
|
5365
5330
|
if (sorted.isEmpty) return 'Monday';
|
|
5366
5331
|
return sorted.map((day) => _taskWeekdayLabels[day - 1]).join(', ');
|
|
5367
5332
|
}
|
|
5333
|
+
|
|
5368
5334
|
Future<String?> _pickTaskTriggerType(
|
|
5369
5335
|
BuildContext context,
|
|
5370
5336
|
String selectedType,
|
|
@@ -6545,9 +6511,7 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
6545
6511
|
final selectedConnectionId = ValueNotifier<int?>(
|
|
6546
6512
|
task?.triggerConfig['connectionId'] is int
|
|
6547
6513
|
? task!.triggerConfig['connectionId'] as int
|
|
6548
|
-
: int.tryParse(
|
|
6549
|
-
task?.triggerConfig['connectionId']?.toString() ?? '',
|
|
6550
|
-
),
|
|
6514
|
+
: int.tryParse(task?.triggerConfig['connectionId']?.toString() ?? ''),
|
|
6551
6515
|
);
|
|
6552
6516
|
final selectedDeliveryTarget = ValueNotifier<TaskDeliveryTarget?>(
|
|
6553
6517
|
_taskDeliveryTargetFromTask(task),
|