@molecule/api-ai-tools 1.5.0 → 1.5.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/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +50 -1
- package/package.json +1 -1
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA2B9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAgCnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAg6CxF"}
|
package/dist/tools.js
CHANGED
|
@@ -16,6 +16,13 @@ import { TOOL_SCHEMAS } from './schemas.js';
|
|
|
16
16
|
const stuckAfterMs = () => Number(process.env.MOL_AI_BG_STUCK_AFTER_MS) || 5 * 60 * 1000;
|
|
17
17
|
/** Cumulative wait_for_task time per task id, this process. */
|
|
18
18
|
const waitedByTask = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Each waited task's log size at the end of its last wait. A command whose log
|
|
21
|
+
* keeps growing is slow, not stuck: a serial 139-test suite was called stuck at
|
|
22
|
+
* 560 s and the executor was told to kill it while its log still grew (X1 run
|
|
23
|
+
* m21, 2026-10-15).
|
|
24
|
+
*/
|
|
25
|
+
const logBytesByTask = new Map();
|
|
19
26
|
import { checkBlockedCommand, declaredBudgetSeconds, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, isEnvFilePath, isOutsideRoot, isValidGlob, MAX_BATCH_READ_BYTES, MAX_BATCH_READ_FILES, MAX_FIND_RESULTS, MAX_OUTPUT_SIZE, MAX_READ_RETURN_CHARS, MAX_READ_SIZE, MAX_SEARCH_CONTEXT_LINES, MAX_SEARCH_RESULTS, MAX_WRITE_SIZE, outputIsWithheldUntilExit, parseCheckCommand, parseCheckProblem, pathArgError, redactSecrets, redactSecretsInCode, resolvePath, shellQuote, sliceLines, stripControlChars, truncateMiddle, whitespaceTolerantReplace, } from './utilities.js';
|
|
20
27
|
/**
|
|
21
28
|
* Build a complete set of AI agent tools bound to an execution backend.
|
|
@@ -1152,7 +1159,33 @@ export function buildTools(backend, config) {
|
|
|
1152
1159
|
// exiting is not going to: on one run the executor waited five times,
|
|
1153
1160
|
// 120 s each, on an e2e suite that could never start (no browser page
|
|
1154
1161
|
// attached). Say so once, name the pid, and refuse to wait on it again.
|
|
1155
|
-
|
|
1162
|
+
let waitedBefore = waitedByTask.get(taskId) ?? 0;
|
|
1163
|
+
// Output since the last wait means the command is working: the stuck
|
|
1164
|
+
// clock starts again from here.
|
|
1165
|
+
const logBytes = async () => {
|
|
1166
|
+
if (!/^mol-bg-[a-z0-9]+-[a-z0-9]+$/.test(taskId))
|
|
1167
|
+
return null;
|
|
1168
|
+
let r;
|
|
1169
|
+
try {
|
|
1170
|
+
r = await backend.run(`wc -c < /tmp/${taskId}.log 2>/dev/null`, { timeout: 5_000 });
|
|
1171
|
+
}
|
|
1172
|
+
catch (_error) {
|
|
1173
|
+
// No answer about the log: treat the size as unknown, which keeps the
|
|
1174
|
+
// stuck verdict exactly as before.
|
|
1175
|
+
r = null;
|
|
1176
|
+
}
|
|
1177
|
+
const n = Number.parseInt(r?.stdout?.trim() ?? '', 10);
|
|
1178
|
+
return Number.isFinite(n) ? n : null;
|
|
1179
|
+
};
|
|
1180
|
+
if (taskId && waitedBefore >= stuckAfterMs()) {
|
|
1181
|
+
const now = await logBytes();
|
|
1182
|
+
const before = logBytesByTask.get(taskId);
|
|
1183
|
+
if (now !== null && before !== undefined && now > before) {
|
|
1184
|
+
logBytesByTask.set(taskId, now);
|
|
1185
|
+
waitedByTask.set(taskId, 0);
|
|
1186
|
+
waitedBefore = 0;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1156
1189
|
if (taskId && waitedBefore >= stuckAfterMs()) {
|
|
1157
1190
|
return {
|
|
1158
1191
|
taskId,
|
|
@@ -1198,6 +1231,22 @@ export function buildTools(backend, config) {
|
|
|
1198
1231
|
const waitedMs = Date.now() - startedAt;
|
|
1199
1232
|
waitedByTask.set(taskId, waitedBefore + waitedMs);
|
|
1200
1233
|
if (exitCode === null) {
|
|
1234
|
+
const grownTo = await logBytes();
|
|
1235
|
+
const lastSize = logBytesByTask.get(taskId);
|
|
1236
|
+
if (grownTo !== null)
|
|
1237
|
+
logBytesByTask.set(taskId, grownTo);
|
|
1238
|
+
const stillWriting = grownTo !== null && (lastSize === undefined ? grownTo > 0 : grownTo > lastSize);
|
|
1239
|
+
if (stillWriting && waitedBefore + waitedMs >= stuckAfterMs()) {
|
|
1240
|
+
waitedByTask.set(taskId, 0);
|
|
1241
|
+
return {
|
|
1242
|
+
taskId,
|
|
1243
|
+
status: 'running',
|
|
1244
|
+
waitedMs,
|
|
1245
|
+
note: `Still running after ${Math.round((waitedBefore + waitedMs) / 1000)}s of waiting, and its ` +
|
|
1246
|
+
`output is still growing (${grownTo} bytes) — slow, not stuck. Call wait_for_task again to ` +
|
|
1247
|
+
`keep waiting; peek with exec_command: tail ${log}.`,
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1201
1250
|
if (waitedBefore + waitedMs >= stuckAfterMs()) {
|
|
1202
1251
|
return {
|
|
1203
1252
|
taskId,
|