neoagent 2.5.2-beta.21 → 2.5.2-beta.22
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/loop/conversation_loop.js +41 -6
- package/server/services/ai/loopPolicy.js +3 -1
- package/server/services/ai/messagingFallback.js +2 -1
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
7b68be842f70ebca5228682c4fe3dc90
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "1027370389" /* 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("mqgt278r-971ca3d").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("mqgt278r-971ca3d").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,"mqgt278r-971ca3d")){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("mqgt278r-971ca3d").length===0||n.c){s=1
|
|
140545
140545
|
break}n.c=!0
|
|
140546
140546
|
n.F()
|
|
140547
140547
|
p=4
|
|
@@ -248,6 +248,33 @@ function fingerprintOutput(toolName, result, toolArgs = {}) {
|
|
|
248
248
|
return h >>> 0;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
+
// Concise list of files/targets the run has already read or searched, so the
|
|
252
|
+
// analysis-paralysis nudge can name them and tell the model not to re-read them.
|
|
253
|
+
function summarizeReadTargets(toolExecutions = []) {
|
|
254
|
+
const targets = [];
|
|
255
|
+
const seen = new Set();
|
|
256
|
+
for (const item of toolExecutions) {
|
|
257
|
+
if (!item || item.stateChanged) continue; // only read-only steps
|
|
258
|
+
const input = item.input || {};
|
|
259
|
+
let target = '';
|
|
260
|
+
if (typeof input.path === 'string' && input.path.trim()) {
|
|
261
|
+
target = input.path.trim();
|
|
262
|
+
} else if (typeof input.command === 'string') {
|
|
263
|
+
const files = input.command.match(/[\w./-]+\.(?:js|ts|tsx|jsx|py|dart|json|md|kt|c|h|ya?ml|sql|txt|sh)\b/g);
|
|
264
|
+
if (files && files.length) target = [...new Set(files)].slice(0, 2).join(', ');
|
|
265
|
+
} else if (typeof input.query === 'string' && input.query.trim()) {
|
|
266
|
+
target = `search:${input.query.trim().slice(0, 30)}`;
|
|
267
|
+
}
|
|
268
|
+
if (!target) continue;
|
|
269
|
+
const key = target.toLowerCase();
|
|
270
|
+
if (seen.has(key)) continue;
|
|
271
|
+
seen.add(key);
|
|
272
|
+
targets.push(target);
|
|
273
|
+
if (targets.length >= 8) break;
|
|
274
|
+
}
|
|
275
|
+
return targets.join('; ');
|
|
276
|
+
}
|
|
277
|
+
|
|
251
278
|
function cloneInterimHistory(history = []) {
|
|
252
279
|
if (!Array.isArray(history)) return [];
|
|
253
280
|
return history.map((item) => ({
|
|
@@ -789,10 +816,10 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
|
|
|
789
816
|
try {
|
|
790
817
|
const rm = engine.getRunMeta(runId);
|
|
791
818
|
const ledger = rm?.progressLedger || {};
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
819
|
+
// Real, specific evidence (actual commands + their output) so the update is
|
|
820
|
+
// grounded in what happened, not invented. Bare tool names make a weak model
|
|
821
|
+
// confabulate generic activity ("running the build", "training").
|
|
822
|
+
const recent = summarizeToolExecutions(toolExecutions, 5) || '(no tool activity yet)';
|
|
796
823
|
const priorUpdate = String(rm?.lastInterimMessage || '').trim();
|
|
797
824
|
const contextBlock = [
|
|
798
825
|
buildProgressUpdatePrompt(),
|
|
@@ -800,7 +827,7 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
|
|
|
800
827
|
'',
|
|
801
828
|
`Original request: ${summarizeForLog(userMessage, 320)}`,
|
|
802
829
|
`Doing now: ${ledger.currentTool ? `using ${ledger.currentTool}` : (ledger.currentPhase || 'thinking')}`,
|
|
803
|
-
`
|
|
830
|
+
`Actual recent tool activity (newest last) — describe ONLY this, do not extrapolate:\n${recent}`,
|
|
804
831
|
priorUpdate ? `Your previous update (say something different): ${summarizeForLog(priorUpdate, 160)}` : '',
|
|
805
832
|
].filter(Boolean).join('\n');
|
|
806
833
|
// Reuse the run's real system prompt so the update follows the same voice and
|
|
@@ -1125,9 +1152,17 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
|
|
|
1125
1152
|
const readOnlyCount = engine.getRunMeta(runId)?.consecutiveReadOnlyIterations || 0;
|
|
1126
1153
|
if (readOnlyCount >= 3) {
|
|
1127
1154
|
const urgency = readOnlyCount >= 6 ? 'CRITICAL' : 'ACTION REQUIRED';
|
|
1155
|
+
const alreadyRead = summarizeReadTargets(toolExecutions);
|
|
1128
1156
|
messages.push({
|
|
1129
1157
|
role: 'system',
|
|
1130
|
-
content:
|
|
1158
|
+
content: [
|
|
1159
|
+
`${urgency} — ${readOnlyCount} consecutive read-only turns with no concrete action.`,
|
|
1160
|
+
alreadyRead
|
|
1161
|
+
? `You have ALREADY read/searched: ${alreadyRead}. Their output is in this conversation above — do not read or search them again; re-reading what you already have is the main way runs stall.`
|
|
1162
|
+
: 'Do not re-read or re-search anything already in this conversation.',
|
|
1163
|
+
'Act on what you already know now: edit files, run a state-changing command, create the branch/PR, or send the result.',
|
|
1164
|
+
'If you genuinely cannot proceed, call task_complete with your best answer or a concrete blocker. Deciding to finish is a valid action; continuing to gather is not.',
|
|
1165
|
+
].join(' '),
|
|
1131
1166
|
});
|
|
1132
1167
|
}
|
|
1133
1168
|
}
|
|
@@ -24,7 +24,9 @@ const UNLIMITED_ITERATIONS = 1_000_000;
|
|
|
24
24
|
const DEFAULT_MAX_ITERATIONS = UNLIMITED_ITERATIONS;
|
|
25
25
|
const DEFAULT_WIDGET_MAX_ITERATIONS = UNLIMITED_ITERATIONS;
|
|
26
26
|
const DEFAULT_PLAN_EXECUTE_MAX_ITERATIONS = UNLIMITED_ITERATIONS;
|
|
27
|
-
|
|
27
|
+
// Less aggressive than 0.60 so the model retains file contents it already read for
|
|
28
|
+
// longer, instead of losing them to compaction and re-reading the same files.
|
|
29
|
+
const DEFAULT_COMPACTION_THRESHOLD = 0.80;
|
|
28
30
|
const DEFAULT_MAX_CONSECUTIVE_TOOL_FAILURES = 5;
|
|
29
31
|
const DEFAULT_MAX_MODEL_FAILURE_RECOVERIES = 3;
|
|
30
32
|
|
|
@@ -55,7 +55,8 @@ function buildProgressUpdatePrompt() {
|
|
|
55
55
|
// formatting guidelines as every other message and stays maintainable in one place.
|
|
56
56
|
return [
|
|
57
57
|
'You are mid-task and working autonomously while the user waits.',
|
|
58
|
-
'Send ONE brief progress ping saying what you are doing right now,
|
|
58
|
+
'Send ONE brief progress ping saying what you are doing right now, grounded ONLY in the actual recent tool activity below.',
|
|
59
|
+
'Describe what the evidence literally shows (e.g. reading files, searching the repo, cloning, editing). Do NOT invent or guess steps, and never mention builds, compiling, gradle, tests, training, models, evaluation, pipelines, batch jobs, or deployments unless they actually appear in the activity.',
|
|
59
60
|
'This is not the final answer: do not claim the task is done and do not summarize results.',
|
|
60
61
|
'No greeting, no question, no sign-off; vary the wording from your previous update.',
|
|
61
62
|
'Follow your normal voice and formatting rules. Output only the message text.',
|