@lazyingart/agintiflow 0.20.288 → 0.20.289

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.
@@ -130,6 +130,13 @@ only after a categorized provider failure and must not replay verified side
130
130
  effects. Codex and Claude remain explicit opt-in backends rather than hidden
131
131
  fallbacks.
132
132
 
133
+ Timeout compaction also preserves goal-scoped deep-research completion. A
134
+ same-task repair of the immediately preceding report keeps ordinary file,
135
+ shell, and validation tools after a model switch instead of forcing another
136
+ research pass. A genuinely new research request does not inherit that marker
137
+ and still begins with the bounded `deep_research` workflow. Native function
138
+ calling and the text-tool fallback apply the same rule.
139
+
133
140
  ## Machine Host Protocol
134
141
 
135
142
  The supported subprocess boundary is:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.288",
3
+ "version": "0.20.289",
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",
@@ -5151,6 +5151,113 @@ assert(
5151
5151
  "post-research compaction forgot the completed bounded research call"
5152
5152
  );
5153
5153
 
5154
+ const timeoutCompactedResearchRepairGoal =
5155
+ "External verification failed for the existing research report. Preserve the report and evidence, add the missing sources.json and PDF, run the validator, and commit the repair.";
5156
+ const timeoutCompactedResearchRepairState = {
5157
+ goal: timeoutCompactedResearchRepairGoal,
5158
+ meta: {
5159
+ goalContract: {
5160
+ revision: 2,
5161
+ currentHash: "research-repair-goal",
5162
+ currentRequest: timeoutCompactedResearchRepairGoal,
5163
+ history: [
5164
+ { revision: 1, hash: "original-research-goal" },
5165
+ {
5166
+ revision: 2,
5167
+ hash: "research-repair-goal",
5168
+ previousHash: "original-research-goal",
5169
+ },
5170
+ ],
5171
+ },
5172
+ completedDeepResearch: [
5173
+ {
5174
+ goalKey: "original-research-goal",
5175
+ result: {
5176
+ ok: true,
5177
+ version: 14,
5178
+ reportPath: path.join(repoRoot, "package.json"),
5179
+ },
5180
+ },
5181
+ ],
5182
+ },
5183
+ };
5184
+ const timeoutCompactedResearchRepairRuntime = nextStepRuntimeConfig(
5185
+ {
5186
+ provider: "deepseek",
5187
+ goal: timeoutCompactedResearchRepairGoal,
5188
+ commandCwd: repoRoot,
5189
+ },
5190
+ timeoutCompactedResearchRepairState
5191
+ );
5192
+ assertStrict.equal(
5193
+ timeoutCompactedResearchRepairRuntime.deepResearchCompletedForCurrentWork,
5194
+ true,
5195
+ "a successor artifact repair lost the completed research record from its immediately preceding goal"
5196
+ );
5197
+ const timeoutCompactedResearchRepair = selectProgressiveTools(allTools, {
5198
+ config: timeoutCompactedResearchRepairRuntime,
5199
+ goal: timeoutCompactedResearchRepairGoal,
5200
+ profile: "research",
5201
+ messages: [
5202
+ {
5203
+ role: "user",
5204
+ content:
5205
+ "A previous agent-step request was interrupted by a model timeout. Continue from this compacted, valid transcript.",
5206
+ },
5207
+ {
5208
+ role: "user",
5209
+ content:
5210
+ "Retained runtime tool evidence. This operation already completed; use its result and do not repeat it solely because context was compacted.\nTool: read_file\nVerified result: existing evidence report",
5211
+ },
5212
+ ],
5213
+ });
5214
+ assert(names(timeoutCompactedResearchRepair).includes("run_command"), "timeout-compacted research repair omitted shell validation");
5215
+ assert(names(timeoutCompactedResearchRepair).includes("write_file"), "timeout-compacted research repair omitted artifact writing");
5216
+ assert(
5217
+ !(names(timeoutCompactedResearchRepair).length === 2 && names(timeoutCompactedResearchRepair)[0] === "deep_research"),
5218
+ "timeout recovery forced a completed research task back into deep_research"
5219
+ );
5220
+
5221
+ const unrelatedNewResearchGoal =
5222
+ "Write a new deep research report comparing current optical sensor calibration methods.";
5223
+ const unrelatedNewResearchRuntime = nextStepRuntimeConfig(
5224
+ { provider: "deepseek", goal: unrelatedNewResearchGoal, commandCwd: repoRoot },
5225
+ {
5226
+ ...timeoutCompactedResearchRepairState,
5227
+ goal: unrelatedNewResearchGoal,
5228
+ meta: {
5229
+ ...timeoutCompactedResearchRepairState.meta,
5230
+ goalContract: {
5231
+ revision: 3,
5232
+ currentHash: "new-research-goal",
5233
+ currentRequest: unrelatedNewResearchGoal,
5234
+ history: [
5235
+ ...timeoutCompactedResearchRepairState.meta.goalContract.history,
5236
+ {
5237
+ revision: 3,
5238
+ hash: "new-research-goal",
5239
+ previousHash: "research-repair-goal",
5240
+ },
5241
+ ],
5242
+ },
5243
+ },
5244
+ }
5245
+ );
5246
+ assertStrict.equal(
5247
+ unrelatedNewResearchRuntime.deepResearchCompletedForCurrentWork,
5248
+ undefined,
5249
+ "an old completed report suppressed a genuinely new research request"
5250
+ );
5251
+ sameNames(
5252
+ selectProgressiveTools(allTools, {
5253
+ config: unrelatedNewResearchRuntime,
5254
+ goal: unrelatedNewResearchGoal,
5255
+ profile: "research",
5256
+ }),
5257
+ ["deep_research", "finish"],
5258
+ "a genuinely new research request did not retain the bounded deep-research starter"
5259
+ );
5260
+
5154
5261
  const documentRuntimeSnapshot =
