@lazyingart/agintiflow 0.20.310 → 0.20.312
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.312",
|
|
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",
|
|
@@ -1009,6 +1009,93 @@ assert.equal(
|
|
|
1009
1009
|
"the first exact-search mismatch did not immediately open one bounded current-source refresh"
|
|
1010
1010
|
);
|
|
1011
1011
|
const tracebackFirstRefreshState = structuredClone(stalePatchRefreshState);
|
|
1012
|
+
const scopedArtifactPath =
|
|
1013
|
+
"output/webapp/agent/tasks/source-intake-audit/report.md";
|
|
1014
|
+
const scopedArtifactRoot = path.join(
|
|
1015
|
+
repoRoot,
|
|
1016
|
+
"output/webapp/agent/tasks/source-intake-audit"
|
|
1017
|
+
);
|
|
1018
|
+
const scopedArtifactGoal = [
|
|
1019
|
+
"Correct and verify the exact source-intake audit report.",
|
|
1020
|
+
`AGINTI_EVIDENCE_SCOPE_JSON: ${JSON.stringify({
|
|
1021
|
+
mode: "task",
|
|
1022
|
+
request: "Correct and verify the exact source-intake audit report.",
|
|
1023
|
+
artifact_root: scopedArtifactRoot,
|
|
1024
|
+
})}`,
|
|
1025
|
+
].join("\n");
|
|
1026
|
+
const scopedArtifactRefreshState = {
|
|
1027
|
+
commandCwd: repoRoot,
|
|
1028
|
+
meta: {
|
|
1029
|
+
goalContract: {
|
|
1030
|
+
revision: 9,
|
|
1031
|
+
activeGoal: scopedArtifactGoal,
|
|
1032
|
+
taskGoal: scopedArtifactGoal,
|
|
1033
|
+
history: [],
|
|
1034
|
+
},
|
|
1035
|
+
projectVerification: {
|
|
1036
|
+
mutationRevision: 2,
|
|
1037
|
+
testRuns: [],
|
|
1038
|
+
},
|
|
1039
|
+
toolLoop: {
|
|
1040
|
+
stagnationEpoch: 4,
|
|
1041
|
+
recent: [],
|
|
1042
|
+
},
|
|
1043
|
+
},
|
|
1044
|
+
};
|
|
1045
|
+
const scopedArtifactRefresh = patchContextRefreshDecision(
|
|
1046
|
+
scopedArtifactRefreshState,
|
|
1047
|
+
{
|
|
1048
|
+
toolName: "apply_patch",
|
|
1049
|
+
args: {
|
|
1050
|
+
path: scopedArtifactPath,
|
|
1051
|
+
search: "Planned dynamic check: run the guarded document reader test.",
|
|
1052
|
+
replace: "Guarded document reader test: passed.",
|
|
1053
|
+
},
|
|
1054
|
+
ok: false,
|
|
1055
|
+
category: "workspace-patch",
|
|
1056
|
+
error: `Patch search text was not found in ${scopedArtifactPath}.`,
|
|
1057
|
+
}
|
|
1058
|
+
);
|
|
1059
|
+
assert.equal(
|
|
1060
|
+
scopedArtifactRefresh?.path,
|
|
1061
|
+
scopedArtifactPath,
|
|
1062
|
+
"a stale patch inside the exact scoped task artifact root was not recoverable"
|
|
1063
|
+
);
|
|
1064
|
+
scopedArtifactRefreshState.meta.toolLoop.patchContextRequired =
|
|
1065
|
+
scopedArtifactRefresh;
|
|
1066
|
+
assert.equal(
|
|
1067
|
+
activePatchContextRefresh(scopedArtifactRefreshState)?.path,
|
|
1068
|
+
scopedArtifactPath,
|
|
1069
|
+
"the scoped task-artifact refresh marker was rejected as a generic output path"
|
|
1070
|
+
);
|
|
1071
|
+
assert.equal(
|
|
1072
|
+
nextStepRuntimeConfig(baseConfig, scopedArtifactRefreshState)
|
|
1073
|
+
.patchContextRefreshPath,
|
|
1074
|
+
scopedArtifactPath,
|
|
1075
|
+
"the scoped task-artifact refresh path did not reach the next constrained turn"
|
|
1076
|
+
);
|
|
1077
|
+
const scopedArtifactSource = [
|
|
1078
|
+
"# Source Intake Audit",
|
|
1079
|
+
"",
|
|
1080
|
+
"Document reader verification is pending.",
|
|
1081
|
+
"",
|
|
1082
|
+
].join("\n");
|
|
1083
|
+
assert.equal(
|
|
1084
|
+
consumePatchContextRefreshRead(scopedArtifactRefreshState, {
|
|
1085
|
+
toolName: "read_file",
|
|
1086
|
+
args: { path: scopedArtifactPath },
|
|
1087
|
+
result: { path: scopedArtifactPath },
|
|
1088
|
+
content: scopedArtifactSource,
|
|
1089
|
+
ok: true,
|
|
1090
|
+
})?.path,
|
|
1091
|
+
scopedArtifactPath,
|
|
1092
|
+
"an exact reread did not consume the scoped task-artifact refresh"
|
|
1093
|
+
);
|
|
1094
|
+
assert.equal(
|
|
1095
|
+
activePatchContextRepair(scopedArtifactRefreshState)?.path,
|
|
1096
|
+
scopedArtifactPath,
|
|
1097
|
+
"the scoped task-artifact reread did not leave a bounded repair anchor"
|
|
1098
|
+
);
|
|
1012
1099
|
tracebackFirstRefreshState.meta.projectVerification.testRuns[0].failureSummary =
|
|
1013
1100
|
'File "./service_ctl.py", line 139 -> return start_service(args.state_dir, args.host, args.port) parser = argparse.ArgumentParser()';
|
|
1014
1101
|
const tracebackFirstRefresh = patchContextRefreshDecision(tracebackFirstRefreshState, {
|
|
@@ -734,6 +734,41 @@ assertStrict.deepEqual(
|
|
|
734
734
|
{ path: mandatoryRefreshPath },
|
|
735
735
|
"mandatory patch-context recovery did not preserve the exact constrained path"
|
|
736
736
|
);
|
|
737
|
+
const scopedMandatoryRefreshPath =
|
|
738
|
+
"output/webapp/agent/tasks/source-intake-audit/report.md";
|
|
739
|
+
const scopedMandatoryRefreshRoot =
|
|
740
|
+
"output/webapp/agent/tasks/source-intake-audit";
|
|
741
|
+
const scopedMandatoryRefreshReadDescriptor = {
|
|
742
|
+
...canonicalReadDescriptor,
|
|
743
|
+
function: {
|
|
744
|
+
...canonicalReadDescriptor.function,
|
|
745
|
+
parameters: {
|
|
746
|
+
...canonicalReadDescriptor.function.parameters,
|
|
747
|
+
properties: {
|
|
748
|
+
path: { type: "string", enum: [scopedMandatoryRefreshPath] },
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
};
|
|
753
|
+
const recoveredScopedMandatoryRefresh =
|
|
754
|
+
recoverRequiredPatchContextReadWithoutToolCall(
|
|
755
|
+
{
|
|
756
|
+
commandCwd: process.cwd(),
|
|
757
|
+
scopedArtifactRoot: scopedMandatoryRefreshRoot,
|
|
758
|
+
patchContextRefreshRequired: true,
|
|
759
|
+
patchContextRefreshPath: scopedMandatoryRefreshPath,
|
|
760
|
+
},
|
|
761
|
+
[],
|
|
762
|
+
createToolContract([scopedMandatoryRefreshReadDescriptor, tool("finish")]),
|
|
763
|
+
{ ok: true, calls: [], acceptedToolCalls: [], deferredToolCalls: [] }
|
|
764
|
+
);
|
|
765
|
+
assertStrict.deepEqual(
|
|
766
|
+
JSON.parse(
|
|
767
|
+
recoveredScopedMandatoryRefresh.acceptedToolCalls[0].function.arguments
|
|
768
|
+
),
|
|
769
|
+
{ path: scopedMandatoryRefreshPath },
|
|
770
|
+
"mandatory patch-context recovery rejected the exact scoped task artifact"
|
|
771
|
+
);
|
|
737
772
|
const recoveredPrematureRefreshFinish = recoverRequiredPatchContextReadWithoutToolCall(
|
|
738
773
|
{
|
|
739
774
|
patchContextRefreshRequired: true,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
completionRequirementCoverageInstruction,
|
|
9
9
|
continuationExecutionContractDirective,
|
|
10
10
|
removeSupersededCompletionRepairInstructions,
|
|
11
|
+
repositorySourcePrecedenceInstruction,
|
|
11
12
|
runAgent,
|
|
12
13
|
} from "../src/agent-runner.js";
|
|
13
14
|
import { resolveRuntimeConfig } from "../src/config.js";
|
|
@@ -25,6 +26,36 @@ assert.match(completionCoverageInstruction, /authoritative structured routine/i)
|
|
|
25
26
|
assert.match(completionCoverageInstruction, /every relevant section/i);
|
|
26
27
|
assert.match(completionCoverageInstruction, /instead of summarizing only failures or only successes/i);
|
|
27
28
|
|
|
29
|
+
const sourcePrecedenceInstruction = repositorySourcePrecedenceInstruction();
|
|
30
|
+
assert.match(sourcePrecedenceInstruction, /current direct user request/i);
|
|
31
|
+
assert.match(sourcePrecedenceInstruction, /closest project instructions/i);
|
|
32
|
+
assert.match(sourcePrecedenceInstruction, /most specific current implementation and tests/i);
|
|
33
|
+
assert.match(sourcePrecedenceInstruction, /stale guides/i);
|
|
34
|
+
assert.match(sourcePrecedenceInstruction, /AGENTS\.md/i);
|
|
35
|
+
|
|
36
|
+
const readOnlyContractAuditGoal = `
|
|
37
|
+
Audit the current source-intake contract and cover an ordinary video, a hypothetical
|
|
38
|
+
same-chat publish request, a Finder card, and a document attachment. Do not send any
|
|
39
|
+
message, publish anything, alter a queue, open a browser, or modify configuration.
|
|
40
|
+
`;
|
|
41
|
+
const readOnlyContractAudit = deriveScsTaskContract({
|
|
42
|
+
goal: readOnlyContractAuditGoal,
|
|
43
|
+
taskProfile: "auto",
|
|
44
|
+
});
|
|
45
|
+
assert.equal(readOnlyContractAudit.readOnlyReadiness, true);
|
|
46
|
+
assert(
|
|
47
|
+
!readOnlyContractAudit.requiredEvidence.some((item) => item.category === "publish"),
|
|
48
|
+
"a hypothetical publish case inside a forbidden read-only contract audit required live publish evidence"
|
|
49
|
+
);
|
|
50
|
+
assert(
|
|
51
|
+
!readOnlyContractAudit.requiredEvidence.some((item) => item.category === "browser"),
|
|
52
|
+
"a forbidden browser action inside a read-only contract audit required browser evidence"
|
|
53
|
+
);
|
|
54
|
+
assert(
|
|
55
|
+
readOnlyContractAudit.forbiddenActions.some((item) => /publish anything/i.test(item)),
|
|
56
|
+
"the read-only audit lost its explicit publish prohibition"
|
|
57
|
+
);
|
|
58
|
+
|
|
28
59
|
assert.equal(
|
|
29
60
|
finishResultClaimsIncompleteWork(
|
|
30
61
|
"The report is complete and the verification that was previously paused now passes. No work remains."
|
package/src/agent-runner.js
CHANGED
|
@@ -2973,6 +2973,10 @@ export function completionRequirementCoverageInstruction() {
|
|
|
2973
2973
|
return "Before finishing, check the current user request requirement by requirement. Every distinct subject, requested action, and deliverable must be completed, answered, deliberately grouped under one verified shared state, or named with a concrete blocker. When an authoritative structured routine returns named sections relevant to the request, report every relevant section instead of summarizing only failures or only successes.";
|
|
2974
2974
|
}
|
|
2975
2975
|
|
|
2976
|
+
export function repositorySourcePrecedenceInstruction() {
|
|
2977
|
+
return "Treat the current direct user request and the closest project instructions as authoritative. When describing an existing contract, inspect the most specific current implementation and tests, reconcile conflicting documentation, and never let examples, stale guides, or historical notes override AGENTS.md or current code. State any unresolved conflict instead of choosing silently.";
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2976
2980
|
function focusedCapabilityContext(config = {}) {
|
|
2977
2981
|
return [
|
|
2978
2982
|
config.allowFileTools
|
|
@@ -3017,6 +3021,7 @@ function buildFocusedRuntimeMessages({
|
|
|
3017
3021
|
"Answer ordinary conversation directly. For executable work, act through the smallest relevant routine or tool, verify in proportion to risk, then stop.",
|
|
3018
3022
|
"Treat queued user input as a safe-boundary interruption: preserve every material requirement, merge related consecutive messages, revise the durable goal, and never repeat a completed external side effect.",
|
|
3019
3023
|
completionRequirementCoverageInstruction(),
|
|
3024
|
+
repositorySourcePrecedenceInstruction(),
|
|
3020
3025
|
"Established project routines are capabilities to invoke, not workflows to reimplement. Discover more context only when the current task needs it.",
|
|
3021
3026
|
formatBehaviorContractForPrompt({ mode: "focused" }),
|
|
3022
3027
|
languageInstruction(config.language || "en"),
|
|
@@ -3236,6 +3241,7 @@ async function createInitialState(config, sessionId) {
|
|
|
3236
3241
|
"For LaTeX/PDF tasks, check existing latexmk/pdflatex first and compile with the available host or Docker TeX toolchain before installing packages or rebuilding the sandbox.",
|
|
3237
3242
|
"For research or web-search tasks, use browser tools or safe shell network tools when the current policy allows; cite or save useful sources in workspace notes when the task needs traceability.",
|
|
3238
3243
|
completionRequirementCoverageInstruction(),
|
|
3244
|
+
repositorySourcePrecedenceInstruction(),
|
|
3239
3245
|
browserStateReconciliationGuidance(),
|
|
3240
3246
|
isRetainedWorkspaceProfile(config)
|
|
3241
3247
|
? "Choose descriptive non-conflicting workspace paths for durable outputs."
|
|
@@ -10165,7 +10171,8 @@ export function repeatedStaticToolBlock(state, toolName, args = {}, config = {})
|
|
|
10165
10171
|
(
|
|
10166
10172
|
(
|
|
10167
10173
|
requiredPatchRefresh &&
|
|
10168
|
-
|
|
10174
|
+
safePatchContextEvidencePath(args?.path, state, config) ===
|
|
10175
|
+
requiredPatchRefresh.path
|
|
10169
10176
|
) ||
|
|
10170
10177
|
boundedFailedTestReadPaths.includes(safeRecoveryEvidencePath(args?.path))
|
|
10171
10178
|
)
|
|
@@ -12675,7 +12682,9 @@ function isPrivateVerificationEvidencePath(value = "") {
|
|
|
12675
12682
|
}
|
|
12676
12683
|
|
|
12677
12684
|
function isScopedTaskArtifactEvidencePath(value = "", state = {}, config = {}) {
|
|
12678
|
-
const artifactRoot =
|
|
12685
|
+
const artifactRoot =
|
|
12686
|
+
scopedArtifactRoot(completionContractGoal(config, state)) ||
|
|
12687
|
+
String(config.scopedArtifactRoot || "").trim();
|
|
12679
12688
|
if (!artifactRoot) return false;
|
|
12680
12689
|
const raw = String(value || "")
|
|
12681
12690
|
.trim()
|
|
@@ -12694,6 +12703,41 @@ function isScopedTaskArtifactEvidencePath(value = "", state = {}, config = {}) {
|
|
|
12694
12703
|
);
|
|
12695
12704
|
}
|
|
12696
12705
|
|
|
12706
|
+
function safePatchContextEvidencePath(value = "", state = {}, config = {}) {
|
|
12707
|
+
const sourcePath = safeRecoveryEvidencePath(value);
|
|
12708
|
+
if (sourcePath) return sourcePath;
|
|
12709
|
+
|
|
12710
|
+
const raw = String(value || "")
|
|
12711
|
+
.trim()
|
|
12712
|
+
.replace(/^["']|["']$/g, "")
|
|
12713
|
+
.replace(/\\/g, "/");
|
|
12714
|
+
if (
|
|
12715
|
+
!raw ||
|
|
12716
|
+
raw.includes("\0") ||
|
|
12717
|
+
/^https?:\/\//i.test(raw) ||
|
|
12718
|
+
/(?:secret|credential|password|private[-_]?key|access[-_]?token)/i.test(raw)
|
|
12719
|
+
) {
|
|
12720
|
+
return "";
|
|
12721
|
+
}
|
|
12722
|
+
const commandCwd = path.resolve(
|
|
12723
|
+
config.commandCwd || state.commandCwd || process.cwd()
|
|
12724
|
+
);
|
|
12725
|
+
const absolutePath = path.isAbsolute(raw)
|
|
12726
|
+
? path.resolve(raw)
|
|
12727
|
+
: path.resolve(commandCwd, raw);
|
|
12728
|
+
const relativePath = path.relative(commandCwd, absolutePath).replace(/\\/g, "/");
|
|
12729
|
+
if (
|
|
12730
|
+
!relativePath ||
|
|
12731
|
+
relativePath.startsWith("..") ||
|
|
12732
|
+
path.isAbsolute(relativePath) ||
|
|
12733
|
+
!PLAIN_TEXT_FILE_EXTENSIONS.has(path.extname(relativePath).toLowerCase()) ||
|
|
12734
|
+
!isScopedTaskArtifactEvidencePath(raw, state, config)
|
|
12735
|
+
) {
|
|
12736
|
+
return "";
|
|
12737
|
+
}
|
|
12738
|
+
return relativePath;
|
|
12739
|
+
}
|
|
12740
|
+
|
|
12697
12741
|
function commandWritesOnlyEvidenceMatching(command = "", pathMatches = () => false) {
|
|
12698
12742
|
const normalized = String(command || "").trim();
|
|
12699
12743
|
if (!normalized) return false;
|
|
@@ -17604,10 +17648,11 @@ function validatedPatchContextCompleteSource(marker = {}) {
|
|
|
17604
17648
|
|
|
17605
17649
|
export function activePatchContextRefresh(state = {}) {
|
|
17606
17650
|
const marker = state.meta?.toolLoop?.patchContextRequired;
|
|
17651
|
+
const markerPath = safePatchContextEvidencePath(marker?.path, state);
|
|
17607
17652
|
if (
|
|
17608
17653
|
!marker ||
|
|
17609
17654
|
Number(marker.version || 0) !== PATCH_CONTEXT_REFRESH_VERSION ||
|
|
17610
|
-
!
|
|
17655
|
+
!markerPath
|
|
17611
17656
|
) {
|
|
17612
17657
|
return null;
|
|
17613
17658
|
}
|
|
@@ -17638,16 +17683,17 @@ export function activePatchContextRefresh(state = {}) {
|
|
|
17638
17683
|
}
|
|
17639
17684
|
return {
|
|
17640
17685
|
...marker,
|
|
17641
|
-
path:
|
|
17686
|
+
path: markerPath,
|
|
17642
17687
|
};
|
|
17643
17688
|
}
|
|
17644
17689
|
|
|
17645
17690
|
export function activePatchContextRepair(state = {}) {
|
|
17646
17691
|
const marker = state.meta?.toolLoop?.patchContextRepair;
|
|
17692
|
+
const markerPath = safePatchContextEvidencePath(marker?.path, state);
|
|
17647
17693
|
if (
|
|
17648
17694
|
!marker ||
|
|
17649
17695
|
Number(marker.version || 0) !== PATCH_CONTEXT_REPAIR_VERSION ||
|
|
17650
|
-
!
|
|
17696
|
+
!markerPath ||
|
|
17651
17697
|
!String(marker.search || "") ||
|
|
17652
17698
|
!String(marker.searchHash || "")
|
|
17653
17699
|
) {
|
|
@@ -17688,8 +17734,7 @@ export function activePatchContextRepair(state = {}) {
|
|
|
17688
17734
|
const samePathFocuses = diagnosticMatchesRevision
|
|
17689
17735
|
? (Array.isArray(diagnostic.focuses) ? diagnostic.focuses : []).filter(
|
|
17690
17736
|
(focus) =>
|
|
17691
|
-
|
|
17692
|
-
safeRecoveryEvidencePath(marker.path) &&
|
|
17737
|
+
safePatchContextEvidencePath(focus?.path, state) === markerPath &&
|
|
17693
17738
|
String(focus?.directSearch || "")
|
|
17694
17739
|
)
|
|
17695
17740
|
: [];
|
|
@@ -17706,7 +17751,7 @@ export function activePatchContextRepair(state = {}) {
|
|
|
17706
17751
|
const completeSource = validatedPatchContextCompleteSource(marker);
|
|
17707
17752
|
return {
|
|
17708
17753
|
...marker,
|
|
17709
|
-
path:
|
|
17754
|
+
path: markerPath,
|
|
17710
17755
|
completeSource,
|
|
17711
17756
|
completeSourceHash: completeSource ? String(marker.completeSourceHash || "") : "",
|
|
17712
17757
|
completeSourceBytes: completeSource
|
|
@@ -18066,7 +18111,7 @@ function failedTestTracebackLineAnchor(state = {}, targetPath = "") {
|
|
|
18066
18111
|
export function bindPatchContextRepairArguments(state = {}, requestedArgs = {}) {
|
|
18067
18112
|
const marker = activePatchContextRepair(state);
|
|
18068
18113
|
if (!marker || typeof requestedArgs?.replace !== "string") return null;
|
|
18069
|
-
const requestedPath =
|
|
18114
|
+
const requestedPath = safePatchContextEvidencePath(requestedArgs.path, state);
|
|
18070
18115
|
if (requestedPath && requestedPath !== marker.path) return null;
|
|
18071
18116
|
const requestedSearch = String(requestedArgs.search || "");
|
|
18072
18117
|
const boundedSubrange = revisionBoundRequestedPatchSubrange(
|
|
@@ -18158,7 +18203,7 @@ export function bindPatchContextRepairArguments(state = {}, requestedArgs = {})
|
|
|
18158
18203
|
}
|
|
18159
18204
|
|
|
18160
18205
|
export function patchContextScopeMismatchAttemptCount(state = {}, targetPath = "") {
|
|
18161
|
-
const normalizedPath =
|
|
18206
|
+
const normalizedPath = safePatchContextEvidencePath(targetPath, state);
|
|
18162
18207
|
if (!normalizedPath) return 0;
|
|
18163
18208
|
const toolLoop = state.meta?.toolLoop || {};
|
|
18164
18209
|
const stagnationEpoch = Math.max(0, Number(toolLoop.stagnationEpoch || 0));
|
|
@@ -18172,7 +18217,7 @@ export function patchContextScopeMismatchAttemptCount(state = {}, targetPath = "
|
|
|
18172
18217
|
entry?.toolName !== "apply_patch" ||
|
|
18173
18218
|
entry?.ok !== false ||
|
|
18174
18219
|
entry?.category !== "patch-context-scope-mismatch" ||
|
|
18175
|
-
|
|
18220
|
+
safePatchContextEvidencePath(entry?.path, state) !== normalizedPath ||
|
|
18176
18221
|
Number(entry?.stagnationEpoch || 0) !== stagnationEpoch
|
|
18177
18222
|
) {
|
|
18178
18223
|
return false;
|
|
@@ -18253,7 +18298,7 @@ export function patchContextRefreshDecision(state = {}, toolResult = {}) {
|
|
|
18253
18298
|
const recent = Array.isArray(toolLoop.recent) ? toolLoop.recent : [];
|
|
18254
18299
|
const samePathRecent = recent.filter(
|
|
18255
18300
|
(entry) =>
|
|
18256
|
-
|
|
18301
|
+
safePatchContextEvidencePath(entry?.path, state) === targetPath &&
|
|
18257
18302
|
Number(entry?.stagnationEpoch || 0) === stagnationEpoch
|
|
18258
18303
|
);
|
|
18259
18304
|
const priorMissingSearches = samePathRecent.filter(
|
|
@@ -18564,7 +18609,8 @@ export function consumePatchContextRepairMutation(state = {}, toolResult = {}) {
|
|
|
18564
18609
|
String(toolResult.toolName || "") !== "apply_patch" ||
|
|
18565
18610
|
toolResult.ok === false ||
|
|
18566
18611
|
toolResult.blocked === true ||
|
|
18567
|
-
toolResultWorkspacePath(toolResult) !==
|
|
18612
|
+
toolResultWorkspacePath(toolResult) !==
|
|
18613
|
+
safePatchContextEvidencePath(marker.path, state) ||
|
|
18568
18614
|
![
|
|
18569
18615
|
String(marker.searchHash || ""),
|
|
18570
18616
|
String(marker.lastBoundSearchHash || ""),
|
|
@@ -24205,11 +24251,13 @@ export function recoverRequiredPatchContextReadWithoutToolCall(
|
|
|
24205
24251
|
const selectedFailedTestReadMode = Boolean(
|
|
24206
24252
|
!refreshMode && !repairMode && !selectedFailedTestDiagnosticReadMode && failedTestReadMode
|
|
24207
24253
|
);
|
|
24254
|
+
const patchContextPath = (value) =>
|
|
24255
|
+
safePatchContextEvidencePath(value, {}, config);
|
|
24208
24256
|
const exactPath = selectedFailedTestDiagnosticReadMode
|
|
24209
24257
|
? safeGeneratedDiagnosticEvidencePath(
|
|
24210
24258
|
config.testFailureWorkspaceDiagnosticReadPaths?.[0]
|
|
24211
24259
|
)
|
|
24212
|
-
: safeRecoveryEvidencePath(
|
|
24260
|
+
: (refreshMode || repairMode ? patchContextPath : safeRecoveryEvidencePath)(
|
|
24213
24261
|
refreshMode
|
|
24214
24262
|
? config.patchContextRefreshPath
|
|
24215
24263
|
: repairMode
|
|
@@ -24220,7 +24268,9 @@ export function recoverRequiredPatchContextReadWithoutToolCall(
|
|
|
24220
24268
|
const requestedCall = calls.length === 1 ? calls[0] : null;
|
|
24221
24269
|
const requestedToolName = String(requestedCall?.function?.name || "");
|
|
24222
24270
|
const requestedArgs = safeParseToolArgs(requestedCall);
|
|
24223
|
-
const requestedPath =
|
|
24271
|
+
const requestedPath = (refreshMode || repairMode
|
|
24272
|
+
? patchContextPath
|
|
24273
|
+
: safeRecoveryEvidencePath)(requestedArgs.path);
|
|
24224
24274
|
const missingRefreshCall = validation?.ok === true && calls.length === 0 && refreshMode;
|
|
24225
24275
|
const unavailableContextCall =
|
|
24226
24276
|
validation?.ok !== true &&
|
|
@@ -24289,7 +24339,9 @@ export function recoverRequiredPatchContextReadWithoutToolCall(
|
|
|
24289
24339
|
readDescriptor.function?.parameters?.properties?.path?.enum;
|
|
24290
24340
|
const normalizeAllowedPath = selectedFailedTestDiagnosticReadMode
|
|
24291
24341
|
? safeGeneratedDiagnosticEvidencePath
|
|
24292
|
-
:
|
|
24342
|
+
: refreshMode || repairMode
|
|
24343
|
+
? patchContextPath
|
|
24344
|
+
: safeRecoveryEvidencePath;
|
|
24293
24345
|
if (
|
|
24294
24346
|
!Array.isArray(allowedPaths) ||
|
|
24295
24347
|
(!selectedFailedTestReadMode && !selectedFailedTestDiagnosticReadMode && allowedPaths.length !== 1) ||
|
package/src/scs-evidence.js
CHANGED
|
@@ -454,6 +454,13 @@ function normalizeWrappedNegativePrefixes(goal = "") {
|
|
|
454
454
|
);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
+
function normalizeSoftLineWraps(goal = "") {
|
|
458
|
+
return normalizeWrappedNegativePrefixes(goal).replace(
|
|
459
|
+
/([A-Za-z0-9,])[ \t]*\r?\n[ \t]*(?=[a-z])/g,
|
|
460
|
+
"$1 "
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
457
464
|
function inferExactOutputPaths(goal = "") {
|
|
458
465
|
const paths = [];
|
|
459
466
|
const lines = String(goal || "").split(/\n/);
|
|
@@ -1406,10 +1413,17 @@ function isReadOnlyReadinessTask(goal = "") {
|
|
|
1406
1413
|
/\b(?:readiness|capability)\s+(?:audit|check|report|assessment)\b/i.test(text) ||
|
|
1407
1414
|
/\bwhether\s+(?:i|we|the\s+(?:agent|system))\s+can\b/i.test(text) ||
|
|
1408
1415
|
/只读检查|只讀檢查|就绪检查|就緒檢查|能力检查|能力檢查|检查是否|檢查是否/.test(text);
|
|
1416
|
+
const contractAuditSignal =
|
|
1417
|
+
/\b(?:audit|inspect|review|assess|document|report\s+on)\s+(?:the\s+)?(?:current\s+)?[^.\n;]{0,140}\b(?:contract|policy|behavio(?:u)?r|workflow|implementation|routine|routing|readiness|capabilit(?:y|ies))\b/i.test(
|
|
1418
|
+
text
|
|
1419
|
+
) ||
|
|
1420
|
+
/(?:审计|審計|检查|檢查|审查|審查|评估|評估|记录|記錄)[^。;\n]{0,120}(?:契约|契約|策略|行为|行為|流程|实现|實現|例程|路由|就绪|就緒|能力)/.test(
|
|
1421
|
+
text
|
|
1422
|
+
);
|
|
1409
1423
|
const noActionSignal =
|
|
1410
|
-
/\b(?:do not|don't|dont|never|without)\b[^.\n;]{0,260}\b(?:generate|submit|upload|publish|deploy|
|
|
1424
|
+
/\b(?:do not|don't|dont|never|without)\b[^.\n;]{0,260}\b(?:send|generate|submit|upload|publish|deploy|open|browse|focus|restart|alter|change|edit|modify|write|mutate|delete|purchase|pay|log in|login)\b/i.test(text) ||
|
|
1411
1425
|
/(?:不要|禁止)[^。\n;]{0,260}(?:生成|提交|上传|上傳|发布|發布|部署|登录|登入|重启|重啟|编辑|編輯|修改|删除|刪除|购买|購買|支付)/.test(text);
|
|
1412
|
-
return readinessSignal && noActionSignal;
|
|
1426
|
+
return (readinessSignal || contractAuditSignal) && noActionSignal;
|
|
1413
1427
|
}
|
|
1414
1428
|
|
|
1415
1429
|
function requiresSourceGrounding(goal = "") {
|
|
@@ -1550,7 +1564,7 @@ function inferRequirementCategories(goal = "", taskProfile = "", acceptanceCrite
|
|
|
1550
1564
|
}
|
|
1551
1565
|
|
|
1552
1566
|
function inferForbiddenActions(goal = "") {
|
|
1553
|
-
const text =
|
|
1567
|
+
const text = normalizeSoftLineWraps(goal);
|
|
1554
1568
|
const forbidden = [];
|
|
1555
1569
|
const isAction = (value = "") =>
|
|
1556
1570
|
/\b(use|open|click|browse|browser|upload|attach|submit|publish|deploy|run|execute|install|delete|remove|commit|push|call|api|alter|chang(?:e|ing)|edit(?:ing)?|fix(?:ing)?|modif(?:y|ying)|patch(?:ing)?|repair(?:ing)?|rewrit(?:e|ing)|send(?:ing)?|touch(?:ing)?|writ(?:e|ing))\b/i.test(
|
|
@@ -1601,7 +1615,7 @@ function inferRequiredToolCalls(goal = "") {
|
|
|
1601
1615
|
}
|
|
1602
1616
|
|
|
1603
1617
|
function stripForbiddenLanguage(goal = "") {
|
|
1604
|
-
return
|
|
1618
|
+
return normalizeSoftLineWraps(goal)
|
|
1605
1619
|
.replace(/\b(do not|don't|dont|must not|should not|never|no need to)\s+([^.\n;]+)/gi, "")
|
|
1606
1620
|
.replace(/\bwithout\s+([^.,:\uFF1A\n;]+)/gi, "")
|
|
1607
1621
|
.replace(/不要([^。\n;]+)/g, "")
|