@lazyingart/agintiflow 0.20.272 → 0.20.274
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.
|
|
3
|
+
"version": "0.20.274",
|
|
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",
|
|
@@ -5306,8 +5306,19 @@ try {
|
|
|
5306
5306
|
postMutationVerificationRuntime.testVerificationCommand === postMutationVerifier,
|
|
5307
5307
|
"a material failed-test repair did not advance directly to its exact retained verifier"
|
|
5308
5308
|
);
|
|
5309
|
+
const generatedDeckValidatorPath = path.join(
|
|
5310
|
+
tempRoot,
|
|
5311
|
+
"acceptance",
|
|
5312
|
+
"presentation_deck_contract.py"
|
|
5313
|
+
);
|
|
5314
|
+
await fs.mkdir(path.dirname(generatedDeckValidatorPath), { recursive: true });
|
|
5315
|
+
await fs.writeFile(
|
|
5316
|
+
generatedDeckValidatorPath,
|
|
5317
|
+
"raise SystemExit('acceptance fixture')\n",
|
|
5318
|
+
"utf8"
|
|
5319
|
+
);
|
|
5309
5320
|
const generatedDeckValidator =
|
|
5310
|
-
|
|
5321
|
+
`python3 ${generatedDeckValidatorPath} --root .`;
|
|
5311
5322
|
await fs.writeFile(
|
|
5312
5323
|
path.join(workspace, "build_deck.py"),
|
|
5313
5324
|
"print('build canonical deck')\n",
|
|
@@ -5544,6 +5555,41 @@ try {
|
|
|
5544
5555
|
JSON.stringify(["build_deck.py"]),
|
|
5545
5556
|
"failed-test recovery forced immutable evidence reads instead of grounding the canonical producer"
|
|
5546
5557
|
);
|
|
5558
|
+
assert(
|
|
5559
|
+
JSON.stringify(failedAfterProducerRuntime.testFailureDiagnosticReadPaths) ===
|
|
5560
|
+
JSON.stringify([generatedDeckValidatorPath]) &&
|
|
5561
|
+
failedAfterProducerRuntime.readOnlyRoots.includes(
|
|
5562
|
+
path.dirname(generatedDeckValidatorPath)
|
|
5563
|
+
),
|
|
5564
|
+
"an exact external validator from the retained failed command was not exposed through a narrow read-only root"
|
|
5565
|
+
);
|
|
5566
|
+
const consumedExternalValidatorState = structuredClone(failedAfterProducerState);
|
|
5567
|
+
consumedExternalValidatorState.meta.toolLoop =
|
|
5568
|
+
consumedExternalValidatorState.meta.toolLoop || { recent: [] };
|
|
5569
|
+
consumedExternalValidatorState.meta.toolLoop.recent = [
|
|
5570
|
+
...(consumedExternalValidatorState.meta.toolLoop.recent || []),
|
|
5571
|
+
{
|
|
5572
|
+
toolName: "read_file",
|
|
5573
|
+
path: generatedDeckValidatorPath,
|
|
5574
|
+
ok: true,
|
|
5575
|
+
blocked: false,
|
|
5576
|
+
goalRevision: 13,
|
|
5577
|
+
at: "2026-08-27T19:05:02.000Z",
|
|
5578
|
+
},
|
|
5579
|
+
];
|
|
5580
|
+
const consumedExternalValidatorRuntime = nextStepRuntimeConfig(
|
|
5581
|
+
{
|
|
5582
|
+
provider: "deepseek",
|
|
5583
|
+
taskProfile: "slides",
|
|
5584
|
+
commandCwd: workspace,
|
|
5585
|
+
goal: consumedExternalValidatorState.goal,
|
|
5586
|
+
},
|
|
5587
|
+
consumedExternalValidatorState
|
|
5588
|
+
);
|
|
5589
|
+
assert(
|
|
5590
|
+
consumedExternalValidatorRuntime.testFailureDiagnosticReadPaths.length === 0,
|
|
5591
|
+
"an exact external validator remained exposed after its bounded read completed"
|
|
5592
|
+
);
|
|
5547
5593
|
const immutableOnlyRepairState = {
|
|
5548
5594
|
goal: "Treat service_ctl.py as immutable read-only source evidence and finish from existing results.",
|
|
5549
5595
|
meta: {
|
|
@@ -9743,6 +9789,20 @@ try {
|
|
|
9743
9789
|
!shouldReviewToolResult(malformedReadOnlyCheck, { meta: {} }),
|
|
9744
9790
|
"SCS should let the normal agent loop repair simple shell quoting mistakes"
|
|
9745
9791
|
);
|
|
9792
|
+
const prospectivePatchSyntaxCorrection = {
|
|
9793
|
+
toolName: "apply_patch",
|
|
9794
|
+
ok: false,
|
|
9795
|
+
blocked: false,
|
|
9796
|
+
recoverable: true,
|
|
9797
|
+
stopRun: false,
|
|
9798
|
+
category: "python-syntax-regression",
|
|
9799
|
+
error: "Exact Python patch failed prospective syntax validation.",
|
|
9800
|
+
diagnosticHint: "SyntaxError: unterminated string literal",
|
|
9801
|
+
};
|
|
9802
|
+
assert(
|
|
9803
|
+
!shouldReviewToolResult(prospectivePatchSyntaxCorrection, { meta: {} }),
|
|
9804
|
+
"SCS replanned instead of letting the agent correct a deterministic prospective patch rejection"
|
|
9805
|
+
);
|
|
9746
9806
|
const boundedSearchRecovery = {
|
|
9747
9807
|
toolName: "run_command",
|
|
9748
9808
|
ok: false,
|
|
@@ -1804,6 +1804,50 @@ sameNames(
|
|
|
1804
1804
|
"an unchanged failed-test rerun did not close discovery until a real mutation"
|
|
1805
1805
|
);
|
|
1806
1806
|
|
|
1807
|
+
const externalValidatorPath = "/tmp/aginti-acceptance/deck_contract.py";
|
|
1808
|
+
const externalDiagnosticFailedTestRepairTools = selectProgressiveTools(allTools, {
|
|
1809
|
+
config: {
|
|
1810
|
+
provider: "deepseek",
|
|
1811
|
+
testFailureRepairActive: true,
|
|
1812
|
+
testFailureRepairMutationRequired: true,
|
|
1813
|
+
testFailureDiagnosticReadPaths: [externalValidatorPath],
|
|
1814
|
+
},
|
|
1815
|
+
goal: "Repair the canonical producer from the exact external acceptance contract.",
|
|
1816
|
+
profile: "slides",
|
|
1817
|
+
});
|
|
1818
|
+
sameNames(
|
|
1819
|
+
externalDiagnosticFailedTestRepairTools,
|
|
1820
|
+
["read_file", "apply_patch", "finish"],
|
|
1821
|
+
"a retained external validator was not exposed as one bounded read during mutation-only recovery"
|
|
1822
|
+
);
|
|
1823
|
+
assertStrict.deepEqual(
|
|
1824
|
+
externalDiagnosticFailedTestRepairTools[0].function.parameters.properties.path.enum,
|
|
1825
|
+
[externalValidatorPath],
|
|
1826
|
+
"the external validator read was not schema-constrained to its exact path"
|
|
1827
|
+
);
|
|
1828
|
+
|
|
1829
|
+
const canonicalRepairPathAliasTools = selectProgressiveTools(allTools, {
|
|
1830
|
+
config: {
|
|
1831
|
+
provider: "deepseek",
|
|
1832
|
+
commandCwd: "/tmp/aginti-canonical-repair",
|
|
1833
|
+
testFailureRepairActive: true,
|
|
1834
|
+
testFailureRepairMutationRequired: true,
|
|
1835
|
+
testFailureRepairOptionalRereadPaths: ["build_deck.py"],
|
|
1836
|
+
},
|
|
1837
|
+
goal: "Correct the canonical producer after a prospective patch rejection.",
|
|
1838
|
+
profile: "slides",
|
|
1839
|
+
});
|
|
1840
|
+
sameNames(
|
|
1841
|
+
canonicalRepairPathAliasTools,
|
|
1842
|
+
["read_file", "apply_patch", "finish"],
|
|
1843
|
+
"a canonical repair reread did not preserve its bounded tool surface"
|
|
1844
|
+
);
|
|
1845
|
+
assertStrict.deepEqual(
|
|
1846
|
+
canonicalRepairPathAliasTools[0].function.parameters.properties.path.enum,
|
|
1847
|
+
["build_deck.py", "/tmp/aginti-canonical-repair/build_deck.py"],
|
|
1848
|
+
"the exact in-workspace absolute alias was not accepted for the canonical repair path"
|
|
1849
|
+
);
|
|
1850
|
+
|
|
1807
1851
|
const failedTestPatchContextTools = selectProgressiveTools(allTools, {
|
|
1808
1852
|
config: {
|
|
1809
1853
|
provider: "localllm",
|
package/src/agent-runner.js
CHANGED
|
@@ -6683,6 +6683,51 @@ function failedTestCanonicalRepairPaths(state = {}) {
|
|
|
6683
6683
|
.filter((item, index, items) => items.indexOf(item) === index);
|
|
6684
6684
|
}
|
|
6685
6685
|
|
|
6686
|
+
export function failedTestExternalDiagnosticReadPaths(
|
|
6687
|
+
config = {},
|
|
6688
|
+
state = {},
|
|
6689
|
+
testRun = null
|
|
6690
|
+
) {
|
|
6691
|
+
const failure = testRun || currentFailedProjectTest(state)?.test;
|
|
6692
|
+
const command = String(failure?.command || "").trim();
|
|
6693
|
+
if (!command) return [];
|
|
6694
|
+
const commandCwd = path.resolve(
|
|
6695
|
+
config.commandCwd || state.commandCwd || process.cwd()
|
|
6696
|
+
);
|
|
6697
|
+
const candidates = [];
|
|
6698
|
+
for (const token of tokenizeShellWords(command)) {
|
|
6699
|
+
const rawPath = String(token || "").replace(/[;,]+$/g, "").trim();
|
|
6700
|
+
if (!rawPath || !path.isAbsolute(rawPath)) continue;
|
|
6701
|
+
let realPath = "";
|
|
6702
|
+
try {
|
|
6703
|
+
realPath = fsSync.realpathSync(rawPath);
|
|
6704
|
+
const stat = fsSync.statSync(realPath);
|
|
6705
|
+
if (!stat.isFile() || stat.size > 1_000_000) continue;
|
|
6706
|
+
} catch {
|
|
6707
|
+
continue;
|
|
6708
|
+
}
|
|
6709
|
+
const relative = path.relative(commandCwd, realPath);
|
|
6710
|
+
if (!relative.startsWith("..") && !path.isAbsolute(relative)) continue;
|
|
6711
|
+
const normalized = realPath.replace(/\\/g, "/");
|
|
6712
|
+
if (
|
|
6713
|
+
!PLAIN_TEXT_FILE_EXTENSIONS.has(path.extname(normalized).toLowerCase()) ||
|
|
6714
|
+
/(?:secret|credential|password|private[-_]?key|access[-_]?token)/i.test(normalized) ||
|
|
6715
|
+
!(
|
|
6716
|
+
pathLooksLikeTestSource(normalized) ||
|
|
6717
|
+
/(?:^|\/)(?:acceptance|verification)(?:\/|$)|(?:contract|validator)/i.test(
|
|
6718
|
+
normalized
|
|
6719
|
+
)
|
|
6720
|
+
) ||
|
|
6721
|
+
candidates.includes(realPath)
|
|
6722
|
+
) {
|
|
6723
|
+
continue;
|
|
6724
|
+
}
|
|
6725
|
+
candidates.push(realPath);
|
|
6726
|
+
if (candidates.length >= 3) break;
|
|
6727
|
+
}
|
|
6728
|
+
return candidates;
|
|
6729
|
+
}
|
|
6730
|
+
|
|
6686
6731
|
function recoveryEvidenceDependencies(sourcePath = "", content = "") {
|
|
6687
6732
|
const dependencies = [];
|
|
6688
6733
|
const append = (candidate) => {
|
|
@@ -11452,6 +11497,39 @@ export function nextStepRuntimeConfig(config = {}, state = {}) {
|
|
|
11452
11497
|
.slice(0, 8);
|
|
11453
11498
|
const toolLoop = state.meta?.toolLoop || {};
|
|
11454
11499
|
const stagnationEpoch = Math.max(0, Number(toolLoop.stagnationEpoch || 0));
|
|
11500
|
+
const externalDiagnosticPaths = failedTestExternalDiagnosticReadPaths(
|
|
11501
|
+
runtimeConfig,
|
|
11502
|
+
state,
|
|
11503
|
+
retainedFailedTest
|
|
11504
|
+
);
|
|
11505
|
+
const consumedExternalDiagnosticPaths = new Set(
|
|
11506
|
+
(Array.isArray(toolLoop.recent) ? toolLoop.recent : [])
|
|
11507
|
+
.filter(
|
|
11508
|
+
(entry) =>
|
|
11509
|
+
entry?.ok === true &&
|
|
11510
|
+
entry?.blocked !== true &&
|
|
11511
|
+
String(entry?.toolName || "") === "read_file" &&
|
|
11512
|
+
Number(entry?.goalRevision || 0) === groundingGoalRevision
|
|
11513
|
+
)
|
|
11514
|
+
.map((entry) => {
|
|
11515
|
+
const rawPath = String(entry?.path || "").trim();
|
|
11516
|
+
return rawPath ? path.resolve(commandCwd, rawPath) : "";
|
|
11517
|
+
})
|
|
11518
|
+
.filter(Boolean)
|
|
11519
|
+
);
|
|
11520
|
+
runtimeConfig.testFailureDiagnosticReadPaths = externalDiagnosticPaths.filter(
|
|
11521
|
+
(candidate) => !consumedExternalDiagnosticPaths.has(candidate)
|
|
11522
|
+
);
|
|
11523
|
+
if (runtimeConfig.testFailureDiagnosticReadPaths.length) {
|
|
11524
|
+
runtimeConfig.readOnlyRoots = [
|
|
11525
|
+
...(Array.isArray(runtimeConfig.readOnlyRoots)
|
|
11526
|
+
? runtimeConfig.readOnlyRoots
|
|
11527
|
+
: []),
|
|
11528
|
+
...runtimeConfig.testFailureDiagnosticReadPaths.map((candidate) =>
|
|
11529
|
+
path.dirname(candidate)
|
|
11530
|
+
),
|
|
11531
|
+
].filter((item, index, items) => items.indexOf(item) === index);
|
|
11532
|
+
}
|
|
11455
11533
|
const currentRecoveryPacket = Boolean(
|
|
11456
11534
|
state.meta?.failedTestRecoveryPacket &&
|
|
11457
11535
|
Number(state.meta.failedTestRecoveryPacket.packetVersion || 0) ===
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import {
|
|
2
3
|
hasLocalResearchWorkspaceIntent,
|
|
3
4
|
shouldStartWithDeepResearch,
|
|
@@ -733,6 +734,8 @@ function constrainReadFilePaths(tool, paths, phase) {
|
|
|
733
734
|
? "Exact canonical project file selected from current task evidence for the required fresh correction."
|
|
734
735
|
: phase === "failed-test-evidence-refresh"
|
|
735
736
|
? "Exact unread workspace-relative path retained by the current failed-test evidence packet."
|
|
737
|
+
: phase === "failed-test-diagnostic-read"
|
|
738
|
+
? "Exact read-only acceptance or validator source named by the retained failed verification command."
|
|
736
739
|
: "Exact workspace-relative path discovered by inspect_project.",
|
|
737
740
|
};
|
|
738
741
|
return {
|
|
@@ -746,6 +749,8 @@ function constrainReadFilePaths(tool, paths, phase) {
|
|
|
746
749
|
? "Read one exact canonical project file before the required fresh source correction. Tests, Git actions, and finish remain unavailable until a material patch advances the project mutation revision."
|
|
747
750
|
: phase === "failed-test-evidence-refresh"
|
|
748
751
|
? "Read one exact unread source or acceptance-test file from the current failed-test evidence packet. Each packet path is exposed at most once before mutation-only recovery resumes."
|
|
752
|
+
: phase === "failed-test-diagnostic-read"
|
|
753
|
+
? "Read one exact existing external acceptance or validator file from the retained failed command. This path is read-only and no neighboring external files are exposed."
|
|
749
754
|
: phase === "read-instructions"
|
|
750
755
|
? "Read one exact project instruction file discovered by inspect_project before repository mutation or validation commands are enabled."
|
|
751
756
|
: phase === "read-tests"
|
|
@@ -768,6 +773,25 @@ function constrainReadFilePaths(tool, paths, phase) {
|
|
|
768
773
|
};
|
|
769
774
|
}
|
|
770
775
|
|
|
776
|
+
function exactWorkspacePathAliases(paths = [], commandCwd = "") {
|
|
777
|
+
const workspaceRoot = String(commandCwd || "").trim()
|
|
778
|
+
? path.resolve(String(commandCwd))
|
|
779
|
+
: "";
|
|
780
|
+
const aliases = [];
|
|
781
|
+
for (const item of paths) {
|
|
782
|
+
const normalized = String(item || "").replace(/\\/g, "/").trim();
|
|
783
|
+
if (!normalized) continue;
|
|
784
|
+
aliases.push(normalized);
|
|
785
|
+
if (!workspaceRoot || path.isAbsolute(normalized)) continue;
|
|
786
|
+
const absolute = path.resolve(workspaceRoot, normalized);
|
|
787
|
+
const relative = path.relative(workspaceRoot, absolute);
|
|
788
|
+
if (relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative))) {
|
|
789
|
+
aliases.push(absolute.replace(/\\/g, "/"));
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return aliases.filter((item, index, items) => items.indexOf(item) === index);
|
|
793
|
+
}
|
|
794
|
+
|
|
771
795
|
function escapeRegex(value = "") {
|
|
772
796
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
773
797
|
}
|
|
@@ -2017,24 +2041,38 @@ export function selectProgressiveTools(
|
|
|
2017
2041
|
.filter((item, index, items) => items.indexOf(item) === index)
|
|
2018
2042
|
.slice(0, 1)
|
|
2019
2043
|
: [];
|
|
2020
|
-
const
|
|
2021
|
-
?
|
|
2022
|
-
|
|
2044
|
+
const diagnosticReadPaths = Array.isArray(config.testFailureDiagnosticReadPaths)
|
|
2045
|
+
? config.testFailureDiagnosticReadPaths
|
|
2046
|
+
.map((item) => String(item || "").replace(/\\/g, "/").trim())
|
|
2047
|
+
.filter(Boolean)
|
|
2048
|
+
.filter((item, index, items) => items.indexOf(item) === index)
|
|
2049
|
+
.slice(0, 3)
|
|
2050
|
+
: [];
|
|
2051
|
+
const boundedRepairReadPaths = exactWorkspacePathAliases(
|
|
2052
|
+
[
|
|
2053
|
+
...diagnosticReadPaths,
|
|
2054
|
+
...(repairContextPaths.length ? repairContextPaths : optionalRepairRereadPaths),
|
|
2055
|
+
],
|
|
2056
|
+
config.commandCwd
|
|
2057
|
+
)
|
|
2058
|
+
.slice(0, 8);
|
|
2023
2059
|
const constrainedRepairRead = boundedRepairReadPaths.length
|
|
2024
2060
|
? constrainReadFilePaths(
|
|
2025
2061
|
available.get("read_file"),
|
|
2026
2062
|
boundedRepairReadPaths,
|
|
2027
|
-
|
|
2028
|
-
? "failed-test-
|
|
2029
|
-
:
|
|
2063
|
+
diagnosticReadPaths.length
|
|
2064
|
+
? "failed-test-diagnostic-read"
|
|
2065
|
+
: repairContextPaths.length
|
|
2066
|
+
? "failed-test-evidence-refresh"
|
|
2067
|
+
: "deepseek-failed-test-source-reread"
|
|
2030
2068
|
)
|
|
2031
2069
|
: available.get("read_file");
|
|
2032
2070
|
const toolNames = config.testFailureRepairMutationRequired === true
|
|
2033
2071
|
? [
|
|
2034
|
-
...(
|
|
2035
|
-
? ["read_file"
|
|
2036
|
-
:
|
|
2037
|
-
? ["read_file"]
|
|
2072
|
+
...(boundedRepairReadPaths.length
|
|
2073
|
+
? ["read_file"]
|
|
2074
|
+
: config.testFailureRepairNeedsPatchContext === true
|
|
2075
|
+
? ["read_file", "search_files"]
|
|
2038
2076
|
: []),
|
|
2039
2077
|
"apply_patch",
|
|
2040
2078
|
...(constrainedInstructionCreate ? ["write_file"] : []),
|
package/src/scs-controller.js
CHANGED
|
@@ -1156,10 +1156,28 @@ export function shouldRequestScsReplan(decision = {}) {
|
|
|
1156
1156
|
return ["rethink_plan", "reject_phase", "finish_rejected"].includes(String(decision?.decision || ""));
|
|
1157
1157
|
}
|
|
1158
1158
|
|
|
1159
|
+
export function isRecoverablePatchCorrectionResult(toolResult = {}) {
|
|
1160
|
+
if (
|
|
1161
|
+
String(toolResult?.toolName || "") !== "apply_patch" ||
|
|
1162
|
+
toolResult?.ok !== false ||
|
|
1163
|
+
toolResult?.recoverable !== true ||
|
|
1164
|
+
toolResult?.blocked === true ||
|
|
1165
|
+
toolResult?.stopRun === true
|
|
1166
|
+
) {
|
|
1167
|
+
return false;
|
|
1168
|
+
}
|
|
1169
|
+
return new Set([
|
|
1170
|
+
"ambiguous-declaration-token-patch",
|
|
1171
|
+
"ambiguous-python-main-guard-patch",
|
|
1172
|
+
"python-syntax-regression",
|
|
1173
|
+
]).has(String(toolResult?.category || ""));
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1159
1176
|
export function shouldReviewToolResult(toolResult, state = {}) {
|
|
1160
1177
|
if (!toolResult || toolResult.done) return false;
|
|
1161
1178
|
if (toolResult.permissionAdvice?.autoRecover) return false;
|
|
1162
1179
|
if (isRecoverableShellToolResult(toolResult)) return false;
|
|
1180
|
+
if (isRecoverablePatchCorrectionResult(toolResult)) return false;
|
|
1163
1181
|
if (toolResult.ok === false || toolResult.blocked || toolResult.error || toolResult.reason) return true;
|
|
1164
1182
|
if (isSuspiciousBroadBrowserToolResult(toolResult)) return true;
|
|
1165
1183
|
// A later successful call is progress, even when another call using the same
|