@lazyingart/agintiflow 0.20.245 → 0.20.246

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.245",
3
+ "version": "0.20.246",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
@@ -322,4 +322,84 @@ assert.ok(
322
322
  "DeepSeek runtime compaction exceeded the bounded retry target"
323
323
  );
324
324
 
325
+ function noisyFullReadPair(index, generation) {
326
+ const id = `validator-${generation}-${index}`;
327
+ const file = `tmp/validator-${generation}-${index}.py`;
328
+ return [
329
+ {
330
+ role: "assistant",
331
+ content: "",
332
+ reasoning_content: "Inspect the latest validator.",
333
+ tool_calls: [
334
+ {
335
+ id,
336
+ type: "function",
337
+ function: { name: "read_file", arguments: JSON.stringify({ path: file }) },
338
+ },
339
+ ],
340
+ },
341
+ {
342
+ role: "tool",
343
+ tool_call_id: id,
344
+ content: JSON.stringify({
345
+ ok: true,
346
+ toolName: "read_file",
347
+ path: file,
348
+ bytes: 4096,
349
+ lineCount: 120,
350
+ sha256: `${generation}${String(index).padStart(2, "0")}`.repeat(24).slice(0, 64),
351
+ contentTruncated: false,
352
+ content: `VALIDATOR-${generation}-${index}\n${"broad validator content ".repeat(150)}`,
353
+ }),
354
+ },
355
+ ];
356
+ }
357
+
358
+ const twiceCompactedState = {
359
+ ...compactionState,
360
+ messages: [
361
+ ...deepSeekRuntimeMessages,
362
+ ...Array.from({ length: 14 }, (_, index) => noisyFullReadPair(index + 1, 2)).flat(),
363
+ ],
364
+ };
365
+ const twiceCompacted = buildContextBudgetCompactionMessages(
366
+ twiceCompactedState,
367
+ { ...config, provider: "deepseek", model: "deepseek-chat" },
368
+ { title: "", url: "" },
369
+ 8,
370
+ { reason: "second DeepSeek compaction" }
371
+ );
372
+ const twiceCompactedText = twiceCompacted.map((message) => message.content || "").join("\n");
373
+ assert.ok(twiceCompactedText.includes("reliability-evidence-v14"));
374
+ assert.ok(twiceCompactedText.includes("EVIDENCE-CHUNK-ONE"));
375
+ assert.ok(twiceCompactedText.includes("EVIDENCE-CHUNK-TWO"));
376
+ assert.equal(
377
+ (twiceCompactedText.match(/Tool: deep_research/g) || []).length,
378
+ 1,
379
+ "second DeepSeek compaction duplicated the completed research record"
380
+ );
381
+
382
+ const thriceCompactedState = {
383
+ ...compactionState,
384
+ messages: [
385
+ ...twiceCompacted,
386
+ ...Array.from({ length: 14 }, (_, index) => noisyFullReadPair(index + 1, 3)).flat(),
387
+ ],
388
+ };
389
+ const thriceCompacted = buildContextBudgetCompactionMessages(
390
+ thriceCompactedState,
391
+ { ...config, provider: "deepseek", model: "deepseek-chat" },
392
+ { title: "", url: "" },
393
+ 12,
394
+ { reason: "third DeepSeek compaction" }
395
+ );
396
+ const thriceCompactedText = thriceCompacted.map((message) => message.content || "").join("\n");
397
+ assert.ok(thriceCompactedText.includes("reliability-evidence-v14"));
398
+ assert.ok(thriceCompactedText.includes("EVIDENCE-CHUNK-ONE"));
399
+ assert.ok(thriceCompactedText.includes("EVIDENCE-CHUNK-TWO"));
400
+ assert.ok(
401
+ estimateMessageTokens(thriceCompacted) <= 12288,
402
+ "cumulative DeepSeek compaction exceeded the bounded retry target"
403
+ );
404
+
325
405
  console.log("context budget recovery smoke passed");
@@ -838,19 +838,38 @@ function retainedReadRange(payload = {}, args = {}) {
838
838
  };
839
839
  }
840
840
 
