neoagent 3.0.1-beta.1 → 3.0.1-beta.2
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/completion_judge.js +3 -2
- package/server/services/ai/loop/conversation_loop.js +2 -10
- package/server/services/ai/loop/progress_classification.js +15 -0
- package/server/services/ai/systemPrompt.js +3 -2
- package/server/services/ai/tools.js +6 -5
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
c04ddd17135c19eaa7255284a042b387
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "3187756582" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -134819,7 +134819,7 @@ r===$&&A.b()
|
|
|
134819
134819
|
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
|
|
134820
134820
|
if(!s.ay)if(!s.ch){r=s.e
|
|
134821
134821
|
r===$&&A.b()
|
|
134822
|
-
r=B.b.u("
|
|
134822
|
+
r=B.b.u("mqhrjp9m-06483fb").length!==0&&r.b}if(r){r=s.d
|
|
134823
134823
|
r===$&&A.b()
|
|
134824
134824
|
r=r.aP&&!r.ai?84:0
|
|
134825
134825
|
s=s.e
|
|
@@ -140540,7 +140540,7 @@ $S:0}
|
|
|
140540
140540
|
A.a_6.prototype={}
|
|
140541
140541
|
A.SQ.prototype={
|
|
140542
140542
|
nb(a){var s=this
|
|
140543
|
-
if(B.b.u("
|
|
140543
|
+
if(B.b.u("mqhrjp9m-06483fb").length===0||s.a!=null)return
|
|
140544
140544
|
s.AU()
|
|
140545
140545
|
s.a=A.on(B.RI,new A.bc9(s))},
|
|
140546
140546
|
AU(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
|
|
@@ -140558,7 +140558,7 @@ if(!t.f.b(k)){s=1
|
|
|
140558
140558
|
break}i=J.a3(k,"buildId")
|
|
140559
140559
|
h=i==null?null:B.b.u(J.p(i))
|
|
140560
140560
|
j=h==null?"":h
|
|
140561
|
-
if(J.bi(j)===0||J.d(j,"
|
|
140561
|
+
if(J.bi(j)===0||J.d(j,"mqhrjp9m-06483fb")){s=1
|
|
140562
140562
|
break}n.b=!0
|
|
140563
140563
|
n.E()
|
|
140564
140564
|
p=2
|
|
@@ -140575,7 +140575,7 @@ case 2:return A.i(o.at(-1),r)}})
|
|
|
140575
140575
|
return A.k($async$AU,r)},
|
|
140576
140576
|
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
|
|
140577
140577
|
var $async$vE=A.h(function(a2,a3){if(a2===1){o.push(a3)
|
|
140578
|
-
s=p}for(;;)switch(s){case 0:if(B.b.u("
|
|
140578
|
+
s=p}for(;;)switch(s){case 0:if(B.b.u("mqhrjp9m-06483fb").length===0||n.c){s=1
|
|
140579
140579
|
break}n.c=!0
|
|
140580
140580
|
n.E()
|
|
140581
140581
|
p=4
|
|
@@ -202,12 +202,13 @@ function buildCompletionDecisionPrompt({
|
|
|
202
202
|
'Schema: {"status":"continue|complete|blocked","reason":"short concrete reason"}',
|
|
203
203
|
'Rules:',
|
|
204
204
|
'- Use "continue" whenever any safe next step remains in this same run.',
|
|
205
|
-
'- Use "complete"
|
|
206
|
-
'- Use "blocked"
|
|
205
|
+
'- Use "complete" when the requested outcome is achieved, already done, or a no-op because there is nothing matching the request to change, and the latest draft is the finished user-facing answer.',
|
|
206
|
+
'- Use "blocked" when a specific external dependency, missing user input, permission outside this run, or unavailable required capability makes the task impossible in this run and the latest draft is the blocker reply.',
|
|
207
207
|
'- If the latest draft asks the user for a missing required value, confirmation, or choice needed to proceed, use "blocked" so the run waits instead of repeating the same ask.',
|
|
208
208
|
'- A progress note, next-step note, apology, plan, or promise to investigate is "continue", not "complete".',
|
|
209
209
|
'- A single failed tool attempt is not blocked if another safe retry, verification step, or alternative path remains.',
|
|
210
210
|
'- A tool-specific API error, timeout, rate limit, or missing result inside this run is usually "continue", not "blocked", if any other available tool could still make progress.',
|
|
211
|
+
'- Repeated read-only inspection that has already established the relevant object is absent or unchanged is not progress. Accept a concise complete/blocker reply instead of requiring more searching.',
|
|
211
212
|
`- If completion_confidence_required is ${goalContext.effectiveCompletionConfidence} and the latest draft depends on unverified assumptions, use "continue" so the run can gather evidence, inspect state, or narrow the reply.`,
|
|
212
213
|
triggerSource === 'messaging' && messagingSent
|
|
213
214
|
? '- A final reply was already delivered via send_message. Use "complete" unless concrete task work remains.'
|
|
@@ -125,6 +125,7 @@ const {
|
|
|
125
125
|
isReadOnlyToolCall: isReadOnlyToolCallImpl,
|
|
126
126
|
} = require('./tool_dispatch');
|
|
127
127
|
const {
|
|
128
|
+
buildReadOnlyChurnGuidance,
|
|
128
129
|
isProgressToolCall,
|
|
129
130
|
} = require('./progress_classification');
|
|
130
131
|
const {
|
|
@@ -1174,19 +1175,10 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
|
|
|
1174
1175
|
if (analysis.mode === 'execute' || analysis.mode === 'plan_execute') {
|
|
1175
1176
|
const readOnlyCount = engine.getRunMeta(runId)?.consecutiveReadOnlyIterations || 0;
|
|
1176
1177
|
if (readOnlyCount >= 3) {
|
|
1177
|
-
const urgency = readOnlyCount >= 6 ? 'CRITICAL' : 'ACTION REQUIRED';
|
|
1178
1178
|
const alreadyRead = summarizeReadTargets(toolExecutions);
|
|
1179
1179
|
messages.push({
|
|
1180
1180
|
role: 'system',
|
|
1181
|
-
content:
|
|
1182
|
-
`${urgency} — ${readOnlyCount} consecutive read-only turns with no concrete action.`,
|
|
1183
|
-
alreadyRead
|
|
1184
|
-
? `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.`
|
|
1185
|
-
: 'Do not re-read or re-search anything already in this conversation.',
|
|
1186
|
-
'If you are repeatedly extracting evidence through low-level commands, switch to the available file/search/edit tools over the shared workspace.',
|
|
1187
|
-
'Act on what you already know now: edit files, run a state-changing command, create the branch/PR, or send the result.',
|
|
1188
|
-
'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.',
|
|
1189
|
-
].join(' '),
|
|
1181
|
+
content: buildReadOnlyChurnGuidance({ readOnlyCount, alreadyRead }),
|
|
1190
1182
|
});
|
|
1191
1183
|
}
|
|
1192
1184
|
}
|
|
@@ -172,7 +172,22 @@ function isProgressToolCall(toolName, toolArgs = {}) {
|
|
|
172
172
|
return true;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
function buildReadOnlyChurnGuidance({ readOnlyCount = 0, alreadyRead = '' } = {}) {
|
|
176
|
+
const count = Math.max(0, Number(readOnlyCount) || 0);
|
|
177
|
+
const urgency = count >= 6 ? 'CRITICAL' : 'ACTION REQUIRED';
|
|
178
|
+
return [
|
|
179
|
+
`${urgency}: ${count} consecutive read-only turns with no concrete action.`,
|
|
180
|
+
alreadyRead
|
|
181
|
+
? `You have already read/searched: ${alreadyRead}. Their output is in this conversation above, so do not read or search them again.`
|
|
182
|
+
: 'Do not re-read or re-search anything already in this conversation.',
|
|
183
|
+
'Decide from the evidence you have now.',
|
|
184
|
+
'If the requested work is already done, no matching target exists, or the available tools cannot make the change, call task_complete with that truthful final answer or blocker.',
|
|
185
|
+
'If exactly one concrete safe action remains, take that action now. Otherwise finish; more poking around is not progress.',
|
|
186
|
+
].join(' ');
|
|
187
|
+
}
|
|
188
|
+
|
|
175
189
|
module.exports = {
|
|
190
|
+
buildReadOnlyChurnGuidance,
|
|
176
191
|
isClearlyReadOnlyShellCommand,
|
|
177
192
|
isProgressToolCall,
|
|
178
193
|
};
|
|
@@ -125,6 +125,7 @@ Use specific identifiers. If a tool distinguishes message IDs, draft IDs, attach
|
|
|
125
125
|
If the user asks a broad personal-information question such as "what are my todos?", "what did I miss?", or "find everything about X", search across the relevant available private sources in parallel when possible: memory/session context, official integrations, files, email/calendar tools, and MCP tools.
|
|
126
126
|
For coding or system debugging, inspect the code/configuration first, then form a hypothesis. Do not overfit to a single log line if code or environment evidence suggests another path.
|
|
127
127
|
For long tasks, give brief progress only when the user is waiting or the operation is slow. Avoid announcing every internal step.
|
|
128
|
+
When evidence shows the requested work is already done, there is no matching target to change, the available tools cannot perform the required action, or the task now needs outside input, stop cleanly with that result. A truthful no-op, not-found result, or concrete blocker is a valid finish; do not keep searching just to look busy.
|
|
128
129
|
|
|
129
130
|
COMPLEX TASKS
|
|
130
131
|
For anything multi-step or open-ended, plan before you sprint. Break the goal into concrete steps and, for a real job, keep a running checklist (a task or a working file) that tracks done versus pending so nothing quietly falls off the list.
|
|
@@ -185,13 +186,13 @@ Prefer direct file reads and targeted commands over broad log-grep rituals. For
|
|
|
185
186
|
|
|
186
187
|
ERROR RECOVERY
|
|
187
188
|
When a tool call or command fails, first check whether the failure came from wrong arguments, bad assumptions, missing dependencies, environment mismatch, permissions, or transient external state. Fix the likely cause and try again with a different method when one exists.
|
|
188
|
-
Do not stop at the first failed approach if a reasonable fallback exists.
|
|
189
|
+
Do not stop at the first failed approach if a reasonable fallback exists. Once the viable alternatives are exhausted, or the evidence already proves the task is impossible, already done, or a no-op, stop and report that result instead of continuing to poke around.
|
|
189
190
|
|
|
190
191
|
MESSAGING CLAIMS
|
|
191
192
|
Do not claim a messaging platform is blocked, disconnected, receive-only, or unable to send unless a messaging tool or capability check in this run actually showed that failure. If send_message succeeded, do not describe outbound delivery as blocked.
|
|
192
193
|
For any outbound action claim (message sent, email sent, call placed, deletion request submitted, or "already done" status), require run evidence from a successful outbound tool call in this run. If that evidence is missing, provide a draft or a clear "not sent yet" status instead of claiming completion.
|
|
193
194
|
In messaging conversations, do not ask the user to resend, restate, or repeat the same task just because a reply was blank or a transient internal failure happened. Continue from the existing thread context and run evidence. Only ask the user for something when a specific external input, permission, or configuration change is genuinely required.
|
|
194
|
-
In a live messaging conversation, do not send placeholder or meta replies such as "no action required", "what do you need?", "I'm here", or similar presence checks when the user already gave a task. Either continue the task silently or send a concrete answer, outcome, or blocker tied to that request.
|
|
195
|
+
In a live messaging conversation, do not send placeholder or meta replies such as "no action required", "what do you need?", "I'm here", or similar presence checks when the user already gave a task. Do not drip-feed internal status like "still poking around" unless it materially helps the user. Either continue the task silently or send a concrete answer, outcome, or blocker tied to that request.
|
|
195
196
|
Messages to the user in the active conversation do not need extra confirmation. Messages, calls, emails, or edits that affect other people or external shared systems require a clear current-session request or confirmation before sending or committing them. Draft first when the user asks you to write on their behalf but has not explicitly said to send.
|
|
196
197
|
When drafting on behalf of the user, match their likely voice from available context and relationship to the recipient. Keep the draft editable and do not send it until the user approves, unless the current message explicitly says to send.
|
|
197
198
|
If the user approves a previously shown draft, send that draft rather than silently rewriting it.
|
|
@@ -1468,18 +1468,19 @@ function getAvailableTools(app, options = {}) {
|
|
|
1468
1468
|
];
|
|
1469
1469
|
|
|
1470
1470
|
// task_complete — always available. Lets the AI explicitly signal that
|
|
1471
|
-
// the task is
|
|
1472
|
-
// the opaque directAnswerEligible heuristic
|
|
1473
|
-
// mechanism and gives the AI real agency over
|
|
1471
|
+
// the task is finished, already a no-op, or blocked, and provide the
|
|
1472
|
+
// final response. This replaces the opaque directAnswerEligible heuristic
|
|
1473
|
+
// as the primary loop-exit mechanism and gives the AI real agency over
|
|
1474
|
+
// when it's finished.
|
|
1474
1475
|
tools.push({
|
|
1475
1476
|
name: 'task_complete',
|
|
1476
|
-
description: 'Signal that the task is
|
|
1477
|
+
description: 'Signal that the task is terminal and provide the final response. Valid terminal states include: completed successfully, already done/no matching change needed, or impossible/blocked with concrete evidence. Call this exactly once when you have the final user-ready answer. Do NOT call it if you still have a safe useful step to take, unverified claims, unresolved tool failures with viable alternatives, or confidence below the current run requirement.',
|
|
1477
1478
|
parameters: {
|
|
1478
1479
|
type: 'object',
|
|
1479
1480
|
properties: {
|
|
1480
1481
|
message: {
|
|
1481
1482
|
type: 'string',
|
|
1482
|
-
description: 'Your complete final response to the user. Write it as if it were your reply
|
|
1483
|
+
description: 'Your complete final response to the user. Write it as if it were your reply, including a concise already-done/no-op or blocker explanation when that is the truthful terminal result.'
|
|
1483
1484
|
},
|
|
1484
1485
|
confidence: {
|
|
1485
1486
|
type: 'string',
|