@lazyingart/agintiflow 0.20.281 → 0.20.283

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.281",
3
+ "version": "0.20.283",
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",
@@ -25,7 +25,11 @@ import { createToolContract, resolveDispatchableToolCallBatch } from "../src/too
25
25
  import { formatBehaviorContractForPrompt } from "../src/behavior-contract.js";
26
26
  import { resolveRuntimeConfig } from "../src/config.js";
27
27
  import { readCodebaseMap } from "../src/codebase-map.js";
28
- import { classifyCommand, evaluateCommandPolicy } from "../src/command-policy.js";
28
+ import {
29
+ classifyCommand,
30
+ evaluateCommandPolicy,
31
+ externalValidatorCommandContract,
32
+ } from "../src/command-policy.js";
29
33
  import { checkToolUse } from "../src/guardrails.js";
30
34
  import { shouldReviewToolResult } from "../src/scs-controller.js";
31
35
  import {
@@ -96,6 +100,52 @@ async function runMock(goal, sessionId, { resume = false } = {}) {
96
100
  }
97
101
 
98
102
  try {
103
+ const externalValidatorPath = path.join(
104
+ tempRoot,
105
+ "private-acceptance",
106
+ "spreadsheet_contract.py"
107
+ );
108
+ const externalValidatorCommand = `python3 ${externalValidatorPath}`;
109
+ assert(
110
+ externalValidatorCommandContract(externalValidatorCommand, {
111
+ commandCwd: workspace,
112
+ })?.path === externalValidatorPath,
113
+ "an exact external validator command did not produce an opaque contract"
114
+ );
115
+ assert(
116
+ externalValidatorCommandContract("python3 tests/local_contract.py", {
117
+ commandCwd: workspace,
118
+ }) === null,
119
+ "an in-workspace project test was incorrectly treated as an opaque external validator"
120
+ );
121
+ const opaqueValidatorPolicy = {
122
+ commandCwd: workspace,
123
+ allowShellTool: true,
124
+ sandboxMode: "host",
125
+ packageInstallPolicy: "block",
126
+ opaqueExternalValidatorPaths: [externalValidatorPath],
127
+ opaqueExternalValidatorCommands: [externalValidatorCommand],
128
+ };
129
+ assert(
130
+ evaluateCommandPolicy(externalValidatorCommand, opaqueValidatorPolicy).allowed === true,
131
+ "the exact declared external validator execution was blocked"
132
+ );
133
+ for (const inspectionCommand of [
134
+ `cat ${externalValidatorPath}`,
135
+ `sed -n '1,160p' ${externalValidatorPath}`,
136
+ `cat ${path.relative(workspace, externalValidatorPath)}`,
137
+ `V=${externalValidatorPath}; grep -n expected "$V"`,
138
+ `echo validator; cat ${externalValidatorPath}; git status --short`,
139
+ ]) {
140
+ const decision = evaluateCommandPolicy(inspectionCommand, opaqueValidatorPolicy);
141
+ assert(
142
+ decision.allowed === false &&
143
+ decision.category === "opaque-external-validator-inspection" &&
144
+ decision.recoverable === true,
145
+ `external validator source inspection escaped the opaque contract: ${inspectionCommand}`
146
+ );
147
+ }
148
+
99
149
  const genericArtifactBlock = await genericArtifactFilenameBlock(
100
150
  "write_file",
101
151
  { path: "report.md", content: "summary" },
@@ -8,6 +8,43 @@ import {
8
8
  evaluatePdfTextBounds,
9
9
  extractSupersededLiterals,
10
10
  } from "../src/document-artifact-quality.js";
11
+ import { evaluateSpreadsheetStructure } from "../src/spreadsheet-artifact-quality.js";
12
+
13
+ const workbookWithPlaceholder = evaluateSpreadsheetStructure({
14
+ sheets: [
15
+ { name: "Sheet", state: "visible", cellCount: 0, formulaCount: 0 },
16
+ { name: "Raw Inventory", state: "visible", cellCount: 30, formulaCount: 0 },
17
+ { name: "Reorder Plan", state: "visible", cellCount: 20, formulaCount: 8 },
18
+ ],
19
+ chartCount: 1,
20
+ externalLinkCount: 0,
21
+ hasMacros: false,
22
+ });
23
+ assert.equal(workbookWithPlaceholder.ok, false, "an empty default workbook sheet was accepted");
24
+ assert.equal(workbookWithPlaceholder.defects[0]?.code, "unused-default-worksheet");
25
+
26
+ const emptyWorkbook = evaluateSpreadsheetStructure({
27
+ sheets: [{ name: "Sheet", state: "visible", cellCount: 0, formulaCount: 0 }],
28
+ chartCount: 0,
29
+ externalLinkCount: 0,
30
+ hasMacros: false,
31
+ });
32
+ assert.equal(emptyWorkbook.ok, false, "a completely empty workbook was accepted");
33
+ assert.equal(emptyWorkbook.defects[0]?.code, "workbook-has-no-content");
34
+
35
+ const purposefulWorkbook = evaluateSpreadsheetStructure({
36
+ sheets: [
37
+ { name: "Raw Inventory", state: "visible", cellCount: 30, formulaCount: 0 },
38
+ { name: "Reorder Plan", state: "visible", cellCount: 20, formulaCount: 8 },
39
+ { name: "Dashboard", state: "visible", cellCount: 12, formulaCount: 3 },
40
+ ],
41
+ chartCount: 1,
42
+ externalLinkCount: 0,
43
+ hasMacros: false,
44
+ });
45
+ assert.equal(purposefulWorkbook.ok, true, "a workbook with only purposeful sheets was rejected");
46
+ assert.equal(purposefulWorkbook.formulaCount, 11);
47
+ assert.equal(purposefulWorkbook.chartCount, 1);
11
48
 
12
49
  const source = [
13
50
  "Initial plan: the demonstration date was September 12.",
@@ -53,6 +53,7 @@ import {
53
53
  isSubstantiveTestCommand,
54
54
  mergeDurableGitEvidence,
55
55
  nextStepRuntimeConfig,
56
+ patchContextRefreshDecision,
56
57
  patchContextScopeMismatchAttemptCount,
57
58
  parseGitPorcelainStatus,
58
59
  pythonMainGuardOrderDefects,
@@ -1216,6 +1217,100 @@ try {
1216
1217
  Boolean(unrelatedInsertionBinding?.scopeIssue),
1217
1218
  "an unrelated missing declaration escaped the active failed-test symbol contract"
1218
1219
  );
1220
+ const declarationBoundarySource = [
1221
+ "def build_preview():",
1222
+ " path = 'preview.png'",
1223
+ " return path",
1224
+ "",
1225
+ "def main():",
1226
+ " return build_preview()",
1227
+ "",
1228
+ ].join("\n");
1229
+ const declarationBoundaryOffset = declarationBoundarySource.indexOf("def main():");
1230
+ const declarationBoundaryAnchor = declarationBoundarySource.slice(
1231
+ 0,
1232
+ declarationBoundaryOffset
1233
+ );
1234
+ const declarationBoundaryState = {
1235
+ meta: {
1236
+ goalContract: { revision: 1 },
1237
+ projectVerification: { mutationRevision: 1, privateMutationRevision: 0 },
1238
+ toolLoop: {
1239
+ patchContextRepair: {
1240
+ version: 1,
1241
+ path: "preview_builder.py",
1242
+ goalRevision: 1,
1243
+ mutationRevision: 1,
1244
+ privateMutationRevision: 0,
1245
+ search: declarationBoundaryAnchor,
1246
+ searchHash: crypto
1247
+ .createHash("sha256")
1248
+ .update(declarationBoundaryAnchor)
1249
+ .digest("hex"),
1250
+ sourceHash: crypto
1251
+ .createHash("sha256")
1252
+ .update(declarationBoundarySource)
1253
+ .digest("hex"),
1254
+ anchorKind: "declaration-identity",
1255
+ anchorIdentity: "build_preview",
1256
+ },
1257
+ },
1258
+ },
1259
+ };
1260
+ const declarationBoundaryBinding = bindPatchContextRepairArguments(
1261
+ declarationBoundaryState,
1262
+ {
1263
+ replace: [
1264
+ "def build_preview():",
1265
+ " path = 'preview-fixed.png'",
1266
+ " return path",
1267
+ ].join("\n"),
1268
+ }
1269
+ );
1270
+ assert(
1271
+ declarationBoundaryBinding?.boundaryWhitespacePreserved === true &&
1272
+ declarationBoundaryBinding.args.replace.endsWith("\n") &&
1273
+ /return path\n+def main\(\):/.test(
1274
+ `${declarationBoundaryBinding.args.replace}${declarationBoundarySource.slice(declarationBoundaryOffset)}`
1275
+ ),
1276
+ "revision-bound declaration replacement did not preserve its Python declaration boundary"
1277
+ );
1278
+ await fs.writeFile(
1279
+ path.join(workspace, "preview_builder.py"),
1280
+ declarationBoundarySource,
1281
+ "utf8"
1282
+ );
1283
+ assert(
1284
+ (await prospectivePythonExactPatchSyntaxBlock(
1285
+ "apply_patch",
1286
+ declarationBoundaryBinding.args,
1287
+ { commandCwd: workspace }
1288
+ )) === null,
1289
+ "the boundary-preserved declaration replacement still produced invalid Python"
1290
+ );
1291
+ const syntaxRefreshDecision = patchContextRefreshDecision(
1292
+ {
1293
+ meta: {
1294
+ goalContract: { revision: 1 },
1295
+ projectVerification: { mutationRevision: 1, privateMutationRevision: 0 },
1296
+ toolLoop: { stagnationEpoch: 0, recent: [] },
1297
+ },
1298
+ },
1299
+ {
1300
+ toolName: "apply_patch",
1301
+ ok: false,
1302
+ category: "python-syntax-regression",
1303
+ args: {
1304
+ path: "preview_builder.py",
1305
+ search: declarationBoundaryAnchor,
1306
+ },
1307
+ }
1308
+ );
1309
+ assert(
1310
+ syntaxRefreshDecision?.triggerCategory === "python-syntax-regression" &&
1311
+ syntaxRefreshDecision.path === "preview_builder.py",
1312
+ "a prospective Python syntax regression did not force a fresh exact-source read"
1313
+ );
1219
1314
  const semanticScopeMismatchState = {
1220
1315
  meta: {
1221
1316
  goalContract: { revision: 4 },
@@ -5444,6 +5539,43 @@ try {
5444
5539
  );
5445
5540
  const generatedDeckValidator =
5446
5541
  `python3 ${generatedDeckValidatorPath} --root .`;
5542
+ const opaqueExternalValidatorState = {
5543
+ goal: [
5544
+ "Create the requested workbook from the local inputs.",
5545
+ `Run exactly: \`${generatedDeckValidator}\``,
5546
+ "Do not edit that external validator.",
5547
+ ].join("\n"),
5548
+ meta: {
5549
+ taskProfile: "data",
5550
+ goalContract: {
5551
+ revision: 1,
5552
+ currentRequest: "Create the requested workbook and run the exact validator.",
5553
+ },
5554
+ projectVerification: {
5555
+ mutationRevision: 0,
5556
+ mutationHistory: [],
5557
+ commandRuns: [],
5558
+ testRuns: [],
5559
+ },
5560
+ toolLoop: { recent: [] },
5561
+ },
5562
+ };
5563
+ const opaqueExternalValidatorRuntime = nextStepRuntimeConfig(
5564
+ {
5565
+ provider: "deepseek",
5566
+ taskProfile: "data",
5567
+ commandCwd: workspace,
5568
+ goal: opaqueExternalValidatorState.goal,
5569
+ },
5570
+ opaqueExternalValidatorState
5571
+ );
5572
+ assert(
5573
+ JSON.stringify(opaqueExternalValidatorRuntime.opaqueExternalValidatorPaths) ===
5574
+ JSON.stringify([generatedDeckValidatorPath]) &&
5575
+ JSON.stringify(opaqueExternalValidatorRuntime.opaqueExternalValidatorCommands) ===
5576
+ JSON.stringify([generatedDeckValidator]),
5577
+ "an exact external validator was not retained as an opaque execute-only contract before its first run"
5578
+ );
5447
5579
  await fs.writeFile(
5448
5580
  path.join(workspace, "build_deck.py"),
5449
5581
  "print('build canonical deck')\n",
@@ -10364,6 +10496,60 @@ try {
10364
10496
  assert(resumedBudget?.extensionsUsed === 0, "runAgent retained stale extension usage after an explicit resumed max-steps patch");
10365
10497
  assert(resumedBudget?.resetFromExplicitOverride === true, "runAgent did not record the explicit budget reset boundary");
10366
10498
 
10499
+ const educationWorkspace = path.join(tempRoot, "education-artifact-contract");
10500
+ await fs.mkdir(path.join(educationWorkspace, "workshop"), { recursive: true });
10501
+ await fs.writeFile(path.join(educationWorkspace, "workshop", "lesson-deck.md"), "# Lesson\n");
10502
+ const educationGoal =
10503
+ "Create an editable lesson deck, a separate practice sheet and answer key, printable materials, a helpful preview, and a reproducible build entrypoint. Verify and commit the work.";
10504
+ const educationState = {
10505
+ goal: educationGoal,
10506
+ commandCwd: educationWorkspace,
10507
+ plan: "Create every requested artifact, verify them, and commit the complete set.",
10508
+ messages: [
10509
+ {
10510
+ role: "tool",
10511
+ content: JSON.stringify({
10512
+ ok: true,
10513
+ toolName: "write_file",
10514
+ path: "workshop/lesson-deck.md",
10515
+ goalRevision: 1,
10516
+ projectMutationRevision: 1,
10517
+ }),
10518
+ },
10519
+ ],
10520
+ meta: {
10521
+ taskProfile: "education",
10522
+ goalContract: {
10523
+ revision: 1,
10524
+ currentRequest: educationGoal,
10525
+ taskGoal: educationGoal,
10526
+ activeGoalRevision: 1,
10527
+ lifecycle: [{ at: new Date(Date.now() - 2000).toISOString() }],
10528
+ },
10529
+ projectVerification: {
10530
+ mutationRevision: 1,
10531
+ mutationHistory: [
10532
+ {
10533
+ revision: 1,
10534
+ at: new Date().toISOString(),
10535
+ toolName: "write_file",
10536
+ paths: ["workshop/lesson-deck.md"],
10537
+ goalRevision: 1,
10538
+ },
10539
+ ],
10540
+ },
10541
+ },
10542
+ };
10543
+ const incompleteEducationRuntime = nextStepRuntimeConfig(
10544
+ { goal: educationGoal, taskProfile: "education", commandCwd: educationWorkspace },
10545
+ educationState
10546
+ );
10547
+ assert(
10548
+ incompleteEducationRuntime.requestedArtifactRequirementsPending === true &&
10549
+ incompleteEducationRuntime.taskOwnedCommitPending !== true,
10550
+ "a partial multi-artifact task entered task-owned Git completion before its deliverables existed"
10551
+ );
10552
+
10367
10553
  await fs.rm(tempRoot, { recursive: true, force: true });
10368
10554
  console.log("smoke-dynamic-step-budget ok");
10369
10555
  } catch (error) {
@@ -12,6 +12,7 @@ import {
12
12
  import {
13
13
  buildScsEvidenceLedger,
14
14
  deriveScsTaskContract,
15
+ evaluateRequestedArtifactRequirements,
15
16
  evaluateScsSemanticContract,
16
17
  extractMarkdownCommandEvidence,
17
18
  extractMarkdownPathEvidence,
@@ -19,6 +20,73 @@ import {
19
20
  finishResultClaimsIncompleteWork,
20
21
  } from "../src/scs-evidence.js";
21
22
 
23
+ const educationArtifactGoal =
24
+ "Create an editable lesson deck, a separate practice sheet and answer key, printable materials, a helpful preview, and a reproducible build entrypoint.";
25
+ const educationArtifactContract = deriveScsTaskContract({
26
+ goal: educationArtifactGoal,
27
+ taskProfile: "education",
28
+ });
29
+ assert.deepEqual(
30
+ educationArtifactContract.requiredArtifactKinds.map((item) => item.id).sort(),
31
+ [
32
+ "answer-material",
33
+ "editable-presentation",
34
+ "practice-material",
35
+ "printable-document",
36
+ "reproducible-build-entrypoint",
37
+ "visual-preview",
38
+ ],
39
+ "multi-artifact education request did not retain each semantic deliverable"
40
+ );
41
+ assert.deepEqual(
42
+ deriveScsTaskContract({
43
+ goal: "Create a canvas artifact preview for this smoke test.",
44
+ taskProfile: "auto",
45
+ }).requiredArtifactKinds,
46
+ [],
47
+ "a generic frontend canvas preview was incorrectly converted into a required image-file artifact"
48
+ );
49
+ const educationWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), "aginti-education-artifacts-"));
50
+ const educationState = {
51
+ meta: {
52
+ goalContract: {
53
+ lifecycle: [{ at: new Date(Date.now() - 2000).toISOString() }],
54
+ },
55
+ projectVerification: { mutationHistory: [] },
56
+ },
57
+ };
58
+ fs.mkdirSync(path.join(educationWorkspace, "workshop"), { recursive: true });
59
+ fs.writeFileSync(path.join(educationWorkspace, "workshop", "lesson-deck.md"), "# Lesson deck\n");
60
+ const incompleteEducationArtifacts = evaluateRequestedArtifactRequirements(
61
+ educationArtifactContract,
62
+ { commandCwd: educationWorkspace, state: educationState }
63
+ );
64
+ assert.equal(incompleteEducationArtifacts.ok, false);
65
+ assert.ok(
66
+ incompleteEducationArtifacts.missing.some((item) => item.id === "editable-presentation"),
67
+ "Markdown-only deck incorrectly satisfied the editable presentation contract"
68
+ );
69
+ for (const [name, content] of [
70
+ ["lesson-deck.pptx", "pptx"],
71
+ ["practice-sheet.md", "practice"],
72
+ ["answer-key.md", "answers"],
73
+ ["practice-sheet.pdf", "pdf"],
74
+ ["lesson-preview.png", "png"],
75
+ ["build_materials.py", "print('build')\n"],
76
+ ]) {
77
+ fs.writeFileSync(path.join(educationWorkspace, "workshop", name), content);
78
+ }
79
+ const completeEducationArtifacts = evaluateRequestedArtifactRequirements(
80
+ educationArtifactContract,
81
+ { commandCwd: educationWorkspace, state: educationState }
82
+ );
83
+ assert.equal(
84
+ completeEducationArtifacts.ok,
85
+ true,
86
+ `complete semantic artifact set was rejected: ${completeEducationArtifacts.reason}`
87
+ );
88
+ fs.rmSync(educationWorkspace, { recursive: true, force: true });
89
+
22
90
  function fakeStudentClient(json) {
23
91
  return {
24
92
  chat: {
@@ -68,12 +68,23 @@ async function waitForHealth() {
68
68
  async function waitForRun(sessionId, terminalStatuses = ["finished", "failed"]) {
69
69
  const acceptedStatuses = new Set(terminalStatuses);
70
70
  const deadline = Date.now() + 20000;
71
+ let lastRun = null;
71
72
  while (Date.now() < deadline) {
72
73
  const run = await fetchJson(`/api/runs/${encodeURIComponent(sessionId)}`);
74
+ lastRun = run;
73
75
  if (acceptedStatuses.has(run.status)) return run;
74
76
  await delay(400);
75
77
  }
76
- throw new Error(`run ${sessionId} did not finish in time`);
78
+ throw new Error(
79
+ `run ${sessionId} did not finish in time; ` +
80
+ `lastRun=${JSON.stringify(lastRun ? {
81
+ status: lastRun.status,
82
+ error: lastRun.error,
83
+ endedAt: lastRun.endedAt,
84
+ logs: Array.isArray(lastRun.logs) ? lastRun.logs.slice(-12) : [],
85
+ } : null)} ` +
86
+ `stdout=${stdout.slice(-1000)} stderr=${stderr.slice(-1000)}`
87
+ );
77
88
  }
78
89
 
79
90
  try {