nolo-cli 0.161.0-alpha.1 → 0.162.0-alpha.1
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/{_executeModel-3HHZYHHB.js → _executeModel-RK74LZ44.js} +15 -15
- package/{agentDeleteCommand-74EL5T7G.js → agentDeleteCommand-KCZWV2E2.js} +16 -16
- package/{agentEmailCommands-ST7HL3E7.js → agentEmailCommands-Y6Z4A2VX.js} +17 -17
- package/{agentListCommands-L33M3I6V.js → agentListCommands-GOCGOQUB.js} +8 -8
- package/{agentMachineCommands-JSQPNSS5.js → agentMachineCommands-4DYX3GIT.js} +6 -6
- package/{agentRecordCommands-JWW5NQQ7.js → agentRecordCommands-MYS56PPX.js} +16 -16
- package/{agentRunCommand-UTBBUSHP.js → agentRunCommand-NA3YFEQJ.js} +17 -17
- package/{agentRuntimeLocal-XCKO5FVP.js → agentRuntimeLocal-J6I63NZC.js} +3 -3
- package/{agentSlice-YT3VCCEW.js → agentSlice-UPSZMNCZ.js} +1 -1
- package/{appDeleteCommands-2PJFNLAJ.js → appDeleteCommands-KKLAK2UR.js} +7 -7
- package/{appDeployCommands-AZCMCMK6.js → appDeployCommands-PXWK4FAX.js} +7 -7
- package/{appDeployStatusCommands-HSIKPVJN.js → appDeployStatusCommands-3NGWDZTX.js} +7 -7
- package/{appGetCommands-IUZCPAP7.js → appGetCommands-APWYPEO3.js} +7 -7
- package/{appListCommands-JLFVS44M.js → appListCommands-OP7IRALO.js} +7 -7
- package/{chunk-HW7EBEC5.js → chunk-3C73NSB2.js} +3 -3
- package/{chunk-QLQ573SU.js → chunk-3M52COK5.js} +120 -0
- package/{chunk-DD2EOI6S.js → chunk-4JCAW7TO.js} +1 -1
- package/{chunk-K25WQPP3.js → chunk-5E5VB7PS.js} +80 -3
- package/{chunk-KABQ74UQ.js → chunk-5IKRTRRR.js} +1 -1
- package/{chunk-JDKSYQQN.js → chunk-6B7KDQ2S.js} +2 -2
- package/{chunk-7RF4O6AT.js → chunk-BL4HFN6L.js} +1 -1
- package/{chunk-OLVOR45M.js → chunk-BRLQX6PB.js} +2 -2
- package/{chunk-CXCMXNME.js → chunk-DISDUQB6.js} +9 -9
- package/{chunk-RIHQGFFA.js → chunk-DJ2BOPJY.js} +1 -1
- package/{chunk-FCUKCVKN.js → chunk-F6THPP4J.js} +2 -2
- package/{chunk-DT7EWFTY.js → chunk-FBBJ4LXN.js} +3 -3
- package/{chunk-FB5WLEOD.js → chunk-FFAWF2YZ.js} +7 -7
- package/{chunk-ZAV4YVEA.js → chunk-HHFQUSHL.js} +2 -2
- package/{chunk-F5WASHQA.js → chunk-IMPILS7W.js} +8 -8
- package/{chunk-3GTVM7NJ.js → chunk-IRHXPNAX.js} +5 -5
- package/{chunk-BO3ARJRK.js → chunk-IWDCE5B5.js} +9 -9
- package/{chunk-FZYKQFBQ.js → chunk-J6JTTJQA.js} +2 -2
- package/{chunk-BMCPKNL2.js → chunk-JPQ5WKHS.js} +2 -2
- package/{chunk-FFHV45HO.js → chunk-L2JMH4I5.js} +3 -3
- package/{chunk-QZIOZDM6.js → chunk-NWM7G3VC.js} +2 -2
- package/{chunk-OWCHFPWR.js → chunk-NWUS6MP7.js} +4 -4
- package/{chunk-YR47Y7CN.js → chunk-PB4YPX7Z.js} +1 -1
- package/{chunk-2XDQAWBM.js → chunk-UUPXTEZA.js} +2 -2
- package/{chunk-O2IWR23M.js → chunk-W7FGZRLK.js} +1 -1
- package/{chunk-2ZYCNT2O.js → chunk-WTJABB6Y.js} +20 -10
- package/{chunk-VXS4YYJ2.js → chunk-WYJTNSVL.js} +1 -1
- package/{chunk-R2KWTENX.js → chunk-Y4LMOFDJ.js} +2 -2
- package/{chunk-QI2WVWXV.js → chunk-ZZDVBZOP.js} +1 -1
- package/{commandRegistry-HPL2KOVB.js → commandRegistry-5I4TSXV5.js} +40 -40
- package/{contentThunks-QBL5NK2W.js → contentThunks-NQ6DV434.js} +3 -3
- package/{createAgentAutomationAction-5UWBLR2N.js → createAgentAutomationAction-25SQL3JG.js} +3 -3
- package/{createDialogAction-NJ2LE7KC.js → createDialogAction-4BTIAXGB.js} +4 -4
- package/{createPageAction-7T3RINS2.js → createPageAction-FYOSL5UH.js} +3 -3
- package/{dialogCommands-KMECTGCW.js → dialogCommands-ZJRMCP4S.js} +7 -7
- package/{dialogSlice-GQMTD4HR.js → dialogSlice-6BOONGJJ.js} +2 -2
- package/{docCreateCommands-4IT5PUAL.js → docCreateCommands-KQHQNLRX.js} +6 -6
- package/{docDeleteCommands-QS66YNZV.js → docDeleteCommands-O3DWFX2W.js} +7 -7
- package/{docReadCommands-3SAI46YC.js → docReadCommands-2U2BUONC.js} +6 -6
- package/{docStore-PM5PYKPZ.js → docStore-HXC2EYZG.js} +1 -1
- package/{docUpdateCommands-OGYG5BRC.js → docUpdateCommands-MF3C52XI.js} +6 -6
- package/{handleSendMessageAction-EQ3U6K5N.js → handleSendMessageAction-PG3TKIG7.js} +7 -7
- package/index.js +3 -3
- package/{localRuntimeAdapter-74L7FLMW.js → localRuntimeAdapter-FMQGOKGG.js} +14 -14
- package/{machineCommands-BUZTMLYD.js → machineCommands-WBPIQBOD.js} +15 -15
- package/{machineWsRunDispatch-CCDVG5AO.js → machineWsRunDispatch-BSWQUOEW.js} +15 -15
- package/package.json +1 -1
- package/{readlineWorkspace-MS2ZIQ2P.js → readlineWorkspace-2HZ2LPZW.js} +20 -20
- package/{runAgentClientLoop-EXIQDX7G.js → runAgentClientLoop-DDAIRDFF.js} +13 -13
- package/{spaceCommands-WQMUCGV7.js → spaceCommands-NDPGHDMD.js} +6 -6
- package/{streamAgentChatTurn-DI2334G3.js → streamAgentChatTurn-3EBT25D2.js} +15 -15
- package/{tools-23VQGJOX.js → tools-CAJB3VTR.js} +9 -9
- package/{updateDialogTitleAction-AGAYHWS7.js → updateDialogTitleAction-RNSU7H63.js} +3 -3
|
@@ -5,20 +5,20 @@ import {
|
|
|
5
5
|
pickDefined,
|
|
6
6
|
printCliError,
|
|
7
7
|
resolveCliContext
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4JCAW7TO.js";
|
|
9
9
|
import {
|
|
10
10
|
hasFlag,
|
|
11
11
|
hasHelpArg
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DJ2BOPJY.js";
|
|
13
13
|
import {
|
|
14
14
|
t
|
|
15
15
|
} from "./chunk-2AB2HA4M.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-5IKRTRRR.js";
|
|
17
|
+
import "./chunk-BL4HFN6L.js";
|
|
18
18
|
import "./chunk-NBTY7YJF.js";
|
|
19
19
|
import "./chunk-VF4K2QE6.js";
|
|
20
20
|
import "./chunk-UAD2WT54.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-5E5VB7PS.js";
|
|
22
22
|
import "./chunk-KMDDG73K.js";
|
|
23
23
|
import "./chunk-ZNFJWEN4.js";
|
|
24
24
|
import "./chunk-QXZH5UDF.js";
|
|
@@ -30,9 +30,9 @@ import "./chunk-U34KT53V.js";
|
|
|
30
30
|
import "./chunk-G6OOUQWJ.js";
|
|
31
31
|
import "./chunk-56GBUMO5.js";
|
|
32
32
|
import "./chunk-WJZOQR2J.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-ZZDVBZOP.js";
|
|
34
34
|
import "./chunk-4L4K6YR7.js";
|
|
35
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-3M52COK5.js";
|
|
36
36
|
import "./chunk-3MZAGMYY.js";
|
|
37
37
|
import "./chunk-TT644UJD.js";
|
|
38
38
|
import "./chunk-2MBTWINN.js";
|
|
@@ -5,20 +5,20 @@ import {
|
|
|
5
5
|
pickDefined,
|
|
6
6
|
printCliError,
|
|
7
7
|
resolveCliContext
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4JCAW7TO.js";
|
|
9
9
|
import {
|
|
10
10
|
hasFlag,
|
|
11
11
|
hasHelpArg
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-DJ2BOPJY.js";
|
|
13
13
|
import {
|
|
14
14
|
t
|
|
15
15
|
} from "./chunk-2AB2HA4M.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-5IKRTRRR.js";
|
|
17
|
+
import "./chunk-BL4HFN6L.js";
|
|
18
18
|
import "./chunk-NBTY7YJF.js";
|
|
19
19
|
import "./chunk-VF4K2QE6.js";
|
|
20
20
|
import "./chunk-UAD2WT54.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-5E5VB7PS.js";
|
|
22
22
|
import "./chunk-KMDDG73K.js";
|
|
23
23
|
import "./chunk-ZNFJWEN4.js";
|
|
24
24
|
import "./chunk-QXZH5UDF.js";
|
|
@@ -30,9 +30,9 @@ import "./chunk-U34KT53V.js";
|
|
|
30
30
|
import "./chunk-G6OOUQWJ.js";
|
|
31
31
|
import "./chunk-56GBUMO5.js";
|
|
32
32
|
import "./chunk-WJZOQR2J.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-ZZDVBZOP.js";
|
|
34
34
|
import "./chunk-4L4K6YR7.js";
|
|
35
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-3M52COK5.js";
|
|
36
36
|
import "./chunk-3MZAGMYY.js";
|
|
37
37
|
import "./chunk-TT644UJD.js";
|
|
38
38
|
import "./chunk-2MBTWINN.js";
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-HS7MLR74.js";
|
|
4
4
|
import {
|
|
5
5
|
performServerProxyFetchWithRetry
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-NWM7G3VC.js";
|
|
7
7
|
import {
|
|
8
8
|
fetchServerSyncedCredential
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FBBJ4LXN.js";
|
|
10
10
|
import {
|
|
11
11
|
buildSkillGuidancePromptBlock
|
|
12
12
|
} from "./chunk-SH3XD4E2.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
compileContextLayers,
|
|
24
24
|
detectDispatchIntentFromMessages,
|
|
25
25
|
resolveToolGuidedSections
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-ZZDVBZOP.js";
|
|
27
27
|
import {
|
|
28
28
|
convertMessagesToResponsesInput,
|
|
29
29
|
getUsageRequestOptions,
|
|
@@ -1239,6 +1239,121 @@ function buildNoloWorkspaceCommandArgs(call) {
|
|
|
1239
1239
|
}
|
|
1240
1240
|
}
|
|
1241
1241
|
|
|
1242
|
+
// packages/agent-runtime/subtaskBudget.ts
|
|
1243
|
+
var DEFAULT_SUBTASK_MAX_TOOL_CALLS = 200;
|
|
1244
|
+
var DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS = 60 * 60 * 1e3;
|
|
1245
|
+
var SUBTASK_MAX_TOOL_CALLS_ENV = "NOLO_SUBTASK_MAX_TOOL_CALLS";
|
|
1246
|
+
var SUBTASK_MAX_WALL_CLOCK_MS_ENV = "NOLO_SUBTASK_MAX_WALL_CLOCK_MS";
|
|
1247
|
+
var SUBTASK_BUDGET_EXHAUSTED_MARKER = "[budget-exhausted]";
|
|
1248
|
+
function parseSubtaskBudgetLimit(raw, fallback) {
|
|
1249
|
+
if (typeof raw === "number") {
|
|
1250
|
+
if (!Number.isFinite(raw) || raw <= 0) return fallback;
|
|
1251
|
+
return Math.floor(raw);
|
|
1252
|
+
}
|
|
1253
|
+
if (typeof raw !== "string") return fallback;
|
|
1254
|
+
const trimmed = raw.trim();
|
|
1255
|
+
if (!trimmed) return fallback;
|
|
1256
|
+
const parsed = Number(trimmed);
|
|
1257
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
1258
|
+
return Math.floor(parsed);
|
|
1259
|
+
}
|
|
1260
|
+
function resolveSubtaskBudgetLimits(options) {
|
|
1261
|
+
const env = options?.env ?? (typeof process !== "undefined" ? process.env : {});
|
|
1262
|
+
const explicitToolCalls = options?.maxToolCalls;
|
|
1263
|
+
const explicitWallClock = options?.maxWallClockMs;
|
|
1264
|
+
return {
|
|
1265
|
+
maxToolCalls: typeof explicitToolCalls === "number" ? parseSubtaskBudgetLimit(explicitToolCalls, parseSubtaskBudgetLimit(env?.[SUBTASK_MAX_TOOL_CALLS_ENV], DEFAULT_SUBTASK_MAX_TOOL_CALLS)) : parseSubtaskBudgetLimit(env?.[SUBTASK_MAX_TOOL_CALLS_ENV], DEFAULT_SUBTASK_MAX_TOOL_CALLS),
|
|
1266
|
+
maxWallClockMs: typeof explicitWallClock === "number" ? parseSubtaskBudgetLimit(explicitWallClock, parseSubtaskBudgetLimit(env?.[SUBTASK_MAX_WALL_CLOCK_MS_ENV], DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS)) : parseSubtaskBudgetLimit(env?.[SUBTASK_MAX_WALL_CLOCK_MS_ENV], DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS)
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
function resolveSubtaskBudgetDeadlineMs(args) {
|
|
1270
|
+
const ownDeadlineAtMs = args.childStartedAtMs + args.limits.maxWallClockMs;
|
|
1271
|
+
const parentDeadlineAtMs = args.parentDeadlineAtMs;
|
|
1272
|
+
if (typeof parentDeadlineAtMs === "number" && Number.isFinite(parentDeadlineAtMs)) {
|
|
1273
|
+
return Math.min(parentDeadlineAtMs, ownDeadlineAtMs);
|
|
1274
|
+
}
|
|
1275
|
+
return ownDeadlineAtMs;
|
|
1276
|
+
}
|
|
1277
|
+
function resolveDispatchedSubtaskBudget(args) {
|
|
1278
|
+
const limits = resolveSubtaskBudgetLimits({
|
|
1279
|
+
...typeof args?.maxToolCalls === "number" ? { maxToolCalls: args.maxToolCalls } : {},
|
|
1280
|
+
...typeof args?.maxWallClockMs === "number" ? { maxWallClockMs: args.maxWallClockMs } : {},
|
|
1281
|
+
...args?.env ? { env: args.env } : {}
|
|
1282
|
+
});
|
|
1283
|
+
const childStartedAtMs = args?.childStartedAtMs ?? Date.now();
|
|
1284
|
+
const deadlineAtMs = resolveSubtaskBudgetDeadlineMs({
|
|
1285
|
+
parentDeadlineAtMs: args?.parentDeadlineAtMs ?? null,
|
|
1286
|
+
childStartedAtMs,
|
|
1287
|
+
limits
|
|
1288
|
+
});
|
|
1289
|
+
return {
|
|
1290
|
+
// 父截止更早时,子 run 的墙钟额度被压到「距离父截止的剩余时间」。
|
|
1291
|
+
limits: {
|
|
1292
|
+
maxToolCalls: limits.maxToolCalls,
|
|
1293
|
+
maxWallClockMs: Math.max(1, deadlineAtMs - childStartedAtMs)
|
|
1294
|
+
},
|
|
1295
|
+
deadlineAtMs
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function createSubtaskBudgetTracker(options) {
|
|
1299
|
+
const now = options.now ?? (() => Date.now());
|
|
1300
|
+
const startedAtMs = options.startedAtMs ?? now();
|
|
1301
|
+
let toolCallsExecuted = 0;
|
|
1302
|
+
const elapsedMs = () => Math.max(0, now() - startedAtMs);
|
|
1303
|
+
const exhaustion = () => {
|
|
1304
|
+
const elapsed = elapsedMs();
|
|
1305
|
+
if (toolCallsExecuted >= options.limits.maxToolCalls) {
|
|
1306
|
+
return {
|
|
1307
|
+
limit: "max-tool-calls",
|
|
1308
|
+
limits: options.limits,
|
|
1309
|
+
toolCallsExecuted,
|
|
1310
|
+
elapsedMs: elapsed,
|
|
1311
|
+
atMs: now()
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
if (elapsed >= options.limits.maxWallClockMs) {
|
|
1315
|
+
return {
|
|
1316
|
+
limit: "max-wall-clock-ms",
|
|
1317
|
+
limits: options.limits,
|
|
1318
|
+
toolCallsExecuted,
|
|
1319
|
+
elapsedMs: elapsed,
|
|
1320
|
+
atMs: now()
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
return null;
|
|
1324
|
+
};
|
|
1325
|
+
return {
|
|
1326
|
+
limits: options.limits,
|
|
1327
|
+
startedAtMs,
|
|
1328
|
+
get toolCallsExecuted() {
|
|
1329
|
+
return toolCallsExecuted;
|
|
1330
|
+
},
|
|
1331
|
+
elapsedMs,
|
|
1332
|
+
remainingToolCalls: () => Math.max(0, options.limits.maxToolCalls - toolCallsExecuted),
|
|
1333
|
+
isExhausted: () => exhaustion() !== null,
|
|
1334
|
+
exhaustion,
|
|
1335
|
+
recordToolCallExecuted: () => {
|
|
1336
|
+
toolCallsExecuted += 1;
|
|
1337
|
+
return toolCallsExecuted;
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
function buildSubtaskBudgetExhaustedContent(args) {
|
|
1342
|
+
const { exhaustion } = args;
|
|
1343
|
+
const limitLabel = exhaustion.limit === "max-tool-calls" ? `\u5DE5\u5177\u8C03\u7528\u4E0A\u9650\uFF08\u5DF2\u6267\u884C ${exhaustion.toolCallsExecuted}/${exhaustion.limits.maxToolCalls} \u6B21\uFF09` : `\u5899\u949F\u4E0A\u9650\uFF08\u5DF2\u8FD0\u884C ${Math.round(exhaustion.elapsedMs / 1e3)} \u79D2 / \u4E0A\u9650 ${Math.round(
|
|
1344
|
+
exhaustion.limits.maxWallClockMs / 1e3
|
|
1345
|
+
)} \u79D2\uFF09`;
|
|
1346
|
+
const recent = (args.recentToolNames ?? []).slice(-5);
|
|
1347
|
+
const recentText = recent.length > 0 ? recent.join("\u3001") : "\uFF08\u672C\u8F6E\u65E0\u5DE5\u5177\u8C03\u7528\uFF09";
|
|
1348
|
+
return [
|
|
1349
|
+
`${SUBTASK_BUDGET_EXHAUSTED_MARKER} \u5DF2\u8FBE\u5B50\u4EFB\u52A1\u9884\u7B97\u4E0A\u9650\uFF08${limitLabel}\uFF09\uFF0C\u672C\u6B21\u5B50\u4EFB\u52A1\u5230\u6B64\u4F18\u96C5\u7EC8\u6B62\u3002`,
|
|
1350
|
+
"\u8FD9\u662F\u4E00\u4EFD**\u4E2D\u95F4\u7ED3\u8BBA**\uFF0C\u4E0D\u662F\u5B8C\u6574\u4EA4\u4ED8\uFF0C\u4E5F\u4E0D\u662F\u5931\u8D25\uFF1A\u4E0A\u6587\u4FDD\u7559\u7684\u662F\u672C\u8F6E\u5DF2\u5B8C\u6210\u7684\u9636\u6BB5\u6027\u6210\u679C\uFF0C\u53EF\u76F4\u63A5\u4F5C\u4E3A\u9636\u6BB5\u4EA4\u63A5\u4F7F\u7528\u3002",
|
|
1351
|
+
`\u5F53\u524D\u5B8C\u6210\u5230\u54EA\u4E00\u6B65\uFF1A\u5DF2\u5B8C\u6210 ${args.roundsCompleted} \u8F6E\u6A21\u578B\u5F80\u8FD4\u3001${exhaustion.toolCallsExecuted} \u6B21\u5DE5\u5177\u8C03\u7528\uFF1B\u6700\u8FD1\u5B8C\u6210\u7684\u5DE5\u5177\uFF1A${recentText}\u3002`,
|
|
1352
|
+
"\u5DF2\u5B8C\u6210\u7684\u5DE5\u5177\u7ED3\u679C\u5168\u90E8\u4FDD\u7559\u5728\u672C\u56DE\u5408\u7684 transcript / \u7ED3\u679C\u4E2D\uFF0C\u6CA1\u6709\u4EFB\u4F55\u56DE\u6EDA\u6216\u4E22\u5F03\u3002",
|
|
1353
|
+
"\u5982\u9700\u7EE7\u7EED\u63A8\u8FDB\uFF0C\u8BF7\u7531\u7236\u65B9\u643A\u5E26\u5F53\u524D\u4E2D\u95F4\u7ED3\u8BBA\u91CD\u65B0\u6D3E\u53D1\uFF08\u53EF\u6309\u9700\u8C03\u9AD8\u9884\u7B97\u4E0A\u9650\uFF09\u3002"
|
|
1354
|
+
].join("\n");
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1242
1357
|
// packages/ai/agent/agentSelectionPriority.ts
|
|
1243
1358
|
function parseAgentTimestamp(value) {
|
|
1244
1359
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -1328,6 +1443,11 @@ export {
|
|
|
1328
1443
|
verifyNoloDialogSubjectRefQuery,
|
|
1329
1444
|
buildNoloTableQueryRequest,
|
|
1330
1445
|
buildNoloWorkspaceCommandArgs,
|
|
1446
|
+
DEFAULT_SUBTASK_MAX_TOOL_CALLS,
|
|
1447
|
+
DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS,
|
|
1448
|
+
resolveDispatchedSubtaskBudget,
|
|
1449
|
+
createSubtaskBudgetTracker,
|
|
1450
|
+
buildSubtaskBudgetExhaustedContent,
|
|
1331
1451
|
compareAgentSelection,
|
|
1332
1452
|
AGENT_SELECTION_PRIORITY_INSTRUCTIONS,
|
|
1333
1453
|
buildAgentRuntimeAgentLookupKeys,
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
hashStablePrefixContent,
|
|
67
67
|
resolveResponseGuidelines,
|
|
68
68
|
resolveToolGuidedSections
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-ZZDVBZOP.js";
|
|
70
70
|
import {
|
|
71
71
|
classifyUnparsableToolArgs,
|
|
72
72
|
collectStablePromptPrefix,
|
|
@@ -94,18 +94,22 @@ import {
|
|
|
94
94
|
import {
|
|
95
95
|
BRIDGE_STREAM_MAX_CHARS,
|
|
96
96
|
DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS,
|
|
97
|
+
DEFAULT_SUBTASK_MAX_TOOL_CALLS,
|
|
98
|
+
DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS,
|
|
97
99
|
NOLO_WORKSPACE_TOOL_NAMES,
|
|
98
100
|
applyToolSurfaceConstraints,
|
|
99
101
|
buildDialogReadEnvelope,
|
|
100
102
|
buildNoloWorkspaceCommandArgs,
|
|
101
103
|
buildNoloWorkspaceOpenAiTools,
|
|
104
|
+
buildSubtaskBudgetExhaustedContent,
|
|
102
105
|
createStreamingDialogReadProjector,
|
|
106
|
+
createSubtaskBudgetTracker,
|
|
103
107
|
noloPositiveIntegerString,
|
|
104
108
|
noloStringArg,
|
|
105
109
|
parseNoloWorkspaceToolArguments,
|
|
106
110
|
readTextStreamUpToChars,
|
|
107
111
|
resolveNoloDialogInput
|
|
108
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-3M52COK5.js";
|
|
109
113
|
import {
|
|
110
114
|
buildDialogFallbackTitleFromUserInput
|
|
111
115
|
} from "./chunk-2MBTWINN.js";
|
|
@@ -19782,6 +19786,17 @@ async function runLocalAgentTurn(input) {
|
|
|
19782
19786
|
observationBoundary.attachCallbacks(legacyCallbacks);
|
|
19783
19787
|
}
|
|
19784
19788
|
const loopTiming = createLoopTiming();
|
|
19789
|
+
const subtaskBudgetClock = input.subtaskBudgetNow ?? (() => Date.now());
|
|
19790
|
+
const subtaskBudgetLimits = {
|
|
19791
|
+
maxToolCalls: input.subtaskMaxToolCalls ?? input.subtaskBudgetLimits?.maxToolCalls ?? DEFAULT_SUBTASK_MAX_TOOL_CALLS,
|
|
19792
|
+
maxWallClockMs: input.subtaskMaxWallClockMs ?? input.subtaskBudgetLimits?.maxWallClockMs ?? DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS
|
|
19793
|
+
};
|
|
19794
|
+
const subtaskBudgetTracker = input.runKind === "subtask" ? createSubtaskBudgetTracker({
|
|
19795
|
+
limits: subtaskBudgetLimits,
|
|
19796
|
+
now: subtaskBudgetClock,
|
|
19797
|
+
// 墙钟从 run 开始计(含 provider 初始化与首轮前的准备)。
|
|
19798
|
+
startedAtMs: subtaskBudgetClock()
|
|
19799
|
+
}) : null;
|
|
19785
19800
|
try {
|
|
19786
19801
|
loopTiming.mark("turnStart", 0);
|
|
19787
19802
|
let agentConfig = await input.adapter.loadAgentConfig(input.agentRef);
|
|
@@ -20041,7 +20056,7 @@ async function runLocalAgentTurn(input) {
|
|
|
20041
20056
|
});
|
|
20042
20057
|
const userInputText = extractUserInputText(input.input);
|
|
20043
20058
|
let toolCallCount = 0;
|
|
20044
|
-
let result4;
|
|
20059
|
+
let result4 = { content: "" };
|
|
20045
20060
|
const usageLedger = createTurnUsageLedger({
|
|
20046
20061
|
model: agentConfig.model,
|
|
20047
20062
|
provider: agentConfig.provider,
|
|
@@ -20053,12 +20068,36 @@ async function runLocalAgentTurn(input) {
|
|
|
20053
20068
|
if (initialCompactionUsage) usageLedger.addCompaction(initialCompactionUsage);
|
|
20054
20069
|
let loopError;
|
|
20055
20070
|
let round = 0;
|
|
20071
|
+
let budgetExhaustion = null;
|
|
20072
|
+
const executedToolNameLog = [];
|
|
20073
|
+
const markBudgetExhausted = () => {
|
|
20074
|
+
if (!subtaskBudgetTracker || budgetExhaustion) return;
|
|
20075
|
+
const exhaustion = subtaskBudgetTracker.exhaustion();
|
|
20076
|
+
if (!exhaustion) return;
|
|
20077
|
+
budgetExhaustion = exhaustion;
|
|
20078
|
+
emitLoopEvent(observationBoundary, {
|
|
20079
|
+
kind: "budget-exhausted",
|
|
20080
|
+
limit: exhaustion.limit,
|
|
20081
|
+
atMs: exhaustion.atMs,
|
|
20082
|
+
maxToolCalls: exhaustion.limits.maxToolCalls,
|
|
20083
|
+
maxWallClockMs: exhaustion.limits.maxWallClockMs,
|
|
20084
|
+
toolCallsExecuted: exhaustion.toolCallsExecuted,
|
|
20085
|
+
elapsedMs: exhaustion.elapsedMs,
|
|
20086
|
+
round
|
|
20087
|
+
});
|
|
20088
|
+
};
|
|
20056
20089
|
let emptyAssistantRepairPending = false;
|
|
20057
20090
|
let emptyAssistantRepairUsed = false;
|
|
20058
20091
|
let reasoningEmptyRepairCount = 0;
|
|
20059
20092
|
let skipFinalAppend = false;
|
|
20060
20093
|
let partialContent = "";
|
|
20061
20094
|
const progressGuard = createLocalLoopProgressGuard(input.progressGuardConfig);
|
|
20095
|
+
const budgetAdmissionGate = () => {
|
|
20096
|
+
if (!subtaskBudgetTracker) return true;
|
|
20097
|
+
if (!subtaskBudgetTracker.isExhausted()) return true;
|
|
20098
|
+
markBudgetExhausted();
|
|
20099
|
+
return false;
|
|
20100
|
+
};
|
|
20062
20101
|
try {
|
|
20063
20102
|
const provider = await resolveProviderOnce();
|
|
20064
20103
|
const applyPendingInjections = () => {
|
|
@@ -20135,6 +20174,9 @@ async function runLocalAgentTurn(input) {
|
|
|
20135
20174
|
messages: requestMessages,
|
|
20136
20175
|
toolsHash: safeToolNamesHash(agentTools)
|
|
20137
20176
|
});
|
|
20177
|
+
if (!budgetAdmissionGate()) {
|
|
20178
|
+
break;
|
|
20179
|
+
}
|
|
20138
20180
|
result4 = await runCompleteWithTimeout({
|
|
20139
20181
|
provider,
|
|
20140
20182
|
messages: requestMessages,
|
|
@@ -20323,6 +20365,11 @@ ${reasoningTailLog}
|
|
|
20323
20365
|
const slotResults = new Array(toolCalls.length);
|
|
20324
20366
|
const runSingleTool = async ({ index, toolCall }) => {
|
|
20325
20367
|
throwIfAborted(input);
|
|
20368
|
+
if (!budgetAdmissionGate()) {
|
|
20369
|
+
skippedToolCalls.push(toolCall);
|
|
20370
|
+
return;
|
|
20371
|
+
}
|
|
20372
|
+
subtaskBudgetTracker?.recordToolCallExecuted();
|
|
20326
20373
|
const { toolResult, toolExecMs } = await executeToolCall({
|
|
20327
20374
|
input,
|
|
20328
20375
|
toolCall,
|
|
@@ -20342,6 +20389,7 @@ ${reasoningTailLog}
|
|
|
20342
20389
|
toolResult,
|
|
20343
20390
|
toolExecMs
|
|
20344
20391
|
};
|
|
20392
|
+
executedToolNameLog.push(toolCall.function.name);
|
|
20345
20393
|
};
|
|
20346
20394
|
const commitSlot = (i) => {
|
|
20347
20395
|
const toolCall = toolCalls[i];
|
|
@@ -20367,6 +20415,7 @@ ${reasoningTailLog}
|
|
|
20367
20415
|
...observedMetadata ? { tool_result_metadata: observedMetadata } : {}
|
|
20368
20416
|
});
|
|
20369
20417
|
};
|
|
20418
|
+
const skippedToolCalls = [];
|
|
20370
20419
|
const batches = partitionToolCallsIntoBatches(toolCalls);
|
|
20371
20420
|
for (const batch of batches) {
|
|
20372
20421
|
throwIfAborted(input);
|
|
@@ -20390,6 +20439,17 @@ ${reasoningTailLog}
|
|
|
20390
20439
|
}
|
|
20391
20440
|
if (batchError) throw batchError;
|
|
20392
20441
|
}
|
|
20442
|
+
for (const skipped of skippedToolCalls) {
|
|
20443
|
+
transcript.pushTool({
|
|
20444
|
+
role: "tool",
|
|
20445
|
+
content: "[\u5B50\u4EFB\u52A1\u9884\u7B97\u4E0A\u9650\u5DF2\u89E6\u53D1] \u8BE5\u5DE5\u5177\u8C03\u7528\u672A\u6267\u884C\uFF1A\u5DF2\u8FBE\u5B50\u4EFB\u52A1\u9884\u7B97\u4E0A\u9650\uFF0C\u672C\u8F6E\u4E0D\u518D\u53D1\u8D77\u65B0\u7684\u5DE5\u5177\u8C03\u7528\u3002",
|
|
20446
|
+
tool_call_id: skipped.id,
|
|
20447
|
+
toolName: skipped.function.name
|
|
20448
|
+
});
|
|
20449
|
+
}
|
|
20450
|
+
if (budgetExhaustion) {
|
|
20451
|
+
break;
|
|
20452
|
+
}
|
|
20393
20453
|
const toolExecutionGuardVerdict = progressGuard.observeToolExecution(
|
|
20394
20454
|
toolCalls,
|
|
20395
20455
|
executedToolResults
|
|
@@ -20411,12 +20471,29 @@ ${reasoningTailLog}
|
|
|
20411
20471
|
break;
|
|
20412
20472
|
}
|
|
20413
20473
|
await compaction.maybeCompactInLoop();
|
|
20474
|
+
if (!budgetAdmissionGate()) {
|
|
20475
|
+
break;
|
|
20476
|
+
}
|
|
20414
20477
|
loopTiming.mark("roundEnd", round);
|
|
20415
20478
|
round += 1;
|
|
20416
20479
|
}
|
|
20417
20480
|
} catch (error) {
|
|
20418
20481
|
loopError = error;
|
|
20419
20482
|
}
|
|
20483
|
+
if (budgetExhaustion) {
|
|
20484
|
+
const previousContent = typeof result4?.content === "string" ? result4.content.trim() : "";
|
|
20485
|
+
result4 = {
|
|
20486
|
+
...result4,
|
|
20487
|
+
content: [
|
|
20488
|
+
previousContent,
|
|
20489
|
+
buildSubtaskBudgetExhaustedContent({
|
|
20490
|
+
exhaustion: budgetExhaustion,
|
|
20491
|
+
roundsCompleted: round,
|
|
20492
|
+
recentToolNames: executedToolNameLog
|
|
20493
|
+
})
|
|
20494
|
+
].filter((part) => part.length > 0).join("\n\n")
|
|
20495
|
+
};
|
|
20496
|
+
}
|
|
20420
20497
|
if (loopError) {
|
|
20421
20498
|
const turnMessages2 = transcript.persisted(
|
|
20422
20499
|
sanitizedPersistedInput,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addContentToSpace
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PB4YPX7Z.js";
|
|
4
4
|
import {
|
|
5
5
|
format,
|
|
6
6
|
prepareAndPersistMessage,
|
|
7
7
|
uiAskChoiceFunc,
|
|
8
8
|
uiAskChoiceFunctionSchema
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IMPILS7W.js";
|
|
10
10
|
import {
|
|
11
11
|
formatISO
|
|
12
12
|
} from "./chunk-ZRAU6T47.js";
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveRawAgentInput,
|
|
10
10
|
resolveServerUrl,
|
|
11
11
|
writeUsage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HHFQUSHL.js";
|
|
13
13
|
import {
|
|
14
14
|
getReadableCliDb
|
|
15
15
|
} from "./chunk-62TBKWTV.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
resolveBoundMachineId,
|
|
28
28
|
resolveFileWriteGateEnabled,
|
|
29
29
|
resolveLocalUserId
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-IWDCE5B5.js";
|
|
31
31
|
import {
|
|
32
32
|
clearCredentialAvailability,
|
|
33
33
|
readCredentialEntry,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
import {
|
|
61
61
|
readDbRecord,
|
|
62
62
|
resolveAgentRecordFromHybridStore
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-5IKRTRRR.js";
|
|
64
64
|
import {
|
|
65
65
|
isLocalCliAgentKey
|
|
66
66
|
} from "./chunk-NBTY7YJF.js";
|
|
@@ -75,14 +75,14 @@ import {
|
|
|
75
75
|
} from "./chunk-BMQ2MJUK.js";
|
|
76
76
|
import {
|
|
77
77
|
resolveCliLocalRuntimeKeyCapability
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-WTJABB6Y.js";
|
|
79
79
|
import {
|
|
80
80
|
isTransientFetchError
|
|
81
81
|
} from "./chunk-KFHREHUQ.js";
|
|
82
82
|
import {
|
|
83
83
|
parseUiCard,
|
|
84
84
|
uiCardFallback
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-F6THPP4J.js";
|
|
86
86
|
import {
|
|
87
87
|
isGatewayHttpStatus
|
|
88
88
|
} from "./chunk-NF64D32W.js";
|
|
@@ -91,7 +91,7 @@ import {
|
|
|
91
91
|
chooseMemoryOwners,
|
|
92
92
|
loadMemoryCandidatesFromDb,
|
|
93
93
|
resolveAgentMemoryPolicy
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-6B7KDQ2S.js";
|
|
95
95
|
import {
|
|
96
96
|
API_REPORTED_COST_MULTIPLIER,
|
|
97
97
|
estimateMessagesTokens,
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
resolveAgentContextWindow,
|
|
100
100
|
resolveOccupancy,
|
|
101
101
|
resolveOccupancyWindow
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-IMPILS7W.js";
|
|
103
103
|
import {
|
|
104
104
|
buildSkillDiscoveryContextLayer
|
|
105
105
|
} from "./chunk-AU7AXHUL.js";
|
|
@@ -111,7 +111,7 @@ import {
|
|
|
111
111
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
112
112
|
LOCAL_TURN_ABORTED_CODE,
|
|
113
113
|
readActionGate
|
|
114
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-5E5VB7PS.js";
|
|
115
115
|
import {
|
|
116
116
|
resolveAgentRuntimeConfigFromRecord
|
|
117
117
|
} from "./chunk-ULQAD7ZY.js";
|
|
@@ -11224,7 +11224,7 @@ function isBalanceExhaustedError(error) {
|
|
|
11224
11224
|
|
|
11225
11225
|
// packages/cli/client/agentRun.ts
|
|
11226
11226
|
async function loadRunLocalAgentTurn() {
|
|
11227
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
11227
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-J6I63NZC.js");
|
|
11228
11228
|
return runLocalAgentTurn;
|
|
11229
11229
|
}
|
|
11230
11230
|
var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-VYNMQ6HW.js";
|
|
9
9
|
import {
|
|
10
10
|
fetchAndCacheTableRows
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PB4YPX7Z.js";
|
|
12
12
|
import {
|
|
13
13
|
require_react
|
|
14
14
|
} from "./chunk-YDH3FDFQ.js";
|
|
@@ -521,7 +521,7 @@ var executeToolRun = createAsyncThunk(
|
|
|
521
521
|
if (!executionInput) {
|
|
522
522
|
throw new Error(`ToolRun ${id} has no input to execute with.`);
|
|
523
523
|
}
|
|
524
|
-
const { findToolExecutor } = await import("./tools-
|
|
524
|
+
const { findToolExecutor } = await import("./tools-CAJB3VTR.js");
|
|
525
525
|
const { executor } = findToolExecutor(run.toolName);
|
|
526
526
|
toolRunStarted({
|
|
527
527
|
id: run.id,
|
|
@@ -308,7 +308,7 @@ var slice = createSliceWithThunks({
|
|
|
308
308
|
const overrides = {};
|
|
309
309
|
if (args.systemPromptOverride !== void 0) overrides.prompt = args.systemPromptOverride;
|
|
310
310
|
if (args.toolsOverride !== void 0) overrides.tools = args.toolsOverride;
|
|
311
|
-
const { _executeModel } = await import("./_executeModel-
|
|
311
|
+
const { _executeModel } = await import("./_executeModel-RK74LZ44.js");
|
|
312
312
|
return _executeModel(
|
|
313
313
|
{
|
|
314
314
|
isStreaming: args.isStreaming ?? false,
|
|
@@ -329,7 +329,7 @@ var slice = createSliceWithThunks({
|
|
|
329
329
|
* - 循环直到无工具调用或触发其他运行时停止条件
|
|
330
330
|
*/
|
|
331
331
|
runAgent: create.asyncThunk(async (args, thunkApi) => {
|
|
332
|
-
const { runAgentClientLoop } = await import("./runAgentClientLoop-
|
|
332
|
+
const { runAgentClientLoop } = await import("./runAgentClientLoop-DDAIRDFF.js");
|
|
333
333
|
const { content: loopContent, toolCallCount } = await runAgentClientLoop(
|
|
334
334
|
{
|
|
335
335
|
agentKey: args.agentKey,
|
|
@@ -345,7 +345,7 @@ var slice = createSliceWithThunks({
|
|
|
345
345
|
* 聊天轮次流式 Agent 调用
|
|
346
346
|
*/
|
|
347
347
|
streamAgentChatTurn: create.asyncThunk(async (args, thunkApi) => {
|
|
348
|
-
const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-
|
|
348
|
+
const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-3EBT25D2.js");
|
|
349
349
|
return streamAgentChatTurnHandler(args, thunkApi);
|
|
350
350
|
}),
|
|
351
351
|
/**
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
inlineImageUrlsForCustomProvider,
|
|
6
6
|
prepareTools,
|
|
7
7
|
shouldInlineImageUrlsForAgent
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BRLQX6PB.js";
|
|
9
9
|
import {
|
|
10
10
|
CONFIRMATION_INPUT_KEYS,
|
|
11
11
|
INVALID_TOOL_ARGS_REPLACEMENT,
|
|
@@ -14,16 +14,16 @@ import {
|
|
|
14
14
|
performFetchRequest,
|
|
15
15
|
sanitizeOutboundMessages,
|
|
16
16
|
stripModelToolArgs
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3C73NSB2.js";
|
|
18
18
|
import {
|
|
19
19
|
findToolExecutor,
|
|
20
20
|
toolDefinitionsByName
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-WTJABB6Y.js";
|
|
22
22
|
import {
|
|
23
23
|
classifyApiError,
|
|
24
24
|
classifyGenerationError,
|
|
25
25
|
extractErrorDiagnostics
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-NWM7G3VC.js";
|
|
27
27
|
import {
|
|
28
28
|
createSSEParser,
|
|
29
29
|
createToolRunId,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
toolRunSetPending,
|
|
33
33
|
toolRunStarted,
|
|
34
34
|
toolRunSucceeded
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-F6THPP4J.js";
|
|
36
36
|
import {
|
|
37
37
|
getPublicImageAgentMode
|
|
38
38
|
} from "./chunk-VIDPVFP3.js";
|
|
@@ -42,10 +42,10 @@ import {
|
|
|
42
42
|
messageStreaming,
|
|
43
43
|
toolResultNeedsUserConfirmation,
|
|
44
44
|
updateToolMessage
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-IMPILS7W.js";
|
|
46
46
|
import {
|
|
47
47
|
streamAgentChatTurn
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-FBBJ4LXN.js";
|
|
49
49
|
import {
|
|
50
50
|
getCurrentSpaceId
|
|
51
51
|
} from "./chunk-ZJ7UHBJS.js";
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
} from "./chunk-NBTY7YJF.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveCliLocalRuntimeKeyCapability
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WTJABB6Y.js";
|
|
9
9
|
import {
|
|
10
10
|
HIGH_RISK_MUTATION_TOOL_NAMES
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3M52COK5.js";
|
|
12
12
|
import {
|
|
13
13
|
DEFAULT_NOLO_SERVER_URL
|
|
14
14
|
} from "./chunk-OLZBQWZU.js";
|