@wrongstack/core 0.141.0 → 0.148.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.
@@ -1,5 +1,5 @@
1
- export { C as CompactorOptions, D as DefaultErrorHandler, a as DefaultRetryPolicy, E as EternalAutonomyEngine, b as EternalAutonomyOptions, c as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, d as ParallelEternalEngine, e as ParallelEternalOptions, f as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-Dj2SYzha.js';
2
- export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-iuIUTQwk.js';
1
+ export { C as CompactorOptions, D as DefaultErrorHandler, a as DefaultRetryPolicy, E as EternalAutonomyEngine, b as EternalAutonomyOptions, c as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, d as ParallelEternalEngine, e as ParallelEternalOptions, f as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-C75QuhAI.js';
2
+ export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-CYJLg0wk.js';
3
3
  import { P as Provider } from '../context-C7G_MtLV.js';
4
4
  import { B as BrainDecision, a as BrainDecisionRequest, b as BrainArbiter } from '../brain-Cp_3GIS2.js';
5
5
  import '../retry-policy-rutAfVeR.js';
@@ -255,8 +255,8 @@ function findPreserveStart(messages, preserveK) {
255
255
  for (let i = preserveStart; i < messages.length; i++) {
256
256
  const m = messages[i];
257
257
  if (!m || typeof m.content === "string" || !Array.isArray(m.content)) continue;
258
- const hasToolUse2 = m.content.some((b) => b.type === "tool_use");
259
- if (hasToolUse2 && i + 1 < messages.length) {
258
+ const hasToolUse3 = m.content.some((b) => b.type === "tool_use");
259
+ if (hasToolUse3 && i + 1 < messages.length) {
260
260
  const next = messages[i + 1];
261
261
  if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) => b.type === "tool_result")) {
262
262
  preserveStart = i + 1;
@@ -320,6 +320,127 @@ function buildLosslessDigest(messages) {
320
320
  }
321
321
  return lines.join("\n");
322
322
  }
323
+ function extractText(m) {
324
+ if (typeof m.content === "string") return m.content;
325
+ return m.content.filter(isTextBlock).map((b) => b.text).join(" ");
326
+ }
327
+ function hasToolUse2(m) {
328
+ if (typeof m.content === "string") return false;
329
+ return m.content.some((b) => b.type === "tool_use");
330
+ }
331
+ function hasLargeToolResult(m, threshold = 3e3) {
332
+ if (typeof m.content === "string") return false;
333
+ return m.content.some(
334
+ (b) => b.type === "tool_result" && b.content && (typeof b.content === "string" ? b.content.length : JSON.stringify(b.content).length) > threshold
335
+ );
336
+ }
337
+ function scoreMessage(m, context) {
338
+ const text = extractText(m).toLowerCase();
339
+ if (text.trim().length === 0 && (hasToolUse2(m) || typeof m.content !== "string")) {
340
+ const hasResult = typeof m.content !== "string" && m.content.some((b) => b.type === "tool_result");
341
+ if (hasToolUse2(m) || hasResult) return 0;
342
+ }
343
+ if (context?.failureCounts && m.role === "user" && hasToolUse2(m) === false) {
344
+ const isFailure = /error|fail|exception|timeout|enonet|eacces|eperm|enoent|abort/i.test(text);
345
+ if (isFailure) {
346
+ const errKey = /(error|fail|exception|timeout|enonet|eacces|eperm|enoent|abort)/i.exec(text)?.[0]?.toLowerCase() ?? "error";
347
+ const count = (context.failureCounts.get(errKey) ?? 0) + 1;
348
+ context.failureCounts.set(errKey, count);
349
+ if (count >= 5) return 0;
350
+ if (count >= 3) return 1;
351
+ }
352
+ }
353
+ if (m.role === "user") {
354
+ if (/\b(wrong|no\b|stop\b|don'?t\b|actually|fix that|undo|revert|forget|ignore|skip)\b/i.test(
355
+ text
356
+ )) {
357
+ return 5;
358
+ }
359
+ }
360
+ if (/\b(error|exception|fatal|critical|crash|panic|abort|segfault|core dump|undefined is not|null pointer|typeerror|referenceerror|syntaxerror)\b/i.test(
361
+ text
362
+ )) {
363
+ return 5;
364
+ }
365
+ if (/\b(security|vulnerability|injection|xss|csrf|secret|apikey|api.key|hardcoded|leak|exploit|cve)\b/i.test(
366
+ text
367
+ )) {
368
+ return 5;
369
+ }
370
+ if (m.role === "assistant" && /\b(architecture|design|approach|strategy|pattern|refactor|migrate|restructure|decision|trade.?off)\b/i.test(
371
+ text
372
+ )) {
373
+ return 5;
374
+ }
375
+ if (hasLargeToolResult(m)) return 1;
376
+ if (m.role === "user" && !hasToolUse2(m) && /\b(files_with_matches|count|found \d+ match|directory tree|\.\.\. and \d+ more)\b/i.test(text)) {
377
+ return 1;
378
+ }
379
+ return 3;
380
+ }
381
+ function buildSmartDigest(messages) {
382
+ const lines = [];
383
+ const failureCounts = /* @__PURE__ */ new Map();
384
+ let noiseCount = 0;
385
+ for (const m of messages) {
386
+ const score = scoreMessage(m, { failureCounts });
387
+ const text = extractText(m);
388
+ const toolCount = countToolBlocks(m);
389
+ if (score === 0) {
390
+ noiseCount++;
391
+ continue;
392
+ }
393
+ const marker = toolCount > 0 ? ` [${toolCount} tool call(s)]` : "";
394
+ let display;
395
+ switch (score) {
396
+ case 5:
397
+ display = text.trim();
398
+ break;
399
+ case 3:
400
+ display = firstSentence(text);
401
+ break;
402
+ case 1:
403
+ display = oneLineSummary(m, text);
404
+ break;
405
+ default:
406
+ display = firstSentence(text);
407
+ }
408
+ if (display.length === 0 && toolCount === 0) continue;
409
+ lines.push(`[${m.role}]: ${display}${marker}`);
410
+ }
411
+ if (noiseCount > 0) {
412
+ lines.push(`[system]: ${noiseCount} low-importance turn(s) collapsed (repeated failures / pure tool I/O)`);
413
+ }
414
+ return lines.join("\n");
415
+ }
416
+ function countToolBlocks(m) {
417
+ if (typeof m.content === "string") return 0;
418
+ return m.content.filter(
419
+ (b) => b.type === "tool_use" || b.type === "tool_result"
420
+ ).length;
421
+ }
422
+ function firstSentence(text) {
423
+ const trimmed = text.trim();
424
+ if (trimmed.length === 0) return "";
425
+ const dot = trimmed.indexOf(". ");
426
+ if (dot === -1) return trimmed.length > 150 ? `${trimmed.slice(0, 147)}\u2026` : trimmed;
427
+ const sentence = trimmed.slice(0, dot + 1);
428
+ return sentence.length > 150 ? `${sentence.slice(0, 147)}\u2026` : sentence;
429
+ }
430
+ function oneLineSummary(m, text) {
431
+ const trimmed = text.trim();
432
+ if (trimmed.length === 0) {
433
+ if (typeof m.content !== "string") {
434
+ const results = m.content.filter((b) => b.type === "tool_result");
435
+ if (results.length > 0) {
436
+ return `[${results.length} tool result(s) \u2014 see session log]`;
437
+ }
438
+ }
439
+ return "[no text content]";
440
+ }
441
+ const firstLine = trimmed.split("\n")[0] ?? "";
442
+ return firstLine.length > 100 ? `${firstLine.slice(0, 97)}\u2026` : firstLine;
443
+ }
323
444
  function findSafeBoundary(messages, from, to) {
324
445
  for (let i = to; i >= from; i--) {
325
446
  const m = messages[i];
@@ -335,8 +456,8 @@ function findExchangeStart(messages, userIndex) {
335
456
  const m = messages[i];
336
457
  if (!m) continue;
337
458
  if (m.role === "assistant") {
338
- const hasToolUse2 = Array.isArray(m.content) ? m.content.some((b) => b.type === "tool_use") : false;
339
- if (!hasToolUse2) return i + 1;
459
+ const hasToolUse3 = Array.isArray(m.content) ? m.content.some((b) => b.type === "tool_use") : false;
460
+ if (!hasToolUse3) return i + 1;
340
461
  } else if (m.role === "user") {
341
462
  return i;
342
463
  }
@@ -348,9 +469,11 @@ function findExchangeStart(messages, userIndex) {
348
469
  var HybridCompactor = class {
349
470
  preserveK;
350
471
  eliseThreshold;
472
+ smart;
351
473
  constructor(opts = {}) {
352
474
  this.preserveK = opts.preserveK ?? 5;
353
475
  this.eliseThreshold = opts.eliseThreshold ?? 2e3;
476
+ this.smart = opts.smart ?? false;
354
477
  }
355
478
  async compact(ctx, opts = {}) {
356
479
  const beforeTokens = estimateMessages(ctx.messages);
@@ -422,7 +545,7 @@ var HybridCompactor = class {
422
545
  if (boundary <= 0) return { saved: 0 };
423
546
  const removed = messages.slice(0, boundary);
424
547
  const removedTokens = estimateMessages(removed);
425
- const digest = buildLosslessDigest(removed) || `${removed.length} earlier turns (no textual content; tool I/O omitted \u2014 see session log)`;
548
+ const digest = this.smart ? buildSmartDigest(removed) || `${removed.length} earlier turns (no textual content; tool I/O omitted \u2014 see session log)` : buildLosslessDigest(removed) || `${removed.length} earlier turns (no textual content; tool I/O omitted \u2014 see session log)`;
426
549
  const summaryMsg = {
427
550
  role: "system",
428
551
  content: `[prior_turns_digest: ${digest}]`
@@ -946,7 +1069,8 @@ function createStrategyCompactor(opts = {}) {
946
1069
  }
947
1070
  return new HybridCompactor({
948
1071
  preserveK: opts.preserveK,
949
- eliseThreshold: opts.eliseThreshold
1072
+ eliseThreshold: opts.eliseThreshold,
1073
+ smart: opts.smart
950
1074
  });
951
1075
  }
952
1076
  var ProviderBackedCompactor = class {
@@ -1807,7 +1931,7 @@ ${excerpt}`;
1807
1931
  subjectFor(toolName, input, subjectKey) {
1808
1932
  if (!input || typeof input !== "object") return void 0;
1809
1933
  const obj = input;
1810
- const globChars = /[*?\[\]]/g;
1934
+ const globChars = /[*?[\]]/g;
1811
1935
  const escapeGlob = (s) => s.replace(globChars, (c) => `\\${c}`);
1812
1936
  const normalizePath = (s) => escapeGlob(s.replace(/\\/g, "/"));
1813
1937
  if (subjectKey) {
@@ -2237,7 +2361,7 @@ function appendJournal(goal, entry) {
2237
2361
  };
2238
2362
  }
2239
2363
  function parseProgressFromText(text) {
2240
- const re = /\[progress:\s*(\d{1,3})%\]\s*(?:[—\-]\s*(.+))?/i;
2364
+ const re = /\[progress:\s*(\d{1,3})%\]\s*(?:[—-]\s*(.+))?/i;
2241
2365
  const m = text.match(re);
2242
2366
  if (!m) return null;
2243
2367
  const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? "0", 10)));
@@ -2415,7 +2539,7 @@ ${request.context}` : "",
2415
2539
  },
2416
2540
  { signal }
2417
2541
  );
2418
- const text = extractText(response).trim();
2542
+ const text = extractText2(response).trim();
2419
2543
  if (request.options?.length) {
2420
2544
  for (const opt of request.options) {
2421
2545
  if (text.toLowerCase().includes(opt.id.toLowerCase())) {
@@ -2443,7 +2567,7 @@ ${request.context}` : "",
2443
2567
  return { type: "deny", reason: "Autonomy Brain LLM unavailable for decision." };
2444
2568
  }
2445
2569
  }
2446
- function extractText(result) {
2570
+ function extractText2(result) {
2447
2571
  if (!result || typeof result !== "object") return "";
2448
2572
  const r = result;
2449
2573
  if (Array.isArray(r.content)) {