@voybio/ace-swarm 2.4.9 → 2.4.10
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/CHANGELOG.md +52 -14
- package/README.md +14 -10
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +23 -30
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +21 -30
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +1 -1
- package/assets/.agents/skills/learn-from-work/SKILL.md +41 -0
- package/assets/agent-state/ACE_WORKFLOW.md +25 -2
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +143 -2
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +2 -2
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +10 -0
- package/assets/eval-battery/battery.json +1 -1
- package/assets/instructions/ACE_Coder.instructions.md +9 -13
- package/assets/scripts/ace-hook-dispatch.mjs +16 -411
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +1 -2
- package/assets/vendor/README.md +9 -0
- package/assets/vendor/vericify-reader.mjs +272 -0
- package/assets/vendor/vericify-reader.provenance.json +10 -0
- package/dist/ace-autonomy.d.ts +58 -0
- package/dist/ace-autonomy.js +211 -6
- package/dist/ace-internal-tools.d.ts +1 -0
- package/dist/ace-internal-tools.js +3 -3
- package/dist/ace-server-instructions.d.ts +3 -3
- package/dist/ace-server-instructions.js +46 -192
- package/dist/cli.js +44 -6
- package/dist/experience-reflector.d.ts +7 -0
- package/dist/experience-reflector.js +39 -0
- package/dist/goal-engine.d.ts +64 -7
- package/dist/goal-engine.js +197 -41
- package/dist/handoff-registry.d.ts +10 -0
- package/dist/handoff-registry.js +59 -0
- package/dist/helpers/artifacts.d.ts +6 -2
- package/dist/helpers/artifacts.js +8 -6
- package/dist/helpers/bootstrap.js +13 -20
- package/dist/helpers/path-utils.js +2 -0
- package/dist/helpers/store-resolution.js +18 -3
- package/dist/helpers/workspace-root.d.ts +2 -0
- package/dist/helpers/workspace-root.js +9 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +1 -0
- package/dist/hermes/bridge-protocol.d.ts +1 -1
- package/dist/hermes/session-manager.d.ts +17 -0
- package/dist/hermes/session-manager.js +67 -14
- package/dist/host-goal-engine.d.ts +138 -0
- package/dist/host-goal-engine.js +793 -0
- package/dist/host-goal-status.d.ts +113 -0
- package/dist/host-goal-status.js +175 -0
- package/dist/host-learning.d.ts +68 -0
- package/dist/host-learning.js +115 -0
- package/dist/host-observation.d.ts +12 -0
- package/dist/host-observation.js +91 -0
- package/dist/host-plan-revision.d.ts +14 -0
- package/dist/host-plan-revision.js +101 -0
- package/dist/host-verification-job.d.ts +12 -0
- package/dist/host-verification-job.js +183 -0
- package/dist/host-work-context.d.ts +12 -0
- package/dist/host-work-context.js +8 -0
- package/dist/job-scheduler.d.ts +48 -14
- package/dist/job-scheduler.js +169 -23
- package/dist/job-worker.d.ts +3 -1
- package/dist/job-worker.js +10 -3
- package/dist/kanban.d.ts +4 -1
- package/dist/kanban.js +44 -16
- package/dist/learned-artifacts.d.ts +64 -0
- package/dist/learned-artifacts.js +321 -0
- package/dist/learning-controls.d.ts +142 -0
- package/dist/learning-controls.js +135 -0
- package/dist/learning-input-context.d.ts +9 -0
- package/dist/learning-input-context.js +62 -0
- package/dist/learning-lifecycle.d.ts +10 -0
- package/dist/learning-lifecycle.js +11 -0
- package/dist/learning-overlays.d.ts +3 -0
- package/dist/learning-overlays.js +17 -0
- package/dist/learning-policy.d.ts +40 -0
- package/dist/learning-policy.js +38 -0
- package/dist/learning-records.d.ts +35 -0
- package/dist/learning-records.js +17 -0
- package/dist/learning-scorecard.d.ts +82 -0
- package/dist/learning-scorecard.js +86 -0
- package/dist/learning-serving.d.ts +29 -0
- package/dist/learning-serving.js +134 -0
- package/dist/linked-work.d.ts +9 -0
- package/dist/linked-work.js +28 -0
- package/dist/local-model-runtime.js +1 -1
- package/dist/mcp-command-progress.d.ts +16 -0
- package/dist/mcp-command-progress.js +70 -0
- package/dist/model-bridge.d.ts +14 -13
- package/dist/model-bridge.js +73 -41
- package/dist/orchestrator-supervisor.d.ts +108 -6
- package/dist/orchestrator-supervisor.js +4 -32
- package/dist/plan-proposal.js +3 -3
- package/dist/playbook-curator.d.ts +1 -0
- package/dist/playbook-curator.js +11 -9
- package/dist/process-identity.d.ts +8 -0
- package/dist/process-identity.js +38 -0
- package/dist/progress-command.d.ts +34 -0
- package/dist/progress-command.js +153 -0
- package/dist/prompts.js +15 -15
- package/dist/resources.js +2 -2
- package/dist/runtime-command.d.ts +8 -1
- package/dist/runtime-command.js +48 -7
- package/dist/runtime-executor.js +33 -11
- package/dist/runtime-profile-syntax.d.ts +6 -0
- package/dist/runtime-profile-syntax.js +121 -0
- package/dist/runtime-profile.d.ts +37 -5
- package/dist/runtime-profile.js +36 -129
- package/dist/runtime-tool-specs.js +1 -1
- package/dist/safe-edit.d.ts +7 -3
- package/dist/safe-edit.js +40 -47
- package/dist/schemas.js +4 -2
- package/dist/server.d.ts +2 -16
- package/dist/server.js +14 -20
- package/dist/shared.d.ts +2 -0
- package/dist/shared.js +2 -0
- package/dist/skill-auditor.d.ts +19 -0
- package/dist/skill-auditor.js +32 -2
- package/dist/skill-catalog.d.ts +4 -1
- package/dist/skill-catalog.js +6 -5
- package/dist/store/ace-packed-store.d.ts +5 -1
- package/dist/store/ace-packed-store.js +33 -1
- package/dist/store/bootstrap-store.js +19 -12
- package/dist/store/cache-workspace.d.ts +8 -0
- package/dist/store/cache-workspace.js +94 -27
- package/dist/store/importer.js +11 -20
- package/dist/store/knowledge-bake.d.ts +3 -1
- package/dist/store/knowledge-bake.js +10 -1
- package/dist/store/legacy-vericify-posts.d.ts +8 -0
- package/dist/store/legacy-vericify-posts.js +76 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +2 -1
- package/dist/store/materializers/hook-context-materializer.js +6 -2
- package/dist/store/materializers/host-file-materializer.js +2 -2
- package/dist/store/materializers/projection-manager.d.ts +4 -1
- package/dist/store/materializers/projection-manager.js +10 -3
- package/dist/store/materializers/todo-syncer.d.ts +39 -20
- package/dist/store/materializers/todo-syncer.js +208 -110
- package/dist/store/materializers/vericify-projector.js +15 -26
- package/dist/store/repositories/goal-repository.d.ts +51 -2
- package/dist/store/repositories/goal-repository.js +114 -48
- package/dist/store/repositories/playbook-repository.d.ts +41 -3
- package/dist/store/repositories/playbook-repository.js +61 -5
- package/dist/store/repositories/todo-repository.d.ts +8 -2
- package/dist/store/repositories/todo-repository.js +1 -1
- package/dist/store/repositories/vericify-repository.d.ts +4 -0
- package/dist/store/repositories/vericify-repository.js +46 -0
- package/dist/store/skills-install.d.ts +1 -0
- package/dist/store/skills-install.js +20 -16
- package/dist/store/source-preservation.d.ts +24 -0
- package/dist/store/source-preservation.js +79 -0
- package/dist/store/store-artifacts.js +8 -1
- package/dist/store/test-write-boundary.d.ts +16 -0
- package/dist/store/test-write-boundary.js +175 -0
- package/dist/store/types.d.ts +5 -1
- package/dist/store/write-coordinator.js +16 -0
- package/dist/task-plan-context.d.ts +11 -0
- package/dist/task-plan-context.js +59 -0
- package/dist/todo-state.d.ts +19 -9
- package/dist/todo-state.js +204 -321
- package/dist/tools-agent.d.ts +1 -1
- package/dist/tools-agent.js +38 -62
- package/dist/tools-files.d.ts +0 -3
- package/dist/tools-files.js +21 -11
- package/dist/tools-framework.js +16 -25
- package/dist/tools-goal.d.ts +2 -4
- package/dist/tools-goal.js +119 -16
- package/dist/tools-handoff.js +28 -4
- package/dist/tools-lifecycle.js +1 -1
- package/dist/tools-memory.d.ts +0 -3
- package/dist/tools-memory.js +51 -6
- package/dist/tools-scheduler.js +19 -17
- package/dist/tools-todo.js +160 -148
- package/dist/vericify-bridge.d.ts +8 -0
- package/dist/vericify-bridge.js +18 -0
- package/dist/vericify-context.d.ts +4 -0
- package/dist/vericify-context.js +26 -5
- package/dist/vericify-native.d.ts +101 -0
- package/dist/vericify-native.js +221 -0
- package/dist/verification-worker.d.ts +2 -0
- package/dist/verification-worker.js +31 -0
- package/docs/mcp-tool-reference.md +44 -9
- package/package.json +19 -6
- package/scripts/dev/run-tests-isolated.mjs +165 -0
- package/scripts/dev/run_hermes_crispr_live.mjs +1 -0
- package/scripts/dev/test-isolation-guard.mjs +20 -0
- package/scripts/dev/test-preload.mjs +153 -0
- package/scripts/dev/test-source-inventory.mjs +31 -0
- package/docs/development.md +0 -46
package/dist/tools-agent.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { formatStepTaskForBridge } from "./task-plan-context.js";
|
|
1
2
|
/**
|
|
2
3
|
* Agent, skill, kernel, and task-pack tool registrations.
|
|
3
4
|
*/
|
|
@@ -6,7 +7,6 @@ import { type BridgeResult } from "./model-bridge.js";
|
|
|
6
7
|
import { proposePlan as proposePlanImpl, validatePlan as validatePlanImpl, loadAcceptanceTraceContract as loadAcceptanceTraceContractImpl } from "./plan-proposal.js";
|
|
7
8
|
import { type TaskPlan, type TaskStep } from "./orchestrator-supervisor.js";
|
|
8
9
|
export type { TaskPlan, TaskStep } from "./orchestrator-supervisor.js";
|
|
9
|
-
export declare function formatStepTaskForBridge(step: Pick<TaskStep, "task" | "upstream_outputs">): string;
|
|
10
10
|
type IntentVerificationOutcome = "ok" | "revisit_step" | "replan_required";
|
|
11
11
|
type IntentDriftReasonCode = "contract_missing" | "contract_invalid" | "bridge_output_malformed_json" | "role_drift_ui_off_topic" | "coder_artifact_stub" | "qa_rewrote_artifact" | "artifact_mismatch" | "forbidden_pattern" | "required_evidence_missing";
|
|
12
12
|
interface IntentVerificationResult {
|
package/dist/tools-agent.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
1
|
+
import { formatStepTaskForBridge } from "./task-plan-context.js";
|
|
2
|
+
export { formatStepTaskForBridge } from "./task-plan-context.js";
|
|
4
3
|
import { z } from "zod";
|
|
5
4
|
import { ALL_AGENTS, COMPOSABLE_AGENTS, SWARM_AGENTS, SWARM_SUBAGENT_MAP, classifyPathSource, getAgentInstructionPath, getAgentManifestPath, getKernelArtifactPath, isSwarmRole, listAvailableSkills, readAgentInstructions, readAgentManifest, readKernelArtifact, readSkillInstructions, readTaskArtifact, resolveWorkspaceRoot, } from "./helpers.js";
|
|
6
5
|
import { loadRuntimeProfile, readRuntimePromptTemplate, readRuntimeProfileState, validateRuntimeProfileContent, } from "./runtime-profile.js";
|
|
@@ -79,21 +78,6 @@ function extractHandoffId(text) {
|
|
|
79
78
|
const lineMatch = text.match(/handoff_id:\s*([A-Z0-9-]+)/i);
|
|
80
79
|
return lineMatch?.[1];
|
|
81
80
|
}
|
|
82
|
-
export function formatStepTaskForBridge(step) {
|
|
83
|
-
const upstreamOutputs = step.upstream_outputs ?? [];
|
|
84
|
-
if (upstreamOutputs.length === 0) {
|
|
85
|
-
return step.task;
|
|
86
|
-
}
|
|
87
|
-
const renderedOutputs = upstreamOutputs
|
|
88
|
-
.map((output) => `- ${output.step_id}: ${output.result_summary || "[no summary]"}${output.evidence_refs.length > 0 ? ` (evidence: ${output.evidence_refs.join(", ")})` : ""}`)
|
|
89
|
-
.join("\n");
|
|
90
|
-
return [
|
|
91
|
-
step.task,
|
|
92
|
-
"",
|
|
93
|
-
"Upstream outputs:",
|
|
94
|
-
renderedOutputs,
|
|
95
|
-
].join("\n");
|
|
96
|
-
}
|
|
97
81
|
// ── Re-export plan-proposal API ────────────────────────────────────────────
|
|
98
82
|
export { loadAcceptanceTraceContractImpl as loadAcceptanceTraceContract };
|
|
99
83
|
export { proposePlanImpl as proposePlan, validatePlanImpl as validatePlan };
|
|
@@ -658,7 +642,7 @@ export function registerAgentTools(server) {
|
|
|
658
642
|
server.tool("get_agent_instructions", "Load the full instruction file for a specific ACE agent role", {
|
|
659
643
|
role: ROLE_ENUM.describe("Which agent role to load"),
|
|
660
644
|
}, async ({ role }) => {
|
|
661
|
-
const content = readAgentInstructions(role);
|
|
645
|
+
const content = readAgentInstructions(role, { includeLearned: true });
|
|
662
646
|
const sourcePath = getAgentInstructionPath(role);
|
|
663
647
|
const source = classifyPathSource(sourcePath);
|
|
664
648
|
return {
|
|
@@ -1046,15 +1030,15 @@ export function registerAgentTools(server) {
|
|
|
1046
1030
|
max_turns: z
|
|
1047
1031
|
.number()
|
|
1048
1032
|
.int()
|
|
1049
|
-
.
|
|
1033
|
+
.nonnegative()
|
|
1050
1034
|
.optional()
|
|
1051
|
-
.describe("
|
|
1035
|
+
.describe("Explicit maximum turn allowance; 0 means unlimited (default)"),
|
|
1052
1036
|
turn_timeout_ms: z
|
|
1053
1037
|
.number()
|
|
1054
1038
|
.int()
|
|
1055
|
-
.
|
|
1039
|
+
.nonnegative()
|
|
1056
1040
|
.optional()
|
|
1057
|
-
.describe("
|
|
1041
|
+
.describe("Explicit per-turn deadline in milliseconds; 0 means unlimited (default)"),
|
|
1058
1042
|
auto_cleanup: z
|
|
1059
1043
|
.boolean()
|
|
1060
1044
|
.optional()
|
|
@@ -1152,7 +1136,7 @@ export function registerAgentTools(server) {
|
|
|
1152
1136
|
],
|
|
1153
1137
|
};
|
|
1154
1138
|
});
|
|
1155
|
-
server.tool("validate_plan", "Run shape checks against a PlanProposal (coverage, verification chain, tool-scope realism, acceptance criteria presence, stop conditions visibility). Returns { ok, score, blocking_findings, soft_findings }. Persists
|
|
1139
|
+
server.tool("validate_plan", "Run shape checks against a PlanProposal (coverage, verification chain, tool-scope realism, acceptance criteria presence, stop conditions visibility). Returns { ok, score, blocking_findings, soft_findings }. Persists an ACE transition record; legacy Vericify process posts require explicit opt-in.", {
|
|
1156
1140
|
plan_id: z.string().optional().describe("ID of a previously proposed plan to validate"),
|
|
1157
1141
|
proposal: z
|
|
1158
1142
|
.object({
|
|
@@ -1194,9 +1178,9 @@ export function registerAgentTools(server) {
|
|
|
1194
1178
|
max_turns: z
|
|
1195
1179
|
.number()
|
|
1196
1180
|
.int()
|
|
1197
|
-
.
|
|
1181
|
+
.nonnegative()
|
|
1198
1182
|
.optional()
|
|
1199
|
-
.describe("
|
|
1183
|
+
.describe("Explicit turn cap; 0/unset is unlimited for the native bridge. Hermes uses its adapter policy."),
|
|
1200
1184
|
tier: z
|
|
1201
1185
|
.enum(["auto", "full", "compressed", "brief"])
|
|
1202
1186
|
.optional()
|
|
@@ -1348,9 +1332,9 @@ export function registerAgentTools(server) {
|
|
|
1348
1332
|
max_turns_per_step: z
|
|
1349
1333
|
.number()
|
|
1350
1334
|
.int()
|
|
1351
|
-
.
|
|
1335
|
+
.nonnegative()
|
|
1352
1336
|
.optional()
|
|
1353
|
-
.describe("
|
|
1337
|
+
.describe("Explicit child bridge turn cap; 0/unset is unlimited"),
|
|
1354
1338
|
provider: z
|
|
1355
1339
|
.string()
|
|
1356
1340
|
.optional()
|
|
@@ -1483,7 +1467,7 @@ export function registerAgentTools(server) {
|
|
|
1483
1467
|
role: step.role,
|
|
1484
1468
|
workspace: runtime.workspaceRoot,
|
|
1485
1469
|
tier: resolveTier(undefined, runtime.provider, runtime.model, step.role),
|
|
1486
|
-
maxTurns: max_turns_per_step ??
|
|
1470
|
+
maxTurns: max_turns_per_step ?? 0,
|
|
1487
1471
|
provider: runtime.provider,
|
|
1488
1472
|
model: runtime.model,
|
|
1489
1473
|
toolScope: step.tool_scope,
|
|
@@ -1549,11 +1533,13 @@ export function registerAgentTools(server) {
|
|
|
1549
1533
|
},
|
|
1550
1534
|
async getVericifyContext() {
|
|
1551
1535
|
return tryVericifyPacket(() => getVericifyContextPacket({
|
|
1536
|
+
mode: "configured",
|
|
1552
1537
|
workspaceRoot: effectiveWorkspaceRoot,
|
|
1553
1538
|
}), (message) => appendUniqueNote(vericifyWarnings, `Vericify context unavailable for ${plan.plan_id}: ${message}`));
|
|
1554
1539
|
},
|
|
1555
1540
|
async getVericifyDelta(since) {
|
|
1556
1541
|
return tryVericifyPacket(() => getVericifyDelta({
|
|
1542
|
+
mode: "configured",
|
|
1557
1543
|
since,
|
|
1558
1544
|
workspaceRoot: effectiveWorkspaceRoot,
|
|
1559
1545
|
}), (message) => appendUniqueNote(vericifyWarnings, `Vericify delta unavailable for ${plan.plan_id}: ${message}`));
|
|
@@ -1680,7 +1666,8 @@ export function registerAgentTools(server) {
|
|
|
1680
1666
|
],
|
|
1681
1667
|
};
|
|
1682
1668
|
});
|
|
1683
|
-
server.tool("get_vericify_context", "
|
|
1669
|
+
server.tool("get_vericify_context", "Read configured native Vericify metadata, or explicitly request legacy context compatibility", {
|
|
1670
|
+
mode: z.enum(["configured", "legacy"]).optional().describe("Defaults to configured; legacy explicitly enables historical API discovery"),
|
|
1684
1671
|
run_id: z
|
|
1685
1672
|
.string()
|
|
1686
1673
|
.optional()
|
|
@@ -1689,9 +1676,10 @@ export function registerAgentTools(server) {
|
|
|
1689
1676
|
.string()
|
|
1690
1677
|
.optional()
|
|
1691
1678
|
.describe("Optional workspace root override used to locate the Vericify workspace"),
|
|
1692
|
-
}, async ({ run_id, workspace_root }) => {
|
|
1679
|
+
}, async ({ run_id, workspace_root, mode }) => {
|
|
1693
1680
|
try {
|
|
1694
1681
|
const packet = await getVericifyContextPacket({
|
|
1682
|
+
mode: mode ?? "configured",
|
|
1695
1683
|
runId: run_id,
|
|
1696
1684
|
workspaceRoot: workspace_root,
|
|
1697
1685
|
});
|
|
@@ -1716,7 +1704,8 @@ export function registerAgentTools(server) {
|
|
|
1716
1704
|
};
|
|
1717
1705
|
}
|
|
1718
1706
|
});
|
|
1719
|
-
server.tool("get_vericify_delta", "
|
|
1707
|
+
server.tool("get_vericify_delta", "Read a configured native delta, or explicitly request a legacy vcx/checkpoint delta", {
|
|
1708
|
+
mode: z.enum(["configured", "legacy"]).optional().describe("Defaults to configured; legacy explicitly enables historical API discovery"),
|
|
1720
1709
|
since: z
|
|
1721
1710
|
.string()
|
|
1722
1711
|
.describe("Required prior vcx cursor or compatible checkpoint reference"),
|
|
@@ -1728,9 +1717,10 @@ export function registerAgentTools(server) {
|
|
|
1728
1717
|
.string()
|
|
1729
1718
|
.optional()
|
|
1730
1719
|
.describe("Optional workspace root override used to locate the Vericify workspace"),
|
|
1731
|
-
}, async ({ since, run_id, workspace_root }) => {
|
|
1720
|
+
}, async ({ since, run_id, workspace_root, mode }) => {
|
|
1732
1721
|
try {
|
|
1733
1722
|
const delta = await getVericifyDelta({
|
|
1723
|
+
mode: mode ?? "configured",
|
|
1734
1724
|
since,
|
|
1735
1725
|
runId: run_id,
|
|
1736
1726
|
workspaceRoot: workspace_root,
|
|
@@ -2294,9 +2284,15 @@ export function registerAgentTools(server) {
|
|
|
2294
2284
|
});
|
|
2295
2285
|
server.tool("get_skill_instructions", "Load SKILL.md for a specific ACE skill", {
|
|
2296
2286
|
name: z.string().describe("Skill name (e.g., codemunch, codesnipe)"),
|
|
2297
|
-
}, async ({ name }) => {
|
|
2287
|
+
}, async ({ name }, extra) => {
|
|
2298
2288
|
const skills = listAvailableSkills();
|
|
2299
2289
|
const match = skills.find((skill) => skill.name.toLowerCase() === name.trim().toLowerCase());
|
|
2290
|
+
const { getHostBinding } = await import('./host-work-context.js');
|
|
2291
|
+
const binding = getHostBinding(extra.sessionId);
|
|
2292
|
+
if (match && binding?.goal_id && binding.step_id && binding.attempt) {
|
|
2293
|
+
const { recordSkillUse } = await import('./learning-serving.js');
|
|
2294
|
+
await recordSkillUse(resolveWorkspaceRoot(), { goal_id: binding.goal_id, step_id: binding.step_id, attempt: binding.attempt, agent: binding.agent }, match.name);
|
|
2295
|
+
}
|
|
2300
2296
|
const prefix = match
|
|
2301
2297
|
? `# Skill: ${match.name}\n\nSource: ${match.source} (${match.path})\n\n`
|
|
2302
2298
|
: `# Skill: ${name}\n\n`;
|
|
@@ -2304,7 +2300,7 @@ export function registerAgentTools(server) {
|
|
|
2304
2300
|
content: [
|
|
2305
2301
|
{
|
|
2306
2302
|
type: "text",
|
|
2307
|
-
text: `${prefix}${readSkillInstructions(name)}`,
|
|
2303
|
+
text: `${prefix}${readSkillInstructions(name, { includeLearned: true })}`,
|
|
2308
2304
|
},
|
|
2309
2305
|
],
|
|
2310
2306
|
};
|
|
@@ -2350,33 +2346,13 @@ export function registerAgentTools(server) {
|
|
|
2350
2346
|
failure_pattern: z.string().describe("What went wrong"),
|
|
2351
2347
|
guardrail: z.string().describe("Rule to prevent recurrence"),
|
|
2352
2348
|
verification_check: z.string().describe("How to verify compliance"),
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
"tool_timeout",
|
|
2361
|
-
"role_contract_violation",
|
|
2362
|
-
];
|
|
2363
|
-
const scope = {};
|
|
2364
|
-
const lowered = failure_pattern.toLowerCase();
|
|
2365
|
-
const reason = knownReasonCodes.find((code) => lowered.includes(code));
|
|
2366
|
-
if (reason)
|
|
2367
|
-
scope.reason_code = reason;
|
|
2368
|
-
const root = resolveWorkspaceRoot();
|
|
2369
|
-
const bullet = new PlaybookRepository(root).createBullet({
|
|
2370
|
-
section: "failure_modes",
|
|
2371
|
-
scope,
|
|
2372
|
-
content: `${guardrail} Verify: ${verification_check}`,
|
|
2373
|
-
evidence_refs: [],
|
|
2374
|
-
provenance: { source: "operator" },
|
|
2375
|
-
});
|
|
2376
|
-
const path = materializePlaybookMarkdown(root);
|
|
2377
|
-
return {
|
|
2378
|
-
content: [{ type: "text", text: `✅ Lesson recorded as ${bullet.bullet_id} (${bullet.status}) in ${path}. Context: ${context}` }],
|
|
2379
|
-
};
|
|
2349
|
+
evidence_refs: z.array(z.string()).optional(),
|
|
2350
|
+
step_ref: z.object({ goal_id: z.string(), step_id: z.string() }).optional(),
|
|
2351
|
+
paths: z.array(z.string()).optional(),
|
|
2352
|
+
}, async ({ context, failure_pattern, guardrail, verification_check, evidence_refs, step_ref, paths }) => {
|
|
2353
|
+
const { addHostLesson } = await import('./host-learning.js');
|
|
2354
|
+
const result = await addHostLesson(resolveWorkspaceRoot(), { context, failure_pattern, guardrail, verification_check, evidence_refs, step_ref, paths });
|
|
2355
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }], structuredContent: result };
|
|
2380
2356
|
});
|
|
2381
2357
|
// ── CLI Work Split ────────────────────────────────────────────────
|
|
2382
2358
|
server.tool("get_cli_split", "Get the CLI work split contract (Codex vs Gemini routing)", {}, async () => ({
|
package/dist/tools-files.d.ts
CHANGED
package/dist/tools-files.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { commandPolicySchema, withMcpCommandProgress } from "./mcp-command-progress.js";
|
|
2
|
+
import { formatKanbanRefresh } from "./kanban.js";
|
|
1
3
|
/**
|
|
2
4
|
* File operation tool registrations + new safe-edit and diff tools.
|
|
3
5
|
*/
|
|
@@ -1047,13 +1049,16 @@ export function registerFileTools(server) {
|
|
|
1047
1049
|
let todoStateSuffix = "";
|
|
1048
1050
|
if (normalizedPath === `${ACE_TASKS_ROOT_REL}/todo.md`) {
|
|
1049
1051
|
const synced = await syncTodoStateSafe(content);
|
|
1050
|
-
todoStateSuffix = `\nTODO state synced: ${synced.path}`;
|
|
1052
|
+
todoStateSuffix = `\nTODO state synced: ${synced.path}${synced.import_warnings.map((warning) => `\nImport warning: ${warning}`).join("")}${synced.projection_pending ? "\nTodo markdown refresh pending." : ""}`;
|
|
1051
1053
|
}
|
|
1052
1054
|
const storeFallbackKeys = resolveStoreFallbackKeysForPath(normalizedPath);
|
|
1053
1055
|
const useAsyncStoreAdmission = storeFallbackKeys.length > 0 && workspaceRoot === WORKSPACE_ROOT;
|
|
1054
1056
|
// Keep the file as a materialized projection after the canonical store update.
|
|
1055
1057
|
let abs;
|
|
1056
|
-
if (
|
|
1058
|
+
if (normalizedPath === `${ACE_TASKS_ROOT_REL}/todo.md`) {
|
|
1059
|
+
abs = targetPath; // The todo owner already committed and projected this import.
|
|
1060
|
+
}
|
|
1061
|
+
else if (useAsyncStoreAdmission) {
|
|
1057
1062
|
abs = await safeWriteAsync(path, content);
|
|
1058
1063
|
}
|
|
1059
1064
|
else if (workspaceRoot === WORKSPACE_ROOT) {
|
|
@@ -1068,7 +1073,7 @@ export function registerFileTools(server) {
|
|
|
1068
1073
|
const shouldRefreshKanban = shouldAutoRefreshKanbanForPath(normalizedPath);
|
|
1069
1074
|
if (shouldRefreshKanban) {
|
|
1070
1075
|
const kanban = refreshKanbanArtifacts(`tool:write_workspace_file:${normalizedPath}`);
|
|
1071
|
-
kanbanSuffix = `\
|
|
1076
|
+
kanbanSuffix = `\n${formatKanbanRefresh(kanban)}\nKanban counts: backlog=${kanban.counts.backlog}, blocked=${kanban.counts.blocked}, in_progress=${kanban.counts.in_progress}, gated=${kanban.counts.gated}, done=${kanban.counts.done}`;
|
|
1072
1077
|
}
|
|
1073
1078
|
const runLedger = await appendRunLedgerEntrySafe({
|
|
1074
1079
|
tool: "write_workspace_file",
|
|
@@ -1165,6 +1170,7 @@ export function registerFileTools(server) {
|
|
|
1165
1170
|
.string()
|
|
1166
1171
|
.optional()
|
|
1167
1172
|
.describe("Shell command for tests (e.g. 'npm test')"),
|
|
1173
|
+
command_policy: commandPolicySchema.optional(),
|
|
1168
1174
|
backup: z
|
|
1169
1175
|
.boolean()
|
|
1170
1176
|
.optional()
|
|
@@ -1173,15 +1179,16 @@ export function registerFileTools(server) {
|
|
|
1173
1179
|
.string()
|
|
1174
1180
|
.optional()
|
|
1175
1181
|
.describe("Optional source precondition checked immediately before promotion; prefer full sha256:<hex>"),
|
|
1176
|
-
}, async ({ path, content, validation_command, test_command, backup, expected_base_hash }) => {
|
|
1177
|
-
const result = safeEditFile({
|
|
1182
|
+
}, async ({ path, content, validation_command, test_command, backup, expected_base_hash, command_policy }, extra) => {
|
|
1183
|
+
const result = await withMcpCommandProgress(extra, "safe_edit_file checks", (onProgress, workSignal) => safeEditFile({
|
|
1178
1184
|
path,
|
|
1179
1185
|
content,
|
|
1180
1186
|
expected_base_hash,
|
|
1181
1187
|
validation_command,
|
|
1182
1188
|
test_command,
|
|
1183
1189
|
backup,
|
|
1184
|
-
|
|
1190
|
+
command_policy: { ...command_policy, signal: workSignal, onProgress },
|
|
1191
|
+
}), () => Boolean(server.server?.transport));
|
|
1185
1192
|
const ledger = await appendRunLedgerEntrySafe({
|
|
1186
1193
|
tool: "safe_edit_file",
|
|
1187
1194
|
category: result.ok ? "major_update" : "regression",
|
|
@@ -1605,8 +1612,9 @@ export function registerFileTools(server) {
|
|
|
1605
1612
|
confirm_multi_file: z.boolean().optional().describe("Deprecated; multi-file rewrites are always refused"),
|
|
1606
1613
|
validation_command: z.string().optional().describe("Shell command to validate the staged rewrite before promotion"),
|
|
1607
1614
|
test_command: z.string().optional().describe("Shell command to test the staged rewrite before promotion"),
|
|
1615
|
+
command_policy: commandPolicySchema.optional(),
|
|
1608
1616
|
session_id: z.string().optional().describe("Optional runtime session id for transition-record emission"),
|
|
1609
|
-
}, async ({ plan_id, pattern, rewrite, lang, scope, validation_command, test_command, session_id }) => {
|
|
1617
|
+
}, async ({ plan_id, pattern, rewrite, lang, scope, validation_command, test_command, session_id, command_policy }, extra) => {
|
|
1610
1618
|
let compiledPlan;
|
|
1611
1619
|
if (plan_id) {
|
|
1612
1620
|
compiledPlan = loadStructuralEditPlan(plan_id);
|
|
@@ -1700,13 +1708,14 @@ export function registerFileTools(server) {
|
|
|
1700
1708
|
isError: true,
|
|
1701
1709
|
};
|
|
1702
1710
|
}
|
|
1703
|
-
const safeResult = safeEditFile({
|
|
1711
|
+
const safeResult = await withMcpCommandProgress(extra, "astgrep_rewrite checks", (onProgress, workSignal) => safeEditFile({
|
|
1704
1712
|
path: compiledPlan.target.file,
|
|
1705
1713
|
content: preview.rewritten_content,
|
|
1706
1714
|
expected_base_hash: compiledPlan.target.file_hash,
|
|
1707
1715
|
validation_command: validation_command ?? compiledPlan.validation_command,
|
|
1708
1716
|
test_command: test_command ?? compiledPlan.test_command,
|
|
1709
|
-
|
|
1717
|
+
command_policy: { ...command_policy, signal: workSignal, onProgress },
|
|
1718
|
+
}), () => Boolean(server.server?.transport));
|
|
1710
1719
|
if (!safeResult.ok) {
|
|
1711
1720
|
await appendAstgrepRewriteTransition(session_id, "failed", `astgrep_rewrite failed before promotion for ${compiledPlan.target.file}: ${safeResult.error ?? "unknown error"}`, [compiledPlan.artifact_path, preview.artifact.artifact_path, compiledPlan.target.file]);
|
|
1712
1721
|
return {
|
|
@@ -1749,13 +1758,14 @@ export function registerFileTools(server) {
|
|
|
1749
1758
|
};
|
|
1750
1759
|
});
|
|
1751
1760
|
server.tool("apply_patch", "Apply a unified diff patch to a workspace file. Applies the patch to staged content, runs optional validation/tests, and promotes to the target only on success. Cost: moderate.", {
|
|
1761
|
+
command_policy: commandPolicySchema.optional(),
|
|
1752
1762
|
path: z.string().describe("Workspace-relative file path to patch"),
|
|
1753
1763
|
patch: z.string().describe("Unified diff patch (output of diff -u or similar)"),
|
|
1754
1764
|
expected_base_hash: z.string().optional().describe("Optional source precondition checked immediately before promotion; prefer full sha256:<hex>"),
|
|
1755
1765
|
validation_command: z.string().optional().describe("Shell command to validate after applying (e.g. 'npx tsc --noEmit')"),
|
|
1756
1766
|
test_command: z.string().optional().describe("Shell command to run tests after applying"),
|
|
1757
|
-
}, async ({ path: relPath, patch, expected_base_hash, validation_command, test_command }) => {
|
|
1758
|
-
const result = applyPatch({ path: relPath, patch, expected_base_hash, validation_command, test_command });
|
|
1767
|
+
}, async ({ path: relPath, patch, expected_base_hash, validation_command, test_command, command_policy }, extra) => {
|
|
1768
|
+
const result = await withMcpCommandProgress(extra, "apply_patch checks", (onProgress, workSignal) => applyPatch({ path: relPath, patch, expected_base_hash, validation_command, test_command, command_policy: { ...command_policy, signal: workSignal, onProgress } }), () => Boolean(server.server?.transport));
|
|
1759
1769
|
if (!result.ok) {
|
|
1760
1770
|
return {
|
|
1761
1771
|
content: [{ type: "text", text: `apply_patch failed: ${result.error ?? "unknown error"}\n${result.validation_output ?? ""}` }],
|
package/dist/tools-framework.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* plus new run_tests and validate_framework tools.
|
|
4
|
-
*/
|
|
1
|
+
import { commandPolicySchema, withMcpCommandProgress } from "./mcp-command-progress.js";
|
|
2
|
+
import { resolveCurrentWork, formatCurrentWork } from "./ace-autonomy.js";
|
|
5
3
|
import { z } from "zod";
|
|
6
4
|
import { bootstrapStoreWorkspace } from "./store/bootstrap-store.js";
|
|
7
5
|
import { ACE_ROOT_REL, ACE_TASKS_ROOT_REL, ALL_MCP_CLIENTS, ALL_LLM_PROVIDERS, ALL_AGENTS, COMPOSABLE_AGENTS, SWARM_AGENTS, SWARM_SUBAGENT_MAP, WORKSPACE_ROOT, classifyPathSource, detectAssetDrift, getAllMcpServerConfigSnippets, getAgentInstructionPath, getAgentManifestPath, getKernelArtifactPath, getMcpClientInstallHint, getMcpServerConfigSnippet, getTaskArtifactPath, isSwarmRole, listAvailableSkills, normalizePathForValidation, resolveWorkspaceRoot, safeRead, safeWriteAsync, withFileLock, wsPath, } from "./helpers.js";
|
|
@@ -123,11 +121,11 @@ function hasArtifactEvidence(reference) {
|
|
|
123
121
|
return !content.startsWith("[FILE NOT FOUND]") && !content.startsWith("[ACCESS DENIED]");
|
|
124
122
|
});
|
|
125
123
|
}
|
|
126
|
-
function evaluateGateTargets(targets) {
|
|
124
|
+
async function evaluateGateTargets(targets, policy = {}) {
|
|
127
125
|
const results = [];
|
|
128
126
|
for (const gate of targets) {
|
|
129
127
|
if (gate.type === "executable" && gate.command.trim().length > 0) {
|
|
130
|
-
const testResult = runTestSuite(gate.command);
|
|
128
|
+
const testResult = await runTestSuite(gate.command, policy);
|
|
131
129
|
results.push({
|
|
132
130
|
id: gate.id,
|
|
133
131
|
type: gate.type,
|
|
@@ -545,7 +543,6 @@ export function registerFrameworkTools(server) {
|
|
|
545
543
|
structuredContent: {
|
|
546
544
|
detected_domain: detected,
|
|
547
545
|
suggested_execution_role: executionRoleForDomain(detected),
|
|
548
|
-
default_entry_agent: "orchestrator",
|
|
549
546
|
task_contract_ok: taskContract.ok,
|
|
550
547
|
},
|
|
551
548
|
content: [
|
|
@@ -559,11 +556,7 @@ export function registerFrameworkTools(server) {
|
|
|
559
556
|
`**Primary Swarm Agent(s):** ${activeRoute.swarm_agents
|
|
560
557
|
.map((agent) => `ACE-${getRoleTitle(agent)}`)
|
|
561
558
|
.join(", ")}`,
|
|
562
|
-
"**Default Entry Agent:** ACE-Orchestrator",
|
|
563
|
-
"**Hierarchy Rule:** Top-level work starts with ACE-Orchestrator. VOS, UI, and Coders are delegated specialists, not peer replacements.",
|
|
564
|
-
`**Preflight Owner:** ACE-Orchestrator`,
|
|
565
559
|
`**Task Contract:** ${taskContract.ok ? "aligned" : "attention required"}`,
|
|
566
|
-
`**Composable Subagents (Universal):** ${[...COMPOSABLE_AGENTS].join(", ")}`,
|
|
567
560
|
`**Recommended Delegated Subagents:** ${[...recommendedSubagents].join(", ")}`,
|
|
568
561
|
`**Pipeline:** ${activeRoute.pipeline}`,
|
|
569
562
|
`**Recommended Prompt:** ${activeRoute.prompt}`,
|
|
@@ -579,16 +572,9 @@ export function registerFrameworkTools(server) {
|
|
|
579
572
|
]
|
|
580
573
|
: []),
|
|
581
574
|
"",
|
|
582
|
-
"##
|
|
583
|
-
|
|
584
|
-
"
|
|
585
|
-
"3. Route ambiguity or contract drift through skeptic/validation before handoff.",
|
|
586
|
-
"",
|
|
587
|
-
"## Next Steps",
|
|
588
|
-
`1. Activate prompt: \`${activeRoute.prompt}\``,
|
|
589
|
-
"2. Run `validate_framework` and inspect current ACE state before cross-role dispatch.",
|
|
590
|
-
"3. Load shared kernel context with `get_kernel_artifact` (`directive_kernel`, `agent_registry`)",
|
|
591
|
-
"4. Generate a structured handoff with `create_handoff` only after preflight clears",
|
|
575
|
+
"## Next",
|
|
576
|
+
formatCurrentWork(resolveCurrentWork(), "block"),
|
|
577
|
+
"Role, pipeline, prompt and skill suggestions above are optional aids for this work.",
|
|
592
578
|
]
|
|
593
579
|
.filter(Boolean)
|
|
594
580
|
.join("\n"),
|
|
@@ -927,12 +913,13 @@ export function registerFrameworkTools(server) {
|
|
|
927
913
|
});
|
|
928
914
|
// ── Run Tests (new P0 tool) ───────────────────────────────────────
|
|
929
915
|
server.tool("run_tests", "Execute the project test suite and report results", {
|
|
916
|
+
...commandPolicySchema.shape,
|
|
930
917
|
command: z
|
|
931
918
|
.string()
|
|
932
919
|
.optional()
|
|
933
920
|
.describe("Custom test command (auto-detected from package.json if omitted)"),
|
|
934
|
-
}, async ({ command }) => {
|
|
935
|
-
const result = runTestSuite(command);
|
|
921
|
+
}, async ({ command, stall_min, kill_min, deadline_min }, extra) => {
|
|
922
|
+
const result = await withMcpCommandProgress(extra, "run_tests", (onProgress, workSignal) => runTestSuite(command, { stall_min, kill_min, deadline_min, signal: workSignal, onProgress }), () => Boolean(server.server?.transport));
|
|
936
923
|
appendStatusEventSafe({
|
|
937
924
|
source_module: "capability-safety",
|
|
938
925
|
event_type: result.ok ? "TESTS_PASSED" : "TESTS_FAILED",
|
|
@@ -956,6 +943,7 @@ export function registerFrameworkTools(server) {
|
|
|
956
943
|
},
|
|
957
944
|
});
|
|
958
945
|
return {
|
|
946
|
+
structuredContent: { ...result },
|
|
959
947
|
content: [
|
|
960
948
|
{
|
|
961
949
|
type: "text",
|
|
@@ -964,6 +952,7 @@ export function registerFrameworkTools(server) {
|
|
|
964
952
|
`Command: ${result.command}`,
|
|
965
953
|
`Exit code: ${result.exit_code}`,
|
|
966
954
|
`Duration: ${result.duration_ms}ms`,
|
|
955
|
+
...(result.reason_code ? [`Reason: ${result.reason_code}`] : []),
|
|
967
956
|
`Run ledger: ${ledger.path} (${ledger.entry.id})`,
|
|
968
957
|
"",
|
|
969
958
|
"```",
|
|
@@ -1444,6 +1433,7 @@ export function registerFrameworkTools(server) {
|
|
|
1444
1433
|
});
|
|
1445
1434
|
// ── Execute Gates (manifest-driven gate runner) ───────────────────
|
|
1446
1435
|
server.tool("execute_gates", "Run quality gates from agent-state/MODULES/gates/*.json manifests (single source of truth)", {
|
|
1436
|
+
command_policy: commandPolicySchema.optional(),
|
|
1447
1437
|
gate_ids: z
|
|
1448
1438
|
.array(z.string())
|
|
1449
1439
|
.optional()
|
|
@@ -1456,7 +1446,7 @@ export function registerFrameworkTools(server) {
|
|
|
1456
1446
|
.string()
|
|
1457
1447
|
.optional()
|
|
1458
1448
|
.describe("Optional short focus string persisted with skeptic adversarial review evidence."),
|
|
1459
|
-
}, async ({ gate_ids, review_mode, review_focus }) => {
|
|
1449
|
+
}, async ({ gate_ids, review_mode, review_focus, command_policy }, extra) => {
|
|
1460
1450
|
const gatesDir = wsPath("agent-state", "MODULES", "gates");
|
|
1461
1451
|
const resolved = resolveGateManifests(gatesDir);
|
|
1462
1452
|
const allGates = resolved.gates;
|
|
@@ -1556,7 +1546,7 @@ export function registerFrameworkTools(server) {
|
|
|
1556
1546
|
};
|
|
1557
1547
|
}
|
|
1558
1548
|
const gateArtifactRefs = targets.map((gate) => gate.source_ref ?? manifestEvidenceRef);
|
|
1559
|
-
const results = evaluateGateTargets(targets);
|
|
1549
|
+
const results = await withMcpCommandProgress(extra, "execute_gates", (onProgress, workSignal) => evaluateGateTargets(targets, { ...command_policy, signal: workSignal, onProgress }), () => Boolean(server.server?.transport));
|
|
1560
1550
|
const passed = results.filter((r) => r.ok).length;
|
|
1561
1551
|
const failed = results.filter((r) => !r.ok).length;
|
|
1562
1552
|
const review = review_mode === "skeptic_adversarial"
|
|
@@ -1646,6 +1636,7 @@ export function registerFrameworkTools(server) {
|
|
|
1646
1636
|
},
|
|
1647
1637
|
});
|
|
1648
1638
|
return {
|
|
1639
|
+
structuredContent: { ok: allOk, results },
|
|
1649
1640
|
content: [
|
|
1650
1641
|
{
|
|
1651
1642
|
type: "text",
|
package/dist/tools-goal.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ACE Goal Engine tool registrations (WS-F).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* goal: they compile/prepare, then hand execution to a detached `ace goal run`
|
|
7
|
-
* child and return immediately. The host polls `get_goal_status`.
|
|
4
|
+
* Engine goals delegate to the existing detached runner. Host goals return
|
|
5
|
+
* assignments to the connected participant and never invoke that executor.
|
|
8
6
|
*/
|
|
9
7
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
8
|
export declare function registerGoalTools(server: McpServer): void;
|