reasonix 0.46.0 → 0.47.0
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/README.md +64 -12
- package/README.zh-CN.md +54 -9
- package/dashboard/dist/app.js +293 -66
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{acp-LGBLHBKY.js → acp-QK3DMC53.js} +22 -22
- package/dist/cli/chat-VV5UWY4V.js +51 -0
- package/dist/cli/{chunk-AVFXO2EZ.js → chunk-24A7FHGJ.js} +148 -16
- package/dist/cli/chunk-24A7FHGJ.js.map +1 -0
- package/dist/cli/chunk-25T6CVUP.js +0 -0
- package/dist/cli/chunk-2UQP6H6T.js +0 -0
- package/dist/cli/chunk-5QCB62C4.js +0 -0
- package/dist/cli/{chunk-YY227BIQ.js → chunk-6J6BSUCR.js} +2 -2
- package/dist/cli/chunk-6OWJV3YW.js +0 -0
- package/dist/cli/{chunk-A3TSSDS2.js → chunk-BWYVFFKR.js} +2 -2
- package/dist/cli/{chunk-C53JQES5.js → chunk-BYYVYJDX.js} +3 -3
- package/dist/cli/{chunk-HNXDZGC6.js → chunk-CI2PF5QX.js} +2 -2
- package/dist/cli/{chunk-GTZTQNX5.js → chunk-COWPEX54.js} +19 -9
- package/dist/cli/chunk-COWPEX54.js.map +1 -0
- package/dist/cli/{chunk-QJDDIK3Z.js → chunk-E5WCLUIU.js} +2 -2
- package/dist/cli/{chunk-NVURFF27.js → chunk-EQATK2L2.js} +2 -2
- package/dist/cli/{chunk-HKWSPKMU.js → chunk-FDKOUJKZ.js} +8 -8
- package/dist/cli/chunk-FEZK652I.js +0 -0
- package/dist/cli/{chunk-TEUDEGX2.js → chunk-FY4S7TJZ.js} +19 -5
- package/dist/cli/chunk-FY4S7TJZ.js.map +1 -0
- package/dist/cli/{chunk-RDRC3XDT.js → chunk-GDKB2PPK.js} +2 -2
- package/dist/cli/{chunk-XSU4QVFW.js → chunk-HIYTRCSW.js} +27 -14
- package/dist/cli/chunk-HIYTRCSW.js.map +1 -0
- package/dist/cli/{chunk-WL6SNQ5T.js → chunk-ICAFSZHS.js} +307 -114
- package/dist/cli/chunk-ICAFSZHS.js.map +1 -0
- package/dist/cli/{chunk-KQU2TYIL.js → chunk-ICSYGIPN.js} +1916 -1098
- package/dist/cli/chunk-ICSYGIPN.js.map +1 -0
- package/dist/cli/chunk-J5XJHLWM.js +0 -0
- package/dist/cli/chunk-JMBMLOBP.js +0 -0
- package/dist/cli/{chunk-MJ6W5UN3.js → chunk-K6GUKSXH.js} +3 -2
- package/dist/cli/chunk-K6GUKSXH.js.map +1 -0
- package/dist/cli/{chunk-IJ7JA32V.js → chunk-KDRUEXII.js} +189 -26
- package/dist/cli/chunk-KDRUEXII.js.map +1 -0
- package/dist/cli/{chunk-4HCP2UQW.js → chunk-LBLR4CUZ.js} +2 -2
- package/dist/cli/{chunk-2425HK6U.js → chunk-LGEKVMMV.js} +7 -2
- package/dist/cli/{chunk-2425HK6U.js.map → chunk-LGEKVMMV.js.map} +1 -1
- package/dist/cli/{chunk-I4L2GTSE.js → chunk-OJVITDGB.js} +2 -2
- package/dist/cli/chunk-PLHAZOLZ.js +0 -0
- package/dist/cli/{chunk-W7YGWUWU.js → chunk-QVDWH2A2.js} +3 -3
- package/dist/cli/{chunk-R3CTO2HM.js → chunk-QVUFWDD2.js} +2 -2
- package/dist/cli/{chunk-HVUZWNSP.js → chunk-R6GQKKBW.js} +2 -2
- package/dist/cli/{chunk-5ACMUK4Q.js → chunk-RRXUIPWG.js} +20 -18
- package/dist/cli/chunk-RRXUIPWG.js.map +1 -0
- package/dist/cli/chunk-S4XVGLRW.js +0 -0
- package/dist/cli/chunk-SZ5XES2N.js +0 -0
- package/dist/cli/{chunk-CXVWUPA3.js → chunk-TKVXTQ3T.js} +26 -26
- package/dist/cli/chunk-TKVXTQ3T.js.map +1 -0
- package/dist/cli/chunk-TUK7OWJA.js +0 -0
- package/dist/cli/{chunk-JNAQYELD.js → chunk-UDVFBEXC.js} +3 -3
- package/dist/cli/{chunk-CBIQWMS6.js → chunk-VC2CQA5D.js} +9 -9
- package/dist/cli/{chunk-ZZYBBX5N.js → chunk-VJMBISEI.js} +23 -9
- package/dist/cli/chunk-VJMBISEI.js.map +1 -0
- package/dist/cli/{chunk-WK3UFQY3.js → chunk-VKYSZKH2.js} +2 -2
- package/dist/cli/{chunk-LIR2HBQH.js → chunk-VMUUFWFF.js} +2 -2
- package/dist/cli/{chunk-V26WPN3J.js → chunk-VNQGCA3Q.js} +28 -1
- package/dist/cli/chunk-VNQGCA3Q.js.map +1 -0
- package/dist/cli/{chunk-5I2C4JEO.js → chunk-WF7TPVZM.js} +6 -6
- package/dist/cli/{chunk-5I2C4JEO.js.map → chunk-WF7TPVZM.js.map} +1 -1
- package/dist/cli/chunk-X53B3JIX.js +0 -0
- package/dist/cli/chunk-XJXDHAES.js +0 -0
- package/dist/cli/chunk-XXC2BYTV.js +0 -0
- package/dist/cli/{chunk-4CTDEJUF.js → chunk-YDPLF7XR.js} +26 -14
- package/dist/cli/chunk-YDPLF7XR.js.map +1 -0
- package/dist/cli/chunk-ZZM6QJ4W.js +0 -0
- package/dist/cli/{code-DFHSASJ4.js → code-C24TUAE5.js} +39 -35
- package/dist/cli/code-C24TUAE5.js.map +1 -0
- package/dist/cli/{commands-OCU42XG4.js → commands-RR3GIYOK.js} +4 -4
- package/dist/cli/{commit-XCQIQCYG.js → commit-FSHPIINM.js} +3 -3
- package/dist/cli/{desktop-ZCUG7LMF.js → desktop-7NCHPEFB.js} +263 -36
- package/dist/cli/desktop-7NCHPEFB.js.map +1 -0
- package/dist/cli/devtools-HW3WDT3Q.js +0 -0
- package/dist/cli/{diff-66B2KWOJ.js → diff-RAAHHLHV.js} +8 -8
- package/dist/cli/{doctor-Y73CPPRZ.js → doctor-PKVQIXRT.js} +9 -9
- package/dist/cli/{events-NGZ2OJYH.js → events-VRYXOSKI.js} +3 -3
- package/dist/cli/index.js +84 -92
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-MPVGBBJF.js → mcp-CRJ26PP4.js} +2 -2
- package/dist/cli/{mcp-browse-4XOTC3FJ.js → mcp-browse-QPAOWZOP.js} +2 -2
- package/dist/cli/{mcp-inspect-CEMGKKAH.js → mcp-inspect-CVCLABRS.js} +4 -4
- package/dist/cli/{prompt-2D7ID24X.js → prompt-SKYXERSI.js} +4 -4
- package/dist/cli/{prune-sessions-OJEYYLHY.js → prune-sessions-SEWX7GP6.js} +2 -2
- package/dist/cli/{replay-AKYQNAQJ.js → replay-KPDW2ZMJ.js} +9 -9
- package/dist/cli/{run-5DPQFSP6.js → run-WIKDIXTG.js} +18 -19
- package/dist/cli/run-WIKDIXTG.js.map +1 -0
- package/dist/cli/{server-TQ2IHYQJ.js → server-P6V2G3P6.js} +82 -34
- package/dist/cli/server-P6V2G3P6.js.map +1 -0
- package/dist/cli/{sessions-KY54NG45.js → sessions-2NULRMSA.js} +29 -15
- package/dist/cli/sessions-2NULRMSA.js.map +1 -0
- package/dist/cli/{setup-XPIOZWS7.js → setup-Y5WDBQFL.js} +8 -8
- package/dist/cli/setup-Y5WDBQFL.js.map +1 -0
- package/dist/cli/{stats-X2VTWKNS.js → stats-T7BL2YOR.js} +6 -6
- package/dist/cli/update-6ITLPRDV.js +0 -0
- package/dist/cli/{version-7O6A5T7Q.js → version-3KWDNWLN.js} +15 -15
- package/dist/index.d.ts +54 -23
- package/dist/index.js +1613 -1152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/.-3G6VX5S7.js +0 -327
- package/dist/cli/.-6YRPB2C7.js +0 -329
- package/dist/cli/.-EYSVINK3.js +0 -317
- package/dist/cli/chat-ECK5ZGMV.js +0 -51
- package/dist/cli/chunk-4CTDEJUF.js.map +0 -1
- package/dist/cli/chunk-5ACMUK4Q.js.map +0 -1
- package/dist/cli/chunk-AVFXO2EZ.js.map +0 -1
- package/dist/cli/chunk-CXVWUPA3.js.map +0 -1
- package/dist/cli/chunk-GTZTQNX5.js.map +0 -1
- package/dist/cli/chunk-IJ7JA32V.js.map +0 -1
- package/dist/cli/chunk-KQU2TYIL.js.map +0 -1
- package/dist/cli/chunk-MJ6W5UN3.js.map +0 -1
- package/dist/cli/chunk-TEUDEGX2.js.map +0 -1
- package/dist/cli/chunk-V26WPN3J.js.map +0 -1
- package/dist/cli/chunk-WL6SNQ5T.js.map +0 -1
- package/dist/cli/chunk-XSU4QVFW.js.map +0 -1
- package/dist/cli/chunk-ZZYBBX5N.js.map +0 -1
- package/dist/cli/code-DFHSASJ4.js.map +0 -1
- package/dist/cli/desktop-ZCUG7LMF.js.map +0 -1
- package/dist/cli/doctor-Y73CPPRZ.js.map +0 -1
- package/dist/cli/prompt-2D7ID24X.js.map +0 -1
- package/dist/cli/run-5DPQFSP6.js.map +0 -1
- package/dist/cli/server-TQ2IHYQJ.js.map +0 -1
- package/dist/cli/sessions-KY54NG45.js.map +0 -1
- package/dist/cli/setup-XPIOZWS7.js.map +0 -1
- package/dist/cli/stats-X2VTWKNS.js.map +0 -1
- /package/dist/cli/{acp-LGBLHBKY.js.map → acp-QK3DMC53.js.map} +0 -0
- /package/dist/cli/{.-3G6VX5S7.js.map → chat-VV5UWY4V.js.map} +0 -0
- /package/dist/cli/{chunk-YY227BIQ.js.map → chunk-6J6BSUCR.js.map} +0 -0
- /package/dist/cli/{chunk-A3TSSDS2.js.map → chunk-BWYVFFKR.js.map} +0 -0
- /package/dist/cli/{chunk-C53JQES5.js.map → chunk-BYYVYJDX.js.map} +0 -0
- /package/dist/cli/{chunk-HNXDZGC6.js.map → chunk-CI2PF5QX.js.map} +0 -0
- /package/dist/cli/{chunk-QJDDIK3Z.js.map → chunk-E5WCLUIU.js.map} +0 -0
- /package/dist/cli/{chunk-NVURFF27.js.map → chunk-EQATK2L2.js.map} +0 -0
- /package/dist/cli/{chunk-HKWSPKMU.js.map → chunk-FDKOUJKZ.js.map} +0 -0
- /package/dist/cli/{chunk-RDRC3XDT.js.map → chunk-GDKB2PPK.js.map} +0 -0
- /package/dist/cli/{chunk-4HCP2UQW.js.map → chunk-LBLR4CUZ.js.map} +0 -0
- /package/dist/cli/{chunk-I4L2GTSE.js.map → chunk-OJVITDGB.js.map} +0 -0
- /package/dist/cli/{chunk-W7YGWUWU.js.map → chunk-QVDWH2A2.js.map} +0 -0
- /package/dist/cli/{chunk-R3CTO2HM.js.map → chunk-QVUFWDD2.js.map} +0 -0
- /package/dist/cli/{chunk-HVUZWNSP.js.map → chunk-R6GQKKBW.js.map} +0 -0
- /package/dist/cli/{chunk-JNAQYELD.js.map → chunk-UDVFBEXC.js.map} +0 -0
- /package/dist/cli/{chunk-CBIQWMS6.js.map → chunk-VC2CQA5D.js.map} +0 -0
- /package/dist/cli/{chunk-WK3UFQY3.js.map → chunk-VKYSZKH2.js.map} +0 -0
- /package/dist/cli/{chunk-LIR2HBQH.js.map → chunk-VMUUFWFF.js.map} +0 -0
- /package/dist/cli/{commands-OCU42XG4.js.map → commands-RR3GIYOK.js.map} +0 -0
- /package/dist/cli/{commit-XCQIQCYG.js.map → commit-FSHPIINM.js.map} +0 -0
- /package/dist/cli/{diff-66B2KWOJ.js.map → diff-RAAHHLHV.js.map} +0 -0
- /package/dist/cli/{.-6YRPB2C7.js.map → doctor-PKVQIXRT.js.map} +0 -0
- /package/dist/cli/{events-NGZ2OJYH.js.map → events-VRYXOSKI.js.map} +0 -0
- /package/dist/cli/{mcp-MPVGBBJF.js.map → mcp-CRJ26PP4.js.map} +0 -0
- /package/dist/cli/{mcp-browse-4XOTC3FJ.js.map → mcp-browse-QPAOWZOP.js.map} +0 -0
- /package/dist/cli/{mcp-inspect-CEMGKKAH.js.map → mcp-inspect-CVCLABRS.js.map} +0 -0
- /package/dist/cli/{.-EYSVINK3.js.map → prompt-SKYXERSI.js.map} +0 -0
- /package/dist/cli/{prune-sessions-OJEYYLHY.js.map → prune-sessions-SEWX7GP6.js.map} +0 -0
- /package/dist/cli/{replay-AKYQNAQJ.js.map → replay-KPDW2ZMJ.js.map} +0 -0
- /package/dist/cli/{chat-ECK5ZGMV.js.map → stats-T7BL2YOR.js.map} +0 -0
- /package/dist/cli/{version-7O6A5T7Q.js.map → version-3KWDNWLN.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
|
|
|
3
3
|
import {
|
|
4
4
|
MemoryStore,
|
|
5
5
|
sanitizeMemoryName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UDVFBEXC.js";
|
|
7
7
|
import {
|
|
8
8
|
countTokens,
|
|
9
9
|
countTokensBounded,
|
|
@@ -12,23 +12,23 @@ import {
|
|
|
12
12
|
} from "./chunk-6OWJV3YW.js";
|
|
13
13
|
import {
|
|
14
14
|
Usage
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VNQGCA3Q.js";
|
|
16
16
|
import {
|
|
17
17
|
applyEdit,
|
|
18
18
|
applyMultiEdit,
|
|
19
19
|
pauseGate
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GDKB2PPK.js";
|
|
21
21
|
import {
|
|
22
22
|
NEGATIVE_CLAIM_RULE,
|
|
23
23
|
PROJECT_MEMORY_FILES,
|
|
24
24
|
PROJECT_MEMORY_MAX_CHARS,
|
|
25
25
|
TUI_FORMATTING_RULES,
|
|
26
26
|
memoryEnabled
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-FY4S7TJZ.js";
|
|
28
28
|
import {
|
|
29
29
|
formatHookOutcomeMessage,
|
|
30
30
|
runHooks
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-BWYVFFKR.js";
|
|
32
32
|
import {
|
|
33
33
|
ignoredByLayers,
|
|
34
34
|
loadGitignoreAt,
|
|
@@ -41,25 +41,26 @@ import {
|
|
|
41
41
|
loadSessionMeta,
|
|
42
42
|
rewriteSession,
|
|
43
43
|
timestampSuffix
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-RRXUIPWG.js";
|
|
45
45
|
import {
|
|
46
46
|
DEEPSEEK_CONTEXT_TOKENS,
|
|
47
47
|
DEFAULT_CONTEXT_TOKENS,
|
|
48
48
|
SessionStats
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-VJMBISEI.js";
|
|
50
50
|
import {
|
|
51
51
|
t
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-KDRUEXII.js";
|
|
53
53
|
import {
|
|
54
54
|
DEFAULT_INDEX_EXCLUDES,
|
|
55
55
|
addProjectPathAllowed,
|
|
56
56
|
loadMemoryTypeRegistry,
|
|
57
57
|
loadMetasoApiKey,
|
|
58
58
|
loadProjectPathAllowed,
|
|
59
|
+
loadTavilyApiKey,
|
|
59
60
|
require_picomatch,
|
|
60
61
|
webSearchEndpoint,
|
|
61
62
|
webSearchEngine
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-24A7FHGJ.js";
|
|
63
64
|
import {
|
|
64
65
|
__commonJS,
|
|
65
66
|
__esm,
|
|
@@ -6124,11 +6125,42 @@ async function bridgeMcpTools(client, opts = {}) {
|
|
|
6124
6125
|
return { ...result, env };
|
|
6125
6126
|
}
|
|
6126
6127
|
function flattenMcpResult(result, opts = {}) {
|
|
6128
|
+
validateResultShape(result);
|
|
6127
6129
|
const parts = result.content.map(blockToString);
|
|
6128
6130
|
const joined = parts.join("\n").trim();
|
|
6129
6131
|
const prefixed = result.isError ? `ERROR: ${joined || "(no error message from server)"}` : joined;
|
|
6130
6132
|
return opts.maxChars ? truncateForModel(prefixed, opts.maxChars) : prefixed;
|
|
6131
6133
|
}
|
|
6134
|
+
function validateResultShape(result) {
|
|
6135
|
+
if (typeof result !== "object" || !result)
|
|
6136
|
+
throw new Error(`MCP server returned non-object result: ${typeof result}`);
|
|
6137
|
+
const { content, isError: _isError } = result;
|
|
6138
|
+
if (!Array.isArray(content))
|
|
6139
|
+
throw new Error(`MCP server returned result with non-array content: ${typeof content}`);
|
|
6140
|
+
for (let i = 0; i < content.length; i++) {
|
|
6141
|
+
const block = content[i];
|
|
6142
|
+
if (typeof block !== "object" || !block)
|
|
6143
|
+
throw new Error(`MCP server returned result.content[${i}] is not an object`);
|
|
6144
|
+
if (block.type !== "text" && block.type !== "image")
|
|
6145
|
+
throw new Error(
|
|
6146
|
+
`MCP server returned result.content[${i}] with unknown type ${JSON.stringify(block.type)}`
|
|
6147
|
+
);
|
|
6148
|
+
if (block.type === "text" && typeof block.text !== "string")
|
|
6149
|
+
throw new Error(
|
|
6150
|
+
`MCP server returned result.content[${i}] with non-string text (${typeof block.text})`
|
|
6151
|
+
);
|
|
6152
|
+
if (block.type === "image") {
|
|
6153
|
+
if (typeof block.data !== "string")
|
|
6154
|
+
throw new Error(
|
|
6155
|
+
`MCP server returned result.content[${i}] with non-string data (${typeof block.data})`
|
|
6156
|
+
);
|
|
6157
|
+
if (typeof block.mimeType !== "string")
|
|
6158
|
+
throw new Error(
|
|
6159
|
+
`MCP server returned result.content[${i}] with non-string mimeType (${typeof block.mimeType})`
|
|
6160
|
+
);
|
|
6161
|
+
}
|
|
6162
|
+
}
|
|
6163
|
+
}
|
|
6132
6164
|
function truncateForModel(s, maxChars) {
|
|
6133
6165
|
if (s.length <= maxChars) return s;
|
|
6134
6166
|
const tailBudget = Math.min(1024, Math.floor(maxChars * 0.1));
|
|
@@ -6394,6 +6426,12 @@ var ToolRegistry = class {
|
|
|
6394
6426
|
});
|
|
6395
6427
|
}
|
|
6396
6428
|
}
|
|
6429
|
+
if (opts.signal?.aborted) {
|
|
6430
|
+
return JSON.stringify({
|
|
6431
|
+
error: `${name}: aborted before dispatch (user interrupt)`,
|
|
6432
|
+
rejectedReason: "aborted"
|
|
6433
|
+
});
|
|
6434
|
+
}
|
|
6397
6435
|
let finalResult;
|
|
6398
6436
|
try {
|
|
6399
6437
|
try {
|
|
@@ -7180,42 +7218,6 @@ function* hookWarnings(outcomes, turn) {
|
|
|
7180
7218
|
}
|
|
7181
7219
|
}
|
|
7182
7220
|
|
|
7183
|
-
// src/loop/turn-failure-tracker.ts
|
|
7184
|
-
var FAILURE_ESCALATION_THRESHOLD = 3;
|
|
7185
|
-
var TurnFailureTracker = class {
|
|
7186
|
-
count = 0;
|
|
7187
|
-
types = {};
|
|
7188
|
-
threshold;
|
|
7189
|
-
constructor(threshold = FAILURE_ESCALATION_THRESHOLD) {
|
|
7190
|
-
this.threshold = threshold;
|
|
7191
|
-
}
|
|
7192
|
-
reset() {
|
|
7193
|
-
this.count = 0;
|
|
7194
|
-
this.types = {};
|
|
7195
|
-
}
|
|
7196
|
-
/** True ONLY on the call where the count crosses the configured threshold. */
|
|
7197
|
-
noteAndCrossedThreshold(resultJson, repair) {
|
|
7198
|
-
const before = this.count;
|
|
7199
|
-
const bump = (kind, by = 1) => {
|
|
7200
|
-
this.count += by;
|
|
7201
|
-
this.types[kind] = (this.types[kind] ?? 0) + by;
|
|
7202
|
-
};
|
|
7203
|
-
if (resultJson.includes('"error"') && resultJson.includes("search text not found")) {
|
|
7204
|
-
bump("search-mismatch");
|
|
7205
|
-
}
|
|
7206
|
-
if (repair) {
|
|
7207
|
-
if (repair.scavenged > 0) bump("scavenged", repair.scavenged);
|
|
7208
|
-
if (repair.truncationsFixed > 0) bump("truncated", repair.truncationsFixed);
|
|
7209
|
-
if (repair.stormsBroken > 0) bump("repeat-loop", repair.stormsBroken);
|
|
7210
|
-
}
|
|
7211
|
-
return before < this.threshold && this.count >= this.threshold;
|
|
7212
|
-
}
|
|
7213
|
-
formatBreakdown() {
|
|
7214
|
-
const parts = Object.entries(this.types).filter(([, n]) => n > 0).map(([kind, n]) => `${n}\xD7 ${kind}`);
|
|
7215
|
-
return parts.length > 0 ? parts.join(", ") : `${this.count} repair/error signal(s)`;
|
|
7216
|
-
}
|
|
7217
|
-
};
|
|
7218
|
-
|
|
7219
7221
|
// src/repair/scavenge.ts
|
|
7220
7222
|
var MAX_SCAVENGE_INPUT = 100 * 1024;
|
|
7221
7223
|
function scavengeToolCalls(reasoningContent, opts) {
|
|
@@ -7595,7 +7597,6 @@ var CacheFirstLoop = class {
|
|
|
7595
7597
|
}
|
|
7596
7598
|
_proArmedForNextTurn = false;
|
|
7597
7599
|
_escalateThisTurn = false;
|
|
7598
|
-
_turnFailures;
|
|
7599
7600
|
_turnSelfCorrected = false;
|
|
7600
7601
|
_foldedThisTurn = false;
|
|
7601
7602
|
context;
|
|
@@ -7614,9 +7615,6 @@ var CacheFirstLoop = class {
|
|
|
7614
7615
|
this.reasoningEffort = opts.reasoningEffort ?? "max";
|
|
7615
7616
|
if (opts.autoEscalate !== void 0) this.autoEscalate = opts.autoEscalate;
|
|
7616
7617
|
this.budgetUsd = typeof opts.budgetUsd === "number" && opts.budgetUsd > 0 ? opts.budgetUsd : null;
|
|
7617
|
-
this._turnFailures = new TurnFailureTracker(
|
|
7618
|
-
resolveFailureThreshold(opts.failureThreshold, FAILURE_ESCALATION_THRESHOLD)
|
|
7619
|
-
);
|
|
7620
7618
|
this.hooks = opts.hooks ?? [];
|
|
7621
7619
|
this.hookCwd = opts.hookCwd ?? process.cwd();
|
|
7622
7620
|
this.confirmationGate = opts.confirmationGate ?? pauseGate;
|
|
@@ -7724,7 +7722,6 @@ var CacheFirstLoop = class {
|
|
|
7724
7722
|
this._inflight.clear();
|
|
7725
7723
|
this.stats.reset();
|
|
7726
7724
|
this._turn = 0;
|
|
7727
|
-
this._turnFailures.reset();
|
|
7728
7725
|
this._budgetWarned = false;
|
|
7729
7726
|
let systemRebuilt = false;
|
|
7730
7727
|
if (this._rebuildSystem) {
|
|
@@ -7795,13 +7792,6 @@ var CacheFirstLoop = class {
|
|
|
7795
7792
|
modelForCurrentCall() {
|
|
7796
7793
|
return this._escalateThisTurn ? ESCALATION_MODEL : this.model;
|
|
7797
7794
|
}
|
|
7798
|
-
/** Returns true ONLY on the tipping call — caller surfaces a one-shot warning. */
|
|
7799
|
-
noteToolFailureSignal(resultJson, repair) {
|
|
7800
|
-
if (!this._turnFailures.noteAndCrossedThreshold(resultJson, repair)) return false;
|
|
7801
|
-
if (this._escalateThisTurn || !this.autoEscalate) return false;
|
|
7802
|
-
this._escalateThisTurn = true;
|
|
7803
|
-
return true;
|
|
7804
|
-
}
|
|
7805
7795
|
/** A call counts as mutating when its definition reports `readOnly !== true` and any dynamic `readOnlyCheck` doesn't override that for these args. */
|
|
7806
7796
|
isMutating(call) {
|
|
7807
7797
|
const name = call.function?.name;
|
|
@@ -7925,6 +7915,32 @@ ${reason}`
|
|
|
7925
7915
|
}
|
|
7926
7916
|
return userText;
|
|
7927
7917
|
}
|
|
7918
|
+
/** Rewind to the N-th user turn (0-indexed). Drops that turn + everything after. */
|
|
7919
|
+
rewindToUserTurn(userTurnIndex) {
|
|
7920
|
+
const entries = this.log.entries;
|
|
7921
|
+
let count = 0;
|
|
7922
|
+
let targetIdx = -1;
|
|
7923
|
+
for (let i = 0; i < entries.length; i++) {
|
|
7924
|
+
if (entries[i].role !== "user") continue;
|
|
7925
|
+
if (count === userTurnIndex) {
|
|
7926
|
+
targetIdx = i;
|
|
7927
|
+
break;
|
|
7928
|
+
}
|
|
7929
|
+
count++;
|
|
7930
|
+
}
|
|
7931
|
+
if (targetIdx < 0) return null;
|
|
7932
|
+
const raw = entries[targetIdx].content;
|
|
7933
|
+
const userText = typeof raw === "string" ? raw : "";
|
|
7934
|
+
const preserved = entries.slice(0, targetIdx).map((m) => ({ ...m }));
|
|
7935
|
+
this.log.compactInPlace(preserved);
|
|
7936
|
+
if (this.sessionName) {
|
|
7937
|
+
try {
|
|
7938
|
+
rewriteSession(this.sessionName, preserved);
|
|
7939
|
+
} catch {
|
|
7940
|
+
}
|
|
7941
|
+
}
|
|
7942
|
+
return userText;
|
|
7943
|
+
}
|
|
7928
7944
|
async *step(userInput) {
|
|
7929
7945
|
this._steerConsumed = false;
|
|
7930
7946
|
if (this.budgetUsd !== null) {
|
|
@@ -7956,7 +7972,6 @@ ${reason}`
|
|
|
7956
7972
|
this._turn++;
|
|
7957
7973
|
this.scratch.reset();
|
|
7958
7974
|
this.repair.resetStorm();
|
|
7959
|
-
this._turnFailures.reset();
|
|
7960
7975
|
this._turnSelfCorrected = false;
|
|
7961
7976
|
this._escalateThisTurn = false;
|
|
7962
7977
|
this._foldedThisTurn = false;
|
|
@@ -8227,17 +8242,6 @@ ${reason}`
|
|
|
8227
8242
|
stats: turnStats,
|
|
8228
8243
|
repair: report
|
|
8229
8244
|
};
|
|
8230
|
-
if (this.noteToolFailureSignal("", report)) {
|
|
8231
|
-
yield {
|
|
8232
|
-
turn: this._turn,
|
|
8233
|
-
role: "warning",
|
|
8234
|
-
content: t("loop.autoEscalation", {
|
|
8235
|
-
model: ESCALATION_MODEL,
|
|
8236
|
-
breakdown: this._turnFailures.formatBreakdown(),
|
|
8237
|
-
fallback: this.model
|
|
8238
|
-
})
|
|
8239
|
-
};
|
|
8240
|
-
}
|
|
8241
8245
|
const allSuppressed = report.stormsBroken > 0 && repairedCalls.length === 0 && toolCalls.length > 0;
|
|
8242
8246
|
if (allSuppressed && !this._turnSelfCorrected) {
|
|
8243
8247
|
this._turnSelfCorrected = true;
|
|
@@ -8377,17 +8381,6 @@ ${reason}`
|
|
|
8377
8381
|
name,
|
|
8378
8382
|
content: result
|
|
8379
8383
|
});
|
|
8380
|
-
if (this.noteToolFailureSignal(result)) {
|
|
8381
|
-
yield {
|
|
8382
|
-
turn: this._turn,
|
|
8383
|
-
role: "warning",
|
|
8384
|
-
content: t("loop.autoEscalation", {
|
|
8385
|
-
model: ESCALATION_MODEL,
|
|
8386
|
-
breakdown: this._turnFailures.formatBreakdown(),
|
|
8387
|
-
fallback: this.model
|
|
8388
|
-
})
|
|
8389
|
-
};
|
|
8390
|
-
}
|
|
8391
8384
|
yield {
|
|
8392
8385
|
turn: this._turn,
|
|
8393
8386
|
role: "tool",
|
|
@@ -8425,19 +8418,6 @@ function parsePositiveIntEnv(raw) {
|
|
|
8425
8418
|
const n = Number.parseInt(raw, 10);
|
|
8426
8419
|
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
8427
8420
|
}
|
|
8428
|
-
var FAILURE_THRESHOLD_MIN = 1;
|
|
8429
|
-
var FAILURE_THRESHOLD_MAX = 20;
|
|
8430
|
-
function resolveFailureThreshold(raw, fallback) {
|
|
8431
|
-
if (raw === void 0) return fallback;
|
|
8432
|
-
if (!Number.isInteger(raw) || raw < FAILURE_THRESHOLD_MIN || raw > FAILURE_THRESHOLD_MAX) {
|
|
8433
|
-
process.stderr.write(
|
|
8434
|
-
`\u25B2 ignoring escalation failureThreshold=${raw} (must be an integer in [${FAILURE_THRESHOLD_MIN},${FAILURE_THRESHOLD_MAX}]) \u2014 using default ${fallback}
|
|
8435
|
-
`
|
|
8436
|
-
);
|
|
8437
|
-
return fallback;
|
|
8438
|
-
}
|
|
8439
|
-
return raw;
|
|
8440
|
-
}
|
|
8441
8421
|
|
|
8442
8422
|
// src/at-mentions.ts
|
|
8443
8423
|
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
@@ -9241,6 +9221,7 @@ var FETCH_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
9241
9221
|
var USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
|
|
9242
9222
|
var MOJEEK_ENDPOINT = "https://www.mojeek.com/search";
|
|
9243
9223
|
var METASO_ENDPOINT = "https://metaso.cn/api/v1";
|
|
9224
|
+
var TAVILY_ENDPOINT = "https://api.tavily.com/search";
|
|
9244
9225
|
function searchStatusError(status) {
|
|
9245
9226
|
if (status === 429) return t("webErrors.rateLimit429");
|
|
9246
9227
|
if (status === 403) return t("webErrors.forbidden403");
|
|
@@ -9260,6 +9241,9 @@ async function webSearch(query, opts = {}) {
|
|
|
9260
9241
|
if (opts.engine === "searxng") {
|
|
9261
9242
|
return searchSearxng(query, opts);
|
|
9262
9243
|
}
|
|
9244
|
+
if (opts.engine === "tavily") {
|
|
9245
|
+
return searchTavily(query, opts);
|
|
9246
|
+
}
|
|
9263
9247
|
return searchMojeek(query, opts);
|
|
9264
9248
|
}
|
|
9265
9249
|
async function searchMojeek(query, opts = {}) {
|
|
@@ -9394,6 +9378,55 @@ async function searchMetaso(query, opts = {}) {
|
|
|
9394
9378
|
snippet: wp.snippet ?? wp.summary ?? ""
|
|
9395
9379
|
}));
|
|
9396
9380
|
}
|
|
9381
|
+
async function searchTavily(query, opts = {}) {
|
|
9382
|
+
const topK = Math.max(1, Math.min(20, opts.topK ?? DEFAULT_TOPK));
|
|
9383
|
+
const apiKey = loadTavilyApiKey();
|
|
9384
|
+
if (!apiKey) throw new Error(t("webErrors.tavilyMissingKey"));
|
|
9385
|
+
let resp;
|
|
9386
|
+
try {
|
|
9387
|
+
resp = await fetch(TAVILY_ENDPOINT, {
|
|
9388
|
+
method: "POST",
|
|
9389
|
+
headers: {
|
|
9390
|
+
"Content-Type": "application/json",
|
|
9391
|
+
Accept: "application/json"
|
|
9392
|
+
},
|
|
9393
|
+
body: JSON.stringify({
|
|
9394
|
+
api_key: apiKey,
|
|
9395
|
+
query,
|
|
9396
|
+
search_depth: "basic",
|
|
9397
|
+
max_results: topK,
|
|
9398
|
+
include_answer: false,
|
|
9399
|
+
include_raw_content: false,
|
|
9400
|
+
include_images: false
|
|
9401
|
+
}),
|
|
9402
|
+
signal: opts.signal
|
|
9403
|
+
});
|
|
9404
|
+
} catch (err) {
|
|
9405
|
+
if (err instanceof TypeError && err.message.includes("fetch")) {
|
|
9406
|
+
throw new Error(t("webErrors.cannotReach", { endpoint: TAVILY_ENDPOINT }));
|
|
9407
|
+
}
|
|
9408
|
+
throw err;
|
|
9409
|
+
}
|
|
9410
|
+
if (!resp.ok) {
|
|
9411
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
9412
|
+
throw new Error(t("webErrors.tavilyUnauthorized"));
|
|
9413
|
+
}
|
|
9414
|
+
if (resp.status === 429) throw new Error(t("webErrors.tavilyRateLimit"));
|
|
9415
|
+
throw new Error(t("webErrors.tavilyServerError", { status: resp.status }));
|
|
9416
|
+
}
|
|
9417
|
+
let data;
|
|
9418
|
+
try {
|
|
9419
|
+
data = await resp.json();
|
|
9420
|
+
} catch {
|
|
9421
|
+
throw new Error(t("webErrors.tavilyParseError", { status: resp.status }));
|
|
9422
|
+
}
|
|
9423
|
+
const results = data.results ?? [];
|
|
9424
|
+
return results.slice(0, topK).map((r) => ({
|
|
9425
|
+
title: r.title,
|
|
9426
|
+
url: r.url,
|
|
9427
|
+
snippet: r.content ?? ""
|
|
9428
|
+
}));
|
|
9429
|
+
}
|
|
9397
9430
|
function parseSearxngHtmlResults(html) {
|
|
9398
9431
|
const root = (0, import_node_html_parser.parse)(html);
|
|
9399
9432
|
const results = [];
|
|
@@ -9612,7 +9645,7 @@ function registerWebTools(registry, opts = {}) {
|
|
|
9612
9645
|
const maxFetchChars = opts.maxFetchChars ?? DEFAULT_FETCH_MAX_CHARS;
|
|
9613
9646
|
registry.register({
|
|
9614
9647
|
name: "web_search",
|
|
9615
|
-
description: "Search the public web. Returns ranked results with title, url, and snippet. Call this when the answer's correctness depends on current state \u2014 anything that changes over time (events, prices, releases, status of a thing in the real world). Composing such answers from training memory invents stale numbers; search first, then ground the answer in the results. For evergreen / definitional questions you don't need this. To change the backend, use /search-engine mojeek|searxng|metaso.",
|
|
9648
|
+
description: "Search the public web. Returns ranked results with title, url, and snippet. Call this when the answer's correctness depends on current state \u2014 anything that changes over time (events, prices, releases, status of a thing in the real world). Composing such answers from training memory invents stale numbers; search first, then ground the answer in the results. For evergreen / definitional questions you don't need this. To change the backend, use /search-engine mojeek|searxng|metaso|tavily.",
|
|
9616
9649
|
readOnly: true,
|
|
9617
9650
|
parallelSafe: true,
|
|
9618
9651
|
parameters: {
|
|
@@ -9684,13 +9717,13 @@ import * as pathMod4 from "path";
|
|
|
9684
9717
|
// src/memory/subdir.ts
|
|
9685
9718
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
9686
9719
|
import { dirname, join as join2, relative as relative2, resolve as resolve2 } from "path";
|
|
9687
|
-
function
|
|
9720
|
+
function findDirMemory(absDir, rootDir) {
|
|
9688
9721
|
const root = resolve2(rootDir);
|
|
9689
|
-
const target = resolve2(
|
|
9722
|
+
const target = resolve2(absDir);
|
|
9690
9723
|
const rel = relative2(root, target);
|
|
9691
|
-
if (
|
|
9724
|
+
if (rel.startsWith("..")) return [];
|
|
9692
9725
|
const found = [];
|
|
9693
|
-
let cur =
|
|
9726
|
+
let cur = target;
|
|
9694
9727
|
while (cur !== root) {
|
|
9695
9728
|
const r = relative2(root, cur);
|
|
9696
9729
|
if (!r || r.startsWith("..")) break;
|
|
@@ -9707,6 +9740,9 @@ function findSubdirMemoryAncestors(absPath, rootDir) {
|
|
|
9707
9740
|
}
|
|
9708
9741
|
return found;
|
|
9709
9742
|
}
|
|
9743
|
+
function findSubdirMemoryAncestors(absPath, rootDir) {
|
|
9744
|
+
return findDirMemory(dirname(resolve2(absPath)), rootDir);
|
|
9745
|
+
}
|
|
9710
9746
|
function readSubdirMemoryContent(path) {
|
|
9711
9747
|
let raw;
|
|
9712
9748
|
try {
|
|
@@ -9975,6 +10011,129 @@ function formatOutline(entries) {
|
|
|
9975
10011
|
// src/tools/fs/search.ts
|
|
9976
10012
|
import { promises as fs2 } from "fs";
|
|
9977
10013
|
import * as pathMod3 from "path";
|
|
10014
|
+
|
|
10015
|
+
// src/tools/fs/regex-runner.ts
|
|
10016
|
+
import { Worker } from "worker_threads";
|
|
10017
|
+
var WORKER_SOURCE = `
|
|
10018
|
+
const { parentPort } = require("node:worker_threads");
|
|
10019
|
+
parentPort.on("message", (msg) => {
|
|
10020
|
+
const { id, text, source, flags } = msg;
|
|
10021
|
+
let re;
|
|
10022
|
+
try {
|
|
10023
|
+
re = new RegExp(source, flags);
|
|
10024
|
+
} catch (err) {
|
|
10025
|
+
parentPort.postMessage({ id, error: (err && err.message) ? err.message : String(err) });
|
|
10026
|
+
return;
|
|
10027
|
+
}
|
|
10028
|
+
const lines = text.split(/\\r?\\n/);
|
|
10029
|
+
const hits = [];
|
|
10030
|
+
for (let i = 0; i < lines.length; i++) {
|
|
10031
|
+
if (re.test(lines[i])) hits.push(i);
|
|
10032
|
+
}
|
|
10033
|
+
parentPort.postMessage({ id, hits });
|
|
10034
|
+
});
|
|
10035
|
+
`;
|
|
10036
|
+
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
10037
|
+
var RegexRunner = class {
|
|
10038
|
+
worker = null;
|
|
10039
|
+
pending = /* @__PURE__ */ new Map();
|
|
10040
|
+
nextId = 1;
|
|
10041
|
+
defaultTimeoutMs;
|
|
10042
|
+
constructor(opts = {}) {
|
|
10043
|
+
this.defaultTimeoutMs = opts.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
10044
|
+
}
|
|
10045
|
+
testLines(text, source, flags, opts = {}) {
|
|
10046
|
+
return new Promise((resolve5, reject) => {
|
|
10047
|
+
if (opts.signal?.aborted) {
|
|
10048
|
+
reject(new Error("regex evaluation aborted"));
|
|
10049
|
+
return;
|
|
10050
|
+
}
|
|
10051
|
+
if (!this.worker) this.worker = this.spawn();
|
|
10052
|
+
const id = this.nextId++;
|
|
10053
|
+
const timeoutMs = opts.timeoutMs ?? this.defaultTimeoutMs;
|
|
10054
|
+
const timer = setTimeout(() => {
|
|
10055
|
+
this.pending.delete(id);
|
|
10056
|
+
this.killWorker();
|
|
10057
|
+
reject(new Error(`regex evaluation exceeded ${timeoutMs}ms`));
|
|
10058
|
+
}, timeoutMs);
|
|
10059
|
+
const entry = { resolve: resolve5, reject, timer };
|
|
10060
|
+
if (opts.signal) {
|
|
10061
|
+
entry.signal = opts.signal;
|
|
10062
|
+
entry.onAbort = () => {
|
|
10063
|
+
this.pending.delete(id);
|
|
10064
|
+
clearTimeout(timer);
|
|
10065
|
+
this.killWorker();
|
|
10066
|
+
reject(new Error("regex evaluation aborted"));
|
|
10067
|
+
};
|
|
10068
|
+
opts.signal.addEventListener("abort", entry.onAbort, { once: true });
|
|
10069
|
+
}
|
|
10070
|
+
this.pending.set(id, entry);
|
|
10071
|
+
this.worker.postMessage({ id, text, source, flags });
|
|
10072
|
+
});
|
|
10073
|
+
}
|
|
10074
|
+
async shutdown() {
|
|
10075
|
+
if (this.worker) {
|
|
10076
|
+
const w = this.worker;
|
|
10077
|
+
this.worker = null;
|
|
10078
|
+
await w.terminate();
|
|
10079
|
+
}
|
|
10080
|
+
for (const entry of this.pending.values()) {
|
|
10081
|
+
clearTimeout(entry.timer);
|
|
10082
|
+
if (entry.onAbort && entry.signal) {
|
|
10083
|
+
entry.signal.removeEventListener("abort", entry.onAbort);
|
|
10084
|
+
}
|
|
10085
|
+
entry.reject(new Error("regex runner shut down"));
|
|
10086
|
+
}
|
|
10087
|
+
this.pending.clear();
|
|
10088
|
+
}
|
|
10089
|
+
spawn() {
|
|
10090
|
+
const w = new Worker(WORKER_SOURCE, { eval: true });
|
|
10091
|
+
w.on("message", (msg) => {
|
|
10092
|
+
const entry = this.pending.get(msg.id);
|
|
10093
|
+
if (!entry) return;
|
|
10094
|
+
clearTimeout(entry.timer);
|
|
10095
|
+
if (entry.onAbort && entry.signal) {
|
|
10096
|
+
entry.signal.removeEventListener("abort", entry.onAbort);
|
|
10097
|
+
}
|
|
10098
|
+
this.pending.delete(msg.id);
|
|
10099
|
+
if (msg.error !== void 0) entry.reject(new Error(msg.error));
|
|
10100
|
+
else entry.resolve(msg.hits ?? []);
|
|
10101
|
+
});
|
|
10102
|
+
w.on("error", (err) => {
|
|
10103
|
+
if (this.worker !== w) return;
|
|
10104
|
+
this.failPending(err);
|
|
10105
|
+
});
|
|
10106
|
+
w.on("exit", () => {
|
|
10107
|
+
if (this.worker !== w) return;
|
|
10108
|
+
this.worker = null;
|
|
10109
|
+
if (this.pending.size > 0) this.failPending(new Error("regex worker exited"));
|
|
10110
|
+
});
|
|
10111
|
+
return w;
|
|
10112
|
+
}
|
|
10113
|
+
killWorker() {
|
|
10114
|
+
if (!this.worker) return;
|
|
10115
|
+
const w = this.worker;
|
|
10116
|
+
this.worker = null;
|
|
10117
|
+
void w.terminate();
|
|
10118
|
+
}
|
|
10119
|
+
failPending(err) {
|
|
10120
|
+
for (const entry of this.pending.values()) {
|
|
10121
|
+
clearTimeout(entry.timer);
|
|
10122
|
+
if (entry.onAbort && entry.signal) {
|
|
10123
|
+
entry.signal.removeEventListener("abort", entry.onAbort);
|
|
10124
|
+
}
|
|
10125
|
+
entry.reject(err);
|
|
10126
|
+
}
|
|
10127
|
+
this.pending.clear();
|
|
10128
|
+
}
|
|
10129
|
+
};
|
|
10130
|
+
var _runner = null;
|
|
10131
|
+
function getRegexRunner() {
|
|
10132
|
+
if (!_runner) _runner = new RegexRunner();
|
|
10133
|
+
return _runner;
|
|
10134
|
+
}
|
|
10135
|
+
|
|
10136
|
+
// src/tools/fs/search.ts
|
|
9978
10137
|
function throwIfAborted(signal) {
|
|
9979
10138
|
if (!signal?.aborted) return;
|
|
9980
10139
|
throw new DOMException("search aborted by user", "AbortError");
|
|
@@ -10027,17 +10186,20 @@ async function searchFiles(ctx, startAbs, args) {
|
|
|
10027
10186
|
}
|
|
10028
10187
|
var MAX_HITS_PER_FILE = 30;
|
|
10029
10188
|
var SUMMARY_MODE_TRIGGER_RATIO = 0.8;
|
|
10189
|
+
var WALK_DEADLINE_MS = 12e4;
|
|
10030
10190
|
async function searchContent(ctx, startAbs, args) {
|
|
10031
10191
|
throwIfAborted(args.signal);
|
|
10032
10192
|
const caseSensitive = args.case_sensitive === true;
|
|
10033
10193
|
const includeDeps = args.include_deps === true;
|
|
10034
10194
|
const ctxLines = Math.max(0, Math.min(20, Math.floor(args.context ?? 0)));
|
|
10035
10195
|
const summaryOnly = args.summary_only === true;
|
|
10036
|
-
|
|
10196
|
+
const reFlags = caseSensitive ? "" : "i";
|
|
10197
|
+
let reSource = null;
|
|
10037
10198
|
try {
|
|
10038
|
-
|
|
10199
|
+
new RegExp(args.pattern, reFlags);
|
|
10200
|
+
reSource = args.pattern;
|
|
10039
10201
|
} catch {
|
|
10040
|
-
|
|
10202
|
+
reSource = null;
|
|
10041
10203
|
}
|
|
10042
10204
|
const needle = caseSensitive ? args.pattern : args.pattern.toLowerCase();
|
|
10043
10205
|
const matches = [];
|
|
@@ -10047,6 +10209,15 @@ async function searchContent(ctx, startAbs, args) {
|
|
|
10047
10209
|
let summaryMode = summaryOnly;
|
|
10048
10210
|
let summaryNoticeEmitted = false;
|
|
10049
10211
|
const fileHitCounts = /* @__PURE__ */ new Map();
|
|
10212
|
+
const regexSkippedFiles = [];
|
|
10213
|
+
const t0 = Date.now();
|
|
10214
|
+
const throwIfTimedOut = () => {
|
|
10215
|
+
if (Date.now() - t0 > WALK_DEADLINE_MS) {
|
|
10216
|
+
throw new Error(
|
|
10217
|
+
`search_content exceeded ${WALK_DEADLINE_MS}ms \u2014 narrow the scope (path/glob) or simplify the pattern`
|
|
10218
|
+
);
|
|
10219
|
+
}
|
|
10220
|
+
};
|
|
10050
10221
|
const pushLine = (out) => {
|
|
10051
10222
|
if (totalBytes + out.length + 1 > ctx.maxListBytes) {
|
|
10052
10223
|
matches.push(`[\u2026 truncated at ${ctx.maxListBytes} bytes \u2014 refine pattern or path \u2026]`);
|
|
@@ -10081,6 +10252,7 @@ async function searchContent(ctx, startAbs, args) {
|
|
|
10081
10252
|
for (const e of entries) {
|
|
10082
10253
|
if (truncated) return;
|
|
10083
10254
|
throwIfAborted(args.signal);
|
|
10255
|
+
throwIfTimedOut();
|
|
10084
10256
|
if (e.isDirectory()) {
|
|
10085
10257
|
if (!includeDeps && ctx.skipDirNames.has(e.name)) continue;
|
|
10086
10258
|
await walk2(pathMod3.join(dir, e.name));
|
|
@@ -10117,13 +10289,25 @@ async function searchContent(ctx, startAbs, args) {
|
|
|
10117
10289
|
const text = raw.toString("utf8");
|
|
10118
10290
|
const rel = displayRel2(ctx.rootDir, full);
|
|
10119
10291
|
const lines = text.split(/\r?\n/);
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10292
|
+
let hits;
|
|
10293
|
+
if (reSource !== null) {
|
|
10294
|
+
try {
|
|
10295
|
+
hits = await getRegexRunner().testLines(text, reSource, reFlags, {
|
|
10296
|
+
signal: args.signal
|
|
10297
|
+
});
|
|
10298
|
+
} catch (err) {
|
|
10299
|
+
const reason = err.message;
|
|
10300
|
+
if (reason.includes("aborted")) throw err;
|
|
10301
|
+
regexSkippedFiles.push({ rel, reason });
|
|
10302
|
+
continue;
|
|
10303
|
+
}
|
|
10304
|
+
} else {
|
|
10305
|
+
hits = [];
|
|
10306
|
+
for (let li = 0; li < lines.length; li++) {
|
|
10307
|
+
throwIfAborted(args.signal);
|
|
10308
|
+
const lineForCheck = caseSensitive ? lines[li] : lines[li].toLowerCase();
|
|
10309
|
+
if (lineForCheck.includes(needle)) hits.push(li);
|
|
10310
|
+
}
|
|
10127
10311
|
}
|
|
10128
10312
|
scanned++;
|
|
10129
10313
|
if (hits.length === 0) continue;
|
|
@@ -10172,6 +10356,11 @@ async function searchContent(ctx, startAbs, args) {
|
|
|
10172
10356
|
}
|
|
10173
10357
|
};
|
|
10174
10358
|
await walk2(startAbs);
|
|
10359
|
+
if (regexSkippedFiles.length > 0) {
|
|
10360
|
+
pushLine(
|
|
10361
|
+
`[regex timed out on ${regexSkippedFiles.length} file${regexSkippedFiles.length === 1 ? "" : "s"} \u2014 pattern may have catastrophic backtracking; first: ${regexSkippedFiles[0].rel}]`
|
|
10362
|
+
);
|
|
10363
|
+
}
|
|
10175
10364
|
if (matches.length === 0) {
|
|
10176
10365
|
return scanned === 0 ? "(no files scanned \u2014 path empty or all files filtered out)" : `(no matches across ${scanned} file${scanned === 1 ? "" : "s"})`;
|
|
10177
10366
|
}
|
|
@@ -10236,11 +10425,15 @@ function registerFilesystemTools(registry, opts) {
|
|
|
10236
10425
|
const sessionApproved = /* @__PURE__ */ new Set();
|
|
10237
10426
|
const shownSubdirMemory = /* @__PURE__ */ new Set();
|
|
10238
10427
|
function withSubdirMemory(absPath, body) {
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10428
|
+
return prependMemorySections(findSubdirMemoryAncestors(absPath, rootDir), body);
|
|
10429
|
+
}
|
|
10430
|
+
function withDirMemory(absDir, body) {
|
|
10431
|
+
return prependMemorySections(findDirMemory(absDir, rootDir), body);
|
|
10432
|
+
}
|
|
10433
|
+
function prependMemorySections(memPaths, body) {
|
|
10434
|
+
if (!memoryEnabled() || memPaths.length === 0) return body;
|
|
10242
10435
|
const sections = [];
|
|
10243
|
-
for (const memPath of [...
|
|
10436
|
+
for (const memPath of [...memPaths].reverse()) {
|
|
10244
10437
|
if (shownSubdirMemory.has(memPath)) continue;
|
|
10245
10438
|
const content = readSubdirMemoryContent(memPath);
|
|
10246
10439
|
if (!content) continue;
|
|
@@ -10433,7 +10626,7 @@ ${slice.join("\n")}`);
|
|
|
10433
10626
|
for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
10434
10627
|
lines.push(e.isDirectory() ? `${e.name}/` : e.name);
|
|
10435
10628
|
}
|
|
10436
|
-
return lines.join("\n") || "(empty directory)";
|
|
10629
|
+
return withDirMemory(abs, lines.join("\n") || "(empty directory)");
|
|
10437
10630
|
}
|
|
10438
10631
|
});
|
|
10439
10632
|
registry.register({
|
|
@@ -11655,4 +11848,4 @@ export {
|
|
|
11655
11848
|
he/he.js:
|
|
11656
11849
|
(*! https://mths.be/he v1.2.0 by @mathias | MIT license *)
|
|
11657
11850
|
*/
|
|
11658
|
-
//# sourceMappingURL=chunk-
|
|
11851
|
+
//# sourceMappingURL=chunk-ICAFSZHS.js.map
|