reasonix 0.37.0 → 0.38.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 +1 -0
- package/README.zh-CN.md +1 -0
- package/dist/cli/{chat-7257YAPG.js → chat-FPEYKTMI.js} +13 -14
- package/dist/cli/{chunk-T52GAWPP.js → chunk-3VTV4WAH.js} +2 -2
- package/dist/cli/{chunk-MSKUP6PD.js → chunk-4PNXH2MH.js} +910 -659
- package/dist/cli/chunk-4PNXH2MH.js.map +1 -0
- package/dist/cli/{chunk-YER7WCHF.js → chunk-A63QT566.js} +24 -10
- package/dist/cli/chunk-A63QT566.js.map +1 -0
- package/dist/cli/{chunk-4Q3GRJIU.js → chunk-AATCLE5N.js} +2 -2
- package/dist/cli/{chunk-BHLHOS5Y.js → chunk-BW2HWSYH.js} +315 -5
- package/dist/cli/chunk-BW2HWSYH.js.map +1 -0
- package/dist/cli/{chunk-ZJR4QLXB.js → chunk-FB46F6H4.js} +2 -2
- package/dist/cli/{chunk-GKZJXYMY.js → chunk-FYKZB6TX.js} +415 -11
- package/dist/cli/chunk-FYKZB6TX.js.map +1 -0
- package/dist/cli/{chunk-XQIFIB3U.js → chunk-JOFZ6AW5.js} +2 -2
- package/dist/cli/{chunk-JGZKTAOH.js → chunk-LMNAMITH.js} +2 -2
- package/dist/cli/{chunk-S4GF3HPO.js → chunk-LY352GTC.js} +6 -4
- package/dist/cli/chunk-LY352GTC.js.map +1 -0
- package/dist/cli/{chunk-VF57YX2M.js → chunk-NYP2DDDV.js} +40 -1
- package/dist/cli/chunk-NYP2DDDV.js.map +1 -0
- package/dist/cli/{chunk-JULZ7JTO.js → chunk-T5U5JO7Q.js} +11 -8
- package/dist/cli/chunk-T5U5JO7Q.js.map +1 -0
- package/dist/cli/{chunk-SEFXUF24.js → chunk-YJKLNYCP.js} +113 -24
- package/dist/cli/chunk-YJKLNYCP.js.map +1 -0
- package/dist/cli/{code-64EG5IU2.js → code-GTE65OUT.js} +23 -17
- package/dist/cli/{code-64EG5IU2.js.map → code-GTE65OUT.js.map} +1 -1
- package/dist/cli/{commands-FE2UDFBC.js → commands-R4JWISND.js} +3 -4
- package/dist/cli/{commands-FE2UDFBC.js.map → commands-R4JWISND.js.map} +1 -1
- package/dist/cli/{commit-3IAGB22T.js → commit-TQ4DMUNS.js} +2 -3
- package/dist/cli/{commit-3IAGB22T.js.map → commit-TQ4DMUNS.js.map} +1 -1
- package/dist/cli/{doctor-BW5HSQDW.js → doctor-GGK2JKTA.js} +6 -7
- package/dist/cli/index.js +24 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-2RDEQST6.js → mcp-M7I23TQ7.js} +2 -3
- package/dist/cli/{mcp-2RDEQST6.js.map → mcp-M7I23TQ7.js.map} +1 -1
- package/dist/cli/{mcp-browse-VM5GLRBQ.js → mcp-browse-TWO7RYT4.js} +2 -3
- package/dist/cli/{mcp-browse-VM5GLRBQ.js.map → mcp-browse-TWO7RYT4.js.map} +1 -1
- package/dist/cli/{prompt-KGIUONO3.js → prompt-ODPFOKSH.js} +2 -2
- package/dist/cli/{replay-D7RT2DR7.js → replay-R3QRXPI2.js} +13 -9
- package/dist/cli/replay-R3QRXPI2.js.map +1 -0
- package/dist/cli/{run-RWCOA32G.js → run-WGSPYYOJ.js} +7 -8
- package/dist/cli/{run-RWCOA32G.js.map → run-WGSPYYOJ.js.map} +1 -1
- package/dist/cli/{server-6ZW4TQUP.js → server-IZPWQYG3.js} +8 -9
- package/dist/cli/{server-6ZW4TQUP.js.map → server-IZPWQYG3.js.map} +1 -1
- package/dist/cli/{sessions-5ISNWFMU.js → sessions-E4UH5JYL.js} +7 -8
- package/dist/cli/{sessions-5ISNWFMU.js.map → sessions-E4UH5JYL.js.map} +1 -1
- package/dist/cli/{setup-HJG23NKJ.js → setup-FTZNN3TZ.js} +60 -15
- package/dist/cli/setup-FTZNN3TZ.js.map +1 -0
- package/dist/cli/{version-BXAN7Q4V.js → version-MDVCFTKA.js} +7 -8
- package/dist/cli/{version-BXAN7Q4V.js.map → version-MDVCFTKA.js.map} +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +568 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-BHLHOS5Y.js.map +0 -1
- package/dist/cli/chunk-GKZJXYMY.js.map +0 -1
- package/dist/cli/chunk-JULZ7JTO.js.map +0 -1
- package/dist/cli/chunk-MSKUP6PD.js.map +0 -1
- package/dist/cli/chunk-S4GF3HPO.js.map +0 -1
- package/dist/cli/chunk-SEFXUF24.js.map +0 -1
- package/dist/cli/chunk-VF57YX2M.js.map +0 -1
- package/dist/cli/chunk-WUI3P4RA.js +0 -319
- package/dist/cli/chunk-WUI3P4RA.js.map +0 -1
- package/dist/cli/chunk-YER7WCHF.js.map +0 -1
- package/dist/cli/replay-D7RT2DR7.js.map +0 -1
- package/dist/cli/setup-HJG23NKJ.js.map +0 -1
- /package/dist/cli/{chat-7257YAPG.js.map → chat-FPEYKTMI.js.map} +0 -0
- /package/dist/cli/{chunk-T52GAWPP.js.map → chunk-3VTV4WAH.js.map} +0 -0
- /package/dist/cli/{chunk-4Q3GRJIU.js.map → chunk-AATCLE5N.js.map} +0 -0
- /package/dist/cli/{chunk-ZJR4QLXB.js.map → chunk-FB46F6H4.js.map} +0 -0
- /package/dist/cli/{chunk-XQIFIB3U.js.map → chunk-JOFZ6AW5.js.map} +0 -0
- /package/dist/cli/{chunk-JGZKTAOH.js.map → chunk-LMNAMITH.js.map} +0 -0
- /package/dist/cli/{doctor-BW5HSQDW.js.map → doctor-GGK2JKTA.js.map} +0 -0
- /package/dist/cli/{prompt-KGIUONO3.js.map → prompt-ODPFOKSH.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
MemoryStore,
|
|
4
4
|
sanitizeMemoryName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-A63QT566.js";
|
|
6
6
|
import {
|
|
7
7
|
countTokens,
|
|
8
8
|
estimateConversationTokens,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./chunk-KMWKGPFZ.js";
|
|
14
14
|
import {
|
|
15
15
|
pauseGate
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-LY352GTC.js";
|
|
17
17
|
import {
|
|
18
18
|
NEGATIVE_CLAIM_RULE,
|
|
19
19
|
TUI_FORMATTING_RULES
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
import {
|
|
22
22
|
formatHookOutcomeMessage,
|
|
23
23
|
runHooks
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-LMNAMITH.js";
|
|
25
25
|
import {
|
|
26
26
|
ignoredByLayers,
|
|
27
27
|
loadGitignoreAt,
|
|
@@ -36,12 +36,12 @@ import {
|
|
|
36
36
|
} from "./chunk-6CXT5JRM.js";
|
|
37
37
|
import {
|
|
38
38
|
t
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-FYKZB6TX.js";
|
|
40
40
|
import {
|
|
41
41
|
DEFAULT_INDEX_EXCLUDES,
|
|
42
42
|
webSearchEndpoint,
|
|
43
43
|
webSearchEngine
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-BW2HWSYH.js";
|
|
45
45
|
import {
|
|
46
46
|
DEEPSEEK_CONTEXT_TOKENS,
|
|
47
47
|
DEFAULT_CONTEXT_TOKENS,
|
|
@@ -309,6 +309,10 @@ var ToolRegistry = class {
|
|
|
309
309
|
setResultAugmenter(fn) {
|
|
310
310
|
this._resultAugmenter = fn;
|
|
311
311
|
}
|
|
312
|
+
/** True when an augmenter is already wired — lets late-installing callers skip clobbering an earlier one. */
|
|
313
|
+
get hasResultAugmenter() {
|
|
314
|
+
return this._resultAugmenter !== null;
|
|
315
|
+
}
|
|
312
316
|
register(def) {
|
|
313
317
|
if (!def.name) throw new Error("tool requires a name");
|
|
314
318
|
const internal = { ...def };
|
|
@@ -1375,6 +1379,7 @@ function signature(call) {
|
|
|
1375
1379
|
|
|
1376
1380
|
// src/loop.ts
|
|
1377
1381
|
var ESCALATION_MODEL = "deepseek-v4-pro";
|
|
1382
|
+
var PARENT_BUDGET_WARN_THRESHOLD = 5;
|
|
1378
1383
|
var CacheFirstLoop = class {
|
|
1379
1384
|
client;
|
|
1380
1385
|
prefix;
|
|
@@ -1411,6 +1416,7 @@ var CacheFirstLoop = class {
|
|
|
1411
1416
|
_turnFailures = new TurnFailureTracker();
|
|
1412
1417
|
_turnSelfCorrected = false;
|
|
1413
1418
|
_foldedThisTurn = false;
|
|
1419
|
+
_toolDispatchesThisStep = 0;
|
|
1414
1420
|
context;
|
|
1415
1421
|
/** Subscribe API so UI hooks can derive `running` from finally-guaranteed insertions. */
|
|
1416
1422
|
get inflight() {
|
|
@@ -1465,6 +1471,23 @@ var CacheFirstLoop = class {
|
|
|
1465
1471
|
stormThreshold: parsePositiveIntEnv(process.env.REASONIX_STORM_THRESHOLD),
|
|
1466
1472
|
stormWindow: parsePositiveIntEnv(process.env.REASONIX_STORM_WINDOW)
|
|
1467
1473
|
});
|
|
1474
|
+
if (!this.tools.hasResultAugmenter) {
|
|
1475
|
+
this.tools.setResultAugmenter((_name, _args, result) => {
|
|
1476
|
+
this._toolDispatchesThisStep++;
|
|
1477
|
+
const remaining = this.maxToolIters - this._toolDispatchesThisStep;
|
|
1478
|
+
if (remaining <= 0) {
|
|
1479
|
+
return `${result}
|
|
1480
|
+
|
|
1481
|
+
[budget: 0 of ${this.maxToolIters} tool calls left this turn \u2014 finalize NOW; the next iter forces a summary]`;
|
|
1482
|
+
}
|
|
1483
|
+
if (remaining <= PARENT_BUDGET_WARN_THRESHOLD) {
|
|
1484
|
+
return `${result}
|
|
1485
|
+
|
|
1486
|
+
[budget: ${remaining} of ${this.maxToolIters} tool calls left this turn \u2014 wrap up soon]`;
|
|
1487
|
+
}
|
|
1488
|
+
return result;
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1468
1491
|
this.sessionName = opts.session ?? null;
|
|
1469
1492
|
if (this.sessionName) {
|
|
1470
1493
|
const prior = loadSessionMessages(this.sessionName);
|
|
@@ -1718,6 +1741,7 @@ ${reason}`
|
|
|
1718
1741
|
this._turnSelfCorrected = false;
|
|
1719
1742
|
this._escalateThisTurn = false;
|
|
1720
1743
|
this._foldedThisTurn = false;
|
|
1744
|
+
this._toolDispatchesThisStep = 0;
|
|
1721
1745
|
let armedConsumed = false;
|
|
1722
1746
|
if (this._proArmedForNextTurn) {
|
|
1723
1747
|
this._escalateThisTurn = true;
|
|
@@ -3129,6 +3153,74 @@ Prefer \`list_directory\` for a single-level view, \`search_files\` to find spec
|
|
|
3129
3153
|
return `moved ${displayRel4(rootDir, src)} \u2192 ${displayRel4(rootDir, dst)}`;
|
|
3130
3154
|
}
|
|
3131
3155
|
});
|
|
3156
|
+
registry.register({
|
|
3157
|
+
name: "delete_file",
|
|
3158
|
+
description: "Delete one file under the sandbox root. Refuses directories \u2014 use delete_directory for those. Errors if the path doesn't exist.",
|
|
3159
|
+
parameters: {
|
|
3160
|
+
type: "object",
|
|
3161
|
+
properties: { path: { type: "string" } },
|
|
3162
|
+
required: ["path"]
|
|
3163
|
+
},
|
|
3164
|
+
fn: async (args) => {
|
|
3165
|
+
const abs = safePath(args.path);
|
|
3166
|
+
const st = await fs4.lstat(abs);
|
|
3167
|
+
if (st.isDirectory()) {
|
|
3168
|
+
throw new Error(
|
|
3169
|
+
`delete_file: ${args.path} is a directory \u2014 use delete_directory to remove it`
|
|
3170
|
+
);
|
|
3171
|
+
}
|
|
3172
|
+
await fs4.unlink(abs);
|
|
3173
|
+
return `deleted ${displayRel4(rootDir, abs)}`;
|
|
3174
|
+
}
|
|
3175
|
+
});
|
|
3176
|
+
registry.register({
|
|
3177
|
+
name: "delete_directory",
|
|
3178
|
+
description: "Recursively delete a directory under the sandbox root. Pass `recursive:false` to refuse non-empty directories. Errors if the path doesn't exist.",
|
|
3179
|
+
parameters: {
|
|
3180
|
+
type: "object",
|
|
3181
|
+
properties: {
|
|
3182
|
+
path: { type: "string" },
|
|
3183
|
+
recursive: {
|
|
3184
|
+
type: "boolean",
|
|
3185
|
+
description: "When true (default) deletes the directory and all its contents. When false, only removes empty directories \u2014 non-empty refuses with an error."
|
|
3186
|
+
}
|
|
3187
|
+
},
|
|
3188
|
+
required: ["path"]
|
|
3189
|
+
},
|
|
3190
|
+
fn: async (args) => {
|
|
3191
|
+
const abs = safePath(args.path);
|
|
3192
|
+
const st = await fs4.lstat(abs);
|
|
3193
|
+
if (!st.isDirectory()) {
|
|
3194
|
+
throw new Error(`delete_directory: ${args.path} is a file \u2014 use delete_file to remove it`);
|
|
3195
|
+
}
|
|
3196
|
+
const recursive = args.recursive !== false;
|
|
3197
|
+
if (recursive) {
|
|
3198
|
+
await fs4.rm(abs, { recursive: true, force: false });
|
|
3199
|
+
} else {
|
|
3200
|
+
await fs4.rmdir(abs);
|
|
3201
|
+
}
|
|
3202
|
+
return `deleted ${displayRel4(rootDir, abs)}/${recursive ? " (recursive)" : ""}`;
|
|
3203
|
+
}
|
|
3204
|
+
});
|
|
3205
|
+
registry.register({
|
|
3206
|
+
name: "copy_file",
|
|
3207
|
+
description: "Copy a file or directory under the sandbox root. Both source and destination resolve under the sandbox. Parent directories of the destination are created as needed. Refuses to overwrite an existing destination \u2014 delete it first if you want to replace it.",
|
|
3208
|
+
parameters: {
|
|
3209
|
+
type: "object",
|
|
3210
|
+
properties: {
|
|
3211
|
+
source: { type: "string" },
|
|
3212
|
+
destination: { type: "string" }
|
|
3213
|
+
},
|
|
3214
|
+
required: ["source", "destination"]
|
|
3215
|
+
},
|
|
3216
|
+
fn: async (args) => {
|
|
3217
|
+
const src = safePath(args.source);
|
|
3218
|
+
const dst = safePath(args.destination);
|
|
3219
|
+
await fs4.mkdir(pathMod4.dirname(dst), { recursive: true });
|
|
3220
|
+
await fs4.cp(src, dst, { recursive: true, force: false, errorOnExist: true });
|
|
3221
|
+
return `copied ${displayRel4(rootDir, src)} \u2192 ${displayRel4(rootDir, dst)}`;
|
|
3222
|
+
}
|
|
3223
|
+
});
|
|
3132
3224
|
return registry;
|
|
3133
3225
|
}
|
|
3134
3226
|
|
|
@@ -3667,16 +3759,19 @@ async function searchMojeek(query, opts = {}) {
|
|
|
3667
3759
|
signal: opts.signal,
|
|
3668
3760
|
redirect: "follow"
|
|
3669
3761
|
});
|
|
3670
|
-
if (!resp.ok) throw new Error(
|
|
3762
|
+
if (!resp.ok) throw new Error(t("webErrors.status", { status: resp.status }));
|
|
3671
3763
|
const html = await resp.text();
|
|
3672
3764
|
const results = parseMojeekResults(html).slice(0, topK);
|
|
3673
3765
|
if (results.length === 0) {
|
|
3674
3766
|
if (/no results found|did not match any documents/i.test(html)) return [];
|
|
3675
3767
|
if (/captcha|verify you are human|access denied|forbidden/i.test(html)) {
|
|
3676
|
-
throw new Error("
|
|
3768
|
+
throw new Error(t("webErrors.mojeekBlocked"));
|
|
3677
3769
|
}
|
|
3678
3770
|
throw new Error(
|
|
3679
|
-
|
|
3771
|
+
t("webErrors.mojeekNoResults", {
|
|
3772
|
+
chars: html.length,
|
|
3773
|
+
preview: html.slice(0, 120).replace(/\s+/g, " ")
|
|
3774
|
+
})
|
|
3680
3775
|
);
|
|
3681
3776
|
}
|
|
3682
3777
|
return results;
|
|
@@ -3686,10 +3781,10 @@ function normalizeSearxngEndpoint(raw) {
|
|
|
3686
3781
|
try {
|
|
3687
3782
|
url = new URL(raw.includes("://") ? raw : `http://${raw}`);
|
|
3688
3783
|
} catch {
|
|
3689
|
-
throw new Error(
|
|
3784
|
+
throw new Error(t("webErrors.invalidEndpoint", { endpoint: raw }));
|
|
3690
3785
|
}
|
|
3691
3786
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
3692
|
-
throw new Error(
|
|
3787
|
+
throw new Error(t("webErrors.endpointMustBeHttp", { protocol: url.protocol }));
|
|
3693
3788
|
}
|
|
3694
3789
|
return url.origin;
|
|
3695
3790
|
}
|
|
@@ -3709,19 +3804,17 @@ async function searchSearxng(query, opts = {}) {
|
|
|
3709
3804
|
} catch (err) {
|
|
3710
3805
|
if (err instanceof TypeError && err.message.includes("fetch")) {
|
|
3711
3806
|
throw new Error(
|
|
3712
|
-
|
|
3807
|
+
t("webErrors.cannotReach", { endpoint: opts.endpoint ?? "http://localhost:8080" })
|
|
3713
3808
|
);
|
|
3714
3809
|
}
|
|
3715
3810
|
throw err;
|
|
3716
3811
|
}
|
|
3717
|
-
if (!resp.ok) throw new Error(
|
|
3812
|
+
if (!resp.ok) throw new Error(t("webErrors.status", { status: resp.status }));
|
|
3718
3813
|
const html = await resp.text();
|
|
3719
3814
|
const results = parseSearxngHtmlResults(html).slice(0, topK);
|
|
3720
3815
|
if (results.length === 0) {
|
|
3721
3816
|
if (/no results found|did not match any documents/i.test(html)) return [];
|
|
3722
|
-
throw new Error(
|
|
3723
|
-
`web_search: 0 results but SearXNG response doesn't look like an empty results page (${html.length} chars)`
|
|
3724
|
-
);
|
|
3817
|
+
throw new Error(t("webErrors.searxngNoResults", { chars: html.length }));
|
|
3725
3818
|
}
|
|
3726
3819
|
return results;
|
|
3727
3820
|
}
|
|
@@ -3815,13 +3908,11 @@ async function webFetch(url, opts = {}) {
|
|
|
3815
3908
|
clearTimeout(timer);
|
|
3816
3909
|
opts.signal?.removeEventListener("abort", cancel);
|
|
3817
3910
|
}
|
|
3818
|
-
if (!resp.ok) throw new Error(
|
|
3911
|
+
if (!resp.ok) throw new Error(t("webErrors.fetchStatus", { status: resp.status, url }));
|
|
3819
3912
|
const contentType = resp.headers.get("content-type") ?? "";
|
|
3820
3913
|
const declaredLen = Number(resp.headers.get("content-length") ?? "");
|
|
3821
3914
|
if (Number.isFinite(declaredLen) && declaredLen > FETCH_MAX_BYTES) {
|
|
3822
|
-
throw new Error(
|
|
3823
|
-
`web_fetch refused: content-length ${declaredLen} bytes exceeds ${FETCH_MAX_BYTES}-byte cap (${url})`
|
|
3824
|
-
);
|
|
3915
|
+
throw new Error(t("webErrors.fetchTooLarge", { len: declaredLen, cap: FETCH_MAX_BYTES, url }));
|
|
3825
3916
|
}
|
|
3826
3917
|
const raw = await readBodyCapped(resp, FETCH_MAX_BYTES);
|
|
3827
3918
|
const title = extractTitle(raw);
|
|
@@ -3848,9 +3939,7 @@ async function readBodyCapped(resp, maxBytes) {
|
|
|
3848
3939
|
await reader.cancel();
|
|
3849
3940
|
} catch {
|
|
3850
3941
|
}
|
|
3851
|
-
throw new Error(
|
|
3852
|
-
`web_fetch refused: response body exceeded ${maxBytes}-byte cap (${total} bytes seen)`
|
|
3853
|
-
);
|
|
3942
|
+
throw new Error(t("webErrors.fetchBodyTooLarge", { cap: maxBytes, seen: total }));
|
|
3854
3943
|
}
|
|
3855
3944
|
out += decoder.decode(value, { stream: true });
|
|
3856
3945
|
}
|
|
@@ -3978,7 +4067,7 @@ function registerWebTools(registry, opts = {}) {
|
|
|
3978
4067
|
},
|
|
3979
4068
|
fn: async (args, ctx) => {
|
|
3980
4069
|
if (!/^https?:\/\//i.test(args.url)) {
|
|
3981
|
-
throw new Error("
|
|
4070
|
+
throw new Error(t("webErrors.fetchInvalidUrl"));
|
|
3982
4071
|
}
|
|
3983
4072
|
const page = await webFetch(args.url, { maxChars: maxFetchChars, signal: ctx?.signal });
|
|
3984
4073
|
const header = page.title ? `${page.title}
|
|
@@ -5077,4 +5166,4 @@ export {
|
|
|
5077
5166
|
snapshotBeforeEdits,
|
|
5078
5167
|
restoreSnapshots
|
|
5079
5168
|
};
|
|
5080
|
-
//# sourceMappingURL=chunk-
|
|
5169
|
+
//# sourceMappingURL=chunk-YJKLNYCP.js.map
|