@lazyingart/agintiflow 0.20.259 → 0.20.260
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 +1 -1
- package/scripts/smoke-dynamic-step-budget.js +76 -0
- package/src/agent-runner.js +132 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.260",
|
|
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",
|
|
@@ -2650,6 +2650,82 @@ try {
|
|
|
2650
2650
|
JSON.stringify(["python3 -m unittest discover -s tests -v"]),
|
|
2651
2651
|
"ordinary operator examples became mandatory acceptance commands"
|
|
2652
2652
|
);
|
|
2653
|
+
const refreshedAcceptanceState = {
|
|
2654
|
+
commandCwd: workspace,
|
|
2655
|
+
meta: {
|
|
2656
|
+
projectVerification: {
|
|
2657
|
+
requiredOutputs: ["stale-output.txt"],
|
|
2658
|
+
requiredCommands: [
|
|
2659
|
+
"python3 service_ctl.py start --state-dir .runtime",
|
|
2660
|
+
"python3 service_ctl.py status --state-dir .runtime",
|
|
2661
|
+
],
|
|
2662
|
+
acceptanceSource: "README.md",
|
|
2663
|
+
},
|
|
2664
|
+
},
|
|
2665
|
+
};
|
|
2666
|
+
recordProjectVerificationOutcome(
|
|
2667
|
+
refreshedAcceptanceState,
|
|
2668
|
+
{
|
|
2669
|
+
ok: true,
|
|
2670
|
+
toolName: "read_file",
|
|
2671
|
+
path: "README.md",
|
|
2672
|
+
content: operatorGuideMarkdown,
|
|
2673
|
+
},
|
|
2674
|
+
{ commandCwd: workspace, taskProfile: "devops" }
|
|
2675
|
+
);
|
|
2676
|
+
assert(
|
|
2677
|
+
JSON.stringify(refreshedAcceptanceState.meta.projectVerification.requiredCommands) ===
|
|
2678
|
+
JSON.stringify(["python3 -m unittest discover -s tests -v"]) &&
|
|
2679
|
+
refreshedAcceptanceState.meta.projectVerification.requiredOutputs.length === 0,
|
|
2680
|
+
"rereading one authoritative source retained its stale acceptance requirements"
|
|
2681
|
+
);
|
|
2682
|
+
const resumedAcceptanceWorkspace = path.join(workspace, "resumed-acceptance");
|
|
2683
|
+
await fs.mkdir(resumedAcceptanceWorkspace, { recursive: true });
|
|
2684
|
+
await fs.writeFile(
|
|
2685
|
+
path.join(resumedAcceptanceWorkspace, "README.md"),
|
|
2686
|
+
operatorGuideMarkdown,
|
|
2687
|
+
"utf8"
|
|
2688
|
+
);
|
|
2689
|
+
const resumedAcceptanceState = {
|
|
2690
|
+
commandCwd: resumedAcceptanceWorkspace,
|
|
2691
|
+
goal: "Repair the service and run its tests.",
|
|
2692
|
+
meta: {
|
|
2693
|
+
goalContract: { revision: 4, currentRequest: "Repair the service and run its tests." },
|
|
2694
|
+
projectVerification: {
|
|
2695
|
+
requiredCommands: [
|
|
2696
|
+
"python3 service_ctl.py start --state-dir .runtime",
|
|
2697
|
+
"python3 service_ctl.py status --state-dir .runtime",
|
|
2698
|
+
],
|
|
2699
|
+
acceptanceSource: "README.md",
|
|
2700
|
+
},
|
|
2701
|
+
},
|
|
2702
|
+
};
|
|
2703
|
+
resetSameTaskExecutionContract(resumedAcceptanceState, 4);
|
|
2704
|
+
assert(
|
|
2705
|
+
JSON.stringify(resumedAcceptanceState.meta.projectVerification.requiredCommands) ===
|
|
2706
|
+
JSON.stringify(["python3 -m unittest discover -s tests -v"]),
|
|
2707
|
+
"same-task resume retained stale requirements from an older README parser"
|
|
2708
|
+
);
|
|
2709
|
+
recordProjectVerificationOutcome(
|
|
2710
|
+
refreshedAcceptanceState,
|
|
2711
|
+
{
|
|
2712
|
+
ok: true,
|
|
2713
|
+
toolName: "read_file",
|
|
2714
|
+
path: "TASK.md",
|
|
2715
|
+
content: requiredCommandMarkdown,
|
|
2716
|
+
},
|
|
2717
|
+
{ commandCwd: workspace, taskProfile: "devops" }
|
|
2718
|
+
);
|
|
2719
|
+
assert(
|
|
2720
|
+
JSON.stringify(refreshedAcceptanceState.meta.projectVerification.requiredCommands) ===
|
|
2721
|
+
JSON.stringify([
|
|
2722
|
+
"python3 -m unittest discover -s tests -v",
|
|
2723
|
+
"npm run check",
|
|
2724
|
+
"npm test",
|
|
2725
|
+
"python scripts/verify.py --strict",
|
|
2726
|
+
]),
|
|
2727
|
+
"source-scoped acceptance refresh discarded a distinct authoritative source"
|
|
2728
|
+
);
|
|
2653
2729
|
const operatorContinuedCommandMarkdown = [
|
|
2654
2730
|
"# Task",
|
|
2655
2731
|
"",
|
package/src/agent-runner.js
CHANGED
|
@@ -3769,6 +3769,67 @@ export function resetGoalScopedRuntimeState(state = {}) {
|
|
|
3769
3769
|
return removed;
|
|
3770
3770
|
}
|
|
3771
3771
|
|
|
3772
|
+
function refreshPersistedProjectAcceptance(state = {}) {
|
|
3773
|
+
const verification = state.meta?.projectVerification;
|
|
3774
|
+
if (!verification || typeof verification !== "object") return false;
|
|
3775
|
+
const priorBySource =
|
|
3776
|
+
verification.acceptanceBySource &&
|
|
3777
|
+
typeof verification.acceptanceBySource === "object" &&
|
|
3778
|
+
!Array.isArray(verification.acceptanceBySource)
|
|
3779
|
+
? verification.acceptanceBySource
|
|
3780
|
+
: {};
|
|
3781
|
+
const sources = [
|
|
3782
|
+
...Object.keys(priorBySource),
|
|
3783
|
+
String(verification.acceptanceSource || "").trim(),
|
|
3784
|
+
].filter(Boolean);
|
|
3785
|
+
if (!sources.length) return false;
|
|
3786
|
+
|
|
3787
|
+
const commandCwd = path.resolve(state.commandCwd || process.cwd());
|
|
3788
|
+
const refreshed = {};
|
|
3789
|
+
let inspected = 0;
|
|
3790
|
+
for (const source of [...new Set(sources)].slice(-16)) {
|
|
3791
|
+
const sourceKey = normalizedProjectAcceptancePath(source, commandCwd);
|
|
3792
|
+
if (!sourceKey || !projectAcceptanceSourceIsAuthoritative(sourceKey, {
|
|
3793
|
+
commandCwd,
|
|
3794
|
+
authoritativePaths: [sourceKey],
|
|
3795
|
+
})) {
|
|
3796
|
+
continue;
|
|
3797
|
+
}
|
|
3798
|
+
const absolutePath = path.resolve(commandCwd, sourceKey);
|
|
3799
|
+
if (absolutePath !== commandCwd && !absolutePath.startsWith(`${commandCwd}${path.sep}`)) continue;
|
|
3800
|
+
inspected += 1;
|
|
3801
|
+
if (!fsSync.existsSync(absolutePath)) continue;
|
|
3802
|
+
try {
|
|
3803
|
+
const acceptance = projectAcceptanceFromMarkdown(
|
|
3804
|
+
fsSync.readFileSync(absolutePath, "utf8"),
|
|
3805
|
+
sourceKey,
|
|
3806
|
+
{ commandCwd, authoritativePaths: [sourceKey] }
|
|
3807
|
+
);
|
|
3808
|
+
refreshed[sourceKey] = {
|
|
3809
|
+
requiredOutputs: acceptance.requiredOutputs,
|
|
3810
|
+
requiredCommands: acceptance.requiredCommands,
|
|
3811
|
+
readAt: new Date().toISOString(),
|
|
3812
|
+
};
|
|
3813
|
+
} catch {
|
|
3814
|
+
inspected -= 1;
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
if (!inspected) return false;
|
|
3818
|
+
verification.acceptanceBySource = refreshed;
|
|
3819
|
+
verification.requiredOutputs = [
|
|
3820
|
+
...new Set(
|
|
3821
|
+
Object.values(refreshed).flatMap((item) => item.requiredOutputs || [])
|
|
3822
|
+
),
|
|
3823
|
+
].slice(0, 64);
|
|
3824
|
+
verification.requiredCommands = [
|
|
3825
|
+
...new Set(
|
|
3826
|
+
Object.values(refreshed).flatMap((item) => item.requiredCommands || [])
|
|
3827
|
+
),
|
|
3828
|
+
].slice(0, 24);
|
|
3829
|
+
verification.acceptanceRefreshedAt = new Date().toISOString();
|
|
3830
|
+
return true;
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3772
3833
|
export function resetSameTaskExecutionContract(state = {}, revision = 0) {
|
|
3773
3834
|
state.meta = state.meta || {};
|
|
3774
3835
|
const keys = [
|
|
@@ -3786,6 +3847,7 @@ export function resetSameTaskExecutionContract(state = {}, revision = 0) {
|
|
|
3786
3847
|
removed.push(key);
|
|
3787
3848
|
}
|
|
3788
3849
|
state.plan = "";
|
|
3850
|
+
refreshPersistedProjectAcceptance(state);
|
|
3789
3851
|
const activeRevision = Math.max(0, Number(revision || state.meta?.goalContract?.revision || 0));
|
|
3790
3852
|
const currentRequest = String(state.meta?.goalContract?.currentRequest || state.goal || "").trim();
|
|
3791
3853
|
const currentTurnContract = deriveScsTaskContract({
|
|
@@ -5381,11 +5443,9 @@ function normalizedProjectAcceptancePath(sourcePath = "", commandCwd = "") {
|
|
|
5381
5443
|
return raw.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
5382
5444
|
}
|
|
5383
5445
|
|
|
5384
|
-
|
|
5446
|
+
function projectAcceptanceSourceIsAuthoritative(sourcePath = "", options = {}) {
|
|
5385
5447
|
const basename = path.basename(String(sourcePath || "")).toLowerCase();
|
|
5386
|
-
if (!/^(?:readme|task|agents?|aginti)(?:\.[^.]+)?$/.test(basename))
|
|
5387
|
-
return { requiredOutputs: [], requiredCommands: [] };
|
|
5388
|
-
}
|
|
5448
|
+
if (!/^(?:readme|task|agents?|aginti)(?:\.[^.]+)?$/.test(basename)) return false;
|
|
5389
5449
|
const normalizedSource = normalizedProjectAcceptancePath(
|
|
5390
5450
|
sourcePath,
|
|
5391
5451
|
options.commandCwd
|
|
@@ -5395,10 +5455,11 @@ export function projectAcceptanceFromMarkdown(content = "", sourcePath = "", opt
|
|
|
5395
5455
|
.map((item) => normalizedProjectAcceptancePath(item, options.commandCwd))
|
|
5396
5456
|
.filter(Boolean)
|
|
5397
5457
|
);
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5458
|
+
return !normalizedSource.includes("/") || authoritativePaths.has(normalizedSource);
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
export function projectAcceptanceFromMarkdown(content = "", sourcePath = "", options = {}) {
|
|
5462
|
+
if (!projectAcceptanceSourceIsAuthoritative(sourcePath, options)) {
|
|
5402
5463
|
return { requiredOutputs: [], requiredCommands: [] };
|
|
5403
5464
|
}
|
|
5404
5465
|
return {
|
|
@@ -5778,29 +5839,72 @@ export function recordProjectVerificationOutcome(state = {}, toolResult = {}, co
|
|
|
5778
5839
|
goal: completionContractGoal(config, state),
|
|
5779
5840
|
taskProfile: config.taskProfile || state.meta?.taskProfile || "auto",
|
|
5780
5841
|
});
|
|
5842
|
+
const sourcePath = String(toolResult.path || toolResult.args?.path || "");
|
|
5843
|
+
const acceptanceOptions = {
|
|
5844
|
+
commandCwd: config.commandCwd || state.commandCwd || process.cwd(),
|
|
5845
|
+
authoritativePaths: [
|
|
5846
|
+
...(Array.isArray(currentTaskContract.exactInputPaths)
|
|
5847
|
+
? currentTaskContract.exactInputPaths
|
|
5848
|
+
: []),
|
|
5849
|
+
...(Array.isArray(currentTaskContract.exactOutputPaths)
|
|
5850
|
+
? currentTaskContract.exactOutputPaths
|
|
5851
|
+
: []),
|
|
5852
|
+
],
|
|
5853
|
+
};
|
|
5781
5854
|
const acceptance = projectAcceptanceFromMarkdown(
|
|
5782
5855
|
toolResult.content,
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
commandCwd: config.commandCwd || state.commandCwd || process.cwd(),
|
|
5786
|
-
authoritativePaths: [
|
|
5787
|
-
...(Array.isArray(currentTaskContract.exactInputPaths)
|
|
5788
|
-
? currentTaskContract.exactInputPaths
|
|
5789
|
-
: []),
|
|
5790
|
-
...(Array.isArray(currentTaskContract.exactOutputPaths)
|
|
5791
|
-
? currentTaskContract.exactOutputPaths
|
|
5792
|
-
: []),
|
|
5793
|
-
],
|
|
5794
|
-
}
|
|
5856
|
+
sourcePath,
|
|
5857
|
+
acceptanceOptions
|
|
5795
5858
|
);
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5859
|
+
if (projectAcceptanceSourceIsAuthoritative(sourcePath, acceptanceOptions)) {
|
|
5860
|
+
const sourceKey = normalizedProjectAcceptancePath(
|
|
5861
|
+
sourcePath,
|
|
5862
|
+
acceptanceOptions.commandCwd
|
|
5863
|
+
);
|
|
5864
|
+
const acceptanceBySource =
|
|
5865
|
+
verification.acceptanceBySource &&
|
|
5866
|
+
typeof verification.acceptanceBySource === "object" &&
|
|
5867
|
+
!Array.isArray(verification.acceptanceBySource)
|
|
5868
|
+
? { ...verification.acceptanceBySource }
|
|
5869
|
+
: {};
|
|
5870
|
+
const legacySourceKey = normalizedProjectAcceptancePath(
|
|
5871
|
+
verification.acceptanceSource || "",
|
|
5872
|
+
acceptanceOptions.commandCwd
|
|
5873
|
+
);
|
|
5874
|
+
if (
|
|
5875
|
+
!Object.keys(acceptanceBySource).length &&
|
|
5876
|
+
legacySourceKey &&
|
|
5877
|
+
legacySourceKey !== sourceKey
|
|
5878
|
+
) {
|
|
5879
|
+
acceptanceBySource[legacySourceKey] = {
|
|
5880
|
+
requiredOutputs: [...verification.requiredOutputs],
|
|
5881
|
+
requiredCommands: [...verification.requiredCommands],
|
|
5882
|
+
readAt: verification.acceptanceReadAt || "",
|
|
5883
|
+
};
|
|
5884
|
+
}
|
|
5885
|
+
acceptanceBySource[sourceKey] = {
|
|
5886
|
+
requiredOutputs: acceptance.requiredOutputs,
|
|
5887
|
+
requiredCommands: acceptance.requiredCommands,
|
|
5888
|
+
readAt: now,
|
|
5889
|
+
};
|
|
5890
|
+
verification.acceptanceBySource = Object.fromEntries(
|
|
5891
|
+
Object.entries(acceptanceBySource).slice(-16)
|
|
5892
|
+
);
|
|
5893
|
+
verification.requiredOutputs = [
|
|
5894
|
+
...new Set(
|
|
5895
|
+
Object.values(verification.acceptanceBySource).flatMap((item) =>
|
|
5896
|
+
Array.isArray(item?.requiredOutputs) ? item.requiredOutputs : []
|
|
5897
|
+
)
|
|
5898
|
+
),
|
|
5899
|
+
].slice(0, 64);
|
|
5900
|
+
verification.requiredCommands = [
|
|
5901
|
+
...new Set(
|
|
5902
|
+
Object.values(verification.acceptanceBySource).flatMap((item) =>
|
|
5903
|
+
Array.isArray(item?.requiredCommands) ? item.requiredCommands : []
|
|
5904
|
+
)
|
|
5905
|
+
),
|
|
5906
|
+
].slice(0, 24);
|
|
5907
|
+
verification.acceptanceSource = sourcePath;
|
|
5804
5908
|
verification.acceptanceReadAt = now;
|
|
5805
5909
|
}
|
|
5806
5910
|
}
|