neoagent 2.5.2-beta.9 → 3.0.1-beta.0
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 +5 -1
- package/docs/integrations.md +11 -7
- package/flutter_app/lib/main_controller.dart +34 -0
- package/flutter_app/lib/main_security.dart +19 -0
- package/lib/schema_migrations.js +224 -0
- package/package.json +2 -2
- package/server/admin/admin.css +29 -0
- package/server/admin/admin.js +81 -1
- package/server/admin/index.html +97 -9
- package/server/db/database.js +57 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +32788 -32752
- package/server/routes/security.js +19 -0
- package/server/routes/settings.js +1 -0
- package/server/routes/skills.js +9 -5
- package/server/services/ai/deliverables/artifact_helpers.js +92 -9
- package/server/services/ai/deliverables/selector.js +17 -0
- package/server/services/ai/hooks.js +3 -2
- package/server/services/ai/learning.js +8 -3
- package/server/services/ai/loop/agent_engine_core.js +67 -0
- package/server/services/ai/loop/blank_recovery.js +37 -0
- package/server/services/ai/loop/conversation_loop.js +391 -252
- package/server/services/ai/loop/error_recovery.js +38 -0
- package/server/services/ai/loop/messaging_delivery.js +52 -6
- package/server/services/ai/loop/progress_classification.js +178 -0
- package/server/services/ai/loop/progress_monitor.js +6 -5
- package/server/services/ai/loop/tool_dispatch.js +1 -0
- package/server/services/ai/loopPolicy.js +15 -6
- package/server/services/ai/messagingFallback.js +23 -1
- package/server/services/ai/preModelCompaction.js +31 -0
- package/server/services/ai/repetitionGuard.js +47 -2
- package/server/services/ai/settings.js +8 -0
- package/server/services/ai/systemPrompt.js +24 -0
- package/server/services/ai/taskAnalysis.js +10 -0
- package/server/services/ai/toolEvidence.js +39 -3
- package/server/services/ai/toolResult.js +29 -0
- package/server/services/ai/toolRunner.js +262 -55
- package/server/services/ai/toolSelector.js +20 -3
- package/server/services/ai/tools.js +201 -31
- package/server/services/cli/shell_worker_pool.js +87 -5
- package/server/services/integrations/github/common.js +2 -2
- package/server/services/integrations/github/repos.js +123 -55
- package/server/services/manager.js +16 -0
- package/server/services/memory/manager.js +39 -24
- package/server/services/runtime/docker-vm-manager.js +21 -1
- package/server/services/runtime/manager.js +6 -2
- package/server/services/security/approval_gate_service.js +108 -5
- package/server/services/security/tool_categories.js +113 -4
- package/server/services/security/tool_security_hook.js +7 -2
- package/server/services/skills/runtime.js +2 -0
- package/server/services/workspace/manager.js +56 -0
package/server/admin/index.html
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
<title>NeoAgent Admin</title>
|
|
7
7
|
<link rel="icon" href="/admin/logo.svg" type="image/svg+xml">
|
|
8
8
|
<link rel="stylesheet" href="/admin/admin.css">
|
|
9
|
+
<script>
|
|
10
|
+
// Set theme before first paint to avoid a flash of the wrong palette.
|
|
11
|
+
try {
|
|
12
|
+
document.documentElement.setAttribute('data-theme', localStorage.getItem('admin-theme') || 'dark');
|
|
13
|
+
} catch (_) { document.documentElement.setAttribute('data-theme', 'dark'); }
|
|
14
|
+
</script>
|
|
9
15
|
<style>
|
|
10
16
|
/* ── Layout ────────────────────────────────────────────────────── */
|
|
11
17
|
body {
|
|
@@ -62,7 +68,7 @@
|
|
|
62
68
|
text-decoration: none;
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
.nav-item:hover { background:
|
|
71
|
+
.nav-item:hover { background: var(--row-hover); color: var(--text); }
|
|
66
72
|
|
|
67
73
|
.nav-item.active {
|
|
68
74
|
background: rgba(225, 176, 82, 0.12);
|
|
@@ -78,6 +84,51 @@
|
|
|
78
84
|
|
|
79
85
|
.nav-item.active svg { opacity: 1; }
|
|
80
86
|
|
|
87
|
+
.nav-badge {
|
|
88
|
+
margin-left: auto;
|
|
89
|
+
min-width: 18px;
|
|
90
|
+
padding: 1px 6px;
|
|
91
|
+
border-radius: 999px;
|
|
92
|
+
background: var(--danger);
|
|
93
|
+
color: #fff;
|
|
94
|
+
font-size: 11px;
|
|
95
|
+
font-weight: 600;
|
|
96
|
+
line-height: 1.4;
|
|
97
|
+
text-align: center;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.issue-row {
|
|
101
|
+
display: grid;
|
|
102
|
+
grid-template-columns: 1fr auto;
|
|
103
|
+
gap: 12px;
|
|
104
|
+
align-items: start;
|
|
105
|
+
padding: 10px 14px;
|
|
106
|
+
border-bottom: 1px solid var(--border);
|
|
107
|
+
}
|
|
108
|
+
.issue-row:last-child { border-bottom: none; }
|
|
109
|
+
.issue-msg {
|
|
110
|
+
font-family: var(--font-mono);
|
|
111
|
+
font-size: 12.5px;
|
|
112
|
+
color: var(--danger);
|
|
113
|
+
white-space: pre-wrap;
|
|
114
|
+
word-break: break-word;
|
|
115
|
+
}
|
|
116
|
+
.issue-meta {
|
|
117
|
+
font-size: 11px;
|
|
118
|
+
color: var(--text-muted);
|
|
119
|
+
text-align: right;
|
|
120
|
+
white-space: nowrap;
|
|
121
|
+
}
|
|
122
|
+
.issue-count {
|
|
123
|
+
display: inline-block;
|
|
124
|
+
margin-bottom: 3px;
|
|
125
|
+
padding: 1px 7px;
|
|
126
|
+
border-radius: 999px;
|
|
127
|
+
background: var(--accent-muted);
|
|
128
|
+
color: var(--accent);
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
}
|
|
131
|
+
|
|
81
132
|
.sidebar-footer {
|
|
82
133
|
padding: 10px;
|
|
83
134
|
border-top: 1px solid var(--border);
|
|
@@ -202,12 +253,12 @@
|
|
|
202
253
|
.log-row {
|
|
203
254
|
display: grid;
|
|
204
255
|
grid-template-columns: 80px 46px 1fr;
|
|
205
|
-
border-bottom: 1px solid
|
|
256
|
+
border-bottom: 1px solid var(--border);
|
|
206
257
|
}
|
|
207
258
|
|
|
208
259
|
.log-row:last-child { border-bottom: none; }
|
|
209
260
|
|
|
210
|
-
.log-row:hover { background:
|
|
261
|
+
.log-row:hover { background: var(--row-hover); }
|
|
211
262
|
|
|
212
263
|
.log-cell {
|
|
213
264
|
padding: 6px 10px;
|
|
@@ -426,12 +477,12 @@
|
|
|
426
477
|
|
|
427
478
|
.analytics-table td {
|
|
428
479
|
padding: 9px 8px;
|
|
429
|
-
border-bottom: 1px solid
|
|
480
|
+
border-bottom: 1px solid var(--border);
|
|
430
481
|
color: var(--text-secondary);
|
|
431
482
|
}
|
|
432
483
|
|
|
433
484
|
.analytics-table tr:last-child td { border-bottom: none; }
|
|
434
|
-
.analytics-table tr:hover td { background:
|
|
485
|
+
.analytics-table tr:hover td { background: var(--row-hover); }
|
|
435
486
|
|
|
436
487
|
.cell-truncate {
|
|
437
488
|
max-width: 280px;
|
|
@@ -504,12 +555,12 @@
|
|
|
504
555
|
|
|
505
556
|
.users-table td {
|
|
506
557
|
padding: 10px 8px;
|
|
507
|
-
border-bottom: 1px solid
|
|
558
|
+
border-bottom: 1px solid var(--border);
|
|
508
559
|
vertical-align: middle;
|
|
509
560
|
}
|
|
510
561
|
|
|
511
562
|
.users-table tr:last-child td { border-bottom: none; }
|
|
512
|
-
.users-table tr:hover td { background:
|
|
563
|
+
.users-table tr:hover td { background: var(--row-hover); }
|
|
513
564
|
|
|
514
565
|
.gdpr-note {
|
|
515
566
|
font-size: 11px;
|
|
@@ -593,7 +644,7 @@
|
|
|
593
644
|
|
|
594
645
|
.sql-result-table td {
|
|
595
646
|
padding: 6px 12px;
|
|
596
|
-
border-bottom: 1px solid
|
|
647
|
+
border-bottom: 1px solid var(--border);
|
|
597
648
|
color: var(--text-secondary);
|
|
598
649
|
white-space: nowrap;
|
|
599
650
|
max-width: 320px;
|
|
@@ -602,7 +653,7 @@
|
|
|
602
653
|
}
|
|
603
654
|
|
|
604
655
|
.sql-result-table tr:last-child td { border-bottom: none; }
|
|
605
|
-
.sql-result-table tr:hover td { background:
|
|
656
|
+
.sql-result-table tr:hover td { background: var(--row-hover); }
|
|
606
657
|
|
|
607
658
|
.sql-error {
|
|
608
659
|
padding: 12px 14px;
|
|
@@ -821,6 +872,14 @@
|
|
|
821
872
|
Logs
|
|
822
873
|
</button>
|
|
823
874
|
|
|
875
|
+
<button class="nav-item" data-page="issues" onclick="showPage('issues',this)">
|
|
876
|
+
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
877
|
+
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
|
878
|
+
</svg>
|
|
879
|
+
Issues
|
|
880
|
+
<span class="nav-badge" id="issues-badge" hidden>0</span>
|
|
881
|
+
</button>
|
|
882
|
+
|
|
824
883
|
<button class="nav-item" data-page="updates" onclick="showPage('updates',this)">
|
|
825
884
|
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
826
885
|
<path fill-rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" clip-rule="evenodd"/>
|
|
@@ -883,6 +942,12 @@
|
|
|
883
942
|
</nav>
|
|
884
943
|
|
|
885
944
|
<div class="sidebar-footer">
|
|
945
|
+
<button class="nav-item" id="theme-toggle" onclick="toggleTheme()" aria-label="Toggle light and dark theme">
|
|
946
|
+
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
947
|
+
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"/>
|
|
948
|
+
</svg>
|
|
949
|
+
<span id="theme-toggle-label">Light mode</span>
|
|
950
|
+
</button>
|
|
886
951
|
<button class="nav-item btn-danger" onclick="signOut()">
|
|
887
952
|
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
888
953
|
<path fill-rule="evenodd" d="M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z" clip-rule="evenodd"/>
|
|
@@ -938,6 +1003,29 @@
|
|
|
938
1003
|
</div>
|
|
939
1004
|
</section>
|
|
940
1005
|
|
|
1006
|
+
<!-- Issues -->
|
|
1007
|
+
<section id="page-issues" class="page" aria-label="Issues">
|
|
1008
|
+
<div class="page-header">
|
|
1009
|
+
<div>
|
|
1010
|
+
<h1 class="page-title">Issues</h1>
|
|
1011
|
+
<p class="page-subtitle">Critical errors from the log stream that should be addressed, grouped by message</p>
|
|
1012
|
+
</div>
|
|
1013
|
+
<span class="refresh-hint" id="issues-ts" aria-live="polite"></span>
|
|
1014
|
+
</div>
|
|
1015
|
+
<div class="content">
|
|
1016
|
+
<div class="card">
|
|
1017
|
+
<div class="toolbar">
|
|
1018
|
+
<span class="toolbar-count" id="issue-count" aria-live="polite">0 issues</span>
|
|
1019
|
+
<span class="spacer"></span>
|
|
1020
|
+
<button class="btn btn-ghost" onclick="loadIssues()">Refresh</button>
|
|
1021
|
+
</div>
|
|
1022
|
+
<div class="log-table" id="issue-table" role="log" aria-label="Critical issues">
|
|
1023
|
+
<div class="empty">No critical issues</div>
|
|
1024
|
+
</div>
|
|
1025
|
+
</div>
|
|
1026
|
+
</div>
|
|
1027
|
+
</section>
|
|
1028
|
+
|
|
941
1029
|
<!-- Updates -->
|
|
942
1030
|
<section id="page-updates" class="page" aria-label="Updates">
|
|
943
1031
|
<div class="page-header">
|
package/server/db/database.js
CHANGED
|
@@ -91,6 +91,8 @@ function runWithBusyRetry(action, { attempts = 5, delayMs = 50, label = 'SQLite
|
|
|
91
91
|
let db = new Database(DB_PATH);
|
|
92
92
|
db = initializeDatabase(db, DB_PATH);
|
|
93
93
|
|
|
94
|
+
const STALE_RUN_INTERRUPTED_ERROR = 'Server restarted while run was in progress.';
|
|
95
|
+
|
|
94
96
|
db.exec(`
|
|
95
97
|
CREATE TABLE IF NOT EXISTS users (
|
|
96
98
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -441,7 +443,8 @@ db.exec(`
|
|
|
441
443
|
|
|
442
444
|
CREATE TABLE IF NOT EXISTS skills (
|
|
443
445
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
444
|
-
|
|
446
|
+
user_id INTEGER NOT NULL DEFAULT 0,
|
|
447
|
+
name TEXT NOT NULL,
|
|
445
448
|
description TEXT,
|
|
446
449
|
file_path TEXT NOT NULL,
|
|
447
450
|
metadata TEXT DEFAULT '{}',
|
|
@@ -1078,6 +1081,57 @@ db.exec(`
|
|
|
1078
1081
|
|
|
1079
1082
|
runSchemaMigrations(db);
|
|
1080
1083
|
|
|
1084
|
+
function interruptStaleAgentRuns(reason = STALE_RUN_INTERRUPTED_ERROR) {
|
|
1085
|
+
const normalizedReason = String(reason || STALE_RUN_INTERRUPTED_ERROR).trim()
|
|
1086
|
+
|| STALE_RUN_INTERRUPTED_ERROR;
|
|
1087
|
+
const staleRunIds = db.prepare(
|
|
1088
|
+
`SELECT id
|
|
1089
|
+
FROM agent_runs
|
|
1090
|
+
WHERE status = 'running'`
|
|
1091
|
+
).all().map((row) => row.id);
|
|
1092
|
+
const runsResult = db.prepare(
|
|
1093
|
+
`UPDATE agent_runs
|
|
1094
|
+
SET status = 'interrupted',
|
|
1095
|
+
error = COALESCE(NULLIF(error, ''), ?),
|
|
1096
|
+
updated_at = datetime('now'),
|
|
1097
|
+
completed_at = COALESCE(completed_at, datetime('now'))
|
|
1098
|
+
WHERE status = 'running'`
|
|
1099
|
+
).run(normalizedReason);
|
|
1100
|
+
|
|
1101
|
+
db.prepare(
|
|
1102
|
+
`UPDATE agent_steps
|
|
1103
|
+
SET status = 'interrupted',
|
|
1104
|
+
error = COALESCE(NULLIF(error, ''), ?),
|
|
1105
|
+
completed_at = COALESCE(completed_at, datetime('now'))
|
|
1106
|
+
WHERE status = 'running'`
|
|
1107
|
+
).run(normalizedReason);
|
|
1108
|
+
|
|
1109
|
+
db.prepare(
|
|
1110
|
+
`UPDATE agent_delegations
|
|
1111
|
+
SET status = 'interrupted',
|
|
1112
|
+
error = COALESCE(NULLIF(error, ''), ?),
|
|
1113
|
+
updated_at = datetime('now'),
|
|
1114
|
+
completed_at = COALESCE(completed_at, datetime('now'))
|
|
1115
|
+
WHERE status = 'running'`
|
|
1116
|
+
).run(normalizedReason);
|
|
1117
|
+
|
|
1118
|
+
if (staleRunIds.length) {
|
|
1119
|
+
const placeholders = staleRunIds.map(() => '?').join(', ');
|
|
1120
|
+
db.prepare(
|
|
1121
|
+
`UPDATE pending_approvals
|
|
1122
|
+
SET status = 'expired',
|
|
1123
|
+
decided_at = COALESCE(decided_at, datetime('now')),
|
|
1124
|
+
updated_at = datetime('now')
|
|
1125
|
+
WHERE status = 'pending'
|
|
1126
|
+
AND run_id IN (${placeholders})`
|
|
1127
|
+
).run(...staleRunIds);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
return runsResult.changes || 0;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
interruptStaleAgentRuns();
|
|
1134
|
+
|
|
1081
1135
|
try {
|
|
1082
1136
|
db.exec(`
|
|
1083
1137
|
CREATE VIRTUAL TABLE IF NOT EXISTS screen_history_fts USING fts5(
|
|
@@ -2022,3 +2076,5 @@ try {
|
|
|
2022
2076
|
}
|
|
2023
2077
|
|
|
2024
2078
|
module.exports = db;
|
|
2079
|
+
module.exports.STALE_RUN_INTERRUPTED_ERROR = STALE_RUN_INTERRUPTED_ERROR;
|
|
2080
|
+
module.exports.interruptStaleAgentRuns = interruptStaleAgentRuns;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
07f0fa2418c3bb652d9c285ad6a55b0f
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "1807031898" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|