@lazyingart/agintiflow 0.20.253 → 0.20.255
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 +330 -3
- package/scripts/smoke-local-failure-recovery.js +565 -3
- package/scripts/smoke-model-roles.js +72 -0
- package/scripts/smoke-progressive-tool-selection.js +587 -8
- package/src/agent-runner.js +1982 -45
- package/src/local-failure-recovery.js +65 -15
- package/src/model-client.js +126 -1
- package/src/progressive-tool-selection.js +196 -13
- package/src/tool-contract.js +77 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.255",
|
|
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",
|
|
@@ -34,12 +34,14 @@ import {
|
|
|
34
34
|
failedTestIndexComparisons,
|
|
35
35
|
failedTestLiteralOperands,
|
|
36
36
|
failedTestMembershipPredicates,
|
|
37
|
+
failedTestMockBehaviorContract,
|
|
37
38
|
isCompletedContinuationNoop,
|
|
38
39
|
isSubstantiveTestCommand,
|
|
39
40
|
mergeDurableGitEvidence,
|
|
40
41
|
nextStepRuntimeConfig,
|
|
41
42
|
projectAcceptanceFromMarkdown,
|
|
42
43
|
projectTestVerificationFinishBlock,
|
|
44
|
+
pythonTopLevelDefinitionDuplicates,
|
|
43
45
|
recordCanonicalGeneratedOutputProgress,
|
|
44
46
|
recordProjectVerificationOutcome,
|
|
45
47
|
recordExactOutputProgress,
|
|
@@ -57,6 +59,7 @@ import {
|
|
|
57
59
|
reopenedArtifactRepairPending,
|
|
58
60
|
shouldResetStaticDiscoveryPhase,
|
|
59
61
|
trimCommandOutput,
|
|
62
|
+
validateMutatedPythonSourceQuality,
|
|
60
63
|
} from "../src/agent-runner.js";
|
|
61
64
|
import {
|
|
62
65
|
augmentScsTaskContractWithProjectVerification,
|
|
@@ -101,6 +104,40 @@ function toolMessage(payload) {
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
try {
|
|
107
|
+
assert(
|
|
108
|
+
pythonTopLevelDefinitionDuplicates(
|
|
109
|
+
"def start():\n return 1\n\ndef start():\n return 2\n"
|
|
110
|
+
)[0]?.name === "start",
|
|
111
|
+
"duplicate top-level Python functions were not detected"
|
|
112
|
+
);
|
|
113
|
+
assert(
|
|
114
|
+
pythonTopLevelDefinitionDuplicates(
|
|
115
|
+
"from typing import overload\n\n@overload\ndef parse(value: str) -> str: ...\n\n@overload\ndef parse(value: int) -> int: ...\n\ndef parse(value):\n return value\n"
|
|
116
|
+
).length === 0,
|
|
117
|
+
"legitimate Python overload declarations were treated as duplicate implementations"
|
|
118
|
+
);
|
|
119
|
+
const pythonQualityWorkspace = path.join(tempRoot, "python-quality-workspace");
|
|
120
|
+
await fs.mkdir(pythonQualityWorkspace, { recursive: true });
|
|
121
|
+
await fs.writeFile(
|
|
122
|
+
path.join(pythonQualityWorkspace, "service_ctl.py"),
|
|
123
|
+
"def stop_service():\n return 0\n\ndef stop_service():\n return 1\n",
|
|
124
|
+
"utf8"
|
|
125
|
+
);
|
|
126
|
+
const duplicateSourceQuality = await validateMutatedPythonSourceQuality(
|
|
127
|
+
{ commandCwd: pythonQualityWorkspace },
|
|
128
|
+
{
|
|
129
|
+
meta: {
|
|
130
|
+
projectVerification: {
|
|
131
|
+
mutationHistory: [{ revision: 1, paths: ["service_ctl.py"] }],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
assert(
|
|
137
|
+
duplicateSourceQuality.ok === false &&
|
|
138
|
+
duplicateSourceQuality.defects[0]?.name === "stop_service",
|
|
139
|
+
"completion source-quality validation accepted a task-mutated duplicate Python definition"
|
|
140
|
+
);
|
|
104
141
|
assert(normalizeDynamicStepsMode("off") === "off", "dynamic mode off did not normalize");
|
|
105
142
|
for (const command of [
|
|
106
143
|
"npm run build",
|
|
@@ -3364,6 +3401,33 @@ try {
|
|
|
3364
3401
|
)?.category === "repeated-read-only-call",
|
|
3365
3402
|
"an exact successful source reread was not closed after the first call"
|
|
3366
3403
|
);
|
|
3404
|
+
assert(
|
|
3405
|
+
repeatedStaticToolBlock(
|
|
3406
|
+
{
|
|
3407
|
+
meta: {
|
|
3408
|
+
projectVerification: { mutationRevision: 4 },
|
|
3409
|
+
toolLoop: {
|
|
3410
|
+
patchContextRequired: {
|
|
3411
|
+
version: 1,
|
|
3412
|
+
path: "service_ctl.py",
|
|
3413
|
+
mutationRevision: 4,
|
|
3414
|
+
goalRevision: 0,
|
|
3415
|
+
},
|
|
3416
|
+
staticCounts: {
|
|
3417
|
+
[staticToolCallSignature("read_file", { path: "service_ctl.py" }, {
|
|
3418
|
+
commandCwd: workspace,
|
|
3419
|
+
})]: 1,
|
|
3420
|
+
},
|
|
3421
|
+
staticTotal: 1,
|
|
3422
|
+
},
|
|
3423
|
+
},
|
|
3424
|
+
},
|
|
3425
|
+
"read_file",
|
|
3426
|
+
{ path: "service_ctl.py" },
|
|
3427
|
+
{ commandCwd: workspace }
|
|
3428
|
+
) === null,
|
|
3429
|
+
"the repeated-read guard blocked an exact source refresh required after a stale patch"
|
|
3430
|
+
);
|
|
3367
3431
|
assert(
|
|
3368
3432
|
repeatedStaticToolBlock(
|
|
3369
3433
|
{ meta: { toolLoop: { staticCounts: { [exactReadSignature]: 1 }, staticTotal: 1 } } },
|
|
@@ -4005,8 +4069,8 @@ try {
|
|
|
4005
4069
|
"a same-task refresh could not rebuild a missing failed-test evidence packet"
|
|
4006
4070
|
);
|
|
4007
4071
|
missingRecoveryPacketState.meta.failedTestRecoveryPacket = {
|
|
4008
|
-
packetVersion:
|
|
4009
|
-
content: "Bounded failed-test evidence packet
|
|
4072
|
+
packetVersion: 8,
|
|
4073
|
+
content: "Bounded failed-test evidence packet v8.",
|
|
4010
4074
|
mutationRevision: 6,
|
|
4011
4075
|
failureSignature: "same-failure",
|
|
4012
4076
|
};
|
|
@@ -4186,6 +4250,269 @@ try {
|
|
|
4186
4250
|
)) === null,
|
|
4187
4251
|
"a patch to a separate canonical producer was incorrectly blocked"
|
|
4188
4252
|
);
|
|
4253
|
+
const pythonMockContractSource = [
|
|
4254
|
+
"def test_stale_pid_routes_through_patchable_seams(self):",
|
|
4255
|
+
" with mock.patch.object(service_behavior, \"launch_service\") as launch:",
|
|
4256
|
+
" launch.return_value = mock.Mock(pid=32123)",
|
|
4257
|
+
" with mock.patch.object(service_behavior, \"wait_until_healthy\", return_value=True):",
|
|
4258
|
+
" result = service_behavior.start_service(state_dir, \"127.0.0.1\", 8765)",
|
|
4259
|
+
" self.assertEqual(result, 0)",
|
|
4260
|
+
" self.assertTrue(launch.called)",
|
|
4261
|
+
"",
|
|
4262
|
+
].join("\n");
|
|
4263
|
+
const pythonMockContract = failedTestMockBehaviorContract(pythonMockContractSource);
|
|
4264
|
+
assert(
|
|
4265
|
+
pythonMockContract.seams.some(
|
|
4266
|
+
(item) =>
|
|
4267
|
+
item.owner === "service_behavior" &&
|
|
4268
|
+
item.symbol === "launch_service" &&
|
|
4269
|
+
item.callExpectation === "called" &&
|
|
4270
|
+
item.returnAttributes.includes("pid=32123")
|
|
4271
|
+
) &&
|
|
4272
|
+
pythonMockContract.seams.some(
|
|
4273
|
+
(item) =>
|
|
4274
|
+
item.owner === "service_behavior" &&
|
|
4275
|
+
item.symbol === "wait_until_healthy" &&
|
|
4276
|
+
item.returnValue === "True"
|
|
4277
|
+
) &&
|
|
4278
|
+
pythonMockContract.invocations.some(
|
|
4279
|
+
(item) =>
|
|
4280
|
+
item.owner === "service_behavior" &&
|
|
4281
|
+
item.symbol === "start_service" &&
|
|
4282
|
+
item.assignedTo === "result"
|
|
4283
|
+
) &&
|
|
4284
|
+
pythonMockContract.resultAssertions.some(
|
|
4285
|
+
(item) => item.variable === "result" && item.expected === "0"
|
|
4286
|
+
),
|
|
4287
|
+
"the generic Python mock contract did not retain patched returns, observed calls, entrypoint, and result assertion"
|
|
4288
|
+
);
|
|
4289
|
+
await fs.mkdir(path.join(workspace, "tests"), { recursive: true });
|
|
4290
|
+
await fs.writeFile(
|
|
4291
|
+
path.join(workspace, "tests", "test_service_behavior.py"),
|
|
4292
|
+
pythonMockContractSource,
|
|
4293
|
+
"utf8"
|
|
4294
|
+
);
|
|
4295
|
+
await fs.writeFile(
|
|
4296
|
+
path.join(workspace, "service_behavior.py"),
|
|
4297
|
+
"def start_service(state_dir, host, port):\n return 2\n",
|
|
4298
|
+
"utf8"
|
|
4299
|
+
);
|
|
4300
|
+
const mockBehaviorPacketState = {
|
|
4301
|
+
meta: {
|
|
4302
|
+
projectVerification: {
|
|
4303
|
+
mutationRevision: 1,
|
|
4304
|
+
discoveredTests: ["tests/test_service_behavior.py"],
|
|
4305
|
+
lastMutation: { paths: ["service_behavior.py"] },
|
|
4306
|
+
testRuns: [{
|
|
4307
|
+
command: "python3 -m unittest discover -s tests -v",
|
|
4308
|
+
mutationRevision: 1,
|
|
4309
|
+
passed: false,
|
|
4310
|
+
failureEvidenceVersion: 2,
|
|
4311
|
+
failureSignature: "mock-behavior-contract",
|
|
4312
|
+
failureSummary: [
|
|
4313
|
+
'with mock.patch.object(service_behavior, "launch_service") as launch:',
|
|
4314
|
+
'with mock.patch.object(service_behavior, "wait_until_healthy", return_value=True):',
|
|
4315
|
+
"AssertionError: 2 != 0",
|
|
4316
|
+
].join(" "),
|
|
4317
|
+
}],
|
|
4318
|
+
},
|
|
4319
|
+
},
|
|
4320
|
+
};
|
|
4321
|
+
const mockBehaviorPacket = await buildFailedTestRecoveryPacket(
|
|
4322
|
+
{ commandCwd: workspace },
|
|
4323
|
+
mockBehaviorPacketState
|
|
4324
|
+
);
|
|
4325
|
+
assert(
|
|
4326
|
+
mockBehaviorPacket.content.includes(
|
|
4327
|
+
"Acceptance behavior distilled from the exact current test source"
|
|
4328
|
+
) &&
|
|
4329
|
+
mockBehaviorPacket.content.includes(
|
|
4330
|
+
"Tested production call(s): service_behavior.start_service -> result"
|
|
4331
|
+
) &&
|
|
4332
|
+
mockBehaviorPacket.content.includes(
|
|
4333
|
+
"Patchable seam service_behavior.launch_service: explicitly asserted called; test-double attributes pid=32123"
|
|
4334
|
+
) &&
|
|
4335
|
+
mockBehaviorPacket.content.includes(
|
|
4336
|
+
"Patchable seam service_behavior.wait_until_healthy: test-double return True"
|
|
4337
|
+
) &&
|
|
4338
|
+
mockBehaviorPacket.content.includes(
|
|
4339
|
+
"Result contract: service_behavior.start_service returns 0"
|
|
4340
|
+
),
|
|
4341
|
+
"the bounded failed-test packet did not front-load generic mock interaction behavior"
|
|
4342
|
+
);
|
|
4343
|
+
const seamSource = [
|
|
4344
|
+
"def start_service():",
|
|
4345
|
+
" return 0",
|
|
4346
|
+
"",
|
|
4347
|
+
].join("\n");
|
|
4348
|
+
await fs.writeFile(path.join(workspace, "service_topology.py"), seamSource, "utf8");
|
|
4349
|
+
const seamFailureSummary = [
|
|
4350
|
+
"Failing test: test_start_routes_through_mockable_seams.",
|
|
4351
|
+
'with mock.patch.object(service_topology, "launch_service") as launch:',
|
|
4352
|
+
'with mock.patch.object(service_topology, "wait_until_healthy", return_value=True):',
|
|
4353
|
+
"AttributeError: module service_topology has no attribute launch_service",
|
|
4354
|
+
].join(" ");
|
|
4355
|
+
const seamRepairState = {
|
|
4356
|
+
meta: {
|
|
4357
|
+
projectVerification: {
|
|
4358
|
+
mutationRevision: 2,
|
|
4359
|
+
testRuns: [
|
|
4360
|
+
{
|
|
4361
|
+
command: "python3 -m unittest discover -s tests -v",
|
|
4362
|
+
mutationRevision: 2,
|
|
4363
|
+
passed: false,
|
|
4364
|
+
failureEvidenceVersion: 2,
|
|
4365
|
+
failureSignature: "required-seam-topology",
|
|
4366
|
+
failureSummary: seamFailureSummary,
|
|
4367
|
+
},
|
|
4368
|
+
],
|
|
4369
|
+
},
|
|
4370
|
+
failedTestRecoveryPacket: {
|
|
4371
|
+
paths: ["tests/test_service_topology.py", "service_topology.py"],
|
|
4372
|
+
content: seamFailureSummary,
|
|
4373
|
+
},
|
|
4374
|
+
},
|
|
4375
|
+
};
|
|
4376
|
+
const definitionOnlySource = [
|
|
4377
|
+
"def launch_service():",
|
|
4378
|
+
" return object()",
|
|
4379
|
+
"",
|
|
4380
|
+
"def start_service():",
|
|
4381
|
+
" return 0",
|
|
4382
|
+
"",
|
|
4383
|
+
].join("\n");
|
|
4384
|
+
assert(
|
|
4385
|
+
(
|
|
4386
|
+
await failedTestRepairPatchBlock(
|
|
4387
|
+
seamRepairState,
|
|
4388
|
+
"apply_patch",
|
|
4389
|
+
{
|
|
4390
|
+
path: "service_topology.py",
|
|
4391
|
+
search: seamSource,
|
|
4392
|
+
replace: definitionOnlySource,
|
|
4393
|
+
expectedReplacements: 1,
|
|
4394
|
+
},
|
|
4395
|
+
{ commandCwd: workspace }
|
|
4396
|
+
)
|
|
4397
|
+
)?.category === "failed-test-required-symbol-topology",
|
|
4398
|
+
"a definition-only acceptance seam repair was allowed without a production call site"
|
|
4399
|
+
);
|
|
4400
|
+
const duplicateDefinitionSource = [
|
|
4401
|
+
"def launch_service():",
|
|
4402
|
+
" return object()",
|
|
4403
|
+
"",
|
|
4404
|
+
"def launch_service():",
|
|
4405
|
+
" return object()",
|
|
4406
|
+
"",
|
|
4407
|
+
"def start_service():",
|
|
4408
|
+
" return launch_service()",
|
|
4409
|
+
"",
|
|
4410
|
+
].join("\n");
|
|
4411
|
+
assert(
|
|
4412
|
+
(
|
|
4413
|
+
await failedTestRepairPatchBlock(
|
|
4414
|
+
seamRepairState,
|
|
4415
|
+
"apply_patch",
|
|
4416
|
+
{
|
|
4417
|
+
path: "service_topology.py",
|
|
4418
|
+
search: seamSource,
|
|
4419
|
+
replace: duplicateDefinitionSource,
|
|
4420
|
+
expectedReplacements: 1,
|
|
4421
|
+
},
|
|
4422
|
+
{ commandCwd: workspace }
|
|
4423
|
+
)
|
|
4424
|
+
)?.category === "failed-test-required-symbol-topology",
|
|
4425
|
+
"duplicate acceptance seam definitions were allowed"
|
|
4426
|
+
);
|
|
4427
|
+
const recursiveDefinitionSource = [
|
|
4428
|
+
"def launch_service():",
|
|
4429
|
+
" return launch_service()",
|
|
4430
|
+
"",
|
|
4431
|
+
"def start_service():",
|
|
4432
|
+
" return 0",
|
|
4433
|
+
"",
|
|
4434
|
+
].join("\n");
|
|
4435
|
+
assert(
|
|
4436
|
+
(
|
|
4437
|
+
await failedTestRepairPatchBlock(
|
|
4438
|
+
seamRepairState,
|
|
4439
|
+
"apply_patch",
|
|
4440
|
+
{
|
|
4441
|
+
path: "service_topology.py",
|
|
4442
|
+
search: seamSource,
|
|
4443
|
+
replace: recursiveDefinitionSource,
|
|
4444
|
+
expectedReplacements: 1,
|
|
4445
|
+
},
|
|
4446
|
+
{ commandCwd: workspace }
|
|
4447
|
+
)
|
|
4448
|
+
)?.category === "failed-test-required-symbol-topology",
|
|
4449
|
+
"a recursive seam wrapper was mistaken for production routing"
|
|
4450
|
+
);
|
|
4451
|
+
const routedSeamSource = [
|
|
4452
|
+
"def launch_service():",
|
|
4453
|
+
" return object()",
|
|
4454
|
+
"",
|
|
4455
|
+
"def start_service():",
|
|
4456
|
+
" return launch_service()",
|
|
4457
|
+
"",
|
|
4458
|
+
].join("\n");
|
|
4459
|
+
assert(
|
|
4460
|
+
(await failedTestRepairPatchBlock(
|
|
4461
|
+
seamRepairState,
|
|
4462
|
+
"apply_patch",
|
|
4463
|
+
{
|
|
4464
|
+
path: "service_topology.py",
|
|
4465
|
+
search: seamSource,
|
|
4466
|
+
replace: routedSeamSource,
|
|
4467
|
+
expectedReplacements: 1,
|
|
4468
|
+
},
|
|
4469
|
+
{ commandCwd: workspace }
|
|
4470
|
+
)) === null,
|
|
4471
|
+
"a single seam definition routed through production was incorrectly blocked"
|
|
4472
|
+
);
|
|
4473
|
+
assert(
|
|
4474
|
+
(
|
|
4475
|
+
await failedTestRepairPatchBlock(
|
|
4476
|
+
seamRepairState,
|
|
4477
|
+
"apply_patch",
|
|
4478
|
+
{
|
|
4479
|
+
patch: [
|
|
4480
|
+
"*** Begin Patch",
|
|
4481
|
+
"*** Update File: tests/test_service_topology.py",
|
|
4482
|
+
"@@",
|
|
4483
|
+
'-with mock.patch.object(service_topology, "launch_service"):',
|
|
4484
|
+
"+with mock.patch.object(service_topology, 'other_service'):",
|
|
4485
|
+
"*** End Patch",
|
|
4486
|
+
].join("\n"),
|
|
4487
|
+
},
|
|
4488
|
+
{ commandCwd: workspace }
|
|
4489
|
+
)
|
|
4490
|
+
)?.category === "failed-test-required-symbol-path",
|
|
4491
|
+
"a unified test-edit patch bypassed the canonical required-seam source path"
|
|
4492
|
+
);
|
|
4493
|
+
assert(
|
|
4494
|
+
(await failedTestRepairPatchBlock(
|
|
4495
|
+
seamRepairState,
|
|
4496
|
+
"apply_patch",
|
|
4497
|
+
{
|
|
4498
|
+
patch: [
|
|
4499
|
+
"*** Begin Patch",
|
|
4500
|
+
"*** Update File: service_topology.py",
|
|
4501
|
+
"@@",
|
|
4502
|
+
"-def start_service():",
|
|
4503
|
+
"- return 0",
|
|
4504
|
+
"+def launch_service():",
|
|
4505
|
+
"+ return object()",
|
|
4506
|
+
"+",
|
|
4507
|
+
"+def start_service():",
|
|
4508
|
+
"+ return launch_service()",
|
|
4509
|
+
"*** End Patch",
|
|
4510
|
+
].join("\n"),
|
|
4511
|
+
},
|
|
4512
|
+
{ commandCwd: workspace }
|
|
4513
|
+
)) === null,
|
|
4514
|
+
"a coherent unified source patch with one declaration and production call was blocked"
|
|
4515
|
+
);
|
|
4189
4516
|
await fs.writeFile(
|
|
4190
4517
|
path.join(workspace, "membership-report.md"),
|
|
4191
4518
|
"Source transport.jsonl was copied here.\nSafe summary follows.\nA second transport.jsonl reference remains.\n",
|
|
@@ -4601,7 +4928,7 @@ try {
|
|
|
4601
4928
|
],
|
|
4602
4929
|
},
|
|
4603
4930
|
failedTestDiagnostic: {
|
|
4604
|
-
packetVersion:
|
|
4931
|
+
packetVersion: 8,
|
|
4605
4932
|
mutationRevision: 0,
|
|
4606
4933
|
failureSignature: "partial-derived-order",
|
|
4607
4934
|
focuses: [
|