@lazyingart/agintiflow 0.20.209 → 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 +1 -1
- package/scripts/smoke-context-budget-recovery.js +11 -0
- package/scripts/smoke-progressive-tool-selection.js +35 -0
- package/scripts/smoke-web-api.js +4 -2
- package/src/progressive-tool-selection.js +6 -3
- package/src/research-routing.js +10 -6
- package/src/scs-evidence.js +52 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
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 = {
|
|
@@ -770,6 +770,41 @@ const explicitDeepResearchFollowup = selectProgressiveTools(allTools, {
|
|
|
770
770
|
});
|
|
771
771
|
assert(names(explicitDeepResearchFollowup).includes("web_search"), "deep-research follow-up did not restore targeted recovery tools");
|
|
772
772
|
|
|
773
|
+
const scopedArtifactPrompt = `You are a persistent workspace agent. The surrounding policy mentions an evidence review.
|
|
774
|
+
AGINTI_EVIDENCE_SCOPE_JSON: {"mode":"task","request":"Create one plain-text artifact and verify it."}
|
|
775
|
+
Repository evidence to consult as relevant: literature review, evidence review, research report.`;
|
|
776
|
+
const scopedArtifactTools = selectProgressiveTools(allTools, {
|
|
777
|
+
config: { provider: "deepseek", progressiveTools: true },
|
|
778
|
+
goal: scopedArtifactPrompt,
|
|
779
|
+
profile: "auto",
|
|
780
|
+
messages: [
|
|
781
|
+
{ role: "user", content: scopedArtifactPrompt },
|
|
782
|
+
{
|
|
783
|
+
role: "user",
|
|
784
|
+
content: "Runtime snapshot: consult the surrounding literature review and evidence review policy before acting.",
|
|
785
|
+
},
|
|
786
|
+
],
|
|
787
|
+
});
|
|
788
|
+
assert(names(scopedArtifactTools).includes("write_file"), "scoped artifact task omitted write_file");
|
|
789
|
+
assert(
|
|
790
|
+
!(names(scopedArtifactTools).length === 2 && names(scopedArtifactTools)[0] === "deep_research"),
|
|
791
|
+
"surrounding policy prose incorrectly forced a scoped artifact task into deep research"
|
|
792
|
+
);
|
|
793
|
+
|
|
794
|
+
const scopedDeepResearchPrompt = `Generic workspace policy.
|
|
795
|
+
AGINTI_EVIDENCE_SCOPE_JSON: {"mode":"task","request":"Write a deep research evidence review comparing three primary papers."}`;
|
|
796
|
+
const scopedDeepResearchTools = selectProgressiveTools(allTools, {
|
|
797
|
+
config: { provider: "deepseek", progressiveTools: true },
|
|
798
|
+
goal: scopedDeepResearchPrompt,
|
|
799
|
+
profile: "auto",
|
|
800
|
+
messages: [{ role: "user", content: scopedDeepResearchPrompt }],
|
|
801
|
+
});
|
|
802
|
+
sameNames(
|
|
803
|
+
scopedDeepResearchTools,
|
|
804
|
+
["deep_research", "finish"],
|
|
805
|
+
"explicit deep research inside the scoped user request was not preserved"
|
|
806
|
+
);
|
|
807
|
+
|
|
773
808
|
const writingTools = selectProgressiveTools(allTools, {
|
|
774
809
|
config: { provider: "localllm" },
|
|
775
810
|
goal: "Draft and revise a chapter, then save it.",
|
package/scripts/smoke-web-api.js
CHANGED
|
@@ -10,7 +10,9 @@ import { WebDatabase } from "../src/web-db.js";
|
|
|
10
10
|
|
|
11
11
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
12
|
const fixtureMcpServer = path.join(repoRoot, "scripts", "fixtures", "mcp-stdio-smoke-server.mjs");
|
|
13
|
-
const
|
|
13
|
+
const fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-api-smoke-root-"));
|
|
14
|
+
const runtimeDir = path.join(fixtureRoot, "workspace");
|
|
15
|
+
await fs.mkdir(runtimeDir, { recursive: true });
|
|
14
16
|
const agintiflowHome = path.join(runtimeDir, ".agintiflow-home");
|
|
15
17
|
process.env.AGINTIFLOW_HOME = agintiflowHome;
|
|
16
18
|
const port = 43000 + Math.floor(Math.random() * 1000);
|
|
@@ -863,5 +865,5 @@ try {
|
|
|
863
865
|
} finally {
|
|
864
866
|
server.kill("SIGTERM");
|
|
865
867
|
await delay(150);
|
|
866
|
-
await fs.rm(
|
|
868
|
+
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
|
867
869
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { shouldStartWithDeepResearch } from "./research-routing.js";
|
|
2
|
+
import { hasAgintiEvidenceScope, scopedChatopsEvidenceGoal } from "./scs-evidence.js";
|
|
2
3
|
import {
|
|
3
4
|
INTEGRATION_TEXT_WORKSPACE_PROFILE_ID,
|
|
4
5
|
isIntegrationTextWorkspaceToolAllowed,
|
|
@@ -514,15 +515,17 @@ function textContent(content) {
|
|
|
514
515
|
}
|
|
515
516
|
|
|
516
517
|
function taskText(goal, config, messages) {
|
|
517
|
-
const
|
|
518
|
+
const rawGoal = goal || config.goal || "";
|
|
519
|
+
const scopedGoal = scopedChatopsEvidenceGoal(rawGoal);
|
|
520
|
+
const recentConversation = !hasAgintiEvidenceScope(rawGoal) && Array.isArray(messages)
|
|
518
521
|
? messages
|
|
519
522
|
.filter((message) => message && (message.role === "user" || message.role === "assistant"))
|
|
520
523
|
.slice(-6)
|
|
521
|
-
.map((message) => textContent(message.content))
|
|
524
|
+
.map((message) => scopedChatopsEvidenceGoal(textContent(message.content)))
|
|
522
525
|
.filter(Boolean)
|
|
523
526
|
.join("\n")
|
|
524
527
|
: "";
|
|
525
|
-
return `${
|
|
528
|
+
return `${scopedGoal}\n${recentConversation}`.trim().toLowerCase();
|
|
526
529
|
}
|
|
527
530
|
|
|
528
531
|
function currentTaskMessages(messages) {
|
package/src/research-routing.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { hasAgintiEvidenceScope, scopedChatopsEvidenceGoal } from "./scs-evidence.js";
|
|
2
|
+
|
|
1
3
|
function messageText(content) {
|
|
2
4
|
if (typeof content === "string") return content;
|
|
3
5
|
if (!Array.isArray(content)) return "";
|
|
@@ -5,12 +7,14 @@ function messageText(content) {
|
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
export function hasExplicitDeepResearchIntent(goal = "", messages = []) {
|
|
8
|
-
const recent =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const recent = hasAgintiEvidenceScope(goal)
|
|
11
|
+
? ""
|
|
12
|
+
: messages
|
|
13
|
+
.filter((message) => message?.role === "user")
|
|
14
|
+
.slice(-4)
|
|
15
|
+
.map((message) => scopedChatopsEvidenceGoal(messageText(message.content)))
|
|
16
|
+
.join("\n");
|
|
17
|
+
const text = `${scopedChatopsEvidenceGoal(goal)}\n${recent}`.toLowerCase();
|
|
14
18
|
return (
|
|
15
19
|
/\b(deep (?:web )?research|literature review|systematic review|multi[- ]source research|evidence review)\b/i.test(text) ||
|
|
16
20
|
/\b(research report|compare at least|independent (?:primary|scholarly|official) sources?)\b.{0,160}\b(primary|scholarly|papers?|pdf|citations?|evidence|sources?)\b/i.test(text) ||
|
package/src/scs-evidence.js
CHANGED
|
@@ -670,9 +670,27 @@ function stripForbiddenLanguage(goal = "") {
|
|
|
670
670
|
.replace(/禁止([^。\n;]+)/g, "");
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
-
function
|
|
674
|
-
const
|
|
675
|
-
|
|
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
|
+
|
|
687
|
+
export function hasAgintiEvidenceScope(goal = "") {
|
|
688
|
+
return Boolean(parseAgintiEvidenceScope(goal));
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
export function scopedChatopsEvidenceGoal(goal = "", taskProfile = "") {
|
|
692
|
+
const payload = parseAgintiEvidenceScope(goal);
|
|
693
|
+
if (!payload) {
|
|
676
694
|
const text = String(goal || "");
|
|
677
695
|
const lines = text
|
|
678
696
|
.split(/\r?\n/)
|
|
@@ -690,22 +708,32 @@ function scopedChatopsEvidenceGoal(goal = "", taskProfile = "") {
|
|
|
690
708
|
}
|
|
691
709
|
return text;
|
|
692
710
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const mode = String(payload.mode || "").trim().toLowerCase();
|
|
697
|
-
if (["chat-response", "host-managed-response", "plan-response", "read-only-answer"].includes(mode)) {
|
|
698
|
-
return "Answer the current chat turn directly without external execution.";
|
|
699
|
-
}
|
|
700
|
-
const request = String(payload.request || "").trim();
|
|
701
|
-
return request || String(goal || "");
|
|
702
|
-
} catch {
|
|
703
|
-
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.";
|
|
704
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
|
+
});
|
|
705
732
|
}
|
|
706
733
|
|
|
707
734
|
export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceCriteria = [] } = {}) {
|
|
708
735
|
const evidenceGoal = scopedChatopsEvidenceGoal(goal, taskProfile);
|
|
736
|
+
const artifactRoot = scopedArtifactRoot(goal);
|
|
709
737
|
const requirementCategories = inferRequirementCategories(evidenceGoal, taskProfile, acceptanceCriteria);
|
|
710
738
|
const requiredToolCalls = inferRequiredToolCalls(evidenceGoal);
|
|
711
739
|
const requiresExternalEvidence = requirementCategories.length > 0 || requiredToolCalls.length > 0 || goalRequiresEvidence(evidenceGoal, taskProfile);
|
|
@@ -714,8 +742,11 @@ export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceC
|
|
|
714
742
|
category,
|
|
715
743
|
description: CATEGORY_LABELS[category] || category,
|
|
716
744
|
}));
|
|
717
|
-
const
|
|
718
|
-
const
|
|
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
|
+
);
|
|
719
750
|
const declaredSourceRoots = inferDeclaredSourceRoots(evidenceGoal);
|
|
720
751
|
return {
|
|
721
752
|
version: 1,
|
|
@@ -725,6 +756,7 @@ export function deriveScsTaskContract({ goal = "", taskProfile = "", acceptanceC
|
|
|
725
756
|
requiredEvidence,
|
|
726
757
|
forbiddenActions: inferForbiddenActions(evidenceGoal),
|
|
727
758
|
exactOutputPaths,
|
|
759
|
+
artifactRoot,
|
|
728
760
|
exactInputPaths,
|
|
729
761
|
declaredSourceRoots,
|
|
730
762
|
readOnlyReadiness: isReadOnlyReadinessTask(evidenceGoal),
|
|
@@ -782,11 +814,12 @@ export function augmentScsTaskContractWithProjectVerification(contract = {}, sta
|
|
|
782
814
|
.map((item) => String(item?.path || item || "").trim())
|
|
783
815
|
.filter(Boolean)
|
|
784
816
|
).slice(0, 80);
|
|
785
|
-
const requiredOutputs = unique(
|
|
817
|
+
const requiredOutputs = unique(applyScopedArtifactRoot(
|
|
786
818
|
(Array.isArray(verification.requiredOutputs) ? verification.requiredOutputs : [])
|
|
787
819
|
.map((item) => String(item || "").trim())
|
|
788
|
-
.filter(Boolean)
|
|
789
|
-
|
|
820
|
+
.filter(Boolean),
|
|
821
|
+
String(contract.artifactRoot || "")
|
|
822
|
+
)).slice(0, 64);
|
|
790
823
|
const requiredProjectCommands = unique(
|
|
791
824
|
(Array.isArray(verification.requiredCommands) ? verification.requiredCommands : [])
|
|
792
825
|
.map(normalizeProjectCommand)
|