jinzd-ai-cli 0.4.260 → 0.4.261
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/dist/{batch-LBMJWMMO.js → batch-YUPAC4CK.js} +2 -2
- package/dist/{chunk-KRENSXPC.js → chunk-323S2X5I.js} +1 -1
- package/dist/{chunk-VJP2GLW5.js → chunk-GC4KA5LF.js} +1 -1
- package/dist/{chunk-K6WMQBUP.js → chunk-H6FND2UG.js} +1 -1
- package/dist/{chunk-3TE7ZWO5.js → chunk-HGTDI5ME.js} +1 -1
- package/dist/{chunk-NEYNE6UE.js → chunk-HU3IYBU5.js} +11 -9
- package/dist/{chunk-XTA3LSPQ.js → chunk-KFNQESEG.js} +1 -1
- package/dist/{chunk-HBR33J6J.js → chunk-KQQHMGK7.js} +1 -1
- package/dist/{chunk-63M2ELJS.js → chunk-NOB2OPQI.js} +4 -4
- package/dist/{chunk-U2HN3EW6.js → chunk-OIOTHBDB.js} +1 -1
- package/dist/{chunk-26C6YZ3A.js → chunk-R6DXWVVN.js} +1 -1
- package/dist/{chunk-CLJKNKUN.js → chunk-T7R7ILYT.js} +1 -1
- package/dist/{chunk-Y7UZSFGS.js → chunk-W5XUZYQE.js} +1 -1
- package/dist/{chunk-FCPYMBTA.js → chunk-XZNRZGG2.js} +57 -25
- package/dist/{chunk-AAWV4BP4.js → chunk-YXMBP567.js} +2 -2
- package/dist/{chunk-2BGNEVS5.js → chunk-Z5TCAE4L.js} +4 -4
- package/dist/{ci-PSA7F4EI.js → ci-FX26BNT2.js} +6 -6
- package/dist/{ci-format-WAHEZZMY.js → ci-format-GEWIAIZD.js} +2 -2
- package/dist/{constants-C55LGUR7.js → constants-YN4B6C7B.js} +1 -1
- package/dist/{doctor-cli-YANDJBHC.js → doctor-cli-PXGXZYQB.js} +6 -6
- package/dist/electron-server.js +69 -35
- package/dist/{hub-CBOC3TT3.js → hub-RCANK6SK.js} +1 -1
- package/dist/index.js +86 -39
- package/dist/{persistent-memory-DUFOZTDV.js → persistent-memory-P3COUZZM.js} +2 -2
- package/dist/{persistent-memory-KEYVKD54.js → persistent-memory-UARSSYAA.js} +2 -2
- package/dist/{pr-T6KCK5DT.js → pr-7LQTAUFK.js} +6 -6
- package/dist/{run-tests-S2RLPMCR.js → run-tests-7RYU4BK5.js} +2 -2
- package/dist/{run-tests-K43DLTA3.js → run-tests-YNHESHYY.js} +2 -2
- package/dist/{server-SV3TV5BJ.js → server-SSAWGNT7.js} +13 -13
- package/dist/{server-GTRCCOXN.js → server-YZ37TL46.js} +6 -6
- package/dist/{task-orchestrator-DW5AWW7J.js → task-orchestrator-ZFL4E6NZ.js} +6 -6
- package/dist/{usage-BP442V2Q.js → usage-PDKM7J75.js} +2 -2
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-H6FND2UG.js";
|
|
5
5
|
import "./chunk-TU3L3PW7.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-323S2X5I.js";
|
|
7
7
|
import {
|
|
8
8
|
atomicWriteFileSync
|
|
9
9
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
searchPersistentMemories,
|
|
8
8
|
touchMemoryReferences,
|
|
9
9
|
updateMemoryEntry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HGTDI5ME.js";
|
|
11
11
|
import {
|
|
12
12
|
indexProject
|
|
13
13
|
} from "./chunk-GLSR2NR3.js";
|
|
@@ -23,13 +23,13 @@ import {
|
|
|
23
23
|
runHook,
|
|
24
24
|
runLifecycleHooks,
|
|
25
25
|
runTool
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-W5XUZYQE.js";
|
|
27
27
|
import {
|
|
28
28
|
buildTruncatedArgumentsError,
|
|
29
29
|
getDangerLevel,
|
|
30
30
|
isFileWriteTool,
|
|
31
31
|
runLeanAgentLoop
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-XZNRZGG2.js";
|
|
33
33
|
import {
|
|
34
34
|
EnvLoader,
|
|
35
35
|
NetworkError,
|
|
@@ -40,14 +40,14 @@ import {
|
|
|
40
40
|
} from "./chunk-4BKXL7SM.js";
|
|
41
41
|
import {
|
|
42
42
|
runTestsTool
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-KQQHMGK7.js";
|
|
44
44
|
import {
|
|
45
45
|
CONFIG_DIR_NAME,
|
|
46
46
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
47
47
|
SUBAGENT_ALLOWED_TOOLS,
|
|
48
48
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
49
49
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-323S2X5I.js";
|
|
51
51
|
import {
|
|
52
52
|
loadChatIndex,
|
|
53
53
|
searchChatMemory
|
|
@@ -169,9 +169,9 @@ function buildWrappedCommand(command, id, isWindows) {
|
|
|
169
169
|
if (!isWindows) {
|
|
170
170
|
return `echo "${markerStart}"; ${command}; echo "${markerEnd}:$?"`;
|
|
171
171
|
}
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
return
|
|
172
|
+
const b64 = Buffer.from(command, "utf-8").toString("base64");
|
|
173
|
+
const decoded = `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${b64}'))`;
|
|
174
|
+
return `${WIN_UTF8_PREAMBLE} Write-Output "${markerStart}"; $global:LASTEXITCODE = 0; Invoke-Expression (${decoded}); $__ok = $?; $__ec = $LASTEXITCODE; $__code = if ($null -ne $__ec -and $__ec -ne 0) { $__ec } elseif ($__ok) { 0 } else { 1 }; Write-Output "${markerEnd}:$__code"`;
|
|
175
175
|
}
|
|
176
176
|
async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
177
177
|
let entry = pool.get(sessionKey);
|
|
@@ -3477,7 +3477,9 @@ Note: Path can be absolute or relative to cwd.`,
|
|
|
3477
3477
|
}
|
|
3478
3478
|
const lines = [];
|
|
3479
3479
|
if (anyFailed && stopOnError) {
|
|
3480
|
-
|
|
3480
|
+
const failedIdx = reports.find((r) => !r.ok)?.index;
|
|
3481
|
+
const failedLabel = failedIdx != null ? `#${failedIdx + 1}` : "an edit";
|
|
3482
|
+
lines.push(`ERROR: Batch edit aborted \u2014 ${appliedCount}/${edits.length} applied, then edit ${failedLabel} failed. No changes written (stop_on_error=true).`);
|
|
3481
3483
|
} else if (anyFailed) {
|
|
3482
3484
|
lines.push(`Partial success: ${appliedCount}/${edits.length} edits applied to ${filePath} (stop_on_error=false).`);
|
|
3483
3485
|
} else {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ProviderRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OIOTHBDB.js";
|
|
5
5
|
import {
|
|
6
6
|
ConfigManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-H6FND2UG.js";
|
|
8
8
|
import {
|
|
9
9
|
getActivePluginAssets,
|
|
10
10
|
getPendingHookTrust,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
listHooks,
|
|
15
15
|
listInstalledPlugins,
|
|
16
16
|
resetStats
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-W5XUZYQE.js";
|
|
18
18
|
import {
|
|
19
19
|
getGitRoot
|
|
20
20
|
} from "./chunk-HOSJZMQS.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
MCP_PROJECT_CONFIG_NAME,
|
|
27
27
|
MEMORY_FILE_NAME,
|
|
28
28
|
VERSION
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-323S2X5I.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -188,6 +188,52 @@ function buildWriteRoundReminder(writtenCount) {
|
|
|
188
188
|
You have successfully called write_file ${writtenCount} time(s) so far in this turn. If there are more files to write, call write_file NOW for the next file. Do NOT produce a text summary until ALL files have been written via tool calls.`;
|
|
189
189
|
}
|
|
190
190
|
var HALLUCINATION_CORRECTION_MESSAGE = "You did NOT actually call the write_file tool \u2014 the file was NOT created! Please immediately use the write_file tool via the function calling API to perform the actual file write. Do NOT describe file content in text \u2014 you MUST invoke write_file through the tool_calls mechanism.";
|
|
191
|
+
var ACTION_WORD_RE = /(?:已[生保写创]|saved|written|created|完成.*(?:写入|保存|创建|生成)|输出|file\s+(?:saved|written|created))/i;
|
|
192
|
+
var CLAUSE_BOUNDARY_RE = /[。.!?!?;;,,]/;
|
|
193
|
+
var LIST_LINE_RE = /^\s*(?:[-*+]|\d+[.)]|\|)/;
|
|
194
|
+
function hasWriteIntentNear(content, pathStart, pathEnd) {
|
|
195
|
+
const lineStart = content.lastIndexOf("\n", pathStart - 1) + 1;
|
|
196
|
+
const lineEndRaw = content.indexOf("\n", pathEnd);
|
|
197
|
+
const lineEnd = lineEndRaw === -1 ? content.length : lineEndRaw;
|
|
198
|
+
const currentLine = content.slice(lineStart, lineEnd);
|
|
199
|
+
const prevLineStart = lineStart === 0 ? 0 : content.lastIndexOf("\n", lineStart - 2) + 1;
|
|
200
|
+
const prevLine = lineStart === 0 ? "" : content.slice(prevLineStart, lineStart - 1);
|
|
201
|
+
const introColon = /[::]\s*$/.test(prevLine);
|
|
202
|
+
if (LIST_LINE_RE.test(currentLine) || introColon) {
|
|
203
|
+
let pos = pathStart;
|
|
204
|
+
let linesBack = 0;
|
|
205
|
+
while (linesBack < 9 && pos > 0) {
|
|
206
|
+
pos--;
|
|
207
|
+
if (content[pos] === "\n") linesBack++;
|
|
208
|
+
}
|
|
209
|
+
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
210
|
+
return ACTION_WORD_RE.test(content.slice(windowStart, lineEnd));
|
|
211
|
+
}
|
|
212
|
+
const boundaryBefore = (from) => {
|
|
213
|
+
for (let i = from - 1; i >= lineStart; i--) {
|
|
214
|
+
if (CLAUSE_BOUNDARY_RE.test(content[i] ?? "")) return i + 1;
|
|
215
|
+
}
|
|
216
|
+
return lineStart;
|
|
217
|
+
};
|
|
218
|
+
let clauseEnd = lineEnd;
|
|
219
|
+
for (let i = pathEnd; i < lineEnd; i++) {
|
|
220
|
+
if (CLAUSE_BOUNDARY_RE.test(content[i] ?? "")) {
|
|
221
|
+
clauseEnd = i + 1;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const isBareClause = (text2) => text2.replace(/`[^`\n]*`/g, "").replace(content.slice(pathStart, pathEnd), "").replace(/[\s'"“”‘’()()、,,。;;::+\-和与及]/g, "").length <= 2;
|
|
226
|
+
let start = boundaryBefore(pathStart);
|
|
227
|
+
let text = content.slice(start, clauseEnd);
|
|
228
|
+
if (ACTION_WORD_RE.test(text)) return true;
|
|
229
|
+
for (let step = 0; step < 6 && start > lineStart && isBareClause(text); step++) {
|
|
230
|
+
const prevEnd = start - 1;
|
|
231
|
+
start = boundaryBefore(prevEnd);
|
|
232
|
+
text = content.slice(start, prevEnd);
|
|
233
|
+
if (ACTION_WORD_RE.test(text)) return true;
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
191
237
|
function extractClaimedFilePaths(content) {
|
|
192
238
|
const paths = /* @__PURE__ */ new Set();
|
|
193
239
|
const add = (p) => {
|
|
@@ -195,36 +241,19 @@ function extractClaimedFilePaths(content) {
|
|
|
195
241
|
if (trimmed && /\.\w{1,6}$/.test(trimmed)) paths.add(trimmed);
|
|
196
242
|
};
|
|
197
243
|
let m;
|
|
198
|
-
const actionLineRe = /(?:已[生保写创]|saved|written|created|完成.*(?:写入|保存|创建|生成)|输出|file\s+(?:saved|written|created))/i;
|
|
199
244
|
const backtickRe = /`([^`\n]+?\.\w{1,6})`/g;
|
|
200
245
|
while ((m = backtickRe.exec(content)) !== null) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
while (linesBack < 9 && pos > 0) {
|
|
204
|
-
pos--;
|
|
205
|
-
if (content[pos] === "\n") linesBack++;
|
|
206
|
-
}
|
|
207
|
-
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
208
|
-
const lineEndIdx = content.indexOf("\n", m.index + m[0].length);
|
|
209
|
-
const window = content.slice(windowStart, lineEndIdx === -1 ? void 0 : lineEndIdx);
|
|
210
|
-
if (actionLineRe.test(window)) add(m[1]);
|
|
246
|
+
const pathStart = m.index + m[0].indexOf(m[1]);
|
|
247
|
+
if (hasWriteIntentNear(content, pathStart, pathStart + m[1].length)) add(m[1]);
|
|
211
248
|
}
|
|
212
|
-
const zhRe = /(?:已保存(?:到)?|已写入(?:到)?|已创建|已生成|文件路径[::]|保存为|写入到)\s*[`'”””]?([^\s`'”””,,。\n]
|
|
249
|
+
const zhRe = /(?:已保存(?:到)?|已写入(?:到)?|已创建|已生成|文件路径[::]|保存为|写入到)\s*[`'”””]?([^\s`'”””,,。\n]+\.\w{1,6})/g;
|
|
213
250
|
while ((m = zhRe.exec(content)) !== null) add(m[1]);
|
|
214
|
-
const enRe = /(?:saved|written|created)\s+(?:to|as|at)\s+[`'”]?([^\s`'”\n,]
|
|
251
|
+
const enRe = /(?:saved|written|created)\s+(?:to|as|at)\s+[`'”]?([^\s`'”\n,]+\.\w{1,6})/gi;
|
|
215
252
|
while ((m = enRe.exec(content)) !== null) add(m[1]);
|
|
216
253
|
const checkRe = /✅[^\n`]*?[`'”]?([^\s`'”\n,,。]+?\.\w{1,6})/g;
|
|
217
254
|
while ((m = checkRe.exec(content)) !== null) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
while (linesBack < 9 && pos > 0) {
|
|
221
|
-
pos--;
|
|
222
|
-
if (content[pos] === "\n") linesBack++;
|
|
223
|
-
}
|
|
224
|
-
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
225
|
-
const lineEndIdx = content.indexOf("\n", m.index + m[0].length);
|
|
226
|
-
const window = content.slice(windowStart, lineEndIdx === -1 ? void 0 : lineEndIdx);
|
|
227
|
-
if (actionLineRe.test(window)) add(m[1]);
|
|
255
|
+
const pathStart = m.index + m[0].lastIndexOf(m[1]);
|
|
256
|
+
if (hasWriteIntentNear(content, pathStart, pathStart + m[1].length)) add(m[1]);
|
|
228
257
|
}
|
|
229
258
|
return Array.from(paths);
|
|
230
259
|
}
|
|
@@ -337,7 +366,7 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
337
366
|
}
|
|
338
367
|
function buildPhantomCorrectionMessage(phantoms) {
|
|
339
368
|
const list = phantoms.map((p) => ` - ${p}`).join("\n");
|
|
340
|
-
return
|
|
369
|
+
return 'Your reply mentions the following file(s) alongside a "written / saved / created" claim, but no matching write_file or edit_file tool call was made in this turn:\n' + list + "\n\nIf you did intend to create or modify them, invoke write_file / edit_file NOW \u2014 they do not exist on disk yet, and you must not report the task as done until the tool calls return.\n\nIf you were only REFERENCING them (files you merely read, cited as examples, or named as prior art), then this was a false alarm: do NOT create them, do NOT overwrite anything. Simply restate your answer and say explicitly which of the listed paths you only read or cited. Creating a file that the user never asked for is worse than the false alarm.";
|
|
341
370
|
}
|
|
342
371
|
var DSML_PIPE_CLASS = "[|\\uFF5C\\u2502\\u2503\\u01C0]";
|
|
343
372
|
var PSEUDO_TOOL_CALL_PATTERNS = [
|
|
@@ -972,6 +1001,8 @@ async function runAgentLoop(host) {
|
|
|
972
1001
|
const freeRounds = new FreeRoundTracker();
|
|
973
1002
|
const roundToolHistory = [];
|
|
974
1003
|
const hasWriteTools = host.toolDefs.some((t) => t.name === "write_file" || t.name === "edit_file");
|
|
1004
|
+
let hallucinationRetries = 0;
|
|
1005
|
+
const MAX_HALLUCINATION_RETRIES = 2;
|
|
975
1006
|
for (let round = 0; round < maxToolRounds; round++) {
|
|
976
1007
|
if (host.signal?.aborted) return { reason: "aborted", usage };
|
|
977
1008
|
host.onRoundStart?.(round, maxToolRounds);
|
|
@@ -1009,7 +1040,8 @@ async function runAgentLoop(host) {
|
|
|
1009
1040
|
const phantomPaths = (coarseHallucination || alreadyWrote) && !host.planMode && hasWriteTools && content ? findPhantomClaims(content, extraMessages) : [];
|
|
1010
1041
|
const bashRanThisTurn = extractBashCommands(extraMessages).length > 0;
|
|
1011
1042
|
const coarseShouldFire = coarseHallucination && !bashRanThisTurn;
|
|
1012
|
-
if ((phantomPaths.length > 0 || coarseShouldFire) && round < maxToolRounds - 1) {
|
|
1043
|
+
if ((phantomPaths.length > 0 || coarseShouldFire) && round < maxToolRounds - 1 && hallucinationRetries < MAX_HALLUCINATION_RETRIES) {
|
|
1044
|
+
hallucinationRetries++;
|
|
1013
1045
|
host.onHallucinationRetry?.({ phantomPaths, round, alreadyRendered });
|
|
1014
1046
|
const correctionMsg = phantomPaths.length > 0 ? buildPhantomCorrectionMessage(phantomPaths) : HALLUCINATION_CORRECTION_MESSAGE;
|
|
1015
1047
|
const reasoningField = outcome.reasoningContent ? { reasoning_content: outcome.reasoningContent } : host.providerId === "deepseek" ? { reasoning_content: "" } : {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
truncateForPersist
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HU3IYBU5.js";
|
|
5
5
|
import {
|
|
6
6
|
APP_NAME,
|
|
7
7
|
CONFIG_DIR_NAME,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
MCP_PROTOCOL_VERSION,
|
|
12
12
|
MCP_TOOL_PREFIX,
|
|
13
13
|
VERSION
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-323S2X5I.js";
|
|
15
15
|
import {
|
|
16
16
|
atomicWriteFileSync
|
|
17
17
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-GC4KA5LF.js";
|
|
6
6
|
import {
|
|
7
7
|
buildReviewPrompt,
|
|
8
8
|
buildSecurityReviewPrompt,
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
} from "./chunk-HLWUDRBO.js";
|
|
11
11
|
import {
|
|
12
12
|
ProviderRegistry
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-OIOTHBDB.js";
|
|
14
14
|
import {
|
|
15
15
|
ConfigManager
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-H6FND2UG.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-323S2X5I.js";
|
|
20
20
|
|
|
21
21
|
// src/cli/ci.ts
|
|
22
22
|
import { execFileSync } from "child_process";
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
CI_COMMENT_MARKER,
|
|
4
4
|
countSeverity,
|
|
5
5
|
runCi
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-Z5TCAE4L.js";
|
|
7
|
+
import "./chunk-GC4KA5LF.js";
|
|
8
8
|
import "./chunk-HLWUDRBO.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-OIOTHBDB.js";
|
|
10
|
+
import "./chunk-H6FND2UG.js";
|
|
11
|
+
import "./chunk-XZNRZGG2.js";
|
|
12
12
|
import "./chunk-TU3L3PW7.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-323S2X5I.js";
|
|
14
14
|
import "./chunk-IW3Q7AE5.js";
|
|
15
15
|
export {
|
|
16
16
|
CI_COMMENT_MARKER,
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
formatDoctorReport,
|
|
4
4
|
runDoctorCli
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-NOB2OPQI.js";
|
|
6
|
+
import "./chunk-OIOTHBDB.js";
|
|
7
|
+
import "./chunk-H6FND2UG.js";
|
|
8
|
+
import "./chunk-W5XUZYQE.js";
|
|
9
|
+
import "./chunk-XZNRZGG2.js";
|
|
10
10
|
import "./chunk-TU3L3PW7.js";
|
|
11
11
|
import "./chunk-HOSJZMQS.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-323S2X5I.js";
|
|
13
13
|
import "./chunk-IW3Q7AE5.js";
|
|
14
14
|
export {
|
|
15
15
|
formatDoctorReport,
|
package/dist/electron-server.js
CHANGED
|
@@ -34,14 +34,14 @@ import {
|
|
|
34
34
|
touchMemoryReferences,
|
|
35
35
|
updateMemoryApproval,
|
|
36
36
|
updateMemoryEntry
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-T7R7ILYT.js";
|
|
38
38
|
import {
|
|
39
39
|
redactJson,
|
|
40
40
|
scanString
|
|
41
41
|
} from "./chunk-YVTASHS5.js";
|
|
42
42
|
import {
|
|
43
43
|
runTestsTool
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-KFNQESEG.js";
|
|
45
45
|
import {
|
|
46
46
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
47
47
|
APP_NAME,
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
SUBAGENT_MAX_ROUNDS_LIMIT,
|
|
74
74
|
VERSION,
|
|
75
75
|
buildUserIdentityPrompt
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-R6DXWVVN.js";
|
|
77
77
|
import {
|
|
78
78
|
hasSemanticIndex,
|
|
79
79
|
semanticSearch
|
|
@@ -1813,6 +1813,52 @@ CRITICAL \u2014 Batch file generation rules:
|
|
|
1813
1813
|
4. Only produce a text summary AFTER all write_file calls have been made and returned success.
|
|
1814
1814
|
5. The system compares every "file saved" claim against actual tool calls. Phantom claims trigger an automatic retry \u2014 do not waste rounds.`;
|
|
1815
1815
|
var HALLUCINATION_CORRECTION_MESSAGE = "You did NOT actually call the write_file tool \u2014 the file was NOT created! Please immediately use the write_file tool via the function calling API to perform the actual file write. Do NOT describe file content in text \u2014 you MUST invoke write_file through the tool_calls mechanism.";
|
|
1816
|
+
var ACTION_WORD_RE = /(?:已[生保写创]|saved|written|created|完成.*(?:写入|保存|创建|生成)|输出|file\s+(?:saved|written|created))/i;
|
|
1817
|
+
var CLAUSE_BOUNDARY_RE = /[。.!?!?;;,,]/;
|
|
1818
|
+
var LIST_LINE_RE = /^\s*(?:[-*+]|\d+[.)]|\|)/;
|
|
1819
|
+
function hasWriteIntentNear(content, pathStart, pathEnd) {
|
|
1820
|
+
const lineStart = content.lastIndexOf("\n", pathStart - 1) + 1;
|
|
1821
|
+
const lineEndRaw = content.indexOf("\n", pathEnd);
|
|
1822
|
+
const lineEnd = lineEndRaw === -1 ? content.length : lineEndRaw;
|
|
1823
|
+
const currentLine = content.slice(lineStart, lineEnd);
|
|
1824
|
+
const prevLineStart = lineStart === 0 ? 0 : content.lastIndexOf("\n", lineStart - 2) + 1;
|
|
1825
|
+
const prevLine = lineStart === 0 ? "" : content.slice(prevLineStart, lineStart - 1);
|
|
1826
|
+
const introColon = /[::]\s*$/.test(prevLine);
|
|
1827
|
+
if (LIST_LINE_RE.test(currentLine) || introColon) {
|
|
1828
|
+
let pos = pathStart;
|
|
1829
|
+
let linesBack = 0;
|
|
1830
|
+
while (linesBack < 9 && pos > 0) {
|
|
1831
|
+
pos--;
|
|
1832
|
+
if (content[pos] === "\n") linesBack++;
|
|
1833
|
+
}
|
|
1834
|
+
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
1835
|
+
return ACTION_WORD_RE.test(content.slice(windowStart, lineEnd));
|
|
1836
|
+
}
|
|
1837
|
+
const boundaryBefore = (from) => {
|
|
1838
|
+
for (let i = from - 1; i >= lineStart; i--) {
|
|
1839
|
+
if (CLAUSE_BOUNDARY_RE.test(content[i] ?? "")) return i + 1;
|
|
1840
|
+
}
|
|
1841
|
+
return lineStart;
|
|
1842
|
+
};
|
|
1843
|
+
let clauseEnd = lineEnd;
|
|
1844
|
+
for (let i = pathEnd; i < lineEnd; i++) {
|
|
1845
|
+
if (CLAUSE_BOUNDARY_RE.test(content[i] ?? "")) {
|
|
1846
|
+
clauseEnd = i + 1;
|
|
1847
|
+
break;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
const isBareClause = (text2) => text2.replace(/`[^`\n]*`/g, "").replace(content.slice(pathStart, pathEnd), "").replace(/[\s'"“”‘’()()、,,。;;::+\-和与及]/g, "").length <= 2;
|
|
1851
|
+
let start = boundaryBefore(pathStart);
|
|
1852
|
+
let text = content.slice(start, clauseEnd);
|
|
1853
|
+
if (ACTION_WORD_RE.test(text)) return true;
|
|
1854
|
+
for (let step = 0; step < 6 && start > lineStart && isBareClause(text); step++) {
|
|
1855
|
+
const prevEnd = start - 1;
|
|
1856
|
+
start = boundaryBefore(prevEnd);
|
|
1857
|
+
text = content.slice(start, prevEnd);
|
|
1858
|
+
if (ACTION_WORD_RE.test(text)) return true;
|
|
1859
|
+
}
|
|
1860
|
+
return false;
|
|
1861
|
+
}
|
|
1816
1862
|
function extractClaimedFilePaths(content) {
|
|
1817
1863
|
const paths = /* @__PURE__ */ new Set();
|
|
1818
1864
|
const add = (p) => {
|
|
@@ -1820,36 +1866,19 @@ function extractClaimedFilePaths(content) {
|
|
|
1820
1866
|
if (trimmed && /\.\w{1,6}$/.test(trimmed)) paths.add(trimmed);
|
|
1821
1867
|
};
|
|
1822
1868
|
let m;
|
|
1823
|
-
const actionLineRe = /(?:已[生保写创]|saved|written|created|完成.*(?:写入|保存|创建|生成)|输出|file\s+(?:saved|written|created))/i;
|
|
1824
1869
|
const backtickRe = /`([^`\n]+?\.\w{1,6})`/g;
|
|
1825
1870
|
while ((m = backtickRe.exec(content)) !== null) {
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
while (linesBack < 9 && pos > 0) {
|
|
1829
|
-
pos--;
|
|
1830
|
-
if (content[pos] === "\n") linesBack++;
|
|
1831
|
-
}
|
|
1832
|
-
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
1833
|
-
const lineEndIdx = content.indexOf("\n", m.index + m[0].length);
|
|
1834
|
-
const window = content.slice(windowStart, lineEndIdx === -1 ? void 0 : lineEndIdx);
|
|
1835
|
-
if (actionLineRe.test(window)) add(m[1]);
|
|
1871
|
+
const pathStart = m.index + m[0].indexOf(m[1]);
|
|
1872
|
+
if (hasWriteIntentNear(content, pathStart, pathStart + m[1].length)) add(m[1]);
|
|
1836
1873
|
}
|
|
1837
|
-
const zhRe = /(?:已保存(?:到)?|已写入(?:到)?|已创建|已生成|文件路径[::]|保存为|写入到)\s*[`'”””]?([^\s`'”””,,。\n]
|
|
1874
|
+
const zhRe = /(?:已保存(?:到)?|已写入(?:到)?|已创建|已生成|文件路径[::]|保存为|写入到)\s*[`'”””]?([^\s`'”””,,。\n]+\.\w{1,6})/g;
|
|
1838
1875
|
while ((m = zhRe.exec(content)) !== null) add(m[1]);
|
|
1839
|
-
const enRe = /(?:saved|written|created)\s+(?:to|as|at)\s+[`'”]?([^\s`'”\n,]
|
|
1876
|
+
const enRe = /(?:saved|written|created)\s+(?:to|as|at)\s+[`'”]?([^\s`'”\n,]+\.\w{1,6})/gi;
|
|
1840
1877
|
while ((m = enRe.exec(content)) !== null) add(m[1]);
|
|
1841
1878
|
const checkRe = /✅[^\n`]*?[`'”]?([^\s`'”\n,,。]+?\.\w{1,6})/g;
|
|
1842
1879
|
while ((m = checkRe.exec(content)) !== null) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
while (linesBack < 9 && pos > 0) {
|
|
1846
|
-
pos--;
|
|
1847
|
-
if (content[pos] === "\n") linesBack++;
|
|
1848
|
-
}
|
|
1849
|
-
const windowStart = pos === 0 ? 0 : pos + 1;
|
|
1850
|
-
const lineEndIdx = content.indexOf("\n", m.index + m[0].length);
|
|
1851
|
-
const window = content.slice(windowStart, lineEndIdx === -1 ? void 0 : lineEndIdx);
|
|
1852
|
-
if (actionLineRe.test(window)) add(m[1]);
|
|
1880
|
+
const pathStart = m.index + m[0].lastIndexOf(m[1]);
|
|
1881
|
+
if (hasWriteIntentNear(content, pathStart, pathStart + m[1].length)) add(m[1]);
|
|
1853
1882
|
}
|
|
1854
1883
|
return Array.from(paths);
|
|
1855
1884
|
}
|
|
@@ -1962,7 +1991,7 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
1962
1991
|
}
|
|
1963
1992
|
function buildPhantomCorrectionMessage(phantoms) {
|
|
1964
1993
|
const list = phantoms.map((p) => ` - ${p}`).join("\n");
|
|
1965
|
-
return
|
|
1994
|
+
return 'Your reply mentions the following file(s) alongside a "written / saved / created" claim, but no matching write_file or edit_file tool call was made in this turn:\n' + list + "\n\nIf you did intend to create or modify them, invoke write_file / edit_file NOW \u2014 they do not exist on disk yet, and you must not report the task as done until the tool calls return.\n\nIf you were only REFERENCING them (files you merely read, cited as examples, or named as prior art), then this was a false alarm: do NOT create them, do NOT overwrite anything. Simply restate your answer and say explicitly which of the listed paths you only read or cited. Creating a file that the user never asked for is worse than the false alarm.";
|
|
1966
1995
|
}
|
|
1967
1996
|
var DSML_PIPE_CLASS = "[|\\uFF5C\\u2502\\u2503\\u01C0]";
|
|
1968
1997
|
var PSEUDO_TOOL_CALL_PATTERNS = [
|
|
@@ -2597,6 +2626,8 @@ async function runAgentLoop(host) {
|
|
|
2597
2626
|
const freeRounds = new FreeRoundTracker();
|
|
2598
2627
|
const roundToolHistory = [];
|
|
2599
2628
|
const hasWriteTools = host.toolDefs.some((t) => t.name === "write_file" || t.name === "edit_file");
|
|
2629
|
+
let hallucinationRetries = 0;
|
|
2630
|
+
const MAX_HALLUCINATION_RETRIES = 2;
|
|
2600
2631
|
for (let round = 0; round < maxToolRounds; round++) {
|
|
2601
2632
|
if (host.signal?.aborted) return { reason: "aborted", usage };
|
|
2602
2633
|
host.onRoundStart?.(round, maxToolRounds);
|
|
@@ -2634,7 +2665,8 @@ async function runAgentLoop(host) {
|
|
|
2634
2665
|
const phantomPaths = (coarseHallucination || alreadyWrote) && !host.planMode && hasWriteTools && content ? findPhantomClaims(content, extraMessages) : [];
|
|
2635
2666
|
const bashRanThisTurn = extractBashCommands(extraMessages).length > 0;
|
|
2636
2667
|
const coarseShouldFire = coarseHallucination && !bashRanThisTurn;
|
|
2637
|
-
if ((phantomPaths.length > 0 || coarseShouldFire) && round < maxToolRounds - 1) {
|
|
2668
|
+
if ((phantomPaths.length > 0 || coarseShouldFire) && round < maxToolRounds - 1 && hallucinationRetries < MAX_HALLUCINATION_RETRIES) {
|
|
2669
|
+
hallucinationRetries++;
|
|
2638
2670
|
host.onHallucinationRetry?.({ phantomPaths, round, alreadyRendered });
|
|
2639
2671
|
const correctionMsg = phantomPaths.length > 0 ? buildPhantomCorrectionMessage(phantomPaths) : HALLUCINATION_CORRECTION_MESSAGE;
|
|
2640
2672
|
const reasoningField = outcome.reasoningContent ? { reasoning_content: outcome.reasoningContent } : host.providerId === "deepseek" ? { reasoning_content: "" } : {};
|
|
@@ -5081,9 +5113,9 @@ function buildWrappedCommand(command, id, isWindows) {
|
|
|
5081
5113
|
if (!isWindows) {
|
|
5082
5114
|
return `echo "${markerStart}"; ${command}; echo "${markerEnd}:$?"`;
|
|
5083
5115
|
}
|
|
5084
|
-
const
|
|
5085
|
-
const
|
|
5086
|
-
return
|
|
5116
|
+
const b64 = Buffer.from(command, "utf-8").toString("base64");
|
|
5117
|
+
const decoded = `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${b64}'))`;
|
|
5118
|
+
return `${WIN_UTF8_PREAMBLE} Write-Output "${markerStart}"; $global:LASTEXITCODE = 0; Invoke-Expression (${decoded}); $__ok = $?; $__ec = $LASTEXITCODE; $__code = if ($null -ne $__ec -and $__ec -ne 0) { $__ec } elseif ($__ok) { 0 } else { 1 }; Write-Output "${markerEnd}:$__code"`;
|
|
5087
5119
|
}
|
|
5088
5120
|
async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
5089
5121
|
let entry = pool.get(sessionKey);
|
|
@@ -8446,7 +8478,9 @@ Note: Path can be absolute or relative to cwd.`,
|
|
|
8446
8478
|
}
|
|
8447
8479
|
const lines = [];
|
|
8448
8480
|
if (anyFailed && stopOnError) {
|
|
8449
|
-
|
|
8481
|
+
const failedIdx = reports.find((r) => !r.ok)?.index;
|
|
8482
|
+
const failedLabel = failedIdx != null ? `#${failedIdx + 1}` : "an edit";
|
|
8483
|
+
lines.push(`ERROR: Batch edit aborted \u2014 ${appliedCount}/${edits.length} applied, then edit ${failedLabel} failed. No changes written (stop_on_error=true).`);
|
|
8450
8484
|
} else if (anyFailed) {
|
|
8451
8485
|
lines.push(`Partial success: ${appliedCount}/${edits.length} edits applied to ${filePath} (stop_on_error=false).`);
|
|
8452
8486
|
} else {
|
|
@@ -15335,7 +15369,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
15335
15369
|
Cost: ${formatCost(cost)}` : "";
|
|
15336
15370
|
let memoryLine = "";
|
|
15337
15371
|
try {
|
|
15338
|
-
const { countPendingMemories } = await import("./persistent-memory-
|
|
15372
|
+
const { countPendingMemories } = await import("./persistent-memory-P3COUZZM.js");
|
|
15339
15373
|
const pending = countPendingMemories(ctx.config.getConfigDir());
|
|
15340
15374
|
if (pending > 0) memoryLine = `
|
|
15341
15375
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -16144,7 +16178,7 @@ async function handleSecurityReview(args, ctx) {
|
|
|
16144
16178
|
async function handleTest(args, ctx) {
|
|
16145
16179
|
ctx.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
16146
16180
|
try {
|
|
16147
|
-
const { executeTests } = await import("./run-tests-
|
|
16181
|
+
const { executeTests } = await import("./run-tests-7RYU4BK5.js");
|
|
16148
16182
|
const argStr = args.join(" ").trim();
|
|
16149
16183
|
let testArgs = {};
|
|
16150
16184
|
if (argStr) {
|
|
@@ -16408,7 +16442,7 @@ async function handleMemory(args, ctx) {
|
|
|
16408
16442
|
ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
|
|
16409
16443
|
} else if (sub === "export") {
|
|
16410
16444
|
if (args[1] === "md") {
|
|
16411
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
16445
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-P3COUZZM.js");
|
|
16412
16446
|
ctx.send({
|
|
16413
16447
|
type: "export_data",
|
|
16414
16448
|
format: "md",
|