@wrongstack/core 0.268.0 → 0.269.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/dist/{agent-bridge-UhojbpWx.d.ts → agent-bridge-PcHQl_UQ.d.ts} +1 -1
- package/dist/{agent-subagent-runner-Bvtf1o9K.d.ts → agent-subagent-runner-SHJW7t8q.d.ts} +8 -8
- package/dist/{brain-69wzMKp1.d.ts → brain-BYcK__Ym.d.ts} +1 -1
- package/dist/{compactor-CBQAJoDc.d.ts → compactor-C2RKEBtC.d.ts} +1 -1
- package/dist/{config-VKfOZ-6X.d.ts → config-C_ae2k86.d.ts} +11 -2
- package/dist/{context-C0U8B9NF.d.ts → context-Dp87Bcaq.d.ts} +24 -1
- package/dist/coordination/index.d.ts +22 -16
- package/dist/coordination/index.js +233 -86
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +272 -69
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -15
- package/dist/execution/index.js +116 -19
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-KByEFFBa.d.ts → global-mailbox-Bvrz1P3f.d.ts} +2 -1
- package/dist/{goal-preamble-CrYjmdw4.d.ts → goal-preamble-CA_4yiGQ.d.ts} +9 -9
- package/dist/{goal-store-Y_zdLZ3q.d.ts → goal-store-DhuJoUNG.d.ts} +1 -1
- package/dist/hq/index.d.ts +15 -6
- package/dist/hq/index.js +55 -8
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-CtQnmkaS.d.ts → index-CZQ6Pwbs.d.ts} +8 -8
- package/dist/{index-gCv830d7.d.ts → index-W4VJCzHa.d.ts} +5 -5
- package/dist/{index-BfaS-f_m.d.ts → index-whDfTANu.d.ts} +2 -2
- package/dist/index.d.ts +41 -41
- package/dist/index.js +531 -167
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +3 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/{mcp-servers-HT3Fi7Bl.d.ts → mcp-servers-DJdZiRcv.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-Bvcl3Vaa.d.ts → models-registry-C3a-2-Yd.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-BACjsmkC.d.ts → multi-agent-coordinator-CJSpTe5O.d.ts} +1 -1
- package/dist/{null-fleet-bus-DA7fvhUg.d.ts → null-fleet-bus-QVshIsDx.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-Ci71gYu_.d.ts → parallel-eternal-engine-D9y5Pkcc.d.ts} +9 -9
- package/dist/{path-resolver-O1IJnmKE.d.ts → path-resolver-CnQ8SIfh.d.ts} +3 -3
- package/dist/{permission-Bd-57Lbl.d.ts → permission-CvYQNUqZ.d.ts} +1 -1
- package/dist/{permission-policy-uNXC6Kge.d.ts → permission-policy-D5Ss8j4B.d.ts} +2 -2
- package/dist/{pipeline-BDNvENyV.d.ts → pipeline-l_zzFRh3.d.ts} +2 -2
- package/dist/{plan-templates-EMsalEtN.d.ts → plan-templates-NtPgyeJA.d.ts} +6 -5
- package/dist/{provider-model-resolve-CEb9x886.d.ts → provider-model-resolve-d5poT5y0.d.ts} +3 -3
- package/dist/{provider-runner-DWJbpo70.d.ts → provider-runner-gkctlQV_.d.ts} +3 -3
- package/dist/{retry-policy-C3s_lvdK.d.ts → retry-policy-CtFhfwa8.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +1 -1
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-Cgduf5xL.d.ts → secret-vault-BLsVmTIK.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-47LBnBVk.d.ts → selector-CXl2_y9W.d.ts} +1 -1
- package/dist/{session-event-bridge-Cw7oqmW2.d.ts → session-event-bridge-Ccud20CC.d.ts} +1 -1
- package/dist/{session-reader-DD4v2Obw.d.ts → session-reader-ZeXQmsmE.d.ts} +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +13 -11
- package/dist/storage/index.js +210 -64
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +110 -19
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +58 -24
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/chimera/SKILL.md +1 -1
- package/skills/typescript-strict/SKILL.md +3 -3
- package/skills/typescript-strict/SKILL.save.md +1 -1
package/dist/defaults/index.js
CHANGED
|
@@ -331,6 +331,9 @@ function formatCtx(ctx) {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
// src/storage/session-store.ts
|
|
335
|
+
init_atomic_write();
|
|
336
|
+
|
|
334
337
|
// src/utils/expect-defined.ts
|
|
335
338
|
function expectDefined(value, label) {
|
|
336
339
|
if (value === null || value === void 0) {
|
|
@@ -341,9 +344,6 @@ function expectDefined(value, label) {
|
|
|
341
344
|
return value;
|
|
342
345
|
}
|
|
343
346
|
|
|
344
|
-
// src/storage/session-store.ts
|
|
345
|
-
init_atomic_write();
|
|
346
|
-
|
|
347
347
|
// src/utils/message-invariants.ts
|
|
348
348
|
function repairToolUseAdjacency(messages) {
|
|
349
349
|
const removedToolUses = [];
|
|
@@ -406,7 +406,7 @@ function hasToolResult(msg) {
|
|
|
406
406
|
}
|
|
407
407
|
function toolUseIds(msg) {
|
|
408
408
|
const ids = /* @__PURE__ */ new Set();
|
|
409
|
-
if (
|
|
409
|
+
if (msg?.role !== "assistant") return ids;
|
|
410
410
|
for (const block of contentBlocks(msg)) {
|
|
411
411
|
if (block.type === "tool_use") ids.add(block.id);
|
|
412
412
|
}
|
|
@@ -414,7 +414,7 @@ function toolUseIds(msg) {
|
|
|
414
414
|
}
|
|
415
415
|
function toolResultIds(msg) {
|
|
416
416
|
const ids = /* @__PURE__ */ new Set();
|
|
417
|
-
if (
|
|
417
|
+
if (msg?.role !== "user") return ids;
|
|
418
418
|
for (const block of contentBlocks(msg)) {
|
|
419
419
|
if (block.type === "tool_result") ids.add(block.tool_use_id);
|
|
420
420
|
}
|
|
@@ -1206,8 +1206,19 @@ function calState(key) {
|
|
|
1206
1206
|
return state;
|
|
1207
1207
|
}
|
|
1208
1208
|
var MIN_SAMPLES_FOR_CALIBRATION = 3;
|
|
1209
|
+
var MODEL_FAMILY_RATIO = {
|
|
1210
|
+
// Anthropic: ~3.8-4.0 chars/token depending on model
|
|
1211
|
+
claude: 3.8,
|
|
1212
|
+
// OpenAI: ~4.0 chars/token
|
|
1213
|
+
"gpt-4": 4,
|
|
1214
|
+
"gpt-3.5": 4,
|
|
1215
|
+
// Google: ~3.5 chars/token
|
|
1216
|
+
gemini: 3.5,
|
|
1217
|
+
// DeepSeek: ~3.5 chars/token
|
|
1218
|
+
deepseek: 3.5
|
|
1219
|
+
};
|
|
1209
1220
|
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
1210
|
-
var ESTIMATE_CACHE_MAX_SIZE =
|
|
1221
|
+
var ESTIMATE_CACHE_MAX_SIZE = 5e4;
|
|
1211
1222
|
function getCachedEstimate(key, compute) {
|
|
1212
1223
|
const existing = ESTIMATE_CACHE.get(key);
|
|
1213
1224
|
if (existing !== void 0) return existing;
|
|
@@ -1335,8 +1346,24 @@ function estimateRequestTokensCalibrated(messages, systemPrompt, tools, calibrat
|
|
|
1335
1346
|
total: Math.round(result.total * safeRatio)
|
|
1336
1347
|
};
|
|
1337
1348
|
}
|
|
1349
|
+
const fallbackRatio = getModelFamilyRatio(calibrationKey);
|
|
1350
|
+
if (fallbackRatio !== null) {
|
|
1351
|
+
return {
|
|
1352
|
+
messages: Math.round(result.messages * fallbackRatio),
|
|
1353
|
+
systemPrompt: Math.round(result.systemPrompt * fallbackRatio),
|
|
1354
|
+
tools: Math.round(result.tools * fallbackRatio),
|
|
1355
|
+
total: Math.round(result.total * fallbackRatio)
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1338
1358
|
return result;
|
|
1339
1359
|
}
|
|
1360
|
+
function getModelFamilyRatio(calibrationKey) {
|
|
1361
|
+
const lower = calibrationKey.toLowerCase();
|
|
1362
|
+
for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {
|
|
1363
|
+
if (lower.includes(family)) return ratio / 3.5;
|
|
1364
|
+
}
|
|
1365
|
+
return null;
|
|
1366
|
+
}
|
|
1340
1367
|
|
|
1341
1368
|
// src/utils/tool-output-serializer.ts
|
|
1342
1369
|
var DEFAULT_LIST_LIMIT = 500;
|
|
@@ -1347,6 +1374,7 @@ var GREP_MATCHES_PER_FILE = 3;
|
|
|
1347
1374
|
var DIFF_INLINE_LINE_LIMIT = 260;
|
|
1348
1375
|
var DIFF_HUNK_LIMIT = 8;
|
|
1349
1376
|
var DIFF_HUNK_CONTEXT = 14;
|
|
1377
|
+
var GREP_LINE_RE = /^(.+?):(\d+):(.*)$/;
|
|
1350
1378
|
function createToolOutputSerializer(opts = {}) {
|
|
1351
1379
|
const capBytes = opts.perIterationOutputCapBytes ?? 1e5;
|
|
1352
1380
|
function serialize(value, context = {}) {
|
|
@@ -1732,7 +1760,7 @@ ${renderStringList(passthrough, "", 50)}`);
|
|
|
1732
1760
|
return sections.join("\n");
|
|
1733
1761
|
}
|
|
1734
1762
|
function parseGrepContentLine(line) {
|
|
1735
|
-
const match =
|
|
1763
|
+
const match = GREP_LINE_RE.exec(line);
|
|
1736
1764
|
if (!match?.[1] || !match[2]) return void 0;
|
|
1737
1765
|
return { file: match[1], line: match[2], text: match[3] ?? "" };
|
|
1738
1766
|
}
|
|
@@ -1750,22 +1778,20 @@ function compactDiff(diff) {
|
|
|
1750
1778
|
const hunks = lines.filter((line) => line.startsWith("@@")).length;
|
|
1751
1779
|
const added = lines.filter((line) => line.startsWith("+") && !line.startsWith("+++")).length;
|
|
1752
1780
|
const removed = lines.filter((line) => line.startsWith("-") && !line.startsWith("---")).length;
|
|
1753
|
-
const
|
|
1781
|
+
const intervals = [];
|
|
1754
1782
|
let hunkCount = 0;
|
|
1755
1783
|
for (let i = 0; i < lines.length; i++) {
|
|
1756
1784
|
const line = lines[i] ?? "";
|
|
1757
1785
|
if (line.startsWith("diff --git") || line.startsWith("--- ") || line.startsWith("+++ ")) {
|
|
1758
|
-
|
|
1786
|
+
intervals.push([i, i]);
|
|
1759
1787
|
continue;
|
|
1760
1788
|
}
|
|
1761
1789
|
if (!line.startsWith("@@")) continue;
|
|
1762
1790
|
if (hunkCount >= DIFF_HUNK_LIMIT) continue;
|
|
1763
1791
|
hunkCount++;
|
|
1764
|
-
|
|
1765
|
-
selected.add(j);
|
|
1766
|
-
}
|
|
1792
|
+
intervals.push([i, Math.min(lines.length - 1, i + DIFF_HUNK_CONTEXT)]);
|
|
1767
1793
|
}
|
|
1768
|
-
if (
|
|
1794
|
+
if (intervals.length === 0) {
|
|
1769
1795
|
return joinSections([
|
|
1770
1796
|
renderHeader("diff_summary", {
|
|
1771
1797
|
files: fileCount,
|
|
@@ -1778,17 +1804,29 @@ function compactDiff(diff) {
|
|
|
1778
1804
|
`[serializer omitted ${Math.max(0, lines.length - DIFF_INLINE_LINE_LIMIT)} diff line(s)]`
|
|
1779
1805
|
]);
|
|
1780
1806
|
}
|
|
1807
|
+
const merged = [intervals[0]];
|
|
1808
|
+
for (let i = 1; i < intervals.length; i++) {
|
|
1809
|
+
const last = merged[merged.length - 1];
|
|
1810
|
+
const current = intervals[i];
|
|
1811
|
+
if (current[0] <= last[1] + 1) {
|
|
1812
|
+
last[1] = Math.max(last[1], current[1]);
|
|
1813
|
+
} else {
|
|
1814
|
+
merged.push(current);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1781
1817
|
const excerpt = [];
|
|
1782
|
-
let
|
|
1783
|
-
for (const
|
|
1784
|
-
if (
|
|
1785
|
-
const omitted =
|
|
1818
|
+
let prevLine = -1;
|
|
1819
|
+
for (const [start, end] of merged) {
|
|
1820
|
+
if (start > prevLine + 1) {
|
|
1821
|
+
const omitted = prevLine === -1 ? start : start - prevLine - 1;
|
|
1786
1822
|
excerpt.push(`[serializer omitted ${omitted} diff line(s)]`);
|
|
1787
1823
|
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1824
|
+
for (let j = start; j <= end; j++) {
|
|
1825
|
+
excerpt.push(lines[j] ?? "");
|
|
1826
|
+
}
|
|
1827
|
+
prevLine = end;
|
|
1790
1828
|
}
|
|
1791
|
-
const trailing = lines.length -
|
|
1829
|
+
const trailing = lines.length - prevLine - 1;
|
|
1792
1830
|
if (trailing > 0) excerpt.push(`[serializer omitted ${trailing} trailing diff line(s)]`);
|
|
1793
1831
|
return joinSections([
|
|
1794
1832
|
renderHeader("diff_summary", {
|
|
@@ -2062,6 +2100,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2062
2100
|
* processes. When the limit is reached, the oldest entry is evicted.
|
|
2063
2101
|
*/
|
|
2064
2102
|
_loadCache = /* @__PURE__ */ new Map();
|
|
2103
|
+
_indexCache = null;
|
|
2065
2104
|
static LOAD_CACHE_MAX_ENTRIES = 50;
|
|
2066
2105
|
constructor(opts) {
|
|
2067
2106
|
this.dir = opts.dir;
|
|
@@ -2223,13 +2262,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2223
2262
|
let errorMsg;
|
|
2224
2263
|
let cacheHit = false;
|
|
2225
2264
|
try {
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
const s = await fsp2.stat(file);
|
|
2229
|
-
stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2230
|
-
} catch (err) {
|
|
2231
|
-
throw err;
|
|
2232
|
-
}
|
|
2265
|
+
const s = await fsp2.stat(file);
|
|
2266
|
+
const stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2233
2267
|
const cached = this._loadCache.get(id);
|
|
2234
2268
|
if (cached && cached.mtimeMs === stat6.mtimeMs && cached.size === stat6.size) {
|
|
2235
2269
|
cacheHit = true;
|
|
@@ -2320,6 +2354,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2320
2354
|
await ensureDir(this.dir);
|
|
2321
2355
|
const line = JSON.stringify(summary) + "\n";
|
|
2322
2356
|
await fsp2.appendFile(this.indexFile, line, "utf8");
|
|
2357
|
+
this._indexCache = null;
|
|
2323
2358
|
this.indexAppendCount++;
|
|
2324
2359
|
if (this.indexAppendCount >= _DefaultSessionStore.COMPACT_EVERY) {
|
|
2325
2360
|
await this.compactIndex();
|
|
@@ -2334,6 +2369,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2334
2369
|
await ensureDir(this.dir);
|
|
2335
2370
|
const line = JSON.stringify({ action: "delete", id }) + "\n";
|
|
2336
2371
|
await fsp2.appendFile(this.indexFile, line, "utf8");
|
|
2372
|
+
this._indexCache = null;
|
|
2337
2373
|
this.indexAppendCount++;
|
|
2338
2374
|
} catch {
|
|
2339
2375
|
}
|
|
@@ -2353,6 +2389,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2353
2389
|
const lines = entries.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
2354
2390
|
await fsp2.writeFile(tmp, lines, "utf8");
|
|
2355
2391
|
await fsp2.rename(tmp, this.indexFile);
|
|
2392
|
+
this._indexCache = null;
|
|
2356
2393
|
} catch (err) {
|
|
2357
2394
|
outcome = "failure";
|
|
2358
2395
|
errorMsg = toErrorMessage(err);
|
|
@@ -2366,10 +2403,22 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2366
2403
|
* Returns empty array when the index doesn't exist or is corrupt.
|
|
2367
2404
|
*/
|
|
2368
2405
|
async readIndex() {
|
|
2406
|
+
let stat6;
|
|
2407
|
+
try {
|
|
2408
|
+
const s = await fsp2.stat(this.indexFile);
|
|
2409
|
+
stat6 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
2410
|
+
} catch {
|
|
2411
|
+
this._indexCache = null;
|
|
2412
|
+
return [];
|
|
2413
|
+
}
|
|
2414
|
+
if (this._indexCache !== null && this._indexCache.mtimeMs === stat6.mtimeMs && this._indexCache.size === stat6.size) {
|
|
2415
|
+
return [...this._indexCache.summaries];
|
|
2416
|
+
}
|
|
2369
2417
|
let raw;
|
|
2370
2418
|
try {
|
|
2371
2419
|
raw = await fsp2.readFile(this.indexFile, "utf8");
|
|
2372
2420
|
} catch {
|
|
2421
|
+
this._indexCache = null;
|
|
2373
2422
|
return [];
|
|
2374
2423
|
}
|
|
2375
2424
|
const deleted = /* @__PURE__ */ new Set();
|
|
@@ -2389,7 +2438,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2389
2438
|
} catch {
|
|
2390
2439
|
}
|
|
2391
2440
|
}
|
|
2392
|
-
|
|
2441
|
+
const summaries = Array.from(seen.values());
|
|
2442
|
+
this._indexCache = { ...stat6, summaries };
|
|
2443
|
+
return [...summaries];
|
|
2393
2444
|
}
|
|
2394
2445
|
/**
|
|
2395
2446
|
* Rebuild the index from disk by scanning all sessions and writing a
|
|
@@ -2403,6 +2454,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
2403
2454
|
const lines = valid.map((s) => JSON.stringify(s)).join("\n") + "\n";
|
|
2404
2455
|
await fsp2.writeFile(tmp, lines, "utf8");
|
|
2405
2456
|
await fsp2.rename(tmp, this.indexFile);
|
|
2457
|
+
this._indexCache = null;
|
|
2406
2458
|
return valid.length;
|
|
2407
2459
|
}
|
|
2408
2460
|
/** Recursively collect session IDs from date-shard subdirectories.
|
|
@@ -3102,6 +3154,12 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
3102
3154
|
files
|
|
3103
3155
|
});
|
|
3104
3156
|
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Truncate the session file to the checkpoint with the given promptIndex,
|
|
3159
|
+
* removing all events that follow it. Uses a single-pass byte-offset scan
|
|
3160
|
+
* so post-checkpoint content is never read or parsed — O(1) memory instead
|
|
3161
|
+
* of O(N) JSON.parse calls over the full file.
|
|
3162
|
+
*/
|
|
3105
3163
|
async truncateToCheckpoint(targetPromptIndex) {
|
|
3106
3164
|
if (!this.filePath) return 0;
|
|
3107
3165
|
if (this.flushTimer) {
|
|
@@ -3110,51 +3168,118 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
3110
3168
|
}
|
|
3111
3169
|
await this.flushBuffer();
|
|
3112
3170
|
await this.writeChain;
|
|
3113
|
-
const
|
|
3114
|
-
|
|
3115
|
-
|
|
3171
|
+
const CHUNK_SIZE = 65536;
|
|
3172
|
+
let fd;
|
|
3173
|
+
let fileOffset = 0;
|
|
3174
|
+
let lineStartOffset = 0;
|
|
3175
|
+
let checkpointByteOffset = -1;
|
|
3116
3176
|
let removedCount = 0;
|
|
3117
|
-
let
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3177
|
+
let targetCheckpointSeen = false;
|
|
3178
|
+
try {
|
|
3179
|
+
fd = await fsp2.open(this.filePath, "r", 384);
|
|
3180
|
+
while (true) {
|
|
3181
|
+
const buf = Buffer.alloc(CHUNK_SIZE);
|
|
3182
|
+
const { bytesRead } = await fd.read(buf, 0, CHUNK_SIZE, fileOffset);
|
|
3183
|
+
if (bytesRead === 0) break;
|
|
3184
|
+
let chunkPos = 0;
|
|
3185
|
+
while (chunkPos < bytesRead) {
|
|
3186
|
+
const idx = buf.indexOf("\n", chunkPos);
|
|
3187
|
+
if (idx === -1) {
|
|
3188
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
3189
|
+
break;
|
|
3190
|
+
}
|
|
3191
|
+
if (checkpointByteOffset !== -1) {
|
|
3192
|
+
removedCount++;
|
|
3193
|
+
} else {
|
|
3194
|
+
const lineBytes = buf.subarray(chunkPos, idx);
|
|
3195
|
+
const line = new TextDecoder("utf-8", { fatal: false }).decode(lineBytes);
|
|
3196
|
+
if (line.trim()) {
|
|
3197
|
+
try {
|
|
3198
|
+
const event = JSON.parse(line);
|
|
3199
|
+
if (event.type === "checkpoint") {
|
|
3200
|
+
if (event.promptIndex === targetPromptIndex) {
|
|
3201
|
+
checkpointByteOffset = lineStartOffset;
|
|
3202
|
+
targetCheckpointSeen = true;
|
|
3203
|
+
} else if (event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3204
|
+
checkpointByteOffset = lineStartOffset;
|
|
3205
|
+
}
|
|
3206
|
+
} else if (targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3207
|
+
removedCount++;
|
|
3208
|
+
} else if (targetCheckpointSeen && event.promptIndex === void 0) {
|
|
3209
|
+
removedCount++;
|
|
3210
|
+
} else if (!targetCheckpointSeen && event.promptIndex === void 0) {
|
|
3211
|
+
removedCount++;
|
|
3212
|
+
} else if (!targetCheckpointSeen && event.promptIndex !== void 0 && event.promptIndex > targetPromptIndex) {
|
|
3213
|
+
removedCount++;
|
|
3214
|
+
}
|
|
3215
|
+
} catch {
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
chunkPos = idx + 1;
|
|
3220
|
+
lineStartOffset = fileOffset + chunkPos;
|
|
3135
3221
|
}
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
} else if (event.promptIndex === void 0) {
|
|
3140
|
-
if (!afterTarget || targetCheckpointLine === -1) {
|
|
3141
|
-
kept.push(line);
|
|
3142
|
-
} else {
|
|
3143
|
-
removedCount++;
|
|
3222
|
+
fileOffset += bytesRead;
|
|
3223
|
+
if (chunkPos >= bytesRead) {
|
|
3224
|
+
lineStartOffset = fileOffset;
|
|
3144
3225
|
}
|
|
3145
|
-
} else {
|
|
3146
|
-
kept.push(line);
|
|
3147
3226
|
}
|
|
3227
|
+
} finally {
|
|
3228
|
+
await fd?.close();
|
|
3148
3229
|
}
|
|
3149
|
-
|
|
3230
|
+
if (checkpointByteOffset === -1) return 0;
|
|
3231
|
+
await this.writeChain;
|
|
3232
|
+
await this.handle.close();
|
|
3150
3233
|
const tmpPath = `${this.filePath}.rewind.tmp`;
|
|
3151
|
-
await fsp2.
|
|
3234
|
+
const src = await fsp2.open(this.filePath, "r", 384);
|
|
3152
3235
|
try {
|
|
3153
|
-
await
|
|
3236
|
+
const statResult = await src.stat();
|
|
3237
|
+
const totalSize = statResult.size;
|
|
3238
|
+
const prefixBytes = checkpointByteOffset;
|
|
3239
|
+
let newlineAfterCheckpoint = prefixBytes;
|
|
3240
|
+
if (prefixBytes < totalSize) {
|
|
3241
|
+
const probeBuf = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize - prefixBytes));
|
|
3242
|
+
const { bytesRead: probeRead } = await src.read(probeBuf, 0, probeBuf.length, prefixBytes);
|
|
3243
|
+
if (probeRead > 0) {
|
|
3244
|
+
const nl = probeBuf.indexOf("\n");
|
|
3245
|
+
newlineAfterCheckpoint = nl !== -1 ? prefixBytes + nl + 1 : totalSize;
|
|
3246
|
+
}
|
|
3247
|
+
} else {
|
|
3248
|
+
newlineAfterCheckpoint = totalSize;
|
|
3249
|
+
}
|
|
3250
|
+
const writeFd = await fsp2.open(tmpPath, "w", 384);
|
|
3251
|
+
try {
|
|
3252
|
+
let copied = 0;
|
|
3253
|
+
let readOffset = 0;
|
|
3254
|
+
while (readOffset < newlineAfterCheckpoint) {
|
|
3255
|
+
const toCopy = Math.min(CHUNK_SIZE, newlineAfterCheckpoint - readOffset);
|
|
3256
|
+
const copyBuf = Buffer.alloc(toCopy);
|
|
3257
|
+
const { bytesRead: r } = await src.read(copyBuf, 0, toCopy, readOffset);
|
|
3258
|
+
if (r === 0) break;
|
|
3259
|
+
await writeFd.write(copyBuf, 0, r);
|
|
3260
|
+
readOffset += r;
|
|
3261
|
+
copied += r;
|
|
3262
|
+
}
|
|
3263
|
+
const raw = await fsp2.readFile(this.filePath);
|
|
3264
|
+
const tail = raw.subarray(newlineAfterCheckpoint).toString("utf8");
|
|
3265
|
+
for (const line of tail.split("\n")) {
|
|
3266
|
+
if (!line.trim()) continue;
|
|
3267
|
+
try {
|
|
3268
|
+
JSON.parse(line);
|
|
3269
|
+
} catch {
|
|
3270
|
+
await writeFd.write(`${line}
|
|
3271
|
+
`, void 0, "utf8");
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
} finally {
|
|
3275
|
+
await writeFd.close();
|
|
3276
|
+
}
|
|
3277
|
+
await src.close();
|
|
3154
3278
|
await fsp2.rename(tmpPath, this.filePath);
|
|
3155
3279
|
this.handle = await fsp2.open(this.filePath, "a", 384);
|
|
3156
3280
|
} catch (err) {
|
|
3157
3281
|
await fsp2.unlink(tmpPath).catch(() => void 0);
|
|
3282
|
+
this.handle = await fsp2.open(this.filePath, "a", 384).catch(() => this.handle);
|
|
3158
3283
|
throw err;
|
|
3159
3284
|
}
|
|
3160
3285
|
await this.append({
|
|
@@ -3554,6 +3679,7 @@ var MEMORY_TYPE_LABELS = {
|
|
|
3554
3679
|
init_atomic_write();
|
|
3555
3680
|
var TYPE_PRIORITY_RE = /^\[(\w+)\|(\w+)\]\s+/;
|
|
3556
3681
|
var TAG_RE = /#([\w-]+)/g;
|
|
3682
|
+
var MAX_MEMORY_CONSOLIDATE_BACKUPS = 5;
|
|
3557
3683
|
function formatMetadata(entry) {
|
|
3558
3684
|
const parts = [];
|
|
3559
3685
|
if (entry.type && entry.priority) {
|
|
@@ -3746,6 +3872,7 @@ ${line}`;
|
|
|
3746
3872
|
const backup = `${file}.bak.${Date.now()}`;
|
|
3747
3873
|
try {
|
|
3748
3874
|
await fsp2.copyFile(file, backup);
|
|
3875
|
+
await pruneConsolidateBackups(file);
|
|
3749
3876
|
} catch {
|
|
3750
3877
|
}
|
|
3751
3878
|
try {
|
|
@@ -3756,6 +3883,20 @@ ${line}`;
|
|
|
3756
3883
|
return removed;
|
|
3757
3884
|
}
|
|
3758
3885
|
};
|
|
3886
|
+
async function pruneConsolidateBackups(file) {
|
|
3887
|
+
const dir = path4.dirname(file);
|
|
3888
|
+
const base = path4.basename(file);
|
|
3889
|
+
const prefix = `${base}.bak.`;
|
|
3890
|
+
const backups = (await fsp2.readdir(dir)).filter((name) => name.startsWith(prefix)).sort().reverse();
|
|
3891
|
+
await Promise.all(
|
|
3892
|
+
backups.slice(MAX_MEMORY_CONSOLIDATE_BACKUPS).map(async (name) => {
|
|
3893
|
+
try {
|
|
3894
|
+
await fsp2.unlink(path4.join(dir, name));
|
|
3895
|
+
} catch {
|
|
3896
|
+
}
|
|
3897
|
+
})
|
|
3898
|
+
);
|
|
3899
|
+
}
|
|
3759
3900
|
function parseEntries(raw, scope = "project-memory") {
|
|
3760
3901
|
const entries = [];
|
|
3761
3902
|
for (const line of raw.split("\n")) {
|
|
@@ -4935,7 +5076,9 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
4935
5076
|
plugins: true,
|
|
4936
5077
|
memory: true,
|
|
4937
5078
|
modelsRegistry: true,
|
|
4938
|
-
skills: true
|
|
5079
|
+
skills: true,
|
|
5080
|
+
tokenSavingMode: "off",
|
|
5081
|
+
allowOutsideProjectRoot: true
|
|
4939
5082
|
},
|
|
4940
5083
|
mcpServers: {},
|
|
4941
5084
|
indexing: {
|
|
@@ -4944,7 +5087,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
4944
5087
|
watchExternal: true,
|
|
4945
5088
|
debounceMs: 400
|
|
4946
5089
|
},
|
|
4947
|
-
session: { ...DEFAULT_SESSION_LOGGING_CONFIG }
|
|
5090
|
+
session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
|
|
5091
|
+
autonomy: { autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs }
|
|
4948
5092
|
};
|
|
4949
5093
|
function envBool(v) {
|
|
4950
5094
|
return !/^(0|false|no|off)$/i.test(v.trim());
|
|
@@ -5951,7 +6095,7 @@ function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
|
5951
6095
|
if (!shouldSample(event)) return;
|
|
5952
6096
|
try {
|
|
5953
6097
|
await target.append(event);
|
|
5954
|
-
} catch (
|
|
6098
|
+
} catch (_err) {
|
|
5955
6099
|
}
|
|
5956
6100
|
},
|
|
5957
6101
|
async appendBatch(events) {
|
|
@@ -9625,6 +9769,7 @@ ${post.additionalContext}`;
|
|
|
9625
9769
|
} catch (err) {
|
|
9626
9770
|
const msg = toErrorMessage(err);
|
|
9627
9771
|
const scrubbed = this.opts.secretScrubber.scrub(msg);
|
|
9772
|
+
const { category, retryable, detail } = classifyToolError(err);
|
|
9628
9773
|
this.opts.renderer?.writeToolResult(tool.name, scrubbed, true);
|
|
9629
9774
|
const result = {
|
|
9630
9775
|
type: "tool_result",
|
|
@@ -9635,6 +9780,9 @@ ${post.additionalContext}`;
|
|
|
9635
9780
|
budget = this.budgetForString(result.content, budget);
|
|
9636
9781
|
if (err instanceof Error) span?.recordError(err);
|
|
9637
9782
|
span?.setAttribute("tool.is_error", true);
|
|
9783
|
+
span?.setAttribute("tool.error_category", category);
|
|
9784
|
+
span?.setAttribute("tool.error_retryable", retryable);
|
|
9785
|
+
if (detail) span?.setAttribute("tool.error_detail", detail);
|
|
9638
9786
|
return { result, tool, durationMs: Date.now() - start };
|
|
9639
9787
|
} finally {
|
|
9640
9788
|
span?.end();
|
|
@@ -9646,6 +9794,9 @@ ${post.additionalContext}`;
|
|
|
9646
9794
|
} catch (err) {
|
|
9647
9795
|
const msg = toErrorMessage(err);
|
|
9648
9796
|
const scrubbed = this.opts.secretScrubber.scrub(msg);
|
|
9797
|
+
const { category, retryable, detail } = classifyToolError(err);
|
|
9798
|
+
const tool = this.registry.get(use.name);
|
|
9799
|
+
this.opts.renderer?.writeToolResult(tool?.name ?? use.name, scrubbed, true);
|
|
9649
9800
|
const result = {
|
|
9650
9801
|
type: "tool_result",
|
|
9651
9802
|
tool_use_id: use.id,
|
|
@@ -9653,7 +9804,7 @@ ${post.additionalContext}`;
|
|
|
9653
9804
|
is_error: true
|
|
9654
9805
|
};
|
|
9655
9806
|
budget = this.budgetForString(result.content, budget);
|
|
9656
|
-
return { result, tool
|
|
9807
|
+
return { result, tool, durationMs: 0 };
|
|
9657
9808
|
}
|
|
9658
9809
|
};
|
|
9659
9810
|
if (strategy === "sequential") {
|
|
@@ -9885,6 +10036,58 @@ function extractMalformedRaw(input) {
|
|
|
9885
10036
|
}
|
|
9886
10037
|
}
|
|
9887
10038
|
var TOOL_OUTPUT_ARTIFACT_THRESHOLD_BYTES = 64 * 1024;
|
|
10039
|
+
function classifyToolError(err) {
|
|
10040
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
10041
|
+
return { category: "fatal" /* FATAL */, retryable: false, detail: "aborted" };
|
|
10042
|
+
}
|
|
10043
|
+
if (err instanceof Error && "code" in err) {
|
|
10044
|
+
const code = err.code;
|
|
10045
|
+
switch (code) {
|
|
10046
|
+
case "ETIMEDOUT":
|
|
10047
|
+
case "ECONNRESET":
|
|
10048
|
+
case "ECONNREFUSED":
|
|
10049
|
+
case "ENETUNREACH":
|
|
10050
|
+
case "EHOSTUNREACH":
|
|
10051
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: code };
|
|
10052
|
+
case "ENOENT":
|
|
10053
|
+
case "ENOTDIR":
|
|
10054
|
+
return { category: "not_found" /* NOT_FOUND */, retryable: false, detail: code };
|
|
10055
|
+
case "EACCES":
|
|
10056
|
+
case "EPERM":
|
|
10057
|
+
return { category: "permission" /* PERMISSION */, retryable: false, detail: code };
|
|
10058
|
+
case "EBUSY":
|
|
10059
|
+
case "EMFILE":
|
|
10060
|
+
case "ENFILE":
|
|
10061
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: code };
|
|
10062
|
+
}
|
|
10063
|
+
}
|
|
10064
|
+
if (err instanceof Error && "response" in err) {
|
|
10065
|
+
const response = err.response;
|
|
10066
|
+
const status = response?.status;
|
|
10067
|
+
if (status !== void 0) {
|
|
10068
|
+
if (status === 429 || status === 503 || status === 502 || status === 504) {
|
|
10069
|
+
return { category: "transient" /* TRANSIENT */, retryable: true, detail: `HTTP ${status}` };
|
|
10070
|
+
}
|
|
10071
|
+
if (status === 404 || status === 410) {
|
|
10072
|
+
return { category: "not_found" /* NOT_FOUND */, retryable: false, detail: `HTTP ${status}` };
|
|
10073
|
+
}
|
|
10074
|
+
if (status === 401 || status === 403) {
|
|
10075
|
+
return { category: "permission" /* PERMISSION */, retryable: false, detail: `HTTP ${status}` };
|
|
10076
|
+
}
|
|
10077
|
+
if (status === 400) {
|
|
10078
|
+
return { category: "validation" /* VALIDATION */, retryable: false, detail: `HTTP ${status}` };
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
10082
|
+
if (err instanceof Error && err.message.includes("validation")) {
|
|
10083
|
+
return { category: "validation" /* VALIDATION */, retryable: false, detail: "validation" };
|
|
10084
|
+
}
|
|
10085
|
+
return {
|
|
10086
|
+
category: "fatal" /* FATAL */,
|
|
10087
|
+
retryable: false,
|
|
10088
|
+
detail: err instanceof Error ? err.message.slice(0, 100) : String(err).slice(0, 100)
|
|
10089
|
+
};
|
|
10090
|
+
}
|
|
9888
10091
|
async function maybePersistLargeToolOutput(toolName, content, budget) {
|
|
9889
10092
|
const bytes = Buffer.byteLength(content, "utf8");
|
|
9890
10093
|
if (bytes <= Math.min(TOOL_OUTPUT_ARTIFACT_THRESHOLD_BYTES, Math.max(0, budget))) {
|
|
@@ -10827,8 +11030,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
10827
11030
|
await saveGoal(this.goalPath, abandoned, this.opts.events);
|
|
10828
11031
|
}
|
|
10829
11032
|
try {
|
|
10830
|
-
const { unlink:
|
|
10831
|
-
await
|
|
11033
|
+
const { unlink: unlink11 } = await import('fs/promises');
|
|
11034
|
+
await unlink11(this.goalPath);
|
|
10832
11035
|
} catch {
|
|
10833
11036
|
}
|
|
10834
11037
|
this.opts.onEternalStop?.();
|
|
@@ -11211,7 +11414,7 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
11211
11414
|
*/
|
|
11212
11415
|
_busRequestDecision(entry) {
|
|
11213
11416
|
const bus = this._events;
|
|
11214
|
-
if (!bus
|
|
11417
|
+
if (!bus?.hasListenerFor("budget.threshold_reached")) {
|
|
11215
11418
|
return Promise.resolve("stop");
|
|
11216
11419
|
}
|
|
11217
11420
|
return new Promise((resolve6) => {
|