neoagent 2.5.2-beta.2 → 2.5.2-beta.20
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/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 +4 -4
- package/server/services/ai/deliverables/artifact_helpers.js +109 -16
- package/server/services/ai/deliverables/selector.js +17 -0
- package/server/services/ai/engine.js +2 -4312
- package/server/services/ai/loop/agent_engine_core.js +1590 -0
- package/server/services/ai/loop/blank_recovery.js +37 -0
- package/server/services/ai/loop/callbacks.js +151 -0
- package/server/services/ai/loop/completion_judge.js +252 -0
- package/server/services/ai/loop/conversation_loop.js +2322 -0
- package/server/services/ai/loop/delivery_state.js +27 -0
- package/server/services/ai/loop/error_recovery.js +38 -0
- package/server/services/ai/loop/iteration_budget.js +24 -0
- package/server/services/ai/loop/messaging_delivery.js +250 -0
- package/server/services/ai/loop/model_io.js +258 -0
- package/server/services/ai/loop/progress_classification.js +177 -0
- package/server/services/ai/loop/progress_monitor.js +81 -0
- package/server/services/ai/loop/run_state.js +356 -0
- package/server/services/ai/loop/tool_dispatch.js +230 -0
- package/server/services/ai/loopPolicy.js +3 -3
- package/server/services/ai/repetitionGuard.js +47 -2
- package/server/services/ai/systemPrompt.js +5 -0
- package/server/services/ai/taskAnalysis.js +5 -0
- package/server/services/ai/toolEvidence.js +8 -1
- package/server/services/ai/tools.js +82 -11
- package/server/services/integrations/github/repos.js +39 -29
- package/server/services/messaging/manager.js +7 -0
- package/server/services/runtime/backends/local-vm.js +7 -7
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
efe2ad6d1aff0358de22202a239e2829
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "2093031085" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -134794,7 +134794,7 @@ r===$&&A.b()
|
|
|
134794
134794
|
p.push(A.jP(q,A.j9(!1,new A.a_(B.uG,A.d8(new A.cA(B.jt,new A.a7N(r,q),q),q,q),q),!1,B.H,!0),q,q,0,0,0,q))}r=!1
|
|
134795
134795
|
if(!s.ay)if(!s.ch){r=s.e
|
|
134796
134796
|
r===$&&A.b()
|
|
134797
|
-
r=B.b.u("
|
|
134797
|
+
r=B.b.u("mqgmwb41-5bb5db5").length!==0&&r.b}if(r){r=s.d
|
|
134798
134798
|
r===$&&A.b()
|
|
134799
134799
|
r=r.aP&&!r.ai?84:0
|
|
134800
134800
|
s=s.e
|
|
@@ -140506,7 +140506,7 @@ $S:0}
|
|
|
140506
140506
|
A.a_6.prototype={}
|
|
140507
140507
|
A.SQ.prototype={
|
|
140508
140508
|
nb(a){var s=this
|
|
140509
|
-
if(B.b.u("
|
|
140509
|
+
if(B.b.u("mqgmwb41-5bb5db5").length===0||s.a!=null)return
|
|
140510
140510
|
s.AU()
|
|
140511
140511
|
s.a=A.on(B.RH,new A.bc8(s))},
|
|
140512
140512
|
AU(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
|
|
@@ -140524,7 +140524,7 @@ if(!t.f.b(k)){s=1
|
|
|
140524
140524
|
break}i=J.a3(k,"buildId")
|
|
140525
140525
|
h=i==null?null:B.b.u(J.p(i))
|
|
140526
140526
|
j=h==null?"":h
|
|
140527
|
-
if(J.bi(j)===0||J.d(j,"
|
|
140527
|
+
if(J.bi(j)===0||J.d(j,"mqgmwb41-5bb5db5")){s=1
|
|
140528
140528
|
break}n.b=!0
|
|
140529
140529
|
n.F()
|
|
140530
140530
|
p=2
|
|
@@ -140541,7 +140541,7 @@ case 2:return A.i(o.at(-1),r)}})
|
|
|
140541
140541
|
return A.k($async$AU,r)},
|
|
140542
140542
|
vE(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1
|
|
140543
140543
|
var $async$vE=A.h(function(a2,a3){if(a2===1){o.push(a3)
|
|
140544
|
-
s=p}for(;;)switch(s){case 0:if(B.b.u("
|
|
140544
|
+
s=p}for(;;)switch(s){case 0:if(B.b.u("mqgmwb41-5bb5db5").length===0||n.c){s=1
|
|
140545
140545
|
break}n.c=!0
|
|
140546
140546
|
n.F()
|
|
140547
140547
|
p=4
|
|
@@ -72,10 +72,78 @@ const CANDIDATE_KEYS = [
|
|
|
72
72
|
'mediaPaths',
|
|
73
73
|
'screenshotPath',
|
|
74
74
|
'uiDumpPath',
|
|
75
|
-
'
|
|
76
|
-
'
|
|
75
|
+
'artifact',
|
|
76
|
+
'artifacts',
|
|
77
|
+
'artifactPath',
|
|
78
|
+
'artifactPaths',
|
|
79
|
+
'artifactUrl',
|
|
80
|
+
'artifactUrls',
|
|
81
|
+
'artifactUri',
|
|
82
|
+
'artifactUris',
|
|
83
|
+
'downloadUrl',
|
|
84
|
+
'downloadUrls',
|
|
85
|
+
'downloadUri',
|
|
86
|
+
'downloadUris',
|
|
77
87
|
];
|
|
78
88
|
|
|
89
|
+
const GENERIC_CANDIDATE_KEYS = new Set([
|
|
90
|
+
'path',
|
|
91
|
+
'paths',
|
|
92
|
+
'file',
|
|
93
|
+
'files',
|
|
94
|
+
'filePath',
|
|
95
|
+
'filePaths',
|
|
96
|
+
'fullPath',
|
|
97
|
+
'fullPaths',
|
|
98
|
+
'downloadUrl',
|
|
99
|
+
'downloadUrls',
|
|
100
|
+
'downloadUri',
|
|
101
|
+
'downloadUris',
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
const EXPLICIT_CANDIDATE_KEYS = new Set(
|
|
105
|
+
CANDIDATE_KEYS.filter((key) => !GENERIC_CANDIDATE_KEYS.has(key))
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const ARTIFACT_CONTAINER_KEYS = new Set([
|
|
109
|
+
'artifact',
|
|
110
|
+
'artifacts',
|
|
111
|
+
'attachment',
|
|
112
|
+
'attachments',
|
|
113
|
+
'deliverable',
|
|
114
|
+
'deliverables',
|
|
115
|
+
'download',
|
|
116
|
+
'downloads',
|
|
117
|
+
'file',
|
|
118
|
+
'files',
|
|
119
|
+
'media',
|
|
120
|
+
'preview',
|
|
121
|
+
'screenshot',
|
|
122
|
+
'screenshots',
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
const CONTAINER_URL_KEYS = new Set(['url', 'urls', 'uri', 'uris', 'href', 'hrefs']);
|
|
126
|
+
|
|
127
|
+
const EVIDENCE_RESULT_TOOLS = /^(execute_command|github_|list_|search_|read_|get_|find_|http_request|web_search|browser_get|browser_read|code_navigate|query_structured_data|memory_|session_search|recordings_|read_health_data)/;
|
|
128
|
+
|
|
129
|
+
function allowsGenericCandidateKeys(toolName = '') {
|
|
130
|
+
return !EVIDENCE_RESULT_TOOLS.test(String(toolName || ''));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isExplicitCandidateKey(keyHint = '', parentKeyHint = '', options = {}) {
|
|
134
|
+
if (EXPLICIT_CANDIDATE_KEYS.has(keyHint)) return true;
|
|
135
|
+
if (
|
|
136
|
+
ARTIFACT_CONTAINER_KEYS.has(parentKeyHint)
|
|
137
|
+
&& CANDIDATE_KEYS.includes(keyHint)
|
|
138
|
+
&& (!GENERIC_CANDIDATE_KEYS.has(parentKeyHint) || options.allowGenericKeys === true)
|
|
139
|
+
) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (GENERIC_CANDIDATE_KEYS.has(keyHint)) return options.allowGenericKeys === true;
|
|
143
|
+
if (!CONTAINER_URL_KEYS.has(keyHint)) return false;
|
|
144
|
+
return ARTIFACT_CONTAINER_KEYS.has(parentKeyHint);
|
|
145
|
+
}
|
|
146
|
+
|
|
79
147
|
function inferExtension(candidate = '') {
|
|
80
148
|
return path.extname(String(candidate || '').split('?')[0]).toLowerCase();
|
|
81
149
|
}
|
|
@@ -102,8 +170,17 @@ function normalizePathOrUri(value) {
|
|
|
102
170
|
if (!text) return null;
|
|
103
171
|
if (text.startsWith('/api/artifacts/')) return { uri: text, path: null };
|
|
104
172
|
if (/^https?:\/\//i.test(text)) return { uri: text, path: null };
|
|
105
|
-
if (
|
|
106
|
-
if (
|
|
173
|
+
if (text.startsWith('//')) return null;
|
|
174
|
+
if (/^[A-Za-z]:\\/.test(text)) {
|
|
175
|
+
const ext = path.extname(text.split('?')[0]).toLowerCase();
|
|
176
|
+
if (!FILE_EXTENSION_TO_KIND[ext]) return null;
|
|
177
|
+
return { path: text, uri: null };
|
|
178
|
+
}
|
|
179
|
+
if (path.isAbsolute(text)) {
|
|
180
|
+
const ext = path.extname(text.split('?')[0]).toLowerCase();
|
|
181
|
+
if (!FILE_EXTENSION_TO_KIND[ext]) return null;
|
|
182
|
+
return { path: text, uri: null };
|
|
183
|
+
}
|
|
107
184
|
return null;
|
|
108
185
|
}
|
|
109
186
|
|
|
@@ -123,20 +200,25 @@ async function buildArtifactFromCandidate(candidate, fallbackKind = 'artifact')
|
|
|
123
200
|
artifact.size = (await fs.promises.stat(artifact.path)).size;
|
|
124
201
|
} catch (error) {
|
|
125
202
|
console.warn('[deliverables] Failed to stat artifact candidate:', artifact.path, error?.message || error);
|
|
203
|
+
return null;
|
|
126
204
|
}
|
|
127
205
|
}
|
|
128
206
|
return artifact.path || artifact.uri ? artifact : null;
|
|
129
207
|
}
|
|
130
208
|
|
|
131
|
-
function scanStringForCandidates(text) {
|
|
209
|
+
function scanStringForCandidates(text, { explicit = false } = {}) {
|
|
132
210
|
const input = String(text || '');
|
|
133
211
|
const matches = [];
|
|
134
|
-
const regexes =
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
212
|
+
const regexes = explicit
|
|
213
|
+
? [
|
|
214
|
+
/\/api\/artifacts\/[A-Za-z0-9%_-]+\/content/g,
|
|
215
|
+
/\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
|
|
216
|
+
/[A-Za-z]:\\[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
|
|
217
|
+
/https?:\/\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
|
|
218
|
+
]
|
|
219
|
+
: [
|
|
220
|
+
/\/api\/artifacts\/[A-Za-z0-9%_-]+\/content/g,
|
|
221
|
+
];
|
|
140
222
|
for (const regex of regexes) {
|
|
141
223
|
const found = input.match(regex);
|
|
142
224
|
if (found) matches.push(...found);
|
|
@@ -147,9 +229,14 @@ function scanStringForCandidates(text) {
|
|
|
147
229
|
async function extractArtifactsFromResult(toolName, result) {
|
|
148
230
|
const artifacts = [];
|
|
149
231
|
const seen = new Set();
|
|
232
|
+
const seenCandidates = new Set();
|
|
150
233
|
const fallbackKind = inferArtifactKind(toolName, 'artifact');
|
|
234
|
+
const allowGenericKeys = allowsGenericCandidateKeys(toolName);
|
|
151
235
|
|
|
152
236
|
async function pushCandidate(candidate) {
|
|
237
|
+
const candidateKey = String(candidate || '').trim();
|
|
238
|
+
if (!candidateKey || seenCandidates.has(candidateKey)) return;
|
|
239
|
+
seenCandidates.add(candidateKey);
|
|
153
240
|
const artifact = await buildArtifactFromCandidate(candidate, fallbackKind);
|
|
154
241
|
if (!artifact) return;
|
|
155
242
|
const key = `${artifact.kind}:${artifact.path || artifact.uri}`;
|
|
@@ -158,22 +245,26 @@ async function extractArtifactsFromResult(toolName, result) {
|
|
|
158
245
|
artifacts.push(artifact);
|
|
159
246
|
}
|
|
160
247
|
|
|
161
|
-
async function visit(value, keyHint = '') {
|
|
248
|
+
async function visit(value, keyHint = '', parentKeyHint = '') {
|
|
162
249
|
if (value == null) return;
|
|
163
250
|
if (typeof value === 'string') {
|
|
164
|
-
|
|
165
|
-
|
|
251
|
+
const explicit = isExplicitCandidateKey(keyHint, parentKeyHint, { allowGenericKeys });
|
|
252
|
+
if (explicit) {
|
|
253
|
+
if (normalizePathOrUri(value)) await pushCandidate(value);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
for (const candidate of scanStringForCandidates(value, { explicit })) {
|
|
166
257
|
await pushCandidate(candidate);
|
|
167
258
|
}
|
|
168
259
|
return;
|
|
169
260
|
}
|
|
170
261
|
if (Array.isArray(value)) {
|
|
171
|
-
for (const item of value) await visit(item, keyHint);
|
|
262
|
+
for (const item of value) await visit(item, keyHint, parentKeyHint);
|
|
172
263
|
return;
|
|
173
264
|
}
|
|
174
265
|
if (typeof value === 'object') {
|
|
175
266
|
for (const [key, nested] of Object.entries(value)) {
|
|
176
|
-
await visit(nested, key);
|
|
267
|
+
await visit(nested, key, keyHint);
|
|
177
268
|
}
|
|
178
269
|
}
|
|
179
270
|
}
|
|
@@ -183,8 +274,10 @@ async function extractArtifactsFromResult(toolName, result) {
|
|
|
183
274
|
}
|
|
184
275
|
|
|
185
276
|
module.exports = {
|
|
277
|
+
allowsGenericCandidateKeys,
|
|
186
278
|
extractArtifactsFromResult,
|
|
187
279
|
inferArtifactKind,
|
|
188
280
|
inferMimeType,
|
|
281
|
+
isExplicitCandidateKey,
|
|
189
282
|
normalizePathOrUri,
|
|
190
283
|
};
|
|
@@ -47,6 +47,23 @@ async function selectDeliverableWorkflow({
|
|
|
47
47
|
tools = [],
|
|
48
48
|
options = {},
|
|
49
49
|
}) {
|
|
50
|
+
if (!engine || typeof engine.requestStructuredJson !== 'function') {
|
|
51
|
+
return {
|
|
52
|
+
selection: {
|
|
53
|
+
status: 'standard',
|
|
54
|
+
type: null,
|
|
55
|
+
confidence: 0,
|
|
56
|
+
goal: '',
|
|
57
|
+
requestedOutputs: [],
|
|
58
|
+
supportingCapabilities: [],
|
|
59
|
+
},
|
|
60
|
+
usage: 0,
|
|
61
|
+
raw: '',
|
|
62
|
+
skipped: true,
|
|
63
|
+
reason: 'structured selector unavailable',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
50
67
|
const response = await engine.requestStructuredJson({
|
|
51
68
|
provider,
|
|
52
69
|
providerName,
|