ace-swarm 2.2.0 → 2.3.0
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 -1
- package/README.md +86 -40
- package/assets/.github/hooks/ace-copilot.json +16 -16
- package/assets/agent-state/MODULES/schemas/VERICIFY_PROCESS_POST_LOG.schema.json +1 -0
- package/assets/scripts/ace-hook-dispatch.mjs +447 -0
- package/assets/scripts/copilot-hook-dispatch.mjs +1 -303
- package/assets/scripts/render-mcp-configs.sh +328 -1
- package/dist/ace-context.d.ts +29 -0
- package/dist/ace-context.d.ts.map +1 -0
- package/dist/ace-context.js +240 -0
- package/dist/ace-context.js.map +1 -0
- package/dist/ace-internal-tools.d.ts +8 -0
- package/dist/ace-internal-tools.d.ts.map +1 -0
- package/dist/ace-internal-tools.js +76 -0
- package/dist/ace-internal-tools.js.map +1 -0
- package/dist/ace-server-instructions.d.ts +12 -0
- package/dist/ace-server-instructions.d.ts.map +1 -0
- package/dist/ace-server-instructions.js +299 -0
- package/dist/ace-server-instructions.js.map +1 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +90 -0
- package/dist/helpers.js.map +1 -1
- package/dist/internal-tool-runtime.d.ts +21 -0
- package/dist/internal-tool-runtime.d.ts.map +1 -0
- package/dist/internal-tool-runtime.js +136 -0
- package/dist/internal-tool-runtime.js.map +1 -0
- package/dist/local-model-runtime.d.ts +36 -0
- package/dist/local-model-runtime.d.ts.map +1 -0
- package/dist/local-model-runtime.js +161 -0
- package/dist/local-model-runtime.js.map +1 -0
- package/dist/model-bridge.d.ts +54 -0
- package/dist/model-bridge.d.ts.map +1 -0
- package/dist/model-bridge.js +587 -0
- package/dist/model-bridge.js.map +1 -0
- package/dist/orchestrator-supervisor.d.ts +100 -0
- package/dist/orchestrator-supervisor.d.ts.map +1 -0
- package/dist/orchestrator-supervisor.js +399 -0
- package/dist/orchestrator-supervisor.js.map +1 -0
- package/dist/runtime-executor.d.ts.map +1 -1
- package/dist/runtime-executor.js +5 -42
- package/dist/runtime-executor.js.map +1 -1
- package/dist/schemas.js +1 -1
- package/dist/schemas.js.map +1 -1
- package/dist/server.d.ts +5 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +9 -1
- package/dist/server.js.map +1 -1
- package/dist/shared.d.ts +3 -3
- package/dist/tools-agent.d.ts +1 -0
- package/dist/tools-agent.d.ts.map +1 -1
- package/dist/tools-agent.js +456 -1
- package/dist/tools-agent.js.map +1 -1
- package/dist/tui/agent-runner.d.ts +6 -0
- package/dist/tui/agent-runner.d.ts.map +1 -1
- package/dist/tui/agent-runner.js +15 -1
- package/dist/tui/agent-runner.js.map +1 -1
- package/dist/tui/agent-worker.d.ts +3 -1
- package/dist/tui/agent-worker.d.ts.map +1 -1
- package/dist/tui/agent-worker.js +117 -9
- package/dist/tui/agent-worker.js.map +1 -1
- package/dist/tui/chat.d.ts +19 -0
- package/dist/tui/chat.d.ts.map +1 -1
- package/dist/tui/chat.js +108 -0
- package/dist/tui/chat.js.map +1 -1
- package/dist/tui/index.d.ts +1 -0
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +3 -0
- package/dist/tui/index.js.map +1 -1
- package/dist/vericify-bridge.d.ts +5 -1
- package/dist/vericify-bridge.d.ts.map +1 -1
- package/dist/vericify-bridge.js +10 -0
- package/dist/vericify-bridge.js.map +1 -1
- package/dist/vericify-context.d.ts +10 -0
- package/dist/vericify-context.d.ts.map +1 -0
- package/dist/vericify-context.js +72 -0
- package/dist/vericify-context.js.map +1 -0
- package/package.json +2 -1
package/dist/tools-agent.js
CHANGED
|
@@ -11,6 +11,11 @@ import { getTrackerAdapter, listTrackerAdapterKinds, loadTrackerSnapshot, valida
|
|
|
11
11
|
import { refreshTrackerSnapshot } from "./tracker-sync.js";
|
|
12
12
|
import { appendVericifyProcessPost, loadVericifyBridgeSnapshot, loadVericifyProcessPostLog, refreshVericifyBridgeSnapshot, validateVericifyBridgeSnapshotContent, validateVericifyProcessPostLogContent, } from "./vericify-bridge.js";
|
|
13
13
|
import { getRoleTitle, ROLE_ENUM, KERNEL_KEY_ENUM, ROLE_TITLES } from "./shared.js";
|
|
14
|
+
import { createDefaultModelBridgeClients, resolveLocalModelRuntime, runLocalModelTask, } from "./local-model-runtime.js";
|
|
15
|
+
import { executeAceInternalTool } from "./ace-internal-tools.js";
|
|
16
|
+
import { ModelBridge } from "./model-bridge.js";
|
|
17
|
+
import { getVericifyContextPacket, getVericifyDelta } from "./vericify-context.js";
|
|
18
|
+
import { createTaskPlan, superviseTaskPlan, } from "./orchestrator-supervisor.js";
|
|
14
19
|
function parseOptionalJsonObject(raw) {
|
|
15
20
|
if (!raw)
|
|
16
21
|
return {};
|
|
@@ -35,6 +40,101 @@ function parseUnknownJson(raw) {
|
|
|
35
40
|
return { raw };
|
|
36
41
|
}
|
|
37
42
|
}
|
|
43
|
+
function extractToolTextContent(result) {
|
|
44
|
+
if (!result || typeof result !== "object")
|
|
45
|
+
return "";
|
|
46
|
+
const content = Array.isArray(result.content) ? result.content : [];
|
|
47
|
+
return content
|
|
48
|
+
.filter((entry) => Boolean(entry) &&
|
|
49
|
+
typeof entry === "object" &&
|
|
50
|
+
entry.type === "text")
|
|
51
|
+
.map((entry) => String(entry.text ?? "").trim())
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join("\n");
|
|
54
|
+
}
|
|
55
|
+
function normalizeRoleCandidate(input) {
|
|
56
|
+
if (!input)
|
|
57
|
+
return undefined;
|
|
58
|
+
const normalized = input.trim().toLowerCase().replace(/^ace-/, "").replace(/[^a-z0-9]+/g, "");
|
|
59
|
+
const candidate = normalized === "coder" ? "coders" : normalized;
|
|
60
|
+
return ROLE_ENUM.options.includes(candidate)
|
|
61
|
+
? candidate
|
|
62
|
+
: undefined;
|
|
63
|
+
}
|
|
64
|
+
function parseRoleFromRoutingSummary(summary) {
|
|
65
|
+
const match = summary.match(/\*\*Primary Swarm Agent\(s\):\*\*\s*([^\n]+)/i);
|
|
66
|
+
if (!match?.[1])
|
|
67
|
+
return undefined;
|
|
68
|
+
const firstAgent = match[1]
|
|
69
|
+
.split(",")
|
|
70
|
+
.map((entry) => entry.trim())
|
|
71
|
+
.find(Boolean);
|
|
72
|
+
return normalizeRoleCandidate(firstAgent);
|
|
73
|
+
}
|
|
74
|
+
function mapRoleToTaskType(role) {
|
|
75
|
+
switch (role) {
|
|
76
|
+
case "vos":
|
|
77
|
+
return "venture";
|
|
78
|
+
case "ui":
|
|
79
|
+
return "ux";
|
|
80
|
+
case "orchestrator":
|
|
81
|
+
return "mixed";
|
|
82
|
+
default:
|
|
83
|
+
return "engineering";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function extractHandoffId(text) {
|
|
87
|
+
const jsonMatch = text.match(/"handoff_id"\s*:\s*"([^"]+)"/);
|
|
88
|
+
if (jsonMatch?.[1])
|
|
89
|
+
return jsonMatch[1];
|
|
90
|
+
const lineMatch = text.match(/handoff_id:\s*([A-Z0-9-]+)/i);
|
|
91
|
+
return lineMatch?.[1];
|
|
92
|
+
}
|
|
93
|
+
async function buildOrchestratorSteps(task, sessionId) {
|
|
94
|
+
const routing = await executeAceInternalTool("route_task", { description: task, domain: "unknown" }, sessionId);
|
|
95
|
+
const routedRole = parseRoleFromRoutingSummary(extractToolTextContent(routing)) ?? "orchestrator";
|
|
96
|
+
return [{ role: routedRole, task }];
|
|
97
|
+
}
|
|
98
|
+
function appendUniqueNote(target, note) {
|
|
99
|
+
if (!target.includes(note)) {
|
|
100
|
+
target.push(note);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function buildDefaultOrchestratorAmendment(input) {
|
|
104
|
+
if (input.result.status !== "completed" || input.step.role !== "coders") {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const currentIndex = input.plan.steps.findIndex((step) => step.step_id === input.step.step_id);
|
|
108
|
+
if (currentIndex < 0) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const downstreamSteps = input.plan.steps.slice(currentIndex + 1);
|
|
112
|
+
const hasValidationStep = downstreamSteps.some((step) => step.role === "qa" || step.role === "docs");
|
|
113
|
+
if (hasValidationStep) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
steps_to_add: [
|
|
118
|
+
{
|
|
119
|
+
role: "qa",
|
|
120
|
+
task: `Validate completed work for ${input.step.step_id}: ${input.step.task}`,
|
|
121
|
+
depends_on: [input.step.step_id],
|
|
122
|
+
tool_scope: ["run_tests", "execute_gates", "git_diff"],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
add_after_step_id: input.step.step_id,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
async function tryVericifyPacket(factory, onWarning) {
|
|
129
|
+
try {
|
|
130
|
+
return await factory();
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
134
|
+
onWarning?.(message);
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
38
138
|
export function registerAgentTools(server) {
|
|
39
139
|
// ── Agent Instructions & Manifests ────────────────────────────────
|
|
40
140
|
server.tool("get_agent_instructions", "Load the full instruction file for a specific ACE agent role", {
|
|
@@ -466,6 +566,361 @@ export function registerAgentTools(server) {
|
|
|
466
566
|
],
|
|
467
567
|
};
|
|
468
568
|
});
|
|
569
|
+
server.tool("run_local_model", "Offload a governed ACE subtask to a local model bridge and return the result", {
|
|
570
|
+
task: z.string().describe("Task to execute with the local ACE model bridge"),
|
|
571
|
+
role: ROLE_ENUM.optional().describe("Optional ACE role; defaults to route_task"),
|
|
572
|
+
max_turns: z
|
|
573
|
+
.number()
|
|
574
|
+
.int()
|
|
575
|
+
.positive()
|
|
576
|
+
.optional()
|
|
577
|
+
.describe("Optional max-turn override; defaults by role"),
|
|
578
|
+
tier: z
|
|
579
|
+
.enum(["auto", "full", "compressed", "brief"])
|
|
580
|
+
.optional()
|
|
581
|
+
.describe("Prompt packing tier; default auto-detects from role and model"),
|
|
582
|
+
provider: z
|
|
583
|
+
.string()
|
|
584
|
+
.optional()
|
|
585
|
+
.describe("Optional provider override; otherwise discovered from local runtime context"),
|
|
586
|
+
model: z
|
|
587
|
+
.string()
|
|
588
|
+
.optional()
|
|
589
|
+
.describe("Optional model override; otherwise discovered from local runtime context"),
|
|
590
|
+
ollama_url: z
|
|
591
|
+
.string()
|
|
592
|
+
.optional()
|
|
593
|
+
.describe("Optional Ollama base URL override"),
|
|
594
|
+
tool_scope: z
|
|
595
|
+
.array(z.string())
|
|
596
|
+
.optional()
|
|
597
|
+
.describe("Optional explicit ACE tool allowlist for the delegated run"),
|
|
598
|
+
workspace_root: z
|
|
599
|
+
.string()
|
|
600
|
+
.optional()
|
|
601
|
+
.describe("Optional workspace root override; defaults to the active workspace"),
|
|
602
|
+
}, async ({ task, role, max_turns, tier, provider, model, ollama_url, tool_scope, workspace_root, }) => {
|
|
603
|
+
const delegated = await runLocalModelTask({
|
|
604
|
+
task,
|
|
605
|
+
role,
|
|
606
|
+
workspaceRoot: workspace_root,
|
|
607
|
+
provider,
|
|
608
|
+
model,
|
|
609
|
+
ollamaUrl: ollama_url,
|
|
610
|
+
maxTurns: max_turns,
|
|
611
|
+
tier,
|
|
612
|
+
toolScope: tool_scope,
|
|
613
|
+
});
|
|
614
|
+
return {
|
|
615
|
+
content: [
|
|
616
|
+
{
|
|
617
|
+
type: "text",
|
|
618
|
+
text: [
|
|
619
|
+
"## Local Model Run",
|
|
620
|
+
`- role: ${delegated.role}`,
|
|
621
|
+
`- provider: ${delegated.runtime.provider}`,
|
|
622
|
+
`- model: ${delegated.runtime.model}`,
|
|
623
|
+
`- workspace: ${delegated.runtime.workspaceRoot}`,
|
|
624
|
+
`- status: ${delegated.result.status}`,
|
|
625
|
+
`- turns: ${delegated.result.turns}`,
|
|
626
|
+
delegated.routingSummary
|
|
627
|
+
? ["", "### Routing", delegated.routingSummary].join("\n")
|
|
628
|
+
: "",
|
|
629
|
+
delegated.runtime.notes.length > 0
|
|
630
|
+
? [
|
|
631
|
+
"",
|
|
632
|
+
"### Discovery Notes",
|
|
633
|
+
...delegated.runtime.notes.map((note) => `- ${note}`),
|
|
634
|
+
].join("\n")
|
|
635
|
+
: "",
|
|
636
|
+
"",
|
|
637
|
+
"### Result",
|
|
638
|
+
delegated.result.summary,
|
|
639
|
+
delegated.result.tool_calls.length > 0
|
|
640
|
+
? [
|
|
641
|
+
"",
|
|
642
|
+
"### Tool Calls",
|
|
643
|
+
...delegated.result.tool_calls.map((tool) => `- ${tool.tool}: ${tool.ok ? "ok" : "error"} — ${tool.summary}`),
|
|
644
|
+
].join("\n")
|
|
645
|
+
: "",
|
|
646
|
+
]
|
|
647
|
+
.filter(Boolean)
|
|
648
|
+
.join("\n"),
|
|
649
|
+
},
|
|
650
|
+
],
|
|
651
|
+
};
|
|
652
|
+
});
|
|
653
|
+
server.tool("run_orchestrator", "Execute a supervised plan via model bridge child runs; when steps are omitted, auto-planning falls back to a single route_task-derived step", {
|
|
654
|
+
task: z.string().describe("The task to decompose and execute"),
|
|
655
|
+
steps: z
|
|
656
|
+
.array(z.object({
|
|
657
|
+
role: ROLE_ENUM.describe("ACE role assigned to the step"),
|
|
658
|
+
task: z.string().describe("Task directive for the step"),
|
|
659
|
+
depends_on: z
|
|
660
|
+
.array(z.string())
|
|
661
|
+
.optional()
|
|
662
|
+
.describe("Optional step ids that must complete first"),
|
|
663
|
+
parallel_group: z
|
|
664
|
+
.string()
|
|
665
|
+
.optional()
|
|
666
|
+
.describe("Optional parallel execution group"),
|
|
667
|
+
tool_scope: z
|
|
668
|
+
.array(z.string())
|
|
669
|
+
.optional()
|
|
670
|
+
.describe("Optional ACE tool allowlist for the step"),
|
|
671
|
+
}))
|
|
672
|
+
.optional()
|
|
673
|
+
.describe("Pre-defined steps; if omitted, the orchestrator derives a single routed step"),
|
|
674
|
+
execution_mode: z
|
|
675
|
+
.enum(["sequential", "scheduled"])
|
|
676
|
+
.optional()
|
|
677
|
+
.describe("Execution mode for the task plan"),
|
|
678
|
+
max_turns_per_step: z
|
|
679
|
+
.number()
|
|
680
|
+
.int()
|
|
681
|
+
.positive()
|
|
682
|
+
.optional()
|
|
683
|
+
.describe("Optional max-turn limit applied to each child bridge step"),
|
|
684
|
+
provider: z
|
|
685
|
+
.string()
|
|
686
|
+
.optional()
|
|
687
|
+
.describe("Optional provider override; otherwise discovered from local runtime context"),
|
|
688
|
+
model: z
|
|
689
|
+
.string()
|
|
690
|
+
.optional()
|
|
691
|
+
.describe("Optional model override; otherwise discovered from local runtime context"),
|
|
692
|
+
ollama_url: z
|
|
693
|
+
.string()
|
|
694
|
+
.optional()
|
|
695
|
+
.describe("Optional Ollama base URL override"),
|
|
696
|
+
workspace_root: z
|
|
697
|
+
.string()
|
|
698
|
+
.optional()
|
|
699
|
+
.describe("Optional workspace root override; defaults to the active workspace"),
|
|
700
|
+
}, async ({ task, steps, execution_mode, max_turns_per_step, provider, model, ollama_url, workspace_root }, extra) => {
|
|
701
|
+
const runtime = resolveLocalModelRuntime({
|
|
702
|
+
workspaceRoot: workspace_root,
|
|
703
|
+
provider,
|
|
704
|
+
model,
|
|
705
|
+
ollamaUrl: ollama_url,
|
|
706
|
+
});
|
|
707
|
+
const sessionId = typeof extra?.sessionId === "string" ? extra.sessionId : undefined;
|
|
708
|
+
const planSource = Array.isArray(steps) && steps.length > 0 ? "explicit_steps" : "route_task_single_step";
|
|
709
|
+
const planSteps = Array.isArray(steps) && steps.length > 0
|
|
710
|
+
? steps
|
|
711
|
+
: await buildOrchestratorSteps(task, sessionId);
|
|
712
|
+
const plan = createTaskPlan({
|
|
713
|
+
task,
|
|
714
|
+
steps: planSteps,
|
|
715
|
+
execution_mode: execution_mode ?? "sequential",
|
|
716
|
+
});
|
|
717
|
+
const bridge = new ModelBridge(createDefaultModelBridgeClients(runtime.ollamaUrl));
|
|
718
|
+
const fallbackHandoffPrefix = `LOCAL-${plan.plan_id}-`;
|
|
719
|
+
const vericifyWarnings = [];
|
|
720
|
+
const supervised = await superviseTaskPlan(plan, {
|
|
721
|
+
async spawnStep(step) {
|
|
722
|
+
return bridge.spawn({
|
|
723
|
+
task: step.task,
|
|
724
|
+
role: step.role,
|
|
725
|
+
workspace: runtime.workspaceRoot,
|
|
726
|
+
maxTurns: max_turns_per_step ?? 6,
|
|
727
|
+
provider: runtime.provider,
|
|
728
|
+
model: runtime.model,
|
|
729
|
+
toolScope: step.tool_scope,
|
|
730
|
+
});
|
|
731
|
+
},
|
|
732
|
+
async createHandoff({ step, plan: activePlan }) {
|
|
733
|
+
const created = await executeAceInternalTool("create_handoff", {
|
|
734
|
+
from: "orchestrator",
|
|
735
|
+
to: step.role,
|
|
736
|
+
title: `${activePlan.plan_id}:${step.step_id} ${step.task}`.slice(0, 120),
|
|
737
|
+
task_type: mapRoleToTaskType(step.role),
|
|
738
|
+
priority: "P1",
|
|
739
|
+
directive: step.task,
|
|
740
|
+
acceptance_criteria: [`Complete ${step.step_id}: ${step.task}`],
|
|
741
|
+
context_pointers: {
|
|
742
|
+
engineering_constraint: `plan=${activePlan.plan_id}; step=${step.step_id}`,
|
|
743
|
+
},
|
|
744
|
+
}, sessionId);
|
|
745
|
+
const handoffId = extractHandoffId(extractToolTextContent(created));
|
|
746
|
+
return {
|
|
747
|
+
handoff_id: handoffId ?? `${fallbackHandoffPrefix}${step.step_id}`,
|
|
748
|
+
};
|
|
749
|
+
},
|
|
750
|
+
async ackHandoff(handoffId, status, note) {
|
|
751
|
+
if (handoffId.startsWith(fallbackHandoffPrefix)) {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
await executeAceInternalTool("ack_handoff", {
|
|
755
|
+
handoff_id: handoffId,
|
|
756
|
+
status,
|
|
757
|
+
note,
|
|
758
|
+
}, sessionId);
|
|
759
|
+
},
|
|
760
|
+
amendPlan({ plan: activePlan, step, result }) {
|
|
761
|
+
return buildDefaultOrchestratorAmendment({
|
|
762
|
+
plan: activePlan,
|
|
763
|
+
step,
|
|
764
|
+
result,
|
|
765
|
+
});
|
|
766
|
+
},
|
|
767
|
+
async getVericifyContext() {
|
|
768
|
+
return tryVericifyPacket(() => getVericifyContextPacket({
|
|
769
|
+
workspaceRoot: runtime.workspaceRoot,
|
|
770
|
+
}), (message) => appendUniqueNote(vericifyWarnings, `Vericify context unavailable for ${plan.plan_id}: ${message}`));
|
|
771
|
+
},
|
|
772
|
+
async getVericifyDelta(since) {
|
|
773
|
+
return tryVericifyPacket(() => getVericifyDelta({
|
|
774
|
+
since,
|
|
775
|
+
workspaceRoot: runtime.workspaceRoot,
|
|
776
|
+
}), (message) => appendUniqueNote(vericifyWarnings, `Vericify delta unavailable for ${plan.plan_id}: ${message}`));
|
|
777
|
+
},
|
|
778
|
+
async openCircuitBreaker(reason) {
|
|
779
|
+
await executeAceInternalTool("open_circuit_breaker", {
|
|
780
|
+
reason,
|
|
781
|
+
owner: "capability-ops",
|
|
782
|
+
}, sessionId);
|
|
783
|
+
},
|
|
784
|
+
async closeCircuitBreaker(reason) {
|
|
785
|
+
await executeAceInternalTool("close_circuit_breaker", {
|
|
786
|
+
reason,
|
|
787
|
+
}, sessionId);
|
|
788
|
+
},
|
|
789
|
+
async executeGates() {
|
|
790
|
+
const result = await executeAceInternalTool("execute_gates", {}, sessionId);
|
|
791
|
+
return {
|
|
792
|
+
ok: !Boolean(result?.isError),
|
|
793
|
+
summary: extractToolTextContent(result),
|
|
794
|
+
};
|
|
795
|
+
},
|
|
796
|
+
async contextSnapshot(activePlan) {
|
|
797
|
+
await executeAceInternalTool("context_snapshot", {
|
|
798
|
+
name: `${activePlan.plan_id}-final`,
|
|
799
|
+
summary: `Orchestrator plan ${activePlan.plan_id} finished with status ${activePlan.status}`,
|
|
800
|
+
artifacts: activePlan.steps.map((step) => `${step.step_id}:${step.role}`),
|
|
801
|
+
decisions: activePlan.steps
|
|
802
|
+
.filter((step) => typeof step.result_summary === "string" && step.result_summary.trim())
|
|
803
|
+
.map((step) => `${step.step_id}: ${step.result_summary}`),
|
|
804
|
+
}, sessionId);
|
|
805
|
+
},
|
|
806
|
+
async emitStatusEvent(event) {
|
|
807
|
+
await executeAceInternalTool("emit_status_event", {
|
|
808
|
+
source_module: "capability-ops",
|
|
809
|
+
event_type: "ORCHESTRATOR_STEP",
|
|
810
|
+
status: event.status === "done" ? "done" : event.status === "blocked" ? "blocked" : "in_progress",
|
|
811
|
+
summary: event.summary,
|
|
812
|
+
payload_json: JSON.stringify(event.step_id ? { step_id: event.step_id, plan_id: plan.plan_id } : { plan_id: plan.plan_id }),
|
|
813
|
+
}, sessionId);
|
|
814
|
+
},
|
|
815
|
+
});
|
|
816
|
+
const step_summaries = supervised.plan.steps.map((step) => ({
|
|
817
|
+
step_id: step.step_id,
|
|
818
|
+
role: step.role,
|
|
819
|
+
task: step.task,
|
|
820
|
+
status: step.status,
|
|
821
|
+
result_summary: step.result_summary ?? "",
|
|
822
|
+
handoff_id: step.handoff_id ?? null,
|
|
823
|
+
job_id: step.job_id ?? null,
|
|
824
|
+
blocked_reason: step.blocked_reason ?? null,
|
|
825
|
+
}));
|
|
826
|
+
return {
|
|
827
|
+
content: [
|
|
828
|
+
{
|
|
829
|
+
type: "text",
|
|
830
|
+
text: JSON.stringify({
|
|
831
|
+
runtime,
|
|
832
|
+
plan_source: planSource,
|
|
833
|
+
planning_note: planSource === "route_task_single_step"
|
|
834
|
+
? "Auto-planning currently falls back to a single route_task-derived step. Pass explicit steps for multi-step orchestration."
|
|
835
|
+
: null,
|
|
836
|
+
plan: supervised.plan,
|
|
837
|
+
step_summaries,
|
|
838
|
+
handoff_ids: supervised.handoff_ids,
|
|
839
|
+
job_ids: supervised.job_ids,
|
|
840
|
+
circuit_opened: supervised.circuit_opened,
|
|
841
|
+
final_gate: supervised.final_gate ?? null,
|
|
842
|
+
vericify_warnings: vericifyWarnings,
|
|
843
|
+
}, null, 2),
|
|
844
|
+
},
|
|
845
|
+
],
|
|
846
|
+
};
|
|
847
|
+
});
|
|
848
|
+
server.tool("get_vericify_context", "Build a compact Vericify context packet for workspace:current or a specified run", {
|
|
849
|
+
run_id: z
|
|
850
|
+
.string()
|
|
851
|
+
.optional()
|
|
852
|
+
.describe("Optional Vericify run id; defaults to workspace:current"),
|
|
853
|
+
workspace_root: z
|
|
854
|
+
.string()
|
|
855
|
+
.optional()
|
|
856
|
+
.describe("Optional workspace root override used to locate the Vericify workspace"),
|
|
857
|
+
}, async ({ run_id, workspace_root }) => {
|
|
858
|
+
try {
|
|
859
|
+
const packet = await getVericifyContextPacket({
|
|
860
|
+
runId: run_id,
|
|
861
|
+
workspaceRoot: workspace_root,
|
|
862
|
+
});
|
|
863
|
+
return {
|
|
864
|
+
content: [
|
|
865
|
+
{
|
|
866
|
+
type: "text",
|
|
867
|
+
text: JSON.stringify(packet, null, 2),
|
|
868
|
+
},
|
|
869
|
+
],
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
catch (error) {
|
|
873
|
+
return {
|
|
874
|
+
content: [
|
|
875
|
+
{
|
|
876
|
+
type: "text",
|
|
877
|
+
text: `❌ Vericify context failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
878
|
+
},
|
|
879
|
+
],
|
|
880
|
+
isError: true,
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
server.tool("get_vericify_delta", "Build a compact Vericify delta from a prior vcx cursor or checkpoint reference", {
|
|
885
|
+
since: z
|
|
886
|
+
.string()
|
|
887
|
+
.describe("Required prior vcx cursor or compatible checkpoint reference"),
|
|
888
|
+
run_id: z
|
|
889
|
+
.string()
|
|
890
|
+
.optional()
|
|
891
|
+
.describe("Optional Vericify run id; defaults to workspace:current"),
|
|
892
|
+
workspace_root: z
|
|
893
|
+
.string()
|
|
894
|
+
.optional()
|
|
895
|
+
.describe("Optional workspace root override used to locate the Vericify workspace"),
|
|
896
|
+
}, async ({ since, run_id, workspace_root }) => {
|
|
897
|
+
try {
|
|
898
|
+
const delta = await getVericifyDelta({
|
|
899
|
+
since,
|
|
900
|
+
runId: run_id,
|
|
901
|
+
workspaceRoot: workspace_root,
|
|
902
|
+
});
|
|
903
|
+
return {
|
|
904
|
+
content: [
|
|
905
|
+
{
|
|
906
|
+
type: "text",
|
|
907
|
+
text: JSON.stringify(delta, null, 2),
|
|
908
|
+
},
|
|
909
|
+
],
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
catch (error) {
|
|
913
|
+
return {
|
|
914
|
+
content: [
|
|
915
|
+
{
|
|
916
|
+
type: "text",
|
|
917
|
+
text: `❌ Vericify delta failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
isError: true,
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
});
|
|
469
924
|
server.tool("get_vericify_bridge", "Load the optional Vericify sidecar bridge snapshot derived from ACE runtime artifacts", {}, async () => {
|
|
470
925
|
const result = loadVericifyBridgeSnapshot();
|
|
471
926
|
return {
|
|
@@ -563,7 +1018,7 @@ export function registerAgentTools(server) {
|
|
|
563
1018
|
lane_id: z.string().optional().describe("Optional Vericify lane id"),
|
|
564
1019
|
agent_id: z.string().describe("Posting agent/module id"),
|
|
565
1020
|
kind: z
|
|
566
|
-
.enum(["intent", "progress", "blocker", "handoff_note", "completion"])
|
|
1021
|
+
.enum(["intent", "progress", "blocker", "handoff_note", "stale_ack", "completion"])
|
|
567
1022
|
.describe("Structured process post kind"),
|
|
568
1023
|
summary: z.string().describe("Short operator-facing summary"),
|
|
569
1024
|
tool_refs: z
|