neoagent 2.4.1-beta.32 → 2.4.1-beta.34
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_models.dart +14 -0
- package/flutter_app/lib/main_operations.dart +117 -0
- package/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +34534 -34438
- package/server/services/ai/engine.js +49 -4
- package/server/services/ai/tools.js +12 -0
- package/server/services/tasks/integration_runtime.js +4 -1
- package/server/services/tasks/runtime.js +114 -43
- package/server/services/tasks/task_repository.js +35 -6
|
@@ -3099,6 +3099,9 @@ class TaskItem {
|
|
|
3099
3099
|
required this.model,
|
|
3100
3100
|
required this.enabled,
|
|
3101
3101
|
required this.lastRun,
|
|
3102
|
+
required this.lastRunId,
|
|
3103
|
+
required this.lastRunStatus,
|
|
3104
|
+
required this.lastRunError,
|
|
3102
3105
|
required this.taskType,
|
|
3103
3106
|
required this.widgetId,
|
|
3104
3107
|
});
|
|
@@ -3144,6 +3147,9 @@ class TaskItem {
|
|
|
3144
3147
|
'',
|
|
3145
3148
|
enabled: json['enabled'] != false,
|
|
3146
3149
|
lastRun: _parseOptionalTimestamp(json['lastRun']?.toString()),
|
|
3150
|
+
lastRunId: json['lastRunId']?.toString() ?? '',
|
|
3151
|
+
lastRunStatus: json['lastRunStatus']?.toString() ?? '',
|
|
3152
|
+
lastRunError: json['lastRunError']?.toString() ?? '',
|
|
3147
3153
|
taskType:
|
|
3148
3154
|
json['taskType']?.toString().ifEmpty(
|
|
3149
3155
|
json['task_type']?.toString() ?? 'agent_prompt',
|
|
@@ -3168,12 +3174,20 @@ class TaskItem {
|
|
|
3168
3174
|
final String model;
|
|
3169
3175
|
final bool enabled;
|
|
3170
3176
|
final DateTime? lastRun;
|
|
3177
|
+
final String lastRunId;
|
|
3178
|
+
final String lastRunStatus;
|
|
3179
|
+
final String lastRunError;
|
|
3171
3180
|
final String taskType;
|
|
3172
3181
|
final String widgetId;
|
|
3173
3182
|
|
|
3174
3183
|
String get scheduleLabel =>
|
|
3175
3184
|
triggerSummary.trim().isEmpty ? 'Task trigger' : triggerSummary;
|
|
3176
3185
|
String get lastRunLabel => lastRun == null ? '' : _formatTimestamp(lastRun!);
|
|
3186
|
+
String get lastRunStatusLabel =>
|
|
3187
|
+
_titleCase(lastRunStatus.replaceAll('_', ' '));
|
|
3188
|
+
bool get hasLastRunStatus => lastRunStatus.trim().isNotEmpty;
|
|
3189
|
+
bool get lastRunFailed =>
|
|
3190
|
+
lastRunStatus == 'failed' || lastRunStatus == 'error';
|
|
3177
3191
|
bool get hasModelOverride => model.trim().isNotEmpty;
|
|
3178
3192
|
bool get isWidgetRefresh => taskType == 'widget_refresh';
|
|
3179
3193
|
}
|
|
@@ -4555,6 +4555,89 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4555
4555
|
|
|
4556
4556
|
NeoAgentController get controller => widget.controller;
|
|
4557
4557
|
|
|
4558
|
+
Color _taskRunStatusColor(String status) {
|
|
4559
|
+
switch (status) {
|
|
4560
|
+
case 'completed':
|
|
4561
|
+
return _success;
|
|
4562
|
+
case 'failed':
|
|
4563
|
+
case 'error':
|
|
4564
|
+
return _danger;
|
|
4565
|
+
case 'running':
|
|
4566
|
+
case 'retrying':
|
|
4567
|
+
return _warning;
|
|
4568
|
+
default:
|
|
4569
|
+
return _textSecondary;
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
|
|
4573
|
+
Future<void> _showLastRun(TaskItem task) async {
|
|
4574
|
+
final runId = task.lastRunId.trim();
|
|
4575
|
+
if (runId.isEmpty) return;
|
|
4576
|
+
|
|
4577
|
+
try {
|
|
4578
|
+
final detail = await controller.fetchRunDetail(runId, force: true);
|
|
4579
|
+
if (!mounted) return;
|
|
4580
|
+
await showDialog<void>(
|
|
4581
|
+
context: context,
|
|
4582
|
+
builder: (dialogContext) => AlertDialog(
|
|
4583
|
+
title: Text(detail.run.title),
|
|
4584
|
+
content: ConstrainedBox(
|
|
4585
|
+
constraints: const BoxConstraints(maxWidth: 620),
|
|
4586
|
+
child: SingleChildScrollView(
|
|
4587
|
+
child: Column(
|
|
4588
|
+
mainAxisSize: MainAxisSize.min,
|
|
4589
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
4590
|
+
children: <Widget>[
|
|
4591
|
+
Wrap(
|
|
4592
|
+
spacing: 8,
|
|
4593
|
+
runSpacing: 8,
|
|
4594
|
+
children: <Widget>[
|
|
4595
|
+
_StatusPill(
|
|
4596
|
+
label: detail.run.statusLabel,
|
|
4597
|
+
color: detail.run.statusColor,
|
|
4598
|
+
),
|
|
4599
|
+
_StatusPill(
|
|
4600
|
+
label: '${detail.steps.length} steps',
|
|
4601
|
+
color: _textSecondary,
|
|
4602
|
+
),
|
|
4603
|
+
],
|
|
4604
|
+
),
|
|
4605
|
+
if (detail.run.error.trim().isNotEmpty) ...<Widget>[
|
|
4606
|
+
const SizedBox(height: 16),
|
|
4607
|
+
Text(detail.run.error, style: TextStyle(color: _danger)),
|
|
4608
|
+
],
|
|
4609
|
+
if (detail.response.trim().isNotEmpty) ...<Widget>[
|
|
4610
|
+
const SizedBox(height: 16),
|
|
4611
|
+
SelectableText(detail.response),
|
|
4612
|
+
],
|
|
4613
|
+
if (detail.response.trim().isEmpty &&
|
|
4614
|
+
detail.run.error.trim().isEmpty) ...<Widget>[
|
|
4615
|
+
const SizedBox(height: 16),
|
|
4616
|
+
Text(
|
|
4617
|
+
'This run did not produce a user-facing response.',
|
|
4618
|
+
style: TextStyle(color: _textSecondary),
|
|
4619
|
+
),
|
|
4620
|
+
],
|
|
4621
|
+
],
|
|
4622
|
+
),
|
|
4623
|
+
),
|
|
4624
|
+
),
|
|
4625
|
+
actions: <Widget>[
|
|
4626
|
+
TextButton(
|
|
4627
|
+
onPressed: () => Navigator.of(dialogContext).pop(),
|
|
4628
|
+
child: const Text('Close'),
|
|
4629
|
+
),
|
|
4630
|
+
],
|
|
4631
|
+
),
|
|
4632
|
+
);
|
|
4633
|
+
} catch (error) {
|
|
4634
|
+
if (!mounted) return;
|
|
4635
|
+
ScaffoldMessenger.of(context).showSnackBar(
|
|
4636
|
+
SnackBar(content: Text(controller.friendlyErrorMessage(error))),
|
|
4637
|
+
);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
|
|
4558
4641
|
@override
|
|
4559
4642
|
void didUpdateWidget(covariant TasksPanel oldWidget) {
|
|
4560
4643
|
super.didUpdateWidget(oldWidget);
|
|
@@ -4703,6 +4786,13 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4703
4786
|
label: task.enabled ? 'Active' : 'Paused',
|
|
4704
4787
|
color: task.enabled ? _success : _textSecondary,
|
|
4705
4788
|
),
|
|
4789
|
+
if (task.hasLastRunStatus) ...<Widget>[
|
|
4790
|
+
const SizedBox(width: 8),
|
|
4791
|
+
_StatusPill(
|
|
4792
|
+
label: 'Last: ${task.lastRunStatusLabel}',
|
|
4793
|
+
color: _taskRunStatusColor(task.lastRunStatus),
|
|
4794
|
+
),
|
|
4795
|
+
],
|
|
4706
4796
|
],
|
|
4707
4797
|
),
|
|
4708
4798
|
const SizedBox(height: 10),
|
|
@@ -4734,6 +4824,11 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4734
4824
|
style: TextStyle(color: _textSecondary),
|
|
4735
4825
|
),
|
|
4736
4826
|
],
|
|
4827
|
+
if (task.lastRunFailed &&
|
|
4828
|
+
task.lastRunError.trim().isNotEmpty) ...<Widget>[
|
|
4829
|
+
const SizedBox(height: 8),
|
|
4830
|
+
Text(task.lastRunError, style: TextStyle(color: _danger)),
|
|
4831
|
+
],
|
|
4737
4832
|
const SizedBox(height: 14),
|
|
4738
4833
|
Wrap(
|
|
4739
4834
|
spacing: 10,
|
|
@@ -4753,6 +4848,11 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4753
4848
|
: () => controller.runTaskNow(task.id),
|
|
4754
4849
|
child: Text(_manualRunButtonLabel('Run Now', remaining)),
|
|
4755
4850
|
),
|
|
4851
|
+
if (task.lastRunId.trim().isNotEmpty)
|
|
4852
|
+
OutlinedButton(
|
|
4853
|
+
onPressed: () => _showLastRun(task),
|
|
4854
|
+
child: const Text('View last run'),
|
|
4855
|
+
),
|
|
4756
4856
|
OutlinedButton(
|
|
4757
4857
|
onPressed: () => _confirmDelete(
|
|
4758
4858
|
context,
|
|
@@ -4805,6 +4905,13 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4805
4905
|
label: task.enabled ? 'Active' : 'Paused',
|
|
4806
4906
|
color: task.enabled ? _success : _textSecondary,
|
|
4807
4907
|
),
|
|
4908
|
+
if (task.hasLastRunStatus) ...<Widget>[
|
|
4909
|
+
const SizedBox(width: 8),
|
|
4910
|
+
_StatusPill(
|
|
4911
|
+
label: 'Last: ${task.lastRunStatusLabel}',
|
|
4912
|
+
color: _taskRunStatusColor(task.lastRunStatus),
|
|
4913
|
+
),
|
|
4914
|
+
],
|
|
4808
4915
|
],
|
|
4809
4916
|
),
|
|
4810
4917
|
const SizedBox(height: 10),
|
|
@@ -4839,6 +4946,11 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4839
4946
|
style: TextStyle(color: _textSecondary),
|
|
4840
4947
|
),
|
|
4841
4948
|
],
|
|
4949
|
+
if (task.lastRunFailed &&
|
|
4950
|
+
task.lastRunError.trim().isNotEmpty) ...<Widget>[
|
|
4951
|
+
const SizedBox(height: 8),
|
|
4952
|
+
Text(task.lastRunError, style: TextStyle(color: _danger)),
|
|
4953
|
+
],
|
|
4842
4954
|
const SizedBox(height: 14),
|
|
4843
4955
|
Wrap(
|
|
4844
4956
|
spacing: 10,
|
|
@@ -4868,6 +4980,11 @@ class _TasksPanelState extends State<TasksPanel> {
|
|
|
4868
4980
|
_manualRunButtonLabel('Refresh Now', remaining),
|
|
4869
4981
|
),
|
|
4870
4982
|
),
|
|
4983
|
+
if (task.lastRunId.trim().isNotEmpty)
|
|
4984
|
+
OutlinedButton(
|
|
4985
|
+
onPressed: () => _showLastRun(task),
|
|
4986
|
+
child: const Text('View last run'),
|
|
4987
|
+
),
|
|
4871
4988
|
OutlinedButton(
|
|
4872
4989
|
onPressed: linkedWidget == null
|
|
4873
4990
|
? null
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
79f8662ed3c8bed9a624d3d498b9e894
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"c416acfeb8126e097f758c664aaa3da929e27d
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "3692681921" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|