841
+ function parseRetainedToolEvidenceMessage(message = {}) {
842
+ if (message?.role !== "user") return null;
843
+ const content = String(message.content || "");
844
+ if (!/^Retained runtime tool evidence\./i.test(content.trim())) return null;
845
+ const match = content.match(
846
+ /^Retained runtime tool evidence\.[^\n]*\nTool:\s*([^\n]+)\nArguments:\s*([^\n]+)\nVerified result:\s*([\s\S]+)$/i
847
+ );
848
+ if (!match) return null;
849
+ const name = String(match[1] || "").trim();
850
+ const args = safeParseToolContent(match[2]) || {};
851
+ const payload = safeParseToolContent(match[3]);
852
+ if (!name || !COMPACTION_STATE_TOOL_NAMES.has(name) || !payload || typeof payload !== "object") {
853
+ return null;
854
+ }
855
+ return { name, args, payload };
856
+ }
857
+
841
858
  function summarizeRetainedSourceEvidence(messages = [], limit = 28) {
842
859
  const bySource = new Map();
843
860
  for (const message of messages) {
844
- if (message?.role !== "tool") continue;
845
- const payload = safeParseToolContent(message.content);
861
+ const retained = parseRetainedToolEvidenceMessage(message);
862
+ if (message?.role !== "tool" && !retained) continue;
863
+ const payload = retained?.payload || safeParseToolContent(message.content);
846
864
  if (!payload || payload.ok === false || payload.blocked || payload.skipped) continue;
847
- const toolName = String(payload.toolName || payload.name || "");
865
+ const toolName = String(retained?.name || payload.toolName || payload.name || "");
848
866
  if (!["read_file", "list_files", "search_files", "inspect_project", "run_command"].includes(toolName)) {
849
867
  continue;
850
868
  }
851
- const sourcePath = String(payload.path || payload.args?.path || "").trim();
852
- const command = String(payload.args?.command || "").trim();
853
- const readRange = toolName === "read_file" ? retainedReadRange(payload, payload.args || {}) : null;
869
+ const args = retained?.args || payload.args || {};
870
+ const sourcePath = String(payload.path || args.path || "").trim();
871
+ const command = String(args.command || "").trim();
872
+ const readRange = toolName === "read_file" ? retainedReadRange(payload, args) : null;
854
873
  const key = `${toolName}:${sourcePath || command}${readRange ? `:${readRange.key}` : ""}`;
855
874
  const parts = [`tool=${toolName}`];
856
875
  if (sourcePath) parts.push(`path=${sourcePath}`);
@@ -986,6 +1005,7 @@ function compactRetainedToolPayload(toolName, payload = {}, args = {}) {
986
1005
  result.results = compactPathItems(payload.results, 24, ["path", "file", "line", "match"]);
987
1006
  } else if (toolName === "run_command") {
988
1007
  result.args = { command: compactMultiline(args.command || payload.args?.command || "", 1200) };
1008
+ if (payload.changed !== undefined) result.changed = Boolean(payload.changed);
989
1009
  if (Number.isFinite(Number(payload.exitCode))) result.exitCode = Number(payload.exitCode);
990
1010
  if (payload.stdout) result.stdout = compactMultiline(payload.stdout, 1800);
991
1011
  if (payload.stderr) result.stderr = compactMultiline(payload.stderr, 1200);
@@ -998,11 +1018,51 @@ function compactRetainedToolPayload(toolName, payload = {}, args = {}) {
998
1018
  return redactValue(result);
999
1019
  }
1000
1020
 
1021
+ function retainedToolRecordPriority(record = {}) {
1022
+ const name = String(record.name || "");
1023
+ const args = record.args || {};
1024
+ const payload = record.payload || {};
1025
+ let priority = 100;
1026
+ if (name === "deep_research") priority = 1000;
1027
+ else if (name === "inspect_project") priority = 900;
1028
+ else if (["apply_patch", "write_file"].includes(name)) priority = 850;
1029
+ else if (name === "run_command") {
1030
+ const exitCode = Number(payload.exitCode);
1031
+ priority = payload.changed === true || (Number.isFinite(exitCode) && exitCode !== 0) ? 800 : 500;
1032
+ } else if (name === "read_file") {
1033
+ const range = retainedReadRange(payload, args);
1034
+ priority = range.lineLimit > 0 ? 750 : 600;
1035
+ } else if (["search_files", "list_files"].includes(name)) priority = 400;
1036
+ return priority + Math.min(0.999, Math.max(0, Number(record.ordinal) || 0) / 100000);
1037
+ }
1038
+
1001
1039
  function retainedToolStateMessages(messages = [], limit = 12) {
1002
1040
  const callsById = new Map();
1003
1041
  const recordsByKey = new Map();
1004
1042
  let ordinal = 0;
1043
+ const retainRecord = (name, args = {}, payload = {}) => {
1044
+ if (!COMPACTION_STATE_TOOL_NAMES.has(name)) return;
1045
+ if (!payload || payload.ok === false || payload.blocked || payload.skipped) return;
1046
+ const sourcePath = String(payload.path || args?.path || "").trim();
1047
+ const command = String(args?.command || payload.args?.command || "").trim();
1048
+ const durableIdentity = String(
1049
+ sourcePath || command || payload.researchId || args?.researchId || args?.query || name
1050
+ ).trim();
1051
+ const readRange = name === "read_file" ? retainedReadRange(payload, args) : null;
1052
+ const key = `${name}:${durableIdentity || ordinal}${readRange ? `:${readRange.key}` : ""}`;
1053
+ recordsByKey.set(key, {
1054
+ ordinal: ordinal += 1,
1055
+ name,
1056
+ args: redactValue(args),
1057
+ payload: compactRetainedToolPayload(name, payload, args),
1058
+ });
1059
+ };
1005
1060
  for (const message of messages) {
1061
+ const retained = parseRetainedToolEvidenceMessage(message);
1062
+ if (retained) {
1063
+ retainRecord(retained.name, retained.args, retained.payload);
1064
+ continue;
1065
+ }
1006
1066
  if (message?.role === "assistant" && Array.isArray(message.tool_calls)) {
1007
1067
  for (const call of message.tool_calls) {
1008
1068
  const id = String(call?.id || "").trim();
@@ -1018,27 +1078,19 @@ function retainedToolStateMessages(messages = [], limit = 12) {
1018
1078
  if (message?.role !== "tool") continue;
1019
1079
  const call = callsById.get(String(message.tool_call_id || "").trim());
1020
1080
  const payload = safeParseToolContent(message.content);
1021
- if (!call || !payload || payload.ok === false || payload.blocked || payload.skipped) continue;
1022
- const sourcePath = String(payload.path || call.args?.path || "").trim();
1023
- const command = String(call.args?.command || payload.args?.command || "").trim();
1024
- const readRange = call.name === "read_file" ? retainedReadRange(payload, call.args) : null;
1025
- const key = `${call.name}:${sourcePath || command || ordinal}${readRange ? `:${readRange.key}` : ""}`;
1026
- recordsByKey.set(key, {
1027
- ordinal: ordinal += 1,
1028
- name: call.name,
1029
- args: redactValue(call.args),
1030
- payload: compactRetainedToolPayload(call.name, payload, call.args),
1031
- });
1081
+ if (!call || !payload) continue;
1082
+ retainRecord(call.name, call.args, payload);
1032
1083
  }
1033
1084
 
1034
1085
  const records = [...recordsByKey.values()];
1035
- const pinned = ["inspect_project", "deep_research"]
1036
- .map((name) => [...records].reverse().find((record) => record.name === name))
1037
- .filter(Boolean);
1038
- const remaining = records
1039
- .filter((record) => !pinned.includes(record))
1040
- .slice(-Math.max(0, Number(limit) - pinned.length));
1041
- const selected = [...pinned, ...remaining].sort((left, right) => left.ordinal - right.ordinal);
1086
+ const selected = [...records]
1087
+ .sort(
1088
+ (left, right) =>
1089
+ retainedToolRecordPriority(right) - retainedToolRecordPriority(left) ||
1090
+ right.ordinal - left.ordinal
1091
+ )
1092
+ .slice(0, Math.max(1, Number(limit) || 12))
1093
+ .sort((left, right) => left.ordinal - right.ordinal);
1042
1094
 
1043
1095
  return selected.flatMap((record, index) => {
1044
1096
  const id = `aginti-compacted-tool-${index + 1}`;
@@ -1087,6 +1139,15 @@ function retainedToolStateTextMessages(messages = [], limit = 12) {
1087
1139
  return retained;
1088
1140
  }
1089
1141
 
1142
+ function retainedToolPairPriority(pair = [], order = 0) {
1143
+ const assistantCall = pair[0]?.tool_calls?.[0];
1144
+ const retained = pair.length === 1 ? parseRetainedToolEvidenceMessage(pair[0]) : null;
1145
+ const name = String(retained?.name || assistantCall?.function?.name || "");
1146
+ const args = retained?.args || safeParseToolContent(assistantCall?.function?.arguments) || {};
1147
+ const payload = retained?.payload || safeParseToolContent(pair[1]?.content) || {};
1148
+ return retainedToolRecordPriority({ name, args, payload, ordinal: order });
1149
+ }
1150
+
1090
1151
  function isRuntimeCompactionRequest(content = "") {
1091
1152
  return /^(?:The runtime proactively compacted a long agent history|A previous agent-step model request timed out|Continue from this compacted, valid transcript)/i.test(
1092
1153
  String(content || "").trim()
@@ -1107,6 +1168,7 @@ function summarizeOriginalRequests(messages = [], limit = 6) {
1107
1168
  if (!content.trim()) continue;
1108
1169
  if (/^Step \d+\/\d+ .*Latest runtime snapshot:/i.test(content)) continue;
1109
1170
  if (/^Previous assistant response retained as compacted history/i.test(content)) continue;
1171
+ if (parseRetainedToolEvidenceMessage(message)) continue;
1110
1172
  if (isRuntimeCompactionRequest(content)) continue;
1111
1173
  if (isRuntimeRecoveryRequest(content)) continue;
1112
1174
  requests.push(compactSingleLine(content, 1200));
@@ -1357,20 +1419,29 @@ function buildCompactedRuntimeMessages(state, config, snapshot, step, options =
1357
1419
  ];
1358
1420
  const retainedPairs = [];
1359
1421
  for (let index = 0; index < retainedToolMessages.length; index += deepSeekCompaction ? 1 : 2) {
1360
- retainedPairs.push(retainedToolMessages.slice(index, index + (deepSeekCompaction ? 1 : 2)));
1422
+ const pair = retainedToolMessages.slice(index, index + (deepSeekCompaction ? 1 : 2));
1423
+ retainedPairs.push({
1424
+ pair,
1425
+ order: retainedPairs.length,
1426
+ priority: retainedToolPairPriority(pair, retainedPairs.length),
1427
+ });
1361
1428
  }
1362
1429
  const selectedPairs = [];
1363
- for (const pair of retainedPairs.reverse()) {
1430
+ const prioritizedPairs = [...retainedPairs].sort(
1431
+ (left, right) => right.priority - left.priority || right.order - left.order
1432
+ );
1433
+ for (const candidatePair of prioritizedPairs) {
1364
1434
  const candidate = [
1365
1435
  ...baseMessages,
1366
- ...pair,
1367
- ...selectedPairs.flat(),
1436
+ ...candidatePair.pair,
1437
+ ...selectedPairs.flatMap((item) => item.pair),
1368
1438
  ];
1369
- if (estimateMessageTokens(candidate) <= targetTokens) selectedPairs.unshift(pair);
1439
+ if (estimateMessageTokens(candidate) <= targetTokens) selectedPairs.push(candidatePair);
1370
1440
  }
1441
+ selectedPairs.sort((left, right) => left.order - right.order);
1371
1442
  const compactMessages = [
1372
1443
  ...baseMessages,
1373
- ...selectedPairs.flat(),
1444
+ ...selectedPairs.flatMap((item) => item.pair),
1374
1445
  ];
1375
1446
 
1376
1447
  if (!compactMessages.some((message) => message.role === "system")) {