reasonix 0.41.0 → 0.43.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 +26 -3
- package/dashboard/dist/app.js +98 -3
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{acp-64VQZLDJ.js → acp-DAGPCVFZ.js} +33 -28
- package/dist/cli/acp-DAGPCVFZ.js.map +1 -0
- package/dist/cli/chat-7ES4IBNH.js +50 -0
- package/dist/cli/{chunk-E46ECXJD.js → chunk-2425HK6U.js} +2 -1
- package/dist/cli/{chunk-E46ECXJD.js.map → chunk-2425HK6U.js.map} +1 -1
- package/dist/cli/chunk-25T6CVUP.js +172 -0
- package/dist/cli/chunk-25T6CVUP.js.map +1 -0
- package/dist/cli/{chunk-CD4SCQL4.js → chunk-2K65GZBT.js} +11 -2
- package/dist/cli/chunk-2K65GZBT.js.map +1 -0
- package/dist/cli/{chunk-H4OLWRSX.js → chunk-2KDUS647.js} +5 -4
- package/dist/cli/chunk-2KDUS647.js.map +1 -0
- package/dist/cli/chunk-2R4QCDOZ.js +11392 -0
- package/dist/cli/chunk-2R4QCDOZ.js.map +1 -0
- package/dist/cli/{chunk-3Q3C4W66.js → chunk-2UQP6H6T.js} +2 -1
- package/dist/cli/{chunk-3Q3C4W66.js.map → chunk-2UQP6H6T.js.map} +1 -1
- package/dist/cli/chunk-2Z35JOA4.js +96 -0
- package/dist/cli/chunk-2Z35JOA4.js.map +1 -0
- package/dist/cli/chunk-32TIKD5U.js +54 -0
- package/dist/cli/{chunk-L7W3HJZQ.js.map → chunk-32TIKD5U.js.map} +1 -1
- package/dist/cli/{chunk-A3LL4XDV.js → chunk-3BXRZFWS.js} +59 -3
- package/dist/cli/chunk-3BXRZFWS.js.map +1 -0
- package/dist/cli/{chunk-SXLJBFIV.js → chunk-3Z6IBU3D.js} +11 -7
- package/dist/cli/chunk-3Z6IBU3D.js.map +1 -0
- package/dist/cli/{chunk-A7VHMMDE.js → chunk-45U62RI3.js} +12 -5
- package/dist/cli/chunk-45U62RI3.js.map +1 -0
- package/dist/cli/{chunk-7VFNPMKG.js → chunk-4QUNBQQ2.js} +3 -2
- package/dist/cli/{chunk-7VFNPMKG.js.map → chunk-4QUNBQQ2.js.map} +1 -1
- package/dist/cli/{chunk-ARF3N2SY.js → chunk-5JJRUIPA.js} +4 -3
- package/dist/cli/{chunk-ARF3N2SY.js.map → chunk-5JJRUIPA.js.map} +1 -1
- package/dist/cli/{chunk-CFY2XLY6.js → chunk-6AK4EY3D.js} +7 -5
- package/dist/cli/{chunk-CFY2XLY6.js.map → chunk-6AK4EY3D.js.map} +1 -1
- package/dist/cli/chunk-6G3CUUFG.js +34320 -0
- package/dist/cli/chunk-6G3CUUFG.js.map +1 -0
- package/dist/cli/{chunk-YJFKFTAL.js → chunk-6PBZN4VI.js} +15 -3
- package/dist/cli/chunk-6PBZN4VI.js.map +1 -0
- package/dist/cli/{chunk-4W2CICFQ.js → chunk-6PZ3CXBP.js} +71 -60
- package/dist/cli/chunk-6PZ3CXBP.js.map +1 -0
- package/dist/cli/chunk-74EX7SUH.js +25293 -0
- package/dist/cli/chunk-74EX7SUH.js.map +1 -0
- package/dist/cli/{chunk-WE3YZULK.js → chunk-7O5ALB4C.js} +3 -2
- package/dist/cli/{chunk-WE3YZULK.js.map → chunk-7O5ALB4C.js.map} +1 -1
- package/dist/cli/{chunk-2CXPDAWX.js → chunk-DOYHN4KB.js} +3 -2
- package/dist/cli/{chunk-2CXPDAWX.js.map → chunk-DOYHN4KB.js.map} +1 -1
- package/dist/cli/{chunk-VFG4GIT3.js → chunk-F3PXYSNN.js} +3 -2
- package/dist/cli/{chunk-VFG4GIT3.js.map → chunk-F3PXYSNN.js.map} +1 -1
- package/dist/cli/{chunk-7SPOFTMT.js → chunk-FHOGSSCH.js} +4 -3
- package/dist/cli/{chunk-7SPOFTMT.js.map → chunk-FHOGSSCH.js.map} +1 -1
- package/dist/cli/{chunk-LTXADNCO.js → chunk-H6PS7IUE.js} +3 -2
- package/dist/cli/{chunk-LTXADNCO.js.map → chunk-H6PS7IUE.js.map} +1 -1
- package/dist/cli/{chunk-ZTLZO42A.js → chunk-HFEAY5DT.js} +3 -2
- package/dist/cli/{chunk-ZTLZO42A.js.map → chunk-HFEAY5DT.js.map} +1 -1
- package/dist/cli/{chunk-FWGEHRB7.js → chunk-J5XJHLWM.js} +2 -1
- package/dist/cli/{chunk-FWGEHRB7.js.map → chunk-J5XJHLWM.js.map} +1 -1
- package/dist/cli/{chunk-Y5XNV3NX.js → chunk-JMBMLOBP.js} +2 -1
- package/dist/cli/{chunk-Y5XNV3NX.js.map → chunk-JMBMLOBP.js.map} +1 -1
- package/dist/cli/{chunk-BYZGO3BX.js → chunk-O52OLQL3.js} +11 -3
- package/dist/cli/chunk-O52OLQL3.js.map +1 -0
- package/dist/cli/{chunk-4DCHFFEY.js → chunk-OSZC7C6F.js} +3 -2
- package/dist/cli/{chunk-4DCHFFEY.js.map → chunk-OSZC7C6F.js.map} +1 -1
- package/dist/cli/chunk-P7EKE5ZQ.js +60641 -0
- package/dist/cli/chunk-P7EKE5ZQ.js.map +1 -0
- package/dist/cli/{chunk-FM57FNPJ.js → chunk-PLHAZOLZ.js} +2 -1
- package/dist/cli/{chunk-FM57FNPJ.js.map → chunk-PLHAZOLZ.js.map} +1 -1
- package/dist/cli/{chunk-BOFL3T45.js → chunk-PQXPXJBJ.js} +12 -11
- package/dist/cli/chunk-PQXPXJBJ.js.map +1 -0
- package/dist/cli/{chunk-DAEAAVDF.js → chunk-PV55UMTO.js} +2 -1
- package/dist/cli/{chunk-DAEAAVDF.js.map → chunk-PV55UMTO.js.map} +1 -1
- package/dist/cli/{chunk-MHGPBJ2T.js → chunk-RE4RAVFF.js} +45 -10
- package/dist/cli/chunk-RE4RAVFF.js.map +1 -0
- package/dist/cli/chunk-S4XVGLRW.js +499 -0
- package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
- package/dist/cli/{chunk-WJ3YX4PZ.js → chunk-SZ5XES2N.js} +3 -2
- package/dist/cli/{chunk-WJ3YX4PZ.js.map → chunk-SZ5XES2N.js.map} +1 -1
- package/dist/cli/{chunk-UV7XJUJH.js → chunk-TJX6BFZZ.js} +16 -9
- package/dist/cli/{chunk-UV7XJUJH.js.map → chunk-TJX6BFZZ.js.map} +1 -1
- package/dist/cli/chunk-TUK7OWJA.js +51 -0
- package/dist/cli/{chunk-KZYLMMU5.js → chunk-VK5HG73G.js} +13 -12
- package/dist/cli/{chunk-KZYLMMU5.js.map → chunk-VK5HG73G.js.map} +1 -1
- package/dist/cli/{chunk-4H3ZRJ2U.js → chunk-XCGGEJTI.js} +4 -3
- package/dist/cli/{chunk-4H3ZRJ2U.js.map → chunk-XCGGEJTI.js.map} +1 -1
- package/dist/cli/{chunk-SOZE7V7V.js → chunk-XJXDHAES.js} +3 -2
- package/dist/cli/{chunk-SOZE7V7V.js.map → chunk-XJXDHAES.js.map} +1 -1
- package/dist/cli/chunk-XPDVG52A.js +2648 -0
- package/dist/cli/chunk-XPDVG52A.js.map +1 -0
- package/dist/cli/{chunk-CRPQUBP6.js → chunk-XXC2BYTV.js} +2 -1
- package/dist/cli/{chunk-CRPQUBP6.js.map → chunk-XXC2BYTV.js.map} +1 -1
- package/dist/cli/{chunk-AT6GGIBV.js → chunk-YFGF5NKA.js} +17 -14
- package/dist/cli/{chunk-AT6GGIBV.js.map → chunk-YFGF5NKA.js.map} +1 -1
- package/dist/cli/{chunk-ORM6PK57.js → chunk-YQ6NTIIE.js} +2 -1
- package/dist/cli/{chunk-ORM6PK57.js.map → chunk-YQ6NTIIE.js.map} +1 -1
- package/dist/cli/{chunk-RAUPWSYA.js → chunk-YYQAUTTN.js} +3 -2
- package/dist/cli/{chunk-RAUPWSYA.js.map → chunk-YYQAUTTN.js.map} +1 -1
- package/dist/cli/chunk-ZZM6QJ4W.js +109 -0
- package/dist/cli/chunk-ZZM6QJ4W.js.map +1 -0
- package/dist/cli/{code-X3M6ENTQ.js → code-SMKEW6CD.js} +60 -56
- package/dist/cli/code-SMKEW6CD.js.map +1 -0
- package/dist/cli/{commands-QY7MSQG7.js → commands-FVVB5FZF.js} +7 -5
- package/dist/cli/{commands-QY7MSQG7.js.map → commands-FVVB5FZF.js.map} +1 -1
- package/dist/cli/{commit-BRCQ3OQO.js → commit-HE4VSPZ7.js} +7 -4
- package/dist/cli/{commit-BRCQ3OQO.js.map → commit-HE4VSPZ7.js.map} +1 -1
- package/dist/cli/{desktop-ZTMHQR2Y.js → desktop-Q7NDXCON.js} +162 -74
- package/dist/cli/desktop-Q7NDXCON.js.map +1 -0
- package/dist/cli/devtools-YECO25QO.js +3719 -0
- package/dist/cli/devtools-YECO25QO.js.map +1 -0
- package/dist/cli/diff-435UTPC5.js +165 -0
- package/dist/cli/{diff-YASCB7PU.js.map → diff-435UTPC5.js.map} +1 -1
- package/dist/cli/doctor-OT7KH75K.js +27 -0
- package/dist/cli/{events-2AJTXR7I.js → events-XEFAD5VX.js} +6 -4
- package/dist/cli/{events-2AJTXR7I.js.map → events-XEFAD5VX.js.map} +1 -1
- package/dist/cli/index.js +3209 -133
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-YMWBLRR7.js → mcp-WUL2WO75.js} +6 -4
- package/dist/cli/{mcp-YMWBLRR7.js.map → mcp-WUL2WO75.js.map} +1 -1
- package/dist/cli/{mcp-browse-XLDUE6SB.js → mcp-browse-RR7R4XET.js} +32 -21
- package/dist/cli/{mcp-browse-XLDUE6SB.js.map → mcp-browse-RR7R4XET.js.map} +1 -1
- package/dist/cli/{mcp-inspect-H4D2HSJP.js → mcp-inspect-REGLYBWT.js} +8 -5
- package/dist/cli/{mcp-inspect-H4D2HSJP.js.map → mcp-inspect-REGLYBWT.js.map} +1 -1
- package/dist/cli/package.json +3 -0
- package/dist/cli/prompt-UW6EFLVR.js +16 -0
- package/dist/cli/{prune-sessions-4N3BVST2.js → prune-sessions-3RWUBYRS.js} +4 -2
- package/dist/cli/{prune-sessions-4N3BVST2.js.map → prune-sessions-3RWUBYRS.js.map} +1 -1
- package/dist/cli/{replay-3GTWM75X.js → replay-YOURXV4C.js} +42 -30
- package/dist/cli/{replay-3GTWM75X.js.map → replay-YOURXV4C.js.map} +1 -1
- package/dist/cli/{run-BLZPTRDX.js → run-Q6BUXV66.js} +24 -21
- package/dist/cli/{run-BLZPTRDX.js.map → run-Q6BUXV66.js.map} +1 -1
- package/dist/cli/{server-DRFPXXSH.js → server-XGDBRWMB.js} +40 -43
- package/dist/cli/server-XGDBRWMB.js.map +1 -0
- package/dist/cli/{sessions-BOWFPTXT.js → sessions-FH7QVYSY.js} +22 -19
- package/dist/cli/{sessions-BOWFPTXT.js.map → sessions-FH7QVYSY.js.map} +1 -1
- package/dist/cli/setup-VDS6SVEP.js +618 -0
- package/dist/cli/setup-VDS6SVEP.js.map +1 -0
- package/dist/cli/stats-MQVI2XQH.js +14 -0
- package/dist/cli/update-6ITLPRDV.js +15 -0
- package/dist/cli/update-6ITLPRDV.js.map +1 -0
- package/dist/cli/version-DAHGZY5N.js +33 -0
- package/dist/cli/{version-XQXYSJ5L.js.map → version-DAHGZY5N.js.map} +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +182 -97
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/acp-64VQZLDJ.js.map +0 -1
- package/dist/cli/chat-ZAGX52RV.js +0 -46
- package/dist/cli/chunk-4W2CICFQ.js.map +0 -1
- package/dist/cli/chunk-5X7LZJDE.js +0 -36
- package/dist/cli/chunk-5X7LZJDE.js.map +0 -1
- package/dist/cli/chunk-65Q5HQ26.js +0 -892
- package/dist/cli/chunk-65Q5HQ26.js.map +0 -1
- package/dist/cli/chunk-A3LL4XDV.js.map +0 -1
- package/dist/cli/chunk-A7VHMMDE.js.map +0 -1
- package/dist/cli/chunk-AFFZF3MW.js +0 -36
- package/dist/cli/chunk-AFFZF3MW.js.map +0 -1
- package/dist/cli/chunk-BOFL3T45.js.map +0 -1
- package/dist/cli/chunk-BYZGO3BX.js.map +0 -1
- package/dist/cli/chunk-CD4SCQL4.js.map +0 -1
- package/dist/cli/chunk-CPOV2O73.js +0 -39
- package/dist/cli/chunk-CPOV2O73.js.map +0 -1
- package/dist/cli/chunk-F2AV2QDK.js +0 -16514
- package/dist/cli/chunk-F2AV2QDK.js.map +0 -1
- package/dist/cli/chunk-H4OLWRSX.js.map +0 -1
- package/dist/cli/chunk-IEA6JOIP.js +0 -5430
- package/dist/cli/chunk-IEA6JOIP.js.map +0 -1
- package/dist/cli/chunk-L7W3HJZQ.js +0 -46
- package/dist/cli/chunk-LN27AKV3.js +0 -26
- package/dist/cli/chunk-LN27AKV3.js.map +0 -1
- package/dist/cli/chunk-MHGPBJ2T.js.map +0 -1
- package/dist/cli/chunk-SXLJBFIV.js.map +0 -1
- package/dist/cli/chunk-YJFKFTAL.js.map +0 -1
- package/dist/cli/code-X3M6ENTQ.js.map +0 -1
- package/dist/cli/desktop-ZTMHQR2Y.js.map +0 -1
- package/dist/cli/diff-YASCB7PU.js +0 -153
- package/dist/cli/doctor-XCN5ETVP.js +0 -24
- package/dist/cli/prompt-RSIHN62V.js +0 -14
- package/dist/cli/server-DRFPXXSH.js.map +0 -1
- package/dist/cli/setup-FQL2JJC2.js +0 -516
- package/dist/cli/setup-FQL2JJC2.js.map +0 -1
- package/dist/cli/stats-5RJCATCE.js +0 -12
- package/dist/cli/update-GUCWB4UN.js +0 -13
- package/dist/cli/version-XQXYSJ5L.js +0 -30
- /package/dist/cli/{chat-ZAGX52RV.js.map → chat-7ES4IBNH.js.map} +0 -0
- /package/dist/cli/{doctor-XCN5ETVP.js.map → chunk-TUK7OWJA.js.map} +0 -0
- /package/dist/cli/{prompt-RSIHN62V.js.map → doctor-OT7KH75K.js.map} +0 -0
- /package/dist/cli/{stats-5RJCATCE.js.map → prompt-UW6EFLVR.js.map} +0 -0
- /package/dist/cli/{update-GUCWB4UN.js.map → stats-MQVI2XQH.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -966,6 +966,7 @@ var EN = {
|
|
|
966
966
|
applied: "applied",
|
|
967
967
|
rejected: "rejected",
|
|
968
968
|
noDashboard: "Suppress the auto-launched embedded web dashboard.",
|
|
969
|
+
openDashboardHint: "Open the dashboard URL in your default browser as soon as the server is ready. No-op when --no-dashboard is set.",
|
|
969
970
|
dashboardPortHint: "Pin the dashboard to a fixed port (1\u201365535). Stable across restarts \u2014 required for SSH tunnels. Default: ephemeral.",
|
|
970
971
|
dashboardPortInvalid: "\u25B2 ignoring --dashboard-port={value} (must be an integer 1\u201365535) \u2014 falling back to ephemeral",
|
|
971
972
|
dashboardAutoStartFailed: "\u25B2 dashboard auto-start failed ({reason}) \u2014 try /dashboard, or pass --no-dashboard to silence",
|
|
@@ -1130,7 +1131,13 @@ var EN = {
|
|
|
1130
1131
|
jsonHintCatalog: "output as JSON",
|
|
1131
1132
|
jsonHintReport: "output the inspection report as JSON",
|
|
1132
1133
|
modelOverrideFlash: "override the model (default: deepseek-v4-flash)",
|
|
1133
|
-
skipConfirmHint: "skip the confirmation prompt"
|
|
1134
|
+
skipConfirmHint: "skip the confirmation prompt",
|
|
1135
|
+
yoloHint: "auto-approve plan checkpoints for this invocation (equivalent to editMode=yolo without mutating config)"
|
|
1136
|
+
},
|
|
1137
|
+
code: {
|
|
1138
|
+
workspaceConflict: "\u26A0 workspace contains another agent platform's files ({platforms}). Reasonix Code may read them as project content; relaunch with --dir <your-project> if that's not what you want.\n",
|
|
1139
|
+
systemAppendEmpty: "--system-append is empty \u2014 no prompt text will be appended\n",
|
|
1140
|
+
systemAppendFileReadError: 'Error: cannot read --system-append-file "{filePath}": {errorDetails}\n'
|
|
1134
1141
|
},
|
|
1135
1142
|
slash: {
|
|
1136
1143
|
help: { description: "show the full command reference" },
|
|
@@ -1276,6 +1283,14 @@ var EN = {
|
|
|
1276
1283
|
logs: {
|
|
1277
1284
|
description: "tail a background job's output (default last 80 lines)",
|
|
1278
1285
|
argsHint: "<id> [lines]"
|
|
1286
|
+
},
|
|
1287
|
+
btw: {
|
|
1288
|
+
description: "ask a quick side question \u2014 answered from a blank slate, never added to the conversation context",
|
|
1289
|
+
argsHint: "<question>"
|
|
1290
|
+
},
|
|
1291
|
+
"search-engine": {
|
|
1292
|
+
description: "switch web search backend \u2014 mojeek (default, no deps) or searxng (self-hosted)",
|
|
1293
|
+
argsHint: "<mojeek|searxng> [<endpoint>]"
|
|
1279
1294
|
}
|
|
1280
1295
|
},
|
|
1281
1296
|
wizard: {
|
|
@@ -1478,7 +1493,6 @@ var EN = {
|
|
|
1478
1493
|
flashEscalation: "\u21E7 flash requested escalation \u2014 retrying this turn on {model}{reasonSuffix}",
|
|
1479
1494
|
harvestStatus: "extracting plan state from reasoning\u2026",
|
|
1480
1495
|
autoEscalation: "\u21E7 auto-escalating to {model} for the rest of this turn \u2014 flash hit {breakdown}. Next turn falls back to {fallback} unless /pro is armed.",
|
|
1481
|
-
readOnlyLoopEscalation: "\u21E7 auto-escalating to {model} \u2014 flash made {n} consecutive read-only calls without producing an edit or final answer. Next turn falls back to {fallback} unless /pro is armed.",
|
|
1482
1496
|
repeatToolCallWarning: "Caught a repeated tool call \u2014 let the model see the issue and retry with a different approach.",
|
|
1483
1497
|
stormStuck: "Stopped a stuck retry loop \u2014 the model kept calling the same tool with identical args after a self-correction nudge. Try /retry, rephrase, or rule out the underlying blocker.",
|
|
1484
1498
|
stormSuppressed: "Suppressed {count} repeated tool call(s) \u2014 same name + args fired 3+ times.",
|
|
@@ -1859,7 +1873,8 @@ var EN = {
|
|
|
1859
1873
|
mb: " MB",
|
|
1860
1874
|
evt: " evt",
|
|
1861
1875
|
editsLabel: "edits:",
|
|
1862
|
-
mcpLoading: "MCP"
|
|
1876
|
+
mcpLoading: "MCP",
|
|
1877
|
+
ctx: "ctx"
|
|
1863
1878
|
},
|
|
1864
1879
|
editMode: {
|
|
1865
1880
|
plan: "PLAN MODE",
|
|
@@ -2232,7 +2247,9 @@ var EN = {
|
|
|
2232
2247
|
reconnect: "reconnect\u2026",
|
|
2233
2248
|
initDetail: "initialise \u2192 tools/list \u2192 resources/list",
|
|
2234
2249
|
reconnectDetail: "tearing down \xB7 re-handshake \xB7 listing tools",
|
|
2235
|
-
disabledDetail: "via /mcp disable {name}"
|
|
2250
|
+
disabledDetail: "via /mcp disable {name}",
|
|
2251
|
+
failedSetupHint: "\u2192 run `reasonix setup` to remove this entry, or fix the underlying issue (missing npm package, network, etc.).",
|
|
2252
|
+
failedSetupConfigHint: "\u2192 run `reasonix setup` to remove broken entries from your saved config."
|
|
2236
2253
|
},
|
|
2237
2254
|
checkpointPicker: {
|
|
2238
2255
|
title: "restore a checkpoint \u2014 {workspace}",
|
|
@@ -2330,6 +2347,7 @@ var zhCN = {
|
|
|
2330
2347
|
applied: "\u5DF2\u5E94\u7528",
|
|
2331
2348
|
rejected: "\u5DF2\u62D2\u7EDD",
|
|
2332
2349
|
noDashboard: "\u7981\u6B62\u81EA\u52A8\u542F\u52A8\u5D4C\u5165\u5F0F Web \u4EEA\u8868\u677F\u3002",
|
|
2350
|
+
openDashboardHint: "\u670D\u52A1\u5C31\u7EEA\u540E\u7ACB\u5373\u5728\u9ED8\u8BA4\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u4EEA\u8868\u677F\u5730\u5740\u3002\u8BBE\u7F6E\u4E86 --no-dashboard \u65F6\u4E0D\u751F\u6548\u3002",
|
|
2333
2351
|
dashboardPortHint: "\u5C06\u4EEA\u8868\u677F\u7ED1\u5B9A\u5230\u56FA\u5B9A\u7AEF\u53E3 (1\u201365535)\u3002\u91CD\u542F\u540E\u4FDD\u6301\u7A33\u5B9A \u2014 SSH \u96A7\u9053\u8BBF\u95EE\u5FC5\u9700\u3002\u9ED8\u8BA4\u4E3A\u4E34\u65F6\u7AEF\u53E3\u3002",
|
|
2334
2352
|
dashboardPortInvalid: "\u25B2 \u5FFD\u7565 --dashboard-port={value} (\u5FC5\u987B\u4E3A 1\u201365535 \u4E4B\u95F4\u7684\u6574\u6570) \u2014 \u56DE\u9000\u5230\u4E34\u65F6\u7AEF\u53E3",
|
|
2335
2353
|
dashboardAutoStartFailed: "\u25B2 \u4EEA\u8868\u677F\u81EA\u52A8\u542F\u52A8\u5931\u8D25 ({reason}) \u2014 \u5C1D\u8BD5 /dashboard\uFF0C\u6216\u4F20\u9012 --no-dashboard \u4EE5\u9759\u9ED8",
|
|
@@ -2491,7 +2509,13 @@ var zhCN = {
|
|
|
2491
2509
|
jsonHintCatalog: "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA",
|
|
2492
2510
|
jsonHintReport: "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u68C0\u67E5\u62A5\u544A",
|
|
2493
2511
|
modelOverrideFlash: "\u8986\u76D6\u6A21\u578B\uFF08\u9ED8\u8BA4\uFF1Adeepseek-v4-flash\uFF09",
|
|
2494
|
-
skipConfirmHint: "\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A"
|
|
2512
|
+
skipConfirmHint: "\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A",
|
|
2513
|
+
yoloHint: "\u81EA\u52A8\u6279\u51C6\u672C\u6B21\u8C03\u7528\u7684\u8BA1\u5212\u68C0\u67E5\u70B9\uFF08\u7B49\u540C\u4E8E editMode=yolo\uFF0C\u4F46\u4E0D\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6\uFF09"
|
|
2514
|
+
},
|
|
2515
|
+
code: {
|
|
2516
|
+
workspaceConflict: "\u26A0 \u5DE5\u4F5C\u533A\u5305\u542B\u53E6\u4E00\u4E2A\u667A\u80FD\u4F53\u5E73\u53F0\u7684\u6587\u4EF6 ({platforms})\u3002Reasonix Code \u53EF\u80FD\u4F1A\u5C06\u5176\u4F5C\u4E3A\u9879\u76EE\u5185\u5BB9\u8BFB\u53D6\uFF1B\u5982\u679C\u4E0D\u662F\u60A8\u60F3\u8981\u7684\uFF0C\u8BF7\u4F7F\u7528 --dir <your-project> \u91CD\u65B0\u542F\u52A8\u3002\n",
|
|
2517
|
+
systemAppendEmpty: "--system-append \u4E3A\u7A7A \u2014 \u4E0D\u4F1A\u8FFD\u52A0\u4EFB\u4F55\u63D0\u793A\u6587\u672C\n",
|
|
2518
|
+
systemAppendFileReadError: '\u9519\u8BEF\uFF1A\u65E0\u6CD5\u8BFB\u53D6 --system-append-file "{filePath}"\uFF1A{errorDetails}\n'
|
|
2495
2519
|
},
|
|
2496
2520
|
slash: {
|
|
2497
2521
|
help: { description: "\u663E\u793A\u5B8C\u6574\u547D\u4EE4\u53C2\u8003" },
|
|
@@ -2641,6 +2665,14 @@ var zhCN = {
|
|
|
2641
2665
|
logs: {
|
|
2642
2666
|
description: "\u8DDF\u8E2A\u540E\u53F0\u4F5C\u4E1A\u7684\u8F93\u51FA\uFF08\u9ED8\u8BA4\u6700\u540E 80 \u884C\uFF09",
|
|
2643
2667
|
argsHint: "<id> [lines]"
|
|
2668
|
+
},
|
|
2669
|
+
btw: {
|
|
2670
|
+
description: "\u987A\u4FBF\u95EE\u4E00\u4E0B \u2014 \u4ECE\u7A7A\u767D\u4E0A\u4E0B\u6587\u56DE\u7B54\uFF0C\u4E0D\u5199\u5165\u4F1A\u8BDD\u5386\u53F2",
|
|
2671
|
+
argsHint: "<question>"
|
|
2672
|
+
},
|
|
2673
|
+
"search-engine": {
|
|
2674
|
+
description: "\u5207\u6362\u7F51\u7EDC\u641C\u7D22\u540E\u7AEF \u2014 mojeek\uFF08\u9ED8\u8BA4\uFF0C\u65E0\u4F9D\u8D56\uFF09\u6216 searxng\uFF08\u81EA\u6258\u7BA1\uFF09",
|
|
2675
|
+
argsHint: "<mojeek|searxng> [<endpoint>]"
|
|
2644
2676
|
}
|
|
2645
2677
|
},
|
|
2646
2678
|
wizard: {
|
|
@@ -2843,7 +2875,6 @@ var zhCN = {
|
|
|
2843
2875
|
flashEscalation: "\u21E7 flash \u8BF7\u6C42\u5347\u7EA7 \u2014 \u672C\u8F6E\u6539\u7528 {model}{reasonSuffix}",
|
|
2844
2876
|
harvestStatus: "\u6B63\u5728\u4ECE\u63A8\u7406\u8FC7\u7A0B\u63D0\u53D6\u8BA1\u5212\u72B6\u6001\u2026",
|
|
2845
2877
|
autoEscalation: "\u21E7 \u672C\u8F6E\u5269\u4F59\u8C03\u7528\u81EA\u52A8\u5347\u7EA7\u5230 {model} \u2014 flash \u547D\u4E2D {breakdown}\u3002\u4E0B\u4E00\u8F6E\u56DE\u9000\u5230 {fallback}\uFF0C\u9664\u975E\u5DF2\u88C5\u5907 /pro\u3002",
|
|
2846
|
-
readOnlyLoopEscalation: "\u21E7 \u81EA\u52A8\u5347\u7EA7\u5230 {model} \u2014 flash \u8FDE\u7EED {n} \u6B21\u53EA\u8BFB\u8C03\u7528\uFF0C\u672A\u4EA7\u51FA\u4FEE\u6539\u6216\u6700\u7EC8\u7B54\u6848\u3002\u4E0B\u4E00\u8F6E\u56DE\u9000\u5230 {fallback}\uFF0C\u9664\u975E\u5DF2\u88C5\u5907 /pro\u3002",
|
|
2847
2878
|
repeatToolCallWarning: "\u62E6\u622A\u5230\u91CD\u590D\u5DE5\u5177\u8C03\u7528 \u2014 \u8BA9\u6A21\u578B\u5BDF\u89C9\u95EE\u9898\u5E76\u6362\u79CD\u65B9\u5F0F\u91CD\u8BD5\u3002",
|
|
2848
2879
|
stormStuck: "\u5DF2\u505C\u6B62\u5361\u6B7B\u7684\u91CD\u8BD5\u5FAA\u73AF \u2014 \u6A21\u578B\u5728\u81EA\u7EA0\u63D0\u793A\u540E\u4ECD\u4EE5\u76F8\u540C\u53C2\u6570\u91CD\u590D\u8C03\u7528\u540C\u4E00\u5DE5\u5177\u3002\u8BF7\u5C1D\u8BD5 /retry\u3001\u6362\u79CD\u8BF4\u6CD5\uFF0C\u6216\u6392\u67E5\u5E95\u5C42\u963B\u585E\u3002",
|
|
2849
2880
|
stormSuppressed: "\u5DF2\u6291\u5236 {count} \u6B21\u91CD\u590D\u5DE5\u5177\u8C03\u7528 \u2014 \u540C\u4E00\u540D\u79F0 + \u53C2\u6570\u89E6\u53D1 3 \u6B21\u4EE5\u4E0A\u3002",
|
|
@@ -3224,7 +3255,8 @@ var zhCN = {
|
|
|
3224
3255
|
mb: " MB",
|
|
3225
3256
|
evt: " \u4E8B\u4EF6",
|
|
3226
3257
|
editsLabel: "\u7F16\u8F91:",
|
|
3227
|
-
mcpLoading: "MCP"
|
|
3258
|
+
mcpLoading: "MCP",
|
|
3259
|
+
ctx: "\u4E0A\u4E0B\u6587"
|
|
3228
3260
|
},
|
|
3229
3261
|
editMode: {
|
|
3230
3262
|
plan: "\u8BA1\u5212",
|
|
@@ -3597,7 +3629,9 @@ var zhCN = {
|
|
|
3597
3629
|
reconnect: "\u91CD\u8FDE\u4E2D\u2026",
|
|
3598
3630
|
initDetail: "\u521D\u59CB\u5316 \u2192 tools/list \u2192 resources/list",
|
|
3599
3631
|
reconnectDetail: "\u65AD\u5F00\u65E7\u8FDE\u63A5 \xB7 \u91CD\u65B0\u63E1\u624B \xB7 \u5217\u51FA\u5DE5\u5177",
|
|
3600
|
-
disabledDetail: "\u901A\u8FC7 /mcp disable {name}"
|
|
3632
|
+
disabledDetail: "\u901A\u8FC7 /mcp disable {name}",
|
|
3633
|
+
failedSetupHint: "\u2192 \u8FD0\u884C `reasonix setup` \u79FB\u9664\u6B64\u6761\u76EE\uFF0C\u6216\u4FEE\u590D\u5E95\u5C42\u95EE\u9898\uFF08\u7F3A\u5C11 npm \u5305\u3001\u7F51\u7EDC\u7B49\uFF09\u3002",
|
|
3634
|
+
failedSetupConfigHint: "\u2192 \u8FD0\u884C `reasonix setup` \u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u4E2D\u79FB\u9664\u635F\u574F\u7684\u6761\u76EE\u3002"
|
|
3601
3635
|
},
|
|
3602
3636
|
checkpointPicker: {
|
|
3603
3637
|
title: "\u6062\u590D\u68C0\u67E5\u70B9 \u2014 {workspace}",
|
|
@@ -4581,7 +4615,7 @@ import {
|
|
|
4581
4615
|
writeFileSync as writeFileSync2
|
|
4582
4616
|
} from "fs";
|
|
4583
4617
|
import { homedir as homedir3 } from "os";
|
|
4584
|
-
import { dirname as dirname3, join as join4 } from "path";
|
|
4618
|
+
import { dirname as dirname3, join as join4, posix as posixPath, win32 as win32Path } from "path";
|
|
4585
4619
|
function sessionsDir() {
|
|
4586
4620
|
return join4(homedir3(), ".reasonix", "sessions");
|
|
4587
4621
|
}
|
|
@@ -4868,6 +4902,23 @@ var HISTORY_FOLD_MIN_SAVINGS_FRACTION = 0.3;
|
|
|
4868
4902
|
var FORCE_SUMMARY_THRESHOLD = 0.8;
|
|
4869
4903
|
var PREFLIGHT_EMERGENCY_THRESHOLD = 0.95;
|
|
4870
4904
|
var HISTORY_FOLD_MARKER = "[CONVERSATION HISTORY SUMMARY \u2014 earlier turns folded for context efficiency]\n\n";
|
|
4905
|
+
var SKILL_PIN_MEMO_HEADER = "[Active skill memos \u2014 preserved verbatim across the fold:]";
|
|
4906
|
+
var SKILL_PIN_REGEX = /<skill-pin name="([^"]+)">\n[\s\S]*?\n<\/skill-pin>/g;
|
|
4907
|
+
function extractPinnedSkills(head) {
|
|
4908
|
+
const pinned = /* @__PURE__ */ new Map();
|
|
4909
|
+
const stubbedHead = head.map((msg) => {
|
|
4910
|
+
if (typeof msg.content !== "string") return msg;
|
|
4911
|
+
let hit = false;
|
|
4912
|
+
const next = msg.content.replace(SKILL_PIN_REGEX, (full, name) => {
|
|
4913
|
+
pinned.delete(name);
|
|
4914
|
+
pinned.set(name, full);
|
|
4915
|
+
hit = true;
|
|
4916
|
+
return `[skill ${JSON.stringify(name)} memo \u2014 preserved separately, do not summarize.]`;
|
|
4917
|
+
});
|
|
4918
|
+
return hit ? { ...msg, content: next } : msg;
|
|
4919
|
+
});
|
|
4920
|
+
return { stubbedHead, pinnedBodies: [...pinned.values()] };
|
|
4921
|
+
}
|
|
4871
4922
|
var ContextManager = class {
|
|
4872
4923
|
constructor(deps) {
|
|
4873
4924
|
this.deps = deps;
|
|
@@ -4937,11 +4988,17 @@ var ContextManager = class {
|
|
|
4937
4988
|
const tail = all.slice(boundary);
|
|
4938
4989
|
const headTokens = totalTokens - cumTokens;
|
|
4939
4990
|
if (headTokens < totalTokens * HISTORY_FOLD_MIN_SAVINGS_FRACTION) return noop;
|
|
4940
|
-
const
|
|
4991
|
+
const { stubbedHead, pinnedBodies } = extractPinnedSkills(head);
|
|
4992
|
+
const summary = await this.summarizeForFold(stubbedHead);
|
|
4941
4993
|
if (!summary) return noop;
|
|
4994
|
+
const memoTail = pinnedBodies.length > 0 ? `
|
|
4995
|
+
|
|
4996
|
+
${SKILL_PIN_MEMO_HEADER}
|
|
4997
|
+
|
|
4998
|
+
${pinnedBodies.join("\n\n")}` : "";
|
|
4942
4999
|
const summaryMsg = {
|
|
4943
5000
|
role: "assistant",
|
|
4944
|
-
content: HISTORY_FOLD_MARKER + summary
|
|
5001
|
+
content: HISTORY_FOLD_MARKER + summary + memoTail
|
|
4945
5002
|
};
|
|
4946
5003
|
const replacement = [summaryMsg, ...tail];
|
|
4947
5004
|
this.deps.log.compactInPlace(replacement);
|
|
@@ -5166,6 +5223,8 @@ function buildSyntheticAssistantMessage(content, fallbackModel) {
|
|
|
5166
5223
|
}
|
|
5167
5224
|
|
|
5168
5225
|
// src/loop/force-summary.ts
|
|
5226
|
+
var PAUSE_SUMMARY_MODEL = "deepseek-v4-flash";
|
|
5227
|
+
var PAUSE_SUMMARY_EFFORT = "high";
|
|
5169
5228
|
async function* forceSummaryAfterIterLimit(ctx, opts = { reason: "budget" }) {
|
|
5170
5229
|
try {
|
|
5171
5230
|
yield { turn: ctx.turn, role: "status", content: t("summary.status") };
|
|
@@ -5211,6 +5270,28 @@ ${summary}`;
|
|
|
5211
5270
|
yield { turn: ctx.turn, role: "done", content: "" };
|
|
5212
5271
|
}
|
|
5213
5272
|
}
|
|
5273
|
+
async function summarizePartialProgress(ctx) {
|
|
5274
|
+
try {
|
|
5275
|
+
const messages = ctx.buildMessages();
|
|
5276
|
+
messages.push({
|
|
5277
|
+
role: "user",
|
|
5278
|
+
content: "You're being paused at a checkpoint, not stopped. In 3-6 sentences of plain prose, tell the parent agent: (1) what you accomplished so far, (2) what's still left, (3) any blockers or open questions. Be concrete \u2014 mention specific files / functions / tool results \u2014 so the parent can decide whether to resume you or take over. Do NOT emit any tool calls, function-call markup, DSML invocations, or SEARCH/REPLACE edit blocks \u2014 they will be silently discarded. Just plain text."
|
|
5279
|
+
});
|
|
5280
|
+
const resp = await ctx.client.chat({
|
|
5281
|
+
model: PAUSE_SUMMARY_MODEL,
|
|
5282
|
+
messages,
|
|
5283
|
+
signal: ctx.signal,
|
|
5284
|
+
thinking: thinkingModeForModel(PAUSE_SUMMARY_MODEL),
|
|
5285
|
+
reasoningEffort: PAUSE_SUMMARY_EFFORT
|
|
5286
|
+
});
|
|
5287
|
+
const cleaned = stripHallucinatedToolMarkup(resp.content?.trim() ?? "");
|
|
5288
|
+
if (!cleaned) return null;
|
|
5289
|
+
const stats = ctx.recordStats(PAUSE_SUMMARY_MODEL, resp.usage ?? new Usage());
|
|
5290
|
+
return { summary: cleaned, stats };
|
|
5291
|
+
} catch {
|
|
5292
|
+
return null;
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5214
5295
|
|
|
5215
5296
|
// src/loop/shrink.ts
|
|
5216
5297
|
function looksLikeCompleteJson(s) {
|
|
@@ -5348,32 +5429,6 @@ function* hookWarnings(outcomes, turn) {
|
|
|
5348
5429
|
}
|
|
5349
5430
|
}
|
|
5350
5431
|
|
|
5351
|
-
// src/loop/read-only-loop-tracker.ts
|
|
5352
|
-
var READONLY_LOOP_ESCALATION_THRESHOLD = 8;
|
|
5353
|
-
var ReadOnlyLoopTracker = class {
|
|
5354
|
-
streak = 0;
|
|
5355
|
-
threshold;
|
|
5356
|
-
constructor(threshold = READONLY_LOOP_ESCALATION_THRESHOLD) {
|
|
5357
|
-
this.threshold = Math.max(1, threshold);
|
|
5358
|
-
}
|
|
5359
|
-
reset() {
|
|
5360
|
-
this.streak = 0;
|
|
5361
|
-
}
|
|
5362
|
-
/** True ONLY on the call where the streak crosses the configured threshold. */
|
|
5363
|
-
noteAndCrossedThreshold(isReadOnly) {
|
|
5364
|
-
if (!isReadOnly) {
|
|
5365
|
-
this.streak = 0;
|
|
5366
|
-
return false;
|
|
5367
|
-
}
|
|
5368
|
-
const before = this.streak;
|
|
5369
|
-
this.streak += 1;
|
|
5370
|
-
return before < this.threshold && this.streak >= this.threshold;
|
|
5371
|
-
}
|
|
5372
|
-
get currentStreak() {
|
|
5373
|
-
return this.streak;
|
|
5374
|
-
}
|
|
5375
|
-
};
|
|
5376
|
-
|
|
5377
5432
|
// src/loop/turn-failure-tracker.ts
|
|
5378
5433
|
var FAILURE_ESCALATION_THRESHOLD = 3;
|
|
5379
5434
|
var TurnFailureTracker = class {
|
|
@@ -5856,6 +5911,7 @@ var CacheFirstLoop = class {
|
|
|
5856
5911
|
/** One-shot 80% warning latch — cleared by setBudget so a bump re-arms at the new boundary. */
|
|
5857
5912
|
_budgetWarned = false;
|
|
5858
5913
|
sessionName;
|
|
5914
|
+
onIterBudgetExhausted;
|
|
5859
5915
|
hooks;
|
|
5860
5916
|
hookCwd;
|
|
5861
5917
|
/** PauseGate bridge — defaults to singleton, injectable for tests. */
|
|
@@ -5872,7 +5928,6 @@ var CacheFirstLoop = class {
|
|
|
5872
5928
|
_proArmedForNextTurn = false;
|
|
5873
5929
|
_escalateThisTurn = false;
|
|
5874
5930
|
_turnFailures;
|
|
5875
|
-
_readOnlyLoop;
|
|
5876
5931
|
_turnSelfCorrected = false;
|
|
5877
5932
|
_foldedThisTurn = false;
|
|
5878
5933
|
_toolDispatchesThisStep = 0;
|
|
@@ -5895,10 +5950,8 @@ var CacheFirstLoop = class {
|
|
|
5895
5950
|
this._turnFailures = new TurnFailureTracker(
|
|
5896
5951
|
resolveFailureThreshold(opts.failureThreshold, FAILURE_ESCALATION_THRESHOLD)
|
|
5897
5952
|
);
|
|
5898
|
-
this._readOnlyLoop = new ReadOnlyLoopTracker(
|
|
5899
|
-
parsePositiveIntEnv(process.env.REASONIX_READONLY_LOOP_THRESHOLD) ?? READONLY_LOOP_ESCALATION_THRESHOLD
|
|
5900
|
-
);
|
|
5901
5953
|
this.maxToolIters = opts.maxToolIters ?? 64;
|
|
5954
|
+
this.onIterBudgetExhausted = opts.onIterBudgetExhausted ?? "summarize";
|
|
5902
5955
|
this.hooks = opts.hooks ?? [];
|
|
5903
5956
|
this.hookCwd = opts.hookCwd ?? process.cwd();
|
|
5904
5957
|
this.confirmationGate = opts.confirmationGate ?? pauseGate;
|
|
@@ -6074,14 +6127,6 @@ var CacheFirstLoop = class {
|
|
|
6074
6127
|
this._escalateThisTurn = true;
|
|
6075
6128
|
return true;
|
|
6076
6129
|
}
|
|
6077
|
-
/** Returns true ONLY on the call where the read-only streak crosses the threshold (#681). */
|
|
6078
|
-
noteReadOnlyToolCall(call) {
|
|
6079
|
-
const isReadOnly = !this.isMutating(call);
|
|
6080
|
-
if (!this._readOnlyLoop.noteAndCrossedThreshold(isReadOnly)) return false;
|
|
6081
|
-
if (this._escalateThisTurn || !this.autoEscalate) return false;
|
|
6082
|
-
this._escalateThisTurn = true;
|
|
6083
|
-
return true;
|
|
6084
|
-
}
|
|
6085
6130
|
/** A call counts as mutating when its definition reports `readOnly !== true` and any dynamic `readOnlyCheck` doesn't override that for these args. */
|
|
6086
6131
|
isMutating(call) {
|
|
6087
6132
|
const name = call.function?.name;
|
|
@@ -6223,7 +6268,6 @@ ${reason}`
|
|
|
6223
6268
|
this.scratch.reset();
|
|
6224
6269
|
this.repair.resetStorm();
|
|
6225
6270
|
this._turnFailures.reset();
|
|
6226
|
-
this._readOnlyLoop.reset();
|
|
6227
6271
|
this._turnSelfCorrected = false;
|
|
6228
6272
|
this._escalateThisTurn = false;
|
|
6229
6273
|
this._foldedThisTurn = false;
|
|
@@ -6341,6 +6385,15 @@ ${reason}`
|
|
|
6341
6385
|
thinking: thinkingModeForModel(callModel),
|
|
6342
6386
|
reasoningEffort: this.reasoningEffort
|
|
6343
6387
|
})) {
|
|
6388
|
+
if (chunk.reasoningDelta) {
|
|
6389
|
+
reasoningContent += chunk.reasoningDelta;
|
|
6390
|
+
yield {
|
|
6391
|
+
turn: this._turn,
|
|
6392
|
+
role: "assistant_delta",
|
|
6393
|
+
content: "",
|
|
6394
|
+
reasoningDelta: chunk.reasoningDelta
|
|
6395
|
+
};
|
|
6396
|
+
}
|
|
6344
6397
|
if (chunk.contentDelta) {
|
|
6345
6398
|
assistantContent += chunk.contentDelta;
|
|
6346
6399
|
if (bufferForEscalation && !escalationBufFlushed) {
|
|
@@ -6365,15 +6418,6 @@ ${reason}`
|
|
|
6365
6418
|
};
|
|
6366
6419
|
}
|
|
6367
6420
|
}
|
|
6368
|
-
if (chunk.reasoningDelta) {
|
|
6369
|
-
reasoningContent += chunk.reasoningDelta;
|
|
6370
|
-
yield {
|
|
6371
|
-
turn: this._turn,
|
|
6372
|
-
role: "assistant_delta",
|
|
6373
|
-
content: "",
|
|
6374
|
-
reasoningDelta: chunk.reasoningDelta
|
|
6375
|
-
};
|
|
6376
|
-
}
|
|
6377
6421
|
if (chunk.toolCallDelta) {
|
|
6378
6422
|
const d = chunk.toolCallDelta;
|
|
6379
6423
|
const cur = callBuf.get(d.index) ?? {
|
|
@@ -6650,17 +6694,6 @@ ${reason}`
|
|
|
6650
6694
|
})
|
|
6651
6695
|
};
|
|
6652
6696
|
}
|
|
6653
|
-
if (this.noteReadOnlyToolCall(call)) {
|
|
6654
|
-
yield {
|
|
6655
|
-
turn: this._turn,
|
|
6656
|
-
role: "warning",
|
|
6657
|
-
content: t("loop.readOnlyLoopEscalation", {
|
|
6658
|
-
model: ESCALATION_MODEL,
|
|
6659
|
-
n: this._readOnlyLoop.currentStreak,
|
|
6660
|
-
fallback: this.model
|
|
6661
|
-
})
|
|
6662
|
-
};
|
|
6663
|
-
}
|
|
6664
6697
|
yield {
|
|
6665
6698
|
turn: this._turn,
|
|
6666
6699
|
role: "tool",
|
|
@@ -6672,6 +6705,19 @@ ${reason}`
|
|
|
6672
6705
|
}
|
|
6673
6706
|
}
|
|
6674
6707
|
}
|
|
6708
|
+
if (this.onIterBudgetExhausted === "pause") {
|
|
6709
|
+
const partial = await summarizePartialProgress(this.summaryContext());
|
|
6710
|
+
yield {
|
|
6711
|
+
turn: this._turn,
|
|
6712
|
+
role: "paused",
|
|
6713
|
+
content: "",
|
|
6714
|
+
sessionName: this.sessionName ?? void 0,
|
|
6715
|
+
pausedAtIter: this.maxToolIters,
|
|
6716
|
+
partialSummary: partial?.summary
|
|
6717
|
+
};
|
|
6718
|
+
yield { turn: this._turn, role: "done", content: "" };
|
|
6719
|
+
return;
|
|
6720
|
+
}
|
|
6675
6721
|
yield* forceSummaryAfterIterLimit(this.summaryContext(), { reason: "budget" });
|
|
6676
6722
|
}
|
|
6677
6723
|
summaryContext() {
|
|
@@ -7364,6 +7410,12 @@ function parseAllowedTools(raw) {
|
|
|
7364
7410
|
const names = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7365
7411
|
return names.length > 0 ? Object.freeze(names) : void 0;
|
|
7366
7412
|
}
|
|
7413
|
+
function parseMaxToolIters(raw) {
|
|
7414
|
+
if (raw === void 0) return void 0;
|
|
7415
|
+
const n = Number.parseInt(raw.trim(), 10);
|
|
7416
|
+
if (!Number.isFinite(n) || n < 1) return void 0;
|
|
7417
|
+
return n;
|
|
7418
|
+
}
|
|
7367
7419
|
var SkillStore = class {
|
|
7368
7420
|
homeDir;
|
|
7369
7421
|
projectRoot;
|
|
@@ -7494,7 +7546,8 @@ var SkillStore = class {
|
|
|
7494
7546
|
path: path2,
|
|
7495
7547
|
allowedTools: parseAllowedTools(data["allowed-tools"]),
|
|
7496
7548
|
runAs: parseRunAs(data.runAs),
|
|
7497
|
-
model: data.model?.startsWith("deepseek-") ? data.model : void 0
|
|
7549
|
+
model: data.model?.startsWith("deepseek-") ? data.model : void 0,
|
|
7550
|
+
maxToolIters: parseMaxToolIters(data["max-iters"])
|
|
7498
7551
|
};
|
|
7499
7552
|
}
|
|
7500
7553
|
};
|
|
@@ -7515,6 +7568,7 @@ Tips:
|
|
|
7515
7568
|
- Reference tools by name (run_command, edit_file, search_content, ...)
|
|
7516
7569
|
- Add \`runAs: subagent\` to frontmatter to spawn an isolated subagent loop
|
|
7517
7570
|
- Add \`allowed-tools: read_file, search_content\` to scope a subagent's tools
|
|
7571
|
+
- Add \`max-iters: N\` to change the subagent's pause cadence (default 16). This isn't a budget \u2014 the parent resumes on pause, so N is how often the parent gets a checkpoint, not how much total work the subagent gets.
|
|
7518
7572
|
`;
|
|
7519
7573
|
}
|
|
7520
7574
|
function skillIndexLine(s) {
|
|
@@ -9886,9 +9940,7 @@ ${NEGATIVE_CLAIM_RULE}
|
|
|
9886
9940
|
|
|
9887
9941
|
${TUI_FORMATTING_RULES}`;
|
|
9888
9942
|
var DEFAULT_MAX_RESULT_CHARS2 = 8e3;
|
|
9889
|
-
var
|
|
9890
|
-
var MIN_MAX_ITERS = 1;
|
|
9891
|
-
var MAX_MAX_ITERS = 32;
|
|
9943
|
+
var DEFAULT_PAUSE_EVERY = 16;
|
|
9892
9944
|
var BUDGET_WARN_THRESHOLD = 3;
|
|
9893
9945
|
function budgetParagraph(maxToolIters) {
|
|
9894
9946
|
return `Tool budget: you have ${maxToolIters} tool call${maxToolIters === 1 ? "" : "s"} for this task. The cap is enforced from outside \u2014 the call after #${maxToolIters} is refused. Pace yourself: if you can't fully resolve the task within the budget, stop early and return what you have plus what's missing, rather than burning the budget on one branch.`;
|
|
@@ -9911,12 +9963,13 @@ function subagentBudgetHint(spawnCount, totalTokens) {
|
|
|
9911
9963
|
}
|
|
9912
9964
|
async function spawnSubagent(opts) {
|
|
9913
9965
|
const model = opts.model ?? DEFAULT_SUBAGENT_MODEL;
|
|
9914
|
-
const maxToolIters = opts.maxToolIters ??
|
|
9966
|
+
const maxToolIters = opts.maxToolIters ?? DEFAULT_PAUSE_EVERY;
|
|
9915
9967
|
const maxResultChars = opts.maxResultChars ?? DEFAULT_MAX_RESULT_CHARS2;
|
|
9916
9968
|
const sink = opts.sink;
|
|
9917
9969
|
const skillName = opts.skillName;
|
|
9918
|
-
const startedAt = Date.now();
|
|
9919
9970
|
const runId = nextRunId();
|
|
9971
|
+
const sessionName = opts.resumeSession ?? `subagent-${runId}-${timestampSuffix()}`;
|
|
9972
|
+
const startedAt = Date.now();
|
|
9920
9973
|
const taskPreview = opts.task.length > 30 ? `${opts.task.slice(0, 30)}\u2026` : opts.task;
|
|
9921
9974
|
sink?.current?.({
|
|
9922
9975
|
kind: "start",
|
|
@@ -9996,10 +10049,9 @@ ${budgetParagraph(maxToolIters)}`,
|
|
|
9996
10049
|
reasoningEffort: DEFAULT_SUBAGENT_EFFORT,
|
|
9997
10050
|
maxToolIters,
|
|
9998
10051
|
hooks: [],
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
stream: true
|
|
10052
|
+
stream: true,
|
|
10053
|
+
session: sessionName,
|
|
10054
|
+
onIterBudgetExhausted: "pause"
|
|
10003
10055
|
});
|
|
10004
10056
|
const onParentAbort = () => childLoop.abort();
|
|
10005
10057
|
if (opts.parentSignal?.aborted) {
|
|
@@ -10011,8 +10063,13 @@ ${budgetParagraph(maxToolIters)}`,
|
|
|
10011
10063
|
let errorMessage;
|
|
10012
10064
|
let toolIter = 0;
|
|
10013
10065
|
let summarisingEmitted = false;
|
|
10066
|
+
let paused = false;
|
|
10067
|
+
let partialSummary;
|
|
10068
|
+
const taskForLoop = opts.resumeSession ? `[Resume: your tool-call budget has been refreshed with ${maxToolIters} new calls. Earlier "wrap up" / "finalize NOW" budget hints in this conversation referred to the previous window \u2014 they no longer apply. Continue the work you were given.]
|
|
10069
|
+
|
|
10070
|
+
${opts.task}` : opts.task;
|
|
10014
10071
|
try {
|
|
10015
|
-
for await (const ev of childLoop.step(
|
|
10072
|
+
for await (const ev of childLoop.step(taskForLoop)) {
|
|
10016
10073
|
sink?.current?.({ kind: "inner", runId, task: taskPreview, skillName, model, inner: ev });
|
|
10017
10074
|
if (ev.role === "tool") {
|
|
10018
10075
|
toolIter++;
|
|
@@ -10050,13 +10107,17 @@ ${budgetParagraph(maxToolIters)}`,
|
|
|
10050
10107
|
if (ev.role === "error") {
|
|
10051
10108
|
errorMessage = ev.error ?? "subagent error";
|
|
10052
10109
|
}
|
|
10110
|
+
if (ev.role === "paused") {
|
|
10111
|
+
paused = true;
|
|
10112
|
+
if (ev.partialSummary) partialSummary = ev.partialSummary;
|
|
10113
|
+
}
|
|
10053
10114
|
}
|
|
10054
10115
|
} catch (err) {
|
|
10055
10116
|
errorMessage = err.message;
|
|
10056
10117
|
} finally {
|
|
10057
10118
|
opts.parentSignal?.removeEventListener("abort", onParentAbort);
|
|
10058
10119
|
}
|
|
10059
|
-
if (!errorMessage && !final) {
|
|
10120
|
+
if (!errorMessage && !final && !paused) {
|
|
10060
10121
|
errorMessage = opts.parentSignal?.aborted ? "subagent aborted before producing an answer" : "subagent ended without producing an answer";
|
|
10061
10122
|
}
|
|
10062
10123
|
const elapsedMs = Date.now() - startedAt;
|
|
@@ -10090,7 +10151,10 @@ ${budgetParagraph(maxToolIters)}`,
|
|
|
10090
10151
|
costUsd: costUsd2,
|
|
10091
10152
|
model,
|
|
10092
10153
|
skillName,
|
|
10093
|
-
usage
|
|
10154
|
+
usage,
|
|
10155
|
+
paused: paused || void 0,
|
|
10156
|
+
pausedSession: paused ? sessionName : void 0,
|
|
10157
|
+
partialSummary: paused ? partialSummary : void 0
|
|
10094
10158
|
};
|
|
10095
10159
|
}
|
|
10096
10160
|
function aggregateChildUsage(loop) {
|
|
@@ -10105,6 +10169,18 @@ function aggregateChildUsage(loop) {
|
|
|
10105
10169
|
return agg;
|
|
10106
10170
|
}
|
|
10107
10171
|
function formatSubagentResult(r) {
|
|
10172
|
+
if (r.paused) {
|
|
10173
|
+
return JSON.stringify({
|
|
10174
|
+
success: false,
|
|
10175
|
+
paused: true,
|
|
10176
|
+
resume_session: r.pausedSession,
|
|
10177
|
+
tool_iters: r.toolIters,
|
|
10178
|
+
elapsed_ms: r.elapsedMs,
|
|
10179
|
+
cost_usd: r.costUsd,
|
|
10180
|
+
partial_summary: r.partialSummary,
|
|
10181
|
+
note: `Subagent reached its pause-every interval (${r.toolIters} tool calls) without producing a final answer. Read partial_summary above to see what was done / left / blocked, then decide: resume by calling spawn_subagent again with resume_session="${r.pausedSession}" (the task arg becomes a continuation nudge \u2014 e.g. "finish what you started"), or accept the partial work and proceed with what you already know.`
|
|
10182
|
+
});
|
|
10183
|
+
}
|
|
10108
10184
|
if (!r.success) {
|
|
10109
10185
|
return JSON.stringify({
|
|
10110
10186
|
success: false,
|
|
@@ -10127,7 +10203,7 @@ function registerSubagentTool(parentRegistry, opts) {
|
|
|
10127
10203
|
const baseSystem = opts.defaultSystem ?? SUBAGENT_BASE_SYSTEM;
|
|
10128
10204
|
const defaultSystemBase = opts.projectRoot ? applyProjectMemory(baseSystem, opts.projectRoot) : baseSystem;
|
|
10129
10205
|
const defaultModel = opts.defaultModel ?? DEFAULT_SUBAGENT_MODEL;
|
|
10130
|
-
const maxToolIters = opts.maxToolIters ??
|
|
10206
|
+
const maxToolIters = opts.maxToolIters ?? DEFAULT_PAUSE_EVERY;
|
|
10131
10207
|
const maxResultChars = opts.maxResultChars ?? DEFAULT_MAX_RESULT_CHARS2;
|
|
10132
10208
|
const sink = opts.sink;
|
|
10133
10209
|
let sessionSpawnCount = 0;
|
|
@@ -10135,17 +10211,17 @@ function registerSubagentTool(parentRegistry, opts) {
|
|
|
10135
10211
|
parentRegistry.register({
|
|
10136
10212
|
name: SUBAGENT_TOOL_NAME,
|
|
10137
10213
|
parallelSafe: true,
|
|
10138
|
-
description: "Spawn an isolated subagent to handle a self-contained subtask in a fresh context, returning only its final answer. **Prefer direct tools.** Spawn primarily for parallel fan-out (2+ independent investigations issued in one tool batch) or when the work would otherwise need >10 file reads/searches whose trail you don't need to keep. Single greps, 1-3 file cross-references, and 'keep my context clean for one question' are NOT good reasons to spawn \u2014 direct tools are cheaper and let you reference the evidence later. Each spawn pays a
|
|
10214
|
+
description: "Spawn an isolated subagent to handle a self-contained subtask in a fresh context, returning only its final answer. **Prefer direct tools.** Spawn primarily for parallel fan-out (2+ independent investigations issued in one tool batch) or when the work would otherwise need >10 file reads/searches whose trail you don't need to keep. Single greps, 1-3 file cross-references, and 'keep my context clean for one question' are NOT good reasons to spawn \u2014 direct tools are cheaper and let you reference the evidence later. Each fresh spawn pays a prefix-cache miss plus a full child loop. The subagent inherits your tools but runs in its own isolated message log; only the final assistant message comes back. **Pause/resume**: subagents yield back to you every `max_iters` tool calls. A paused result returns `{ paused: true, resume_session: \"...\" }` \u2014 you can either accept the partial state, or call spawn_subagent again with `resume_session` set to continue where it left off (cheap: the prior prefix is cached). Tasks expected to run much longer than 16 tool calls don't need a huge `max_iters` \u2014 just resume.",
|
|
10139
10215
|
parameters: {
|
|
10140
10216
|
type: "object",
|
|
10141
10217
|
properties: {
|
|
10142
10218
|
task: {
|
|
10143
10219
|
type: "string",
|
|
10144
|
-
description:
|
|
10220
|
+
description: 'The subtask the subagent should perform. Be specific and self-contained \u2014 the subagent has none of your conversation context, only what you write here. When resuming via `resume_session`, this becomes a continuation nudge (e.g. "finish what you started" or a delta instruction).'
|
|
10145
10221
|
},
|
|
10146
10222
|
system: {
|
|
10147
10223
|
type: "string",
|
|
10148
|
-
description: "Optional override for the subagent's system prompt. The default tells it to stay focused and return a concise answer; override only when the subtask needs a specialized persona."
|
|
10224
|
+
description: "Optional override for the subagent's system prompt. The default tells it to stay focused and return a concise answer; override only when the subtask needs a specialized persona. Ignored on resume \u2014 the prior session keeps its original system prompt for cache stability."
|
|
10149
10225
|
},
|
|
10150
10226
|
model: {
|
|
10151
10227
|
type: "string",
|
|
@@ -10154,9 +10230,11 @@ function registerSubagentTool(parentRegistry, opts) {
|
|
|
10154
10230
|
},
|
|
10155
10231
|
max_iters: {
|
|
10156
10232
|
type: "integer",
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10233
|
+
description: "How many tool calls the subagent runs before pausing back to you for a checkpoint. Default 16. This is checkpoint cadence, not a budget \u2014 work continues across pauses via `resume_session`. Pick what feels natural for the granularity of decisions you want to make: small (4-8) when you want frequent control, larger (32-64) when the subagent should mostly run autonomously."
|
|
10234
|
+
},
|
|
10235
|
+
resume_session: {
|
|
10236
|
+
type: "string",
|
|
10237
|
+
description: "Provide the `resume_session` value returned by a previous paused spawn to continue that subagent. When set, prior messages are loaded from disk and the original system prompt is reused (cache-friendly). `task` becomes a continuation nudge."
|
|
10160
10238
|
},
|
|
10161
10239
|
type: {
|
|
10162
10240
|
type: "string",
|
|
@@ -10178,7 +10256,8 @@ function registerSubagentTool(parentRegistry, opts) {
|
|
|
10178
10256
|
const system = typeof args.system === "string" && args.system.trim().length > 0 ? args.system.trim() : typeSpec?.system ?? `${defaultSystemBase}
|
|
10179
10257
|
|
|
10180
10258
|
${escalationContract(model)}`;
|
|
10181
|
-
const callerIters =
|
|
10259
|
+
const callerIters = parseMaxIters(args.max_iters);
|
|
10260
|
+
const resumeSession = typeof args.resume_session === "string" && args.resume_session.trim().length > 0 ? args.resume_session.trim() : void 0;
|
|
10182
10261
|
const result = await spawnSubagent({
|
|
10183
10262
|
client: opts.client,
|
|
10184
10263
|
parentRegistry,
|
|
@@ -10188,7 +10267,8 @@ ${escalationContract(model)}`;
|
|
|
10188
10267
|
maxToolIters: callerIters ?? typeSpec?.maxToolIters ?? maxToolIters,
|
|
10189
10268
|
maxResultChars,
|
|
10190
10269
|
sink,
|
|
10191
|
-
parentSignal: ctx?.signal
|
|
10270
|
+
parentSignal: ctx?.signal,
|
|
10271
|
+
resumeSession
|
|
10192
10272
|
});
|
|
10193
10273
|
sessionSpawnCount++;
|
|
10194
10274
|
sessionSpawnTokens += result.usage.totalTokens;
|
|
@@ -10200,12 +10280,10 @@ ${hint}` : formatted;
|
|
|
10200
10280
|
});
|
|
10201
10281
|
return parentRegistry;
|
|
10202
10282
|
}
|
|
10203
|
-
function
|
|
10283
|
+
function parseMaxIters(raw) {
|
|
10204
10284
|
if (typeof raw !== "number" || !Number.isFinite(raw)) return void 0;
|
|
10205
10285
|
const n = Math.floor(raw);
|
|
10206
|
-
|
|
10207
|
-
if (n > MAX_MAX_ITERS) return MAX_MAX_ITERS;
|
|
10208
|
-
return n;
|
|
10286
|
+
return n >= 1 ? n : void 0;
|
|
10209
10287
|
}
|
|
10210
10288
|
function forkRegistryExcluding(parent, exclude) {
|
|
10211
10289
|
const child = new ToolRegistry();
|
|
@@ -10607,6 +10685,7 @@ import * as pathMod8 from "path";
|
|
|
10607
10685
|
// src/tools/shell-chain.ts
|
|
10608
10686
|
import { spawn as spawn3 } from "child_process";
|
|
10609
10687
|
import { closeSync, openSync } from "fs";
|
|
10688
|
+
import { devNull } from "os";
|
|
10610
10689
|
import * as pathMod7 from "path";
|
|
10611
10690
|
var UnsupportedSyntaxError = class extends Error {
|
|
10612
10691
|
constructor(detail) {
|
|
@@ -10866,6 +10945,12 @@ async function runChain(chain, opts) {
|
|
|
10866
10945
|
[\u2026 truncated ${output.length - opts.maxOutputChars} chars \u2026]` : output;
|
|
10867
10946
|
return { exitCode: lastExit, output: truncated, timedOut };
|
|
10868
10947
|
}
|
|
10948
|
+
function isNullDeviceAlias(target) {
|
|
10949
|
+
const lower = target.toLowerCase();
|
|
10950
|
+
if (lower === "/dev/null") return true;
|
|
10951
|
+
if (process.platform === "win32" && lower === "nul") return true;
|
|
10952
|
+
return false;
|
|
10953
|
+
}
|
|
10869
10954
|
function openRedirects(redirects, cwd) {
|
|
10870
10955
|
let stdinFd = null;
|
|
10871
10956
|
let stdoutFd = null;
|
|
@@ -10874,7 +10959,7 @@ function openRedirects(redirects, cwd) {
|
|
|
10874
10959
|
let bothFd = null;
|
|
10875
10960
|
const toClose = [];
|
|
10876
10961
|
const open = (target, flags) => {
|
|
10877
|
-
const resolved = pathMod7.resolve(cwd, target);
|
|
10962
|
+
const resolved = isNullDeviceAlias(target) ? devNull : pathMod7.resolve(cwd, target);
|
|
10878
10963
|
const fd = openSync(resolved, flags);
|
|
10879
10964
|
toClose.push(fd);
|
|
10880
10965
|
return fd;
|