5155
5262
  'Step 1/30. Latest runtime snapshot:\n{"pageText":"Workspace file tools are ready. Web search and resumable deep research are available when current evidence is required."}';
5156
5263
  const localDocumentStarter = selectProgressiveTools(allTools, {
@@ -13687,6 +13687,45 @@ export function convergenceSuppressedToolNames(state = {}) {
13687
13687
  return [toolName];
13688
13688
  }
13689
13689
 
13690
+ function currentWorkHasCompletedDeepResearch(state = {}, config = {}) {
13691
+ const records = Array.isArray(state.meta?.completedDeepResearch)
13692
+ ? state.meta.completedDeepResearch
13693
+ : [];
13694
+ if (!records.length) return false;
13695
+
13696
+ const goalContract = state.meta?.goalContract || {};
13697
+ const currentKey = String(
13698
+ goalContract.currentHash || goalContract.activeHash || currentGoalKey(state)
13699
+ ).trim();
13700
+ const latestHistory = Array.isArray(goalContract.history)
13701
+ ? goalContract.history.at(-1) || {}
13702
+ : {};
13703
+ const previousKey = String(latestHistory.previousHash || "").trim();
13704
+ const currentRequest = String(
13705
+ goalContract.currentRequest || config.goal || state.goal || ""
13706
+ ).replace(/\s+/g, " ").trim();
13707
+ const continuesExistingResearchArtifact = Boolean(
13708
+ previousKey &&
13709
+ /\b(?:preserve|reuse|continue|recover|repair|fix|correct|revise|validate|verify|rebuild|missing|existing|completed|retained|saved)\b/i.test(currentRequest) &&
13710
+ /\b(?:research|report|evidence|sources?|citations?|manifest|pdf|artifact|validation|validator)\b/i.test(currentRequest)
13711
+ );
13712
+
13713
+ return records.some((record) => {
13714
+ const result = record?.result || {};
13715
+ if (
13716
+ result.ok !== true ||
13717
+ Number(result.version || 0) !== RESEARCH_VERSION ||
13718
+ !String(result.reportPath || "").trim() ||
13719
+ !fsSync.existsSync(String(result.reportPath))
13720
+ ) {
13721
+ return false;
13722
+ }
13723
+ const recordKey = String(record.goalKey || "").trim();
13724
+ if (recordKey && recordKey === currentKey) return true;
13725
+ return continuesExistingResearchArtifact && recordKey === previousKey;
13726
+ });
13727
+ }
13728
+
13690
13729
  export function nextStepRuntimeConfig(config = {}, state = {}) {
13691
13730
  const staticOrder = Array.isArray(state.meta?.toolLoop?.staticOrder)
13692
13731
  ? state.meta.toolLoop.staticOrder
@@ -13699,6 +13738,9 @@ export function nextStepRuntimeConfig(config = {}, state = {}) {
13699
13738
  const runtimeConfig = {
13700
13739
  ...applyLocalFailureRecovery(config, state),
13701
13740
  ...(retainedDataDiscoveryReady ? { dataProjectDiscoveryReady: true } : {}),
13741
+ ...(currentWorkHasCompletedDeepResearch(state, config)
13742
+ ? { deepResearchCompletedForCurrentWork: true }
13743
+ : {}),
13702
13744
  };
13703
13745
  const suppressedToolNames = convergenceSuppressedToolNames(state);
13704
13746
  if (suppressedToolNames.length) {
@@ -517,7 +517,9 @@ function messagesWithTextToolProtocol(config, messages, tools) {
517
517
  }
518
518
  return message;
519
519
  });
520
- const requireDeepResearch = tools.some((tool) => tool?.function?.name === "deep_research") &&
520
+ const requireDeepResearch =
521
+ config.deepResearchCompletedForCurrentWork !== true &&
522
+ tools.some((tool) => tool?.function?.name === "deep_research") &&
521
523
  shouldStartWithDeepResearch(config.goal, messages);
522
524
  const protocol = {
523
525
  role: "system",
@@ -2741,7 +2741,10 @@ export function selectProgressiveTools(
2741
2741
  )
2742
2742
  : enabled;
2743
2743
 
2744
- if (shouldStartWithDeepResearch(goal || config.goal, messages)) {
2744
+ if (
2745
+ config.deepResearchCompletedForCurrentWork !== true &&
2746
+ shouldStartWithDeepResearch(goal || config.goal, messages)
2747
+ ) {
2745
2748
  const deepResearch = phaseEnabled.find(({ name }) => name === "deep_research")?.tool;
2746
2749
  if (deepResearch) return [deepResearch, finish];
2747
2750
  }
@@ -10,7 +10,7 @@ const RUNTIME_USER_MESSAGE_PATTERNS = Object.freeze([
10
10
  /^Step \d+\/\d+\b.*Latest runtime snapshot:/i,
11
11
  /^Retained runtime tool evidence\./i,
12
12
  /^The runtime proactively compacted a long agent history/i,
13
- /^A previous agent-step model request timed out/i,
13
+ /^A previous agent-step (?:model request timed out|request was interrupted by a (?:model timeout|transient provider transport interruption))/i,
14
14
  /^Continue from this compacted, valid transcript/i,
15
15
  /^Previous assistant response retained as compacted history/i,
16
16
  /^Highest-priority retained state:/i,