@lazyingart/agintiflow 0.20.210 → 0.20.211

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.210",
3
+ "version": "0.20.211",
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",
@@ -52,6 +52,17 @@ const artifactContract = deriveScsTaskContract({
52
52
  });
53
53
  assert.equal(artifactContract.requiresExternalEvidence, true, "real chat artifact work lost its evidence gate");
54
54
  assert.ok(artifactContract.requiredEvidence.some((item) => item.category === "artifact"));
55
+ const scopedArtifactRootContract = deriveScsTaskContract({
56
+ goal:
57
+ 'AGINTI_EVIDENCE_SCOPE_JSON: {"mode":"task","request":"Create result.txt with the exact requested content.","artifact_root":"/tmp/labcanvas-task-artifacts"}',
58
+ taskProfile: "chatops",
59
+ });
60
+ assert.equal(scopedArtifactRootContract.artifactRoot, "/tmp/labcanvas-task-artifacts");
61
+ assert.deepEqual(
62
+ scopedArtifactRootContract.exactOutputPaths,
63
+ ["/tmp/labcanvas-task-artifacts/result.txt"],
64
+ "a bare task artifact filename was not resolved against the host-declared artifact root"
65
+ );
55
66
 
56
67
  let capturedPayload = null;
57
68
  const client = {
@@ -670,13 +670,27 @@ function stripForbiddenLanguage(goal = "") {
670
670
  .replace(/禁止([^。\n;]+)/g, "");
671
671
  }
672
672
 
673
+ function parseAgintiEvidenceScope(goal = "") {
674
+ const matches = [
675
+ ...String(goal || "").matchAll(/^AGINTI_EVIDENCE_SCOPE_JSON:\s*(\{[^\n]+\})\s*$/gm),
676
+ ];
677
+ const match = matches.at(-1);
678
+ if (!match) return null;
679
+ try {
680
+ const payload = JSON.parse(match[1]);
681
+ return payload && typeof payload === "object" ? payload : null;
682
+ } catch {
683
+ return null;
684
+ }
685
+ }
686
+
673
687
  export function hasAgintiEvidenceScope(goal = "") {
674
- return /^AGINTI_EVIDENCE_SCOPE_JSON:\s*\{[^\n]+\}\s*$/m.test(String(goal || ""));
688
+ return Boolean(parseAgintiEvidenceScope(goal));
675
689
  }
676
690
 
677
691
  export function scopedChatopsEvidenceGoal(goal = "", taskProfile = "") {
678
- const match = String(goal || "").match(/^AGINTI_EVIDENCE_SCOPE_JSON:\s*(\{[^\n]+\})\s*$/m);
679
- if (!match) {
692
+ const payload = parseAgintiEvidenceScope(goal);
693
+ if (!payload) {
680
694
  const text = String(goal || "");
681
695
  const lines = text
682
696
  .split(/\r?\n/)
@@ -694,22 +708,32 @@ export function scopedChatopsEvidenceGoal(goal = "", taskProfile = "") {
694
708
  }
695
709
  return text;
696
710
  }
697
- try {
698
- const payload = JSON.parse(match[1]);
699
- if (!payload || typeof payload !== "object") return String(goal || "");
700
- const mode = String(payload.mode || "").trim().toLowerCase();
701
- if (["chat-response", "host-managed-response", "plan-response", "read-only-answer"].includes(mode)) {
702
- return "Answer the current chat turn directly without external execution.";
703
- }
704
- const request = String(payload.request || "").trim();
705
- return request || String(goal || "");
706
- } catch {
707
- return String(goal || "");
711
+ const mode = String(payload.mode || "").trim().toLowerCase();
712
+ if (["chat-response", "host-managed-response", "plan-response", "read-only-answer"].includes(mode)) {
713
+ return "Answer the current chat turn directly without external execution.";
708
714
  }
715
+ const request = String(payload.request || "").trim();
716
+ return request || String(goal || "");
717
+ }
718
+
719
+ function scopedArtifactRoot(goal = "") {
720
+ const payload = parseAgintiEvidenceScope(goal);
721
+ if (!payload || String(payload.mode || "").trim().toLowerCase() !== "task") return "";
722
+ return String(payload.artifact_root || "").trim();
723
+ }
724
+
725
+ function applyScopedArtifactRoot(items = [], artifactRoot = "") {
726
+ if (!artifactRoot) return items;
727
+ return items.map((item) => {
728
+ const value = String(item || "").trim();
729
+ if (!value || path.isAbsolute(value) || value.startsWith("~/") || /[\\/]/.test(value)) return value;
730
+ return path.join(artifactRoot, value);
731
+ });
709
732
  }
710
733
 
711
734
  export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceCriteria = [] } = {}) {
712
735
  const evidenceGoal = scopedChatopsEvidenceGoal(goal, taskProfile);
736
+ const artifactRoot = scopedArtifactRoot(goal);
713
737
  const requirementCategories = inferRequirementCategories(evidenceGoal, taskProfile, acceptanceCriteria);
714
738
  const requiredToolCalls = inferRequiredToolCalls(evidenceGoal);
715
739
  const requiresExternalEvidence = requirementCategories.length > 0 || requiredToolCalls.length > 0 || goalRequiresEvidence(evidenceGoal, taskProfile);
@@ -718,8 +742,11 @@ export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceC
718
742
  category,
719
743
  description: CATEGORY_LABELS[category] || category,
720
744
  }));
721
- const exactOutputPaths = inferExactOutputPaths(evidenceGoal);
722
- const exactInputPaths = inferExactInputPaths(evidenceGoal).filter((item) => !exactOutputPaths.includes(item));
745
+ const inferredOutputPaths = inferExactOutputPaths(evidenceGoal);
746
+ const exactOutputPaths = applyScopedArtifactRoot(inferredOutputPaths, artifactRoot);
747
+ const exactInputPaths = inferExactInputPaths(evidenceGoal).filter(
748
+ (item) => !inferredOutputPaths.includes(item) && !exactOutputPaths.includes(item)
749
+ );
723
750
  const declaredSourceRoots = inferDeclaredSourceRoots(evidenceGoal);
724
751
  return {
725
752
  version: 1,
@@ -729,6 +756,7 @@ export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceC
729
756
  requiredEvidence,
730
757
  forbiddenActions: inferForbiddenActions(evidenceGoal),
731
758
  exactOutputPaths,
759
+ artifactRoot,
732
760
  exactInputPaths,
733
761
  declaredSourceRoots,
734
762
  readOnlyReadiness: isReadOnlyReadinessTask(evidenceGoal),
@@ -786,11 +814,12 @@ export function augmentScsTaskContractWithProjectVerification(contract = {}, sta
786
814
  .map((item) => String(item?.path || item || "").trim())
787
815
  .filter(Boolean)
788
816
  ).slice(0, 80);
789
- const requiredOutputs = unique(
817
+ const requiredOutputs = unique(applyScopedArtifactRoot(
790
818
  (Array.isArray(verification.requiredOutputs) ? verification.requiredOutputs : [])
791
819
  .map((item) => String(item || "").trim())
792
- .filter(Boolean)
793
- ).slice(0, 64);
820
+ .filter(Boolean),
821
+ String(contract.artifactRoot || "")
822
+ )).slice(0, 64);
794
823
  const requiredProjectCommands = unique(
795
824
  (Array.isArray(verification.requiredCommands) ? verification.requiredCommands : [])
796
825
  .map(normalizeProjectCommand)