neoagent 2.5.2-beta.6 → 2.5.2-beta.7
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
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
c71ef84ad1471500295da6f6c6f13299
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "2830694115" /* 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("mqfoxi8l-ab0f828").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("mqfoxi8l-ab0f828").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,"mqfoxi8l-ab0f828")){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("mqfoxi8l-ab0f828").length===0||n.c){s=1
|
|
140545
140545
|
break}n.c=!0
|
|
140546
140546
|
n.F()
|
|
140547
140547
|
p=4
|
|
@@ -144,6 +144,7 @@ function normalizeErrorKey(errorMsg) {
|
|
|
144
144
|
if (/enoent|no such file/i.test(msg)) return 'enoent';
|
|
145
145
|
if (/can.?t cd to|no such directory/i.test(msg)) return 'bad_cwd';
|
|
146
146
|
if (/not found/i.test(msg)) return 'not_found';
|
|
147
|
+
if (/owner_repo.*format|must be.*owner.*repo|owner.*repo.*string|owner.*repo.*combined/i.test(msg)) return 'owner_repo_format';
|
|
147
148
|
return msg.slice(0, 60);
|
|
148
149
|
}
|
|
149
150
|
|
|
@@ -155,10 +156,20 @@ function trackErrorPattern(errorMsg, runMeta) {
|
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
function buildErrorPatternGuidance(key, count) {
|
|
159
|
+
// Immediate guidance on first occurrence for high-signal patterns that waste
|
|
160
|
+
// multiple iterations before self-correcting.
|
|
161
|
+
const immediateGuides = {
|
|
162
|
+
eisdir: 'That path is a directory (or a VM-only path like /tmp that read_file cannot reach). Use execute_command with `cat <path>` to read files inside VMs, or list_directory to inspect a directory.',
|
|
163
|
+
owner_repo_format: 'The parameter "owner_repo" expects a single combined string like "NeoLabs-Systems/NeoAgent" — not separate owner/repo fields. Pass the full "owner/repo" as one value.',
|
|
164
|
+
};
|
|
165
|
+
if (immediateGuides[key]) {
|
|
166
|
+
const prefix = count > 1 ? `REPEATED ERROR (${count}×): ` : 'ERROR GUIDANCE: ';
|
|
167
|
+
return `${prefix}${immediateGuides[key]}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
158
170
|
if (count < 3) return null;
|
|
159
171
|
const guides = {
|
|
160
172
|
outside_workspace: 'read_file cannot access /tmp paths. Use execute_command with `cat <path>` instead.',
|
|
161
|
-
eisdir: 'That path is a directory, not a file. Use list_directory or execute_command with `ls` to inspect it.',
|
|
162
173
|
enoent: 'That path does not exist. Use execute_command with `find . -name "..."` to locate the correct path first.',
|
|
163
174
|
bad_cwd: 'The VM home directory is not ~/. Use absolute paths starting from /tmp or discover the workspace root first.',
|
|
164
175
|
not_found: 'This path or resource was not found. Try listing the parent directory or checking with a broader search first.',
|
|
@@ -168,6 +179,19 @@ function buildErrorPatternGuidance(key, count) {
|
|
|
168
179
|
return `REPEATED ERROR (${count}×): ${guide}`;
|
|
169
180
|
}
|
|
170
181
|
|
|
182
|
+
const OUTPUT_FINGERPRINT_TOOLS = /^(list_|search_|read_|get_|find_|github_list|github_get|github_search)/;
|
|
183
|
+
|
|
184
|
+
function fingerprintOutput(toolName, result) {
|
|
185
|
+
if (!toolName || !OUTPUT_FINGERPRINT_TOOLS.test(toolName)) return null;
|
|
186
|
+
const raw = typeof result === 'string' ? result : JSON.stringify(result ?? '');
|
|
187
|
+
if (raw.length < 200) return null;
|
|
188
|
+
// djb2 hash over first 3000 chars — fast, collision-unlikely for our sizes
|
|
189
|
+
let h = 5381;
|
|
190
|
+
const limit = Math.min(raw.length, 3000);
|
|
191
|
+
for (let i = 0; i < limit; i++) h = ((h << 5) + h) ^ raw.charCodeAt(i);
|
|
192
|
+
return h >>> 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
171
195
|
function resolveModelCallTimeoutMs(options = {}) {
|
|
172
196
|
const requested = Number(options?.modelCallTimeoutMs);
|
|
173
197
|
if (Number.isFinite(requested) && requested > 0) {
|
|
@@ -2623,6 +2647,7 @@ class AgentEngine {
|
|
|
2623
2647
|
systemSteeringQueue: [],
|
|
2624
2648
|
toolPids: new Set(),
|
|
2625
2649
|
repetitionGuard: new ToolRepetitionGuard(),
|
|
2650
|
+
seenOutputHashes: new Map(),
|
|
2626
2651
|
messagingContext: triggerSource === 'messaging'
|
|
2627
2652
|
? {
|
|
2628
2653
|
platform: options.source || null,
|
|
@@ -3011,6 +3036,13 @@ class AgentEngine {
|
|
|
3011
3036
|
}
|
|
3012
3037
|
messages = sanitizeConversationMessages(messages);
|
|
3013
3038
|
|
|
3039
|
+
if (analysis.mode === 'execute' || analysis.mode === 'plan_execute') {
|
|
3040
|
+
messages.push({
|
|
3041
|
+
role: 'system',
|
|
3042
|
+
content: 'Research budget: after 3 read/list/search tool calls, you must take a concrete action (write, create, send, update) or explain clearly why you cannot. Work on one item at a time — do not queue up more reads.',
|
|
3043
|
+
});
|
|
3044
|
+
}
|
|
3045
|
+
|
|
3014
3046
|
directAnswerEligible = isDirectAnswerEligibleAnalysis(analysis)
|
|
3015
3047
|
&& Boolean(normalizeOutgoingMessage(analysis.draft_reply));
|
|
3016
3048
|
|
|
@@ -3595,6 +3627,22 @@ class AgentEngine {
|
|
|
3595
3627
|
}
|
|
3596
3628
|
} else {
|
|
3597
3629
|
consecutiveToolFailures = 0;
|
|
3630
|
+
// Output fingerprint guard: steer away from re-fetching data already seen.
|
|
3631
|
+
if (!toolErrorMessage) {
|
|
3632
|
+
const currentRunMeta = this.getRunMeta(runId);
|
|
3633
|
+
const fp = fingerprintOutput(toolName, toolResult);
|
|
3634
|
+
if (fp !== null && currentRunMeta?.seenOutputHashes) {
|
|
3635
|
+
const prior = currentRunMeta.seenOutputHashes.get(fp);
|
|
3636
|
+
if (prior) {
|
|
3637
|
+
messages.push({
|
|
3638
|
+
role: 'system',
|
|
3639
|
+
content: `DUPLICATE DATA: This response is identical to what "${prior.toolName}" returned in iteration ${prior.iteration}. You already have this information. Stop fetching and use what you have — proceed to the next concrete action.`,
|
|
3640
|
+
});
|
|
3641
|
+
} else {
|
|
3642
|
+
currentRunMeta.seenOutputHashes.set(fp, { toolName, iteration });
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3598
3646
|
}
|
|
3599
3647
|
|
|
3600
3648
|
if (toolName === 'send_interim_update') {
|