cool-workflow 0.1.80 → 0.1.81
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +42 -2
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/agent-config.js +21 -7
- package/dist/candidate-scoring.js +42 -22
- package/dist/capability-core.js +94 -17
- package/dist/capability-registry.js +138 -171
- package/dist/cli.js +90 -100
- package/dist/collaboration.js +5 -6
- package/dist/commit.js +20 -6
- package/dist/compare.js +18 -0
- package/dist/coordinator/classify.js +45 -0
- package/dist/coordinator/paths.js +42 -0
- package/dist/coordinator/util.js +129 -0
- package/dist/coordinator.js +127 -300
- package/dist/dispatch.js +35 -0
- package/dist/drive.js +7 -7
- package/dist/error-feedback.js +8 -4
- package/dist/evidence-reasoning.js +1 -1
- package/dist/execution-backend/agent.js +331 -0
- package/dist/execution-backend/probes.js +96 -0
- package/dist/execution-backend/util.js +47 -0
- package/dist/execution-backend.js +67 -420
- package/dist/mcp-server.js +34 -173
- package/dist/multi-agent/graph.js +84 -0
- package/dist/multi-agent/helpers.js +145 -0
- package/dist/multi-agent/paths.js +22 -0
- package/dist/multi-agent-eval/format.js +194 -0
- package/dist/multi-agent-eval/normalize.js +51 -0
- package/dist/multi-agent-eval.js +39 -244
- package/dist/multi-agent-host.js +0 -19
- package/dist/multi-agent.js +125 -314
- package/dist/node-snapshot.js +3 -3
- package/dist/observability/format.js +61 -0
- package/dist/observability/intake.js +98 -0
- package/dist/observability.js +14 -160
- package/dist/operator-ux/format.js +364 -0
- package/dist/operator-ux.js +22 -363
- package/dist/orchestrator/report.js +8 -0
- package/dist/orchestrator.js +25 -8
- package/dist/reclamation.js +26 -21
- package/dist/run-export.js +138 -14
- package/dist/run-registry/derive.js +172 -0
- package/dist/run-registry/format.js +124 -0
- package/dist/run-registry/gc.js +251 -0
- package/dist/run-registry/policy.js +16 -0
- package/dist/run-registry/queue.js +116 -0
- package/dist/run-registry.js +78 -593
- package/dist/run-state-schema.js +1 -0
- package/dist/sandbox-profile.js +43 -2
- package/dist/state-explosion/format.js +159 -0
- package/dist/state-explosion/helpers.js +82 -0
- package/dist/state-explosion.js +65 -283
- package/dist/state-node.js +19 -4
- package/dist/telemetry-attestation.js +55 -0
- package/dist/telemetry-demo.js +15 -3
- package/dist/telemetry-ledger.js +60 -15
- package/dist/topology.js +25 -8
- package/dist/triggers.js +33 -14
- package/dist/trust-audit.js +145 -33
- package/dist/version.js +1 -1
- package/dist/worker-isolation/helpers.js +51 -0
- package/dist/worker-isolation/paths.js +46 -0
- package/dist/worker-isolation.js +39 -115
- package/docs/agent-delegation-drive.7.md +13 -0
- package/docs/cli-mcp-parity.7.md +4 -0
- package/docs/contract-migration-tooling.7.md +2 -0
- package/docs/control-plane-scheduling.7.md +2 -0
- package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +40 -0
- package/docs/durable-state-and-locking.7.md +4 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
- package/docs/execution-backends.7.md +2 -0
- package/docs/index.md +1 -0
- package/docs/launch/launch-kit.md +46 -23
- package/docs/launch/pre-launch-checklist.md +14 -14
- package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
- package/docs/multi-agent-eval-replay-harness.7.md +2 -0
- package/docs/multi-agent-operator-ux.7.md +2 -0
- package/docs/multi-agent-trust-policy-audit.7.md +27 -0
- package/docs/node-snapshot-diff-replay.7.md +2 -0
- package/docs/observability-cost-accounting.7.md +2 -0
- package/docs/project-index.md +18 -5
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +4 -0
- package/docs/release-tooling.7.md +2 -0
- package/docs/run-registry-control-plane.7.md +54 -8
- package/docs/run-retention-reclamation.7.md +4 -0
- package/docs/state-explosion-management.7.md +2 -0
- package/docs/team-collaboration.7.md +2 -0
- package/docs/trust-model.md +267 -0
- package/docs/vendor-manifest-loadability.7.md +43 -0
- package/docs/web-desktop-workbench.7.md +2 -0
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +4 -2
- package/scripts/agents/builtin-templates.json +7 -0
- package/scripts/bump-version.js +5 -11
- package/scripts/canonical-apps-list.js +64 -0
- package/scripts/canonical-apps.js +19 -4
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/parity-check.js +5 -0
- package/scripts/release-check.js +5 -1
- package/scripts/version-sync-check.js +5 -8
- package/dist/capability-dispatcher.js +0 -86
package/dist/multi-agent.js
CHANGED
|
@@ -30,16 +30,19 @@ const pipeline_contract_1 = require("./pipeline-contract");
|
|
|
30
30
|
const state_node_1 = require("./state-node");
|
|
31
31
|
const trust_audit_1 = require("./trust-audit");
|
|
32
32
|
const multi_agent_trust_1 = require("./multi-agent-trust");
|
|
33
|
-
|
|
33
|
+
const paths_1 = require("./multi-agent/paths");
|
|
34
|
+
const graph_1 = require("./multi-agent/graph");
|
|
35
|
+
const helpers_1 = require("./multi-agent/helpers");
|
|
36
|
+
Object.defineProperty(exports, "MULTI_AGENT_SCHEMA_VERSION", { enumerable: true, get: function () { return helpers_1.MULTI_AGENT_SCHEMA_VERSION; } });
|
|
34
37
|
function ensureMultiAgentState(run) {
|
|
35
|
-
run.paths.multiAgentDir = multiAgentRoot(run);
|
|
38
|
+
run.paths.multiAgentDir = (0, paths_1.multiAgentRoot)(run);
|
|
36
39
|
node_fs_1.default.mkdirSync(run.paths.multiAgentDir, { recursive: true });
|
|
37
40
|
for (const dir of ["runs", "roles", "groups", "memberships", "fanouts", "fanins"]) {
|
|
38
41
|
node_fs_1.default.mkdirSync(node_path_1.default.join(run.paths.multiAgentDir, dir), { recursive: true });
|
|
39
42
|
}
|
|
40
43
|
if (!run.multiAgent) {
|
|
41
44
|
run.multiAgent = {
|
|
42
|
-
schemaVersion:
|
|
45
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
43
46
|
runs: [],
|
|
44
47
|
roles: [],
|
|
45
48
|
groups: [],
|
|
@@ -48,7 +51,7 @@ function ensureMultiAgentState(run) {
|
|
|
48
51
|
fanins: []
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
|
-
run.multiAgent.schemaVersion =
|
|
54
|
+
run.multiAgent.schemaVersion = helpers_1.MULTI_AGENT_SCHEMA_VERSION;
|
|
52
55
|
run.multiAgent.runs = run.multiAgent.runs || [];
|
|
53
56
|
run.multiAgent.roles = run.multiAgent.roles || [];
|
|
54
57
|
run.multiAgent.groups = run.multiAgent.groups || [];
|
|
@@ -59,15 +62,15 @@ function ensureMultiAgentState(run) {
|
|
|
59
62
|
}
|
|
60
63
|
function persistMultiAgentState(run) {
|
|
61
64
|
const state = ensureMultiAgentState(run);
|
|
62
|
-
const root = multiAgentRoot(run);
|
|
63
|
-
assertNoRecordPathCollisions("MultiAgentRun", state.runs);
|
|
64
|
-
assertNoRecordPathCollisions("AgentRole", state.roles);
|
|
65
|
-
assertNoRecordPathCollisions("AgentGroup", state.groups);
|
|
66
|
-
assertNoRecordPathCollisions("AgentMembership", state.memberships);
|
|
67
|
-
assertNoRecordPathCollisions("AgentFanout", state.fanouts);
|
|
68
|
-
assertNoRecordPathCollisions("AgentFanin", state.fanins);
|
|
65
|
+
const root = (0, paths_1.multiAgentRoot)(run);
|
|
66
|
+
(0, helpers_1.assertNoRecordPathCollisions)("MultiAgentRun", state.runs);
|
|
67
|
+
(0, helpers_1.assertNoRecordPathCollisions)("AgentRole", state.roles);
|
|
68
|
+
(0, helpers_1.assertNoRecordPathCollisions)("AgentGroup", state.groups);
|
|
69
|
+
(0, helpers_1.assertNoRecordPathCollisions)("AgentMembership", state.memberships);
|
|
70
|
+
(0, helpers_1.assertNoRecordPathCollisions)("AgentFanout", state.fanouts);
|
|
71
|
+
(0, helpers_1.assertNoRecordPathCollisions)("AgentFanin", state.fanins);
|
|
69
72
|
(0, state_1.writeJson)(node_path_1.default.join(root, "index.json"), {
|
|
70
|
-
schemaVersion:
|
|
73
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
71
74
|
runId: run.id,
|
|
72
75
|
counts: {
|
|
73
76
|
runs: state.runs.length,
|
|
@@ -77,12 +80,12 @@ function persistMultiAgentState(run) {
|
|
|
77
80
|
fanouts: state.fanouts.length,
|
|
78
81
|
fanins: state.fanins.length
|
|
79
82
|
},
|
|
80
|
-
runs: state.runs.map(indexRow),
|
|
81
|
-
roles: state.roles.map(indexRow),
|
|
82
|
-
groups: state.groups.map(indexRow),
|
|
83
|
-
memberships: state.memberships.map(indexRow),
|
|
84
|
-
fanouts: state.fanouts.map(indexRow),
|
|
85
|
-
fanins: state.fanins.map(indexRow)
|
|
83
|
+
runs: state.runs.map(helpers_1.indexRow),
|
|
84
|
+
roles: state.roles.map(helpers_1.indexRow),
|
|
85
|
+
groups: state.groups.map(helpers_1.indexRow),
|
|
86
|
+
memberships: state.memberships.map(helpers_1.indexRow),
|
|
87
|
+
fanouts: state.fanouts.map(helpers_1.indexRow),
|
|
88
|
+
fanins: state.fanins.map(helpers_1.indexRow)
|
|
86
89
|
});
|
|
87
90
|
for (const record of state.runs)
|
|
88
91
|
writeRecord(run, "runs", record);
|
|
@@ -99,13 +102,13 @@ function persistMultiAgentState(run) {
|
|
|
99
102
|
}
|
|
100
103
|
function createMultiAgentRun(run, input = {}) {
|
|
101
104
|
const state = ensureMultiAgentState(run);
|
|
102
|
-
const id = input.id || createId("mar");
|
|
105
|
+
const id = input.id || (0, helpers_1.createId)("mar", state.runs.length + 1);
|
|
103
106
|
if (state.runs.some((record) => record.id === id))
|
|
104
107
|
throw new Error(`Duplicate MultiAgentRun id: ${id}`);
|
|
105
108
|
const now = new Date().toISOString();
|
|
106
109
|
const status = input.status || "planned";
|
|
107
110
|
const record = {
|
|
108
|
-
schemaVersion:
|
|
111
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
109
112
|
id,
|
|
110
113
|
runId: run.id,
|
|
111
114
|
createdAt: now,
|
|
@@ -120,14 +123,14 @@ function createMultiAgentRun(run, input = {}) {
|
|
|
120
123
|
fanoutIds: [],
|
|
121
124
|
faninIds: [],
|
|
122
125
|
blackboardId: input.blackboardId,
|
|
123
|
-
topicIds: unique(input.topicIds || []),
|
|
124
|
-
lifecycle: [lifecycleEvent(undefined, status, "created")],
|
|
126
|
+
topicIds: (0, helpers_1.unique)(input.topicIds || []),
|
|
127
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, status, "created")],
|
|
125
128
|
links: {
|
|
126
129
|
workflowRunId: run.id,
|
|
127
130
|
phase: input.phase,
|
|
128
131
|
phaseId: input.phaseId,
|
|
129
132
|
blackboardId: input.blackboardId,
|
|
130
|
-
blackboardTopicIds: unique(input.topicIds || [])
|
|
133
|
+
blackboardTopicIds: (0, helpers_1.unique)(input.topicIds || [])
|
|
131
134
|
},
|
|
132
135
|
policy: {
|
|
133
136
|
schemaVersion: 1,
|
|
@@ -135,7 +138,7 @@ function createMultiAgentRun(run, input = {}) {
|
|
|
135
138
|
policyRef: `multiAgent.runs.${id}.policy`,
|
|
136
139
|
subjectKind: "multi-agent-run",
|
|
137
140
|
subjectId: id,
|
|
138
|
-
allowedBlackboardTopicIds: unique(input.topicIds || ["*"]),
|
|
141
|
+
allowedBlackboardTopicIds: (0, helpers_1.unique)(input.topicIds || ["*"]),
|
|
139
142
|
allowedWriteOperations: ["message", "context", "artifact", "snapshot", "topic", "coordinator-decision"],
|
|
140
143
|
allowedCandidateOperations: ["register", "score", "select"],
|
|
141
144
|
allowedJudgeOperations: ["verdict", "rationale", "panel-decision"],
|
|
@@ -144,15 +147,15 @@ function createMultiAgentRun(run, input = {}) {
|
|
|
144
147
|
deniedOperations: [],
|
|
145
148
|
metadata: { title: input.title }
|
|
146
149
|
},
|
|
147
|
-
metadata: compact(input.metadata)
|
|
150
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
148
151
|
};
|
|
149
152
|
if (record.parentMultiAgentRunId) {
|
|
150
153
|
const parent = requireMultiAgentRun(run, record.parentMultiAgentRunId);
|
|
151
|
-
parent.childMultiAgentRunIds = unique([...parent.childMultiAgentRunIds, record.id]);
|
|
152
|
-
touch(parent);
|
|
154
|
+
parent.childMultiAgentRunIds = (0, helpers_1.unique)([...parent.childMultiAgentRunIds, record.id]);
|
|
155
|
+
(0, helpers_1.touch)(parent);
|
|
153
156
|
}
|
|
154
157
|
state.runs.push(record);
|
|
155
|
-
appendMultiAgentNode(run, "multi-agent-run", record.id, statusToNodeStatus(status), {
|
|
158
|
+
appendMultiAgentNode(run, "multi-agent-run", record.id, (0, helpers_1.statusToNodeStatus)(status), {
|
|
156
159
|
title: record.title,
|
|
157
160
|
objective: record.objective,
|
|
158
161
|
phase: record.links.phase
|
|
@@ -170,16 +173,16 @@ function createMultiAgentRun(run, input = {}) {
|
|
|
170
173
|
function transitionMultiAgentRun(run, multiAgentRunId, status, options = {}) {
|
|
171
174
|
ensureMultiAgentState(run);
|
|
172
175
|
const record = requireMultiAgentRun(run, multiAgentRunId);
|
|
173
|
-
assertLifecycleTransition(record.status, status);
|
|
176
|
+
(0, helpers_1.assertLifecycleTransition)(record.status, status);
|
|
174
177
|
if (status === "completed")
|
|
175
178
|
assertMultiAgentRunCompletionReady(run, record);
|
|
176
179
|
const before = record.status;
|
|
177
180
|
record.status = status;
|
|
178
181
|
record.updatedAt = new Date().toISOString();
|
|
179
|
-
record.lifecycle.push(lifecycleEvent(before, status, options.reason, options.actor, options.metadata));
|
|
182
|
+
record.lifecycle.push((0, helpers_1.lifecycleEvent)(before, status, options.reason, options.actor, options.metadata));
|
|
180
183
|
if (status === "completed")
|
|
181
184
|
completeOwnedMultiAgentRecords(run, record, options.reason);
|
|
182
|
-
appendMultiAgentNode(run, "multi-agent-run", record.id, statusToNodeStatus(status), {
|
|
185
|
+
appendMultiAgentNode(run, "multi-agent-run", record.id, (0, helpers_1.statusToNodeStatus)(status), {
|
|
183
186
|
status,
|
|
184
187
|
reason: options.reason
|
|
185
188
|
});
|
|
@@ -222,7 +225,7 @@ function completeOwnedMultiAgentRecords(run, multiAgentRun, reason) {
|
|
|
222
225
|
const before = role.status;
|
|
223
226
|
role.status = "completed";
|
|
224
227
|
role.updatedAt = multiAgentRun.updatedAt;
|
|
225
|
-
role.lifecycle.push(lifecycleEvent(before, "completed", reason || "multi-agent run completed"));
|
|
228
|
+
role.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
226
229
|
}
|
|
227
230
|
for (const group of state.groups.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
228
231
|
if (group.status === "completed" || group.status === "failed" || group.status === "cancelled")
|
|
@@ -230,7 +233,7 @@ function completeOwnedMultiAgentRecords(run, multiAgentRun, reason) {
|
|
|
230
233
|
const before = group.status;
|
|
231
234
|
group.status = "completed";
|
|
232
235
|
group.updatedAt = multiAgentRun.updatedAt;
|
|
233
|
-
group.lifecycle.push(lifecycleEvent(before, "completed", reason || "multi-agent run completed"));
|
|
236
|
+
group.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
234
237
|
}
|
|
235
238
|
for (const fanout of state.fanouts.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
236
239
|
if (fanout.status === "completed" || fanout.status === "failed" || fanout.status === "cancelled")
|
|
@@ -238,7 +241,7 @@ function completeOwnedMultiAgentRecords(run, multiAgentRun, reason) {
|
|
|
238
241
|
const before = fanout.status;
|
|
239
242
|
fanout.status = "completed";
|
|
240
243
|
fanout.updatedAt = multiAgentRun.updatedAt;
|
|
241
|
-
fanout.lifecycle.push(lifecycleEvent(before, "completed", reason || "multi-agent run completed"));
|
|
244
|
+
fanout.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
242
245
|
}
|
|
243
246
|
for (const fanin of state.fanins.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
244
247
|
if (fanin.status === "completed" || fanin.status === "failed")
|
|
@@ -246,20 +249,20 @@ function completeOwnedMultiAgentRecords(run, multiAgentRun, reason) {
|
|
|
246
249
|
const before = fanin.status;
|
|
247
250
|
fanin.status = "completed";
|
|
248
251
|
fanin.updatedAt = multiAgentRun.updatedAt;
|
|
249
|
-
fanin.lifecycle.push(lifecycleEvent(before, "completed", reason || "multi-agent run completed"));
|
|
252
|
+
fanin.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
250
253
|
}
|
|
251
254
|
}
|
|
252
255
|
function createAgentRole(run, input) {
|
|
253
256
|
const state = ensureMultiAgentState(run);
|
|
254
257
|
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId);
|
|
255
|
-
const id = input.id || createId("role");
|
|
258
|
+
const id = input.id || (0, helpers_1.createId)("role", state.roles.length + 1);
|
|
256
259
|
if (state.roles.some((record) => record.id === id))
|
|
257
260
|
throw new Error(`Duplicate AgentRole id: ${id}`);
|
|
258
261
|
if (input.parentRoleId)
|
|
259
262
|
requireAgentRole(run, input.parentRoleId);
|
|
260
263
|
const now = new Date().toISOString();
|
|
261
264
|
const role = {
|
|
262
|
-
schemaVersion:
|
|
265
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
263
266
|
id,
|
|
264
267
|
runId: run.id,
|
|
265
268
|
multiAgentRunId: multiAgentRun.id,
|
|
@@ -273,22 +276,22 @@ function createAgentRole(run, input) {
|
|
|
273
276
|
expectedArtifacts: input.expectedArtifacts || [],
|
|
274
277
|
faninObligations: input.faninObligations || [],
|
|
275
278
|
blackboardId: input.blackboardId || multiAgentRun.blackboardId,
|
|
276
|
-
topicIds: unique([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
277
|
-
lifecycle: [lifecycleEvent(undefined, "planned", "created")],
|
|
279
|
+
topicIds: (0, helpers_1.unique)([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
280
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "planned", "created")],
|
|
278
281
|
parentRoleId: input.parentRoleId,
|
|
279
282
|
childRoleIds: [],
|
|
280
283
|
policy: undefined,
|
|
281
|
-
metadata: compact(input.metadata)
|
|
284
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
282
285
|
};
|
|
283
286
|
role.policy = (0, multi_agent_trust_1.policyForRole)(role);
|
|
284
287
|
if (role.parentRoleId) {
|
|
285
288
|
const parent = requireAgentRole(run, role.parentRoleId);
|
|
286
|
-
parent.childRoleIds = unique([...parent.childRoleIds, role.id]);
|
|
287
|
-
touch(parent);
|
|
289
|
+
parent.childRoleIds = (0, helpers_1.unique)([...parent.childRoleIds, role.id]);
|
|
290
|
+
(0, helpers_1.touch)(parent);
|
|
288
291
|
}
|
|
289
292
|
state.roles.push(role);
|
|
290
|
-
multiAgentRun.roleIds = unique([...multiAgentRun.roleIds, role.id]);
|
|
291
|
-
touch(multiAgentRun);
|
|
293
|
+
multiAgentRun.roleIds = (0, helpers_1.unique)([...multiAgentRun.roleIds, role.id]);
|
|
294
|
+
(0, helpers_1.touch)(multiAgentRun);
|
|
292
295
|
appendMultiAgentNode(run, "agent-role", role.id, "pending", {
|
|
293
296
|
multiAgentRunId: role.multiAgentRunId,
|
|
294
297
|
title: role.title,
|
|
@@ -315,7 +318,7 @@ function createAgentRole(run, input) {
|
|
|
315
318
|
function createAgentGroup(run, input) {
|
|
316
319
|
const state = ensureMultiAgentState(run);
|
|
317
320
|
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId);
|
|
318
|
-
const id = input.id || createId("group");
|
|
321
|
+
const id = input.id || (0, helpers_1.createId)("group", state.groups.length + 1);
|
|
319
322
|
if (state.groups.some((record) => record.id === id))
|
|
320
323
|
throw new Error(`Duplicate AgentGroup id: ${id}`);
|
|
321
324
|
if (input.parentGroupId)
|
|
@@ -324,7 +327,7 @@ function createAgentGroup(run, input) {
|
|
|
324
327
|
requireRunTask(run, taskId);
|
|
325
328
|
const now = new Date().toISOString();
|
|
326
329
|
const group = {
|
|
327
|
-
schemaVersion:
|
|
330
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
328
331
|
id,
|
|
329
332
|
runId: run.id,
|
|
330
333
|
multiAgentRunId: multiAgentRun.id,
|
|
@@ -334,29 +337,29 @@ function createAgentGroup(run, input) {
|
|
|
334
337
|
title: input.title || id,
|
|
335
338
|
phase: input.phase,
|
|
336
339
|
phaseId: input.phaseId,
|
|
337
|
-
taskIds: unique(input.taskIds || []),
|
|
340
|
+
taskIds: (0, helpers_1.unique)(input.taskIds || []),
|
|
338
341
|
roleIds: [],
|
|
339
342
|
membershipIds: [],
|
|
340
343
|
workerIds: [],
|
|
341
344
|
fanoutIds: [],
|
|
342
345
|
faninIds: [],
|
|
343
346
|
blackboardId: input.blackboardId || multiAgentRun.blackboardId,
|
|
344
|
-
topicIds: unique([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
345
|
-
lifecycle: [lifecycleEvent(undefined, "forming", "created")],
|
|
347
|
+
topicIds: (0, helpers_1.unique)([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
348
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "forming", "created")],
|
|
346
349
|
parentGroupId: input.parentGroupId,
|
|
347
350
|
childGroupIds: [],
|
|
348
351
|
policy: undefined,
|
|
349
|
-
metadata: compact(input.metadata)
|
|
352
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
350
353
|
};
|
|
351
354
|
group.policy = (0, multi_agent_trust_1.policyForGroup)(group);
|
|
352
355
|
if (group.parentGroupId) {
|
|
353
356
|
const parent = requireAgentGroup(run, group.parentGroupId);
|
|
354
|
-
parent.childGroupIds = unique([...parent.childGroupIds, group.id]);
|
|
355
|
-
touch(parent);
|
|
357
|
+
parent.childGroupIds = (0, helpers_1.unique)([...parent.childGroupIds, group.id]);
|
|
358
|
+
(0, helpers_1.touch)(parent);
|
|
356
359
|
}
|
|
357
360
|
state.groups.push(group);
|
|
358
|
-
multiAgentRun.groupIds = unique([...multiAgentRun.groupIds, group.id]);
|
|
359
|
-
touch(multiAgentRun);
|
|
361
|
+
multiAgentRun.groupIds = (0, helpers_1.unique)([...multiAgentRun.groupIds, group.id]);
|
|
362
|
+
(0, helpers_1.touch)(multiAgentRun);
|
|
360
363
|
appendMultiAgentNode(run, "agent-group", group.id, "running", {
|
|
361
364
|
multiAgentRunId: group.multiAgentRunId,
|
|
362
365
|
phase: group.phase,
|
|
@@ -394,13 +397,13 @@ function assignAgentMembership(run, input) {
|
|
|
394
397
|
if (duplicate) {
|
|
395
398
|
throw new Error(`Duplicate AgentMembership for group=${group.id}, role=${role.id}, task=${task.id}, worker=${input.workerId || "none"}`);
|
|
396
399
|
}
|
|
397
|
-
const id = input.id || createId("membership");
|
|
400
|
+
const id = input.id || (0, helpers_1.createId)("membership", state.memberships.length + 1);
|
|
398
401
|
if (state.memberships.some((record) => record.id === id))
|
|
399
402
|
throw new Error(`Duplicate AgentMembership id: ${id}`);
|
|
400
403
|
const now = new Date().toISOString();
|
|
401
404
|
const status = input.status || (input.workerId ? "running" : "assigned");
|
|
402
405
|
const membership = {
|
|
403
|
-
schemaVersion:
|
|
406
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
404
407
|
id,
|
|
405
408
|
runId: run.id,
|
|
406
409
|
multiAgentRunId: group.multiAgentRunId,
|
|
@@ -413,31 +416,31 @@ function assignAgentMembership(run, input) {
|
|
|
413
416
|
createdAt: now,
|
|
414
417
|
updatedAt: now,
|
|
415
418
|
status,
|
|
416
|
-
lifecycle: [lifecycleEvent(undefined, status, "assigned")],
|
|
419
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, status, "assigned")],
|
|
417
420
|
evidenceRefs: [],
|
|
418
421
|
artifactPaths: [],
|
|
419
422
|
blackboardId: input.blackboardId || group.blackboardId || role.blackboardId,
|
|
420
|
-
topicIds: unique([...(group.topicIds || []), ...(role.topicIds || []), ...(input.topicIds || [])]),
|
|
423
|
+
topicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(role.topicIds || []), ...(input.topicIds || [])]),
|
|
421
424
|
blackboardMessageIds: [],
|
|
422
425
|
blackboardArtifactRefIds: [],
|
|
423
426
|
policy: undefined,
|
|
424
|
-
metadata: compact(input.metadata)
|
|
427
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
425
428
|
};
|
|
426
429
|
membership.policy = (0, multi_agent_trust_1.policyForMembership)(membership, role);
|
|
427
430
|
state.memberships.push(membership);
|
|
428
|
-
group.membershipIds = unique([...group.membershipIds, membership.id]);
|
|
429
|
-
group.roleIds = unique([...group.roleIds, role.id]);
|
|
430
|
-
group.taskIds = unique([...group.taskIds, task.id]);
|
|
431
|
+
group.membershipIds = (0, helpers_1.unique)([...group.membershipIds, membership.id]);
|
|
432
|
+
group.roleIds = (0, helpers_1.unique)([...group.roleIds, role.id]);
|
|
433
|
+
group.taskIds = (0, helpers_1.unique)([...group.taskIds, task.id]);
|
|
431
434
|
if (membership.workerId)
|
|
432
|
-
group.workerIds = unique([...group.workerIds, membership.workerId]);
|
|
433
|
-
touch(group);
|
|
435
|
+
group.workerIds = (0, helpers_1.unique)([...group.workerIds, membership.workerId]);
|
|
436
|
+
(0, helpers_1.touch)(group);
|
|
434
437
|
const roleStatusBefore = role.status;
|
|
435
438
|
role.status = "active";
|
|
436
439
|
role.updatedAt = now;
|
|
437
|
-
role.lifecycle.push(lifecycleEvent(roleStatusBefore, "active", "membership assigned"));
|
|
440
|
+
role.lifecycle.push((0, helpers_1.lifecycleEvent)(roleStatusBefore, "active", "membership assigned"));
|
|
438
441
|
if (membership.workerId)
|
|
439
442
|
attachWorkerMetadata(run, membership);
|
|
440
|
-
appendMultiAgentNode(run, "agent-membership", membership.id, statusToNodeStatus(membership.status), {
|
|
443
|
+
appendMultiAgentNode(run, "agent-membership", membership.id, (0, helpers_1.statusToNodeStatus)(membership.status), {
|
|
441
444
|
multiAgentRunId: membership.multiAgentRunId,
|
|
442
445
|
groupId: membership.groupId,
|
|
443
446
|
roleId: membership.roleId,
|
|
@@ -468,7 +471,7 @@ function createAgentFanout(run, input) {
|
|
|
468
471
|
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId || group.multiAgentRunId);
|
|
469
472
|
if (group.multiAgentRunId !== multiAgentRun.id)
|
|
470
473
|
throw new Error(`AgentGroup ${group.id} does not belong to ${multiAgentRun.id}`);
|
|
471
|
-
const id = input.id || createId("fanout");
|
|
474
|
+
const id = input.id || (0, helpers_1.createId)("fanout", state.fanouts.length + 1);
|
|
472
475
|
if (state.fanouts.some((record) => record.id === id))
|
|
473
476
|
throw new Error(`Duplicate AgentFanout id: ${id}`);
|
|
474
477
|
for (const roleId of input.roleIds || [])
|
|
@@ -477,7 +480,7 @@ function createAgentFanout(run, input) {
|
|
|
477
480
|
requireRunTask(run, taskId);
|
|
478
481
|
const now = new Date().toISOString();
|
|
479
482
|
const fanout = {
|
|
480
|
-
schemaVersion:
|
|
483
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
481
484
|
id,
|
|
482
485
|
runId: run.id,
|
|
483
486
|
multiAgentRunId: multiAgentRun.id,
|
|
@@ -486,41 +489,41 @@ function createAgentFanout(run, input) {
|
|
|
486
489
|
updatedAt: now,
|
|
487
490
|
status: "planned",
|
|
488
491
|
reason: input.reason,
|
|
489
|
-
roleIds: unique(input.roleIds || group.roleIds),
|
|
490
|
-
taskIds: unique(input.taskIds || group.taskIds),
|
|
491
|
-
workerIds: unique(input.workerIds || []),
|
|
492
|
-
membershipIds: unique(input.membershipIds || []),
|
|
493
|
-
dispatchIds: unique(input.dispatchIds || []),
|
|
492
|
+
roleIds: (0, helpers_1.unique)(input.roleIds || group.roleIds),
|
|
493
|
+
taskIds: (0, helpers_1.unique)(input.taskIds || group.taskIds),
|
|
494
|
+
workerIds: (0, helpers_1.unique)(input.workerIds || []),
|
|
495
|
+
membershipIds: (0, helpers_1.unique)(input.membershipIds || []),
|
|
496
|
+
dispatchIds: (0, helpers_1.unique)(input.dispatchIds || []),
|
|
494
497
|
concurrencyLimit: input.concurrencyLimit,
|
|
495
498
|
sandboxProfileChoices: input.sandboxProfileChoices || {},
|
|
496
499
|
expectedReturnShape: input.expectedReturnShape || "Each member writes a Markdown result with a cw:result JSON fence containing summary, findings, and evidence.",
|
|
497
500
|
blackboardId: input.blackboardId || group.blackboardId || multiAgentRun.blackboardId,
|
|
498
|
-
topicIds: unique([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
499
|
-
lifecycle: [lifecycleEvent(undefined, "planned", "created")],
|
|
501
|
+
topicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
502
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "planned", "created")],
|
|
500
503
|
policy: {
|
|
501
504
|
schemaVersion: 1,
|
|
502
505
|
id: `${id}-policy`,
|
|
503
506
|
policyRef: `multiAgent.fanouts.${id}.policy`,
|
|
504
507
|
subjectKind: "fanout",
|
|
505
508
|
subjectId: id,
|
|
506
|
-
allowedBlackboardTopicIds: unique(fanoutTopicIds(group, multiAgentRun, input)),
|
|
509
|
+
allowedBlackboardTopicIds: (0, helpers_1.unique)(fanoutTopicIds(group, multiAgentRun, input)),
|
|
507
510
|
allowedWriteOperations: ["message", "context", "artifact"],
|
|
508
511
|
allowedCandidateOperations: ["register"],
|
|
509
512
|
allowedJudgeOperations: [],
|
|
510
|
-
sandboxProfileHints: unique(Object.values(input.sandboxProfileChoices || {}).map(String)),
|
|
513
|
+
sandboxProfileHints: (0, helpers_1.unique)(Object.values(input.sandboxProfileChoices || {}).map(String)),
|
|
511
514
|
requiredEvidenceRefs: [],
|
|
512
515
|
deniedOperations: [],
|
|
513
516
|
metadata: { reason: input.reason }
|
|
514
517
|
},
|
|
515
|
-
metadata: compact(input.metadata)
|
|
518
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
516
519
|
};
|
|
517
520
|
state.fanouts.push(fanout);
|
|
518
|
-
group.fanoutIds = unique([...group.fanoutIds, fanout.id]);
|
|
519
|
-
group.roleIds = unique([...group.roleIds, ...fanout.roleIds]);
|
|
520
|
-
group.taskIds = unique([...group.taskIds, ...fanout.taskIds]);
|
|
521
|
-
touch(group);
|
|
522
|
-
multiAgentRun.fanoutIds = unique([...multiAgentRun.fanoutIds, fanout.id]);
|
|
523
|
-
touch(multiAgentRun);
|
|
521
|
+
group.fanoutIds = (0, helpers_1.unique)([...group.fanoutIds, fanout.id]);
|
|
522
|
+
group.roleIds = (0, helpers_1.unique)([...group.roleIds, ...fanout.roleIds]);
|
|
523
|
+
group.taskIds = (0, helpers_1.unique)([...group.taskIds, ...fanout.taskIds]);
|
|
524
|
+
(0, helpers_1.touch)(group);
|
|
525
|
+
multiAgentRun.fanoutIds = (0, helpers_1.unique)([...multiAgentRun.fanoutIds, fanout.id]);
|
|
526
|
+
(0, helpers_1.touch)(multiAgentRun);
|
|
524
527
|
appendMultiAgentNode(run, "agent-fanout", fanout.id, "pending", {
|
|
525
528
|
multiAgentRunId: fanout.multiAgentRunId,
|
|
526
529
|
groupId: fanout.groupId,
|
|
@@ -561,7 +564,7 @@ function attachDispatchToMultiAgent(run, input) {
|
|
|
561
564
|
throw new Error("Dispatch multi-agent attach requires --multi-agent-group or --multiAgentGroup");
|
|
562
565
|
if (group.multiAgentRunId !== multiAgentRun.id)
|
|
563
566
|
throw new Error(`Group ${group.id} does not belong to MultiAgentRun ${multiAgentRun.id}`);
|
|
564
|
-
const roleIds = input.roleId ? [input.roleId] : unique([...(fanout ? fanout.roleIds : [])]);
|
|
567
|
+
const roleIds = input.roleId ? [input.roleId] : (0, helpers_1.unique)([...(fanout ? fanout.roleIds : [])]);
|
|
565
568
|
if (roleIds.length !== 1) {
|
|
566
569
|
throw new Error(`Dispatch multi-agent attach requires exactly one role for deterministic membership; found ${roleIds.length || 0}`);
|
|
567
570
|
}
|
|
@@ -608,19 +611,19 @@ function attachDispatchToMultiAgent(run, input) {
|
|
|
608
611
|
}
|
|
609
612
|
fanout.status = "dispatched";
|
|
610
613
|
fanout.updatedAt = new Date().toISOString();
|
|
611
|
-
fanout.lifecycle.push(lifecycleEvent("planned", "dispatched", "dispatch created"));
|
|
612
|
-
fanout.dispatchIds = unique([...fanout.dispatchIds, input.dispatchId]);
|
|
613
|
-
fanout.taskIds = unique([...fanout.taskIds, ...input.tasks.map((task) => task.id)]);
|
|
614
|
-
fanout.workerIds = unique([...fanout.workerIds, ...input.tasks.map((task) => task.workerId || "").filter(Boolean)]);
|
|
615
|
-
fanout.membershipIds = unique([...fanout.membershipIds, ...membershipIds]);
|
|
614
|
+
fanout.lifecycle.push((0, helpers_1.lifecycleEvent)("planned", "dispatched", "dispatch created"));
|
|
615
|
+
fanout.dispatchIds = (0, helpers_1.unique)([...fanout.dispatchIds, input.dispatchId]);
|
|
616
|
+
fanout.taskIds = (0, helpers_1.unique)([...fanout.taskIds, ...input.tasks.map((task) => task.id)]);
|
|
617
|
+
fanout.workerIds = (0, helpers_1.unique)([...fanout.workerIds, ...input.tasks.map((task) => task.workerId || "").filter(Boolean)]);
|
|
618
|
+
fanout.membershipIds = (0, helpers_1.unique)([...fanout.membershipIds, ...membershipIds]);
|
|
616
619
|
if (input.sandboxProfileId)
|
|
617
620
|
fanout.sandboxProfileChoices.dispatch = input.sandboxProfileId;
|
|
618
621
|
const groupStatusBefore = group.status;
|
|
619
622
|
group.status = "running";
|
|
620
623
|
group.updatedAt = fanout.updatedAt;
|
|
621
|
-
group.lifecycle.push(lifecycleEvent(groupStatusBefore, "running", "dispatch created"));
|
|
624
|
+
group.lifecycle.push((0, helpers_1.lifecycleEvent)(groupStatusBefore, "running", "dispatch created"));
|
|
622
625
|
multiAgentRun.status = multiAgentRun.status === "planned" || multiAgentRun.status === "forming" ? "running" : multiAgentRun.status;
|
|
623
|
-
touch(multiAgentRun);
|
|
626
|
+
(0, helpers_1.touch)(multiAgentRun);
|
|
624
627
|
appendMultiAgentNode(run, "agent-fanout", fanout.id, "running", {
|
|
625
628
|
status: fanout.status,
|
|
626
629
|
dispatchIds: fanout.dispatchIds,
|
|
@@ -657,10 +660,10 @@ function collectAgentFanin(run, input) {
|
|
|
657
660
|
throw new Error(`Group ${group.id} does not belong to MultiAgentRun ${multiAgentRun.id}`);
|
|
658
661
|
if (fanout && fanout.groupId !== group.id)
|
|
659
662
|
throw new Error(`Fanout ${fanout.id} does not belong to group ${group.id}`);
|
|
660
|
-
const id = input.id || createId("fanin");
|
|
663
|
+
const id = input.id || (0, helpers_1.createId)("fanin", state.fanins.length + 1);
|
|
661
664
|
if (state.fanins.some((record) => record.id === id))
|
|
662
665
|
throw new Error(`Duplicate AgentFanin id: ${id}`);
|
|
663
|
-
const requiredRoleIds = unique(input.requiredRoleIds?.length ? input.requiredRoleIds : group.roleIds);
|
|
666
|
+
const requiredRoleIds = (0, helpers_1.unique)(input.requiredRoleIds?.length ? input.requiredRoleIds : group.roleIds);
|
|
664
667
|
for (const roleId of requiredRoleIds)
|
|
665
668
|
requireAgentRole(run, roleId);
|
|
666
669
|
const scopedMemberships = state.memberships.filter((membership) => membership.groupId === group.id && (!fanout || membership.fanoutId === fanout.id));
|
|
@@ -674,11 +677,11 @@ function collectAgentFanin(run, input) {
|
|
|
674
677
|
blackboardArtifactRefIds: membership.blackboardArtifactRefIds || [],
|
|
675
678
|
resultNodeId: membership.resultNodeId,
|
|
676
679
|
verifierNodeId: membership.verifierNodeId,
|
|
677
|
-
complete: isMembershipReported(membership)
|
|
680
|
+
complete: (0, helpers_1.isMembershipReported)(membership)
|
|
678
681
|
}));
|
|
679
682
|
const missingRoleIds = requiredRoleIds.filter((roleId) => !scopedMemberships.some((membership) => membership.roleId === roleId));
|
|
680
683
|
const missingMembershipIds = scopedMemberships
|
|
681
|
-
.filter((membership) => requiredRoleIds.includes(membership.roleId) && !isMembershipReported(membership))
|
|
684
|
+
.filter((membership) => requiredRoleIds.includes(membership.roleId) && !(0, helpers_1.isMembershipReported)(membership))
|
|
682
685
|
.map((membership) => membership.id);
|
|
683
686
|
const blockedReasons = [
|
|
684
687
|
...missingRoleIds.map((roleId) => `required role ${roleId} has no membership`),
|
|
@@ -701,7 +704,7 @@ function collectAgentFanin(run, input) {
|
|
|
701
704
|
const status = verifierReady ? "ready" : "blocked";
|
|
702
705
|
const now = new Date().toISOString();
|
|
703
706
|
const fanin = {
|
|
704
|
-
schemaVersion:
|
|
707
|
+
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
705
708
|
id,
|
|
706
709
|
runId: run.id,
|
|
707
710
|
multiAgentRunId: multiAgentRun.id,
|
|
@@ -719,34 +722,34 @@ function collectAgentFanin(run, input) {
|
|
|
719
722
|
verifierReady,
|
|
720
723
|
blockedReasons,
|
|
721
724
|
blackboardId,
|
|
722
|
-
topicIds: unique([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
723
|
-
blackboardArtifactRefIds: unique(coverage.flatMap((entry) => entry.blackboardArtifactRefIds || [])),
|
|
724
|
-
blackboardMessageIds: unique(coverage.flatMap((entry) => entry.blackboardMessageIds || [])),
|
|
725
|
-
lifecycle: [lifecycleEvent(undefined, status, "collected")],
|
|
725
|
+
topicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
726
|
+
blackboardArtifactRefIds: (0, helpers_1.unique)(coverage.flatMap((entry) => entry.blackboardArtifactRefIds || [])),
|
|
727
|
+
blackboardMessageIds: (0, helpers_1.unique)(coverage.flatMap((entry) => entry.blackboardMessageIds || [])),
|
|
728
|
+
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, status, "collected")],
|
|
726
729
|
policy: {
|
|
727
730
|
schemaVersion: 1,
|
|
728
731
|
id: `${id}-policy`,
|
|
729
732
|
policyRef: `multiAgent.fanins.${id}.policy`,
|
|
730
733
|
subjectKind: "fanin",
|
|
731
734
|
subjectId: id,
|
|
732
|
-
allowedBlackboardTopicIds: unique([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
735
|
+
allowedBlackboardTopicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
733
736
|
allowedWriteOperations: ["message", "context", "artifact", "snapshot", "coordinator-decision"],
|
|
734
737
|
allowedCandidateOperations: verifierReady ? ["register", "score", "select"] : [],
|
|
735
738
|
allowedJudgeOperations: verifierReady ? ["panel-decision", "rationale"] : [],
|
|
736
739
|
sandboxProfileHints: [],
|
|
737
|
-
requiredEvidenceRefs: unique(coverage.flatMap((entry) => entry.evidenceRefs)),
|
|
740
|
+
requiredEvidenceRefs: (0, helpers_1.unique)(coverage.flatMap((entry) => entry.evidenceRefs)),
|
|
738
741
|
deniedOperations: verifierReady ? [] : blockedReasons.map((reason) => ({ operation: "candidate.select", reason })),
|
|
739
742
|
metadata: { verifierReady, strategy: input.strategy || "required-role-evidence" }
|
|
740
743
|
},
|
|
741
|
-
metadata: compact(input.metadata)
|
|
744
|
+
metadata: (0, helpers_1.compact)(input.metadata)
|
|
742
745
|
};
|
|
743
746
|
state.fanins.push(fanin);
|
|
744
|
-
group.faninIds = unique([...group.faninIds, fanin.id]);
|
|
747
|
+
group.faninIds = (0, helpers_1.unique)([...group.faninIds, fanin.id]);
|
|
745
748
|
group.status = verifierReady ? "verifying" : "collecting";
|
|
746
|
-
touch(group);
|
|
747
|
-
multiAgentRun.faninIds = unique([...multiAgentRun.faninIds, fanin.id]);
|
|
749
|
+
(0, helpers_1.touch)(group);
|
|
750
|
+
multiAgentRun.faninIds = (0, helpers_1.unique)([...multiAgentRun.faninIds, fanin.id]);
|
|
748
751
|
multiAgentRun.status = verifierReady ? "verifying" : "collecting";
|
|
749
|
-
touch(multiAgentRun);
|
|
752
|
+
(0, helpers_1.touch)(multiAgentRun);
|
|
750
753
|
appendMultiAgentNode(run, "agent-fanin", fanin.id, verifierReady ? "verified" : "blocked", {
|
|
751
754
|
multiAgentRunId: fanin.multiAgentRunId,
|
|
752
755
|
groupId: fanin.groupId,
|
|
@@ -792,11 +795,11 @@ function recordMultiAgentWorkerOutput(run, input) {
|
|
|
792
795
|
membership.updatedAt = new Date().toISOString();
|
|
793
796
|
membership.resultNodeId = input.resultNodeId || membership.resultNodeId;
|
|
794
797
|
membership.verifierNodeId = input.verifierNodeId || membership.verifierNodeId;
|
|
795
|
-
membership.evidenceRefs = unique([...membership.evidenceRefs, ...evidenceRefs]);
|
|
796
|
-
membership.artifactPaths = unique([...(membership.artifactPaths || []), ...(input.artifactPaths || [])]);
|
|
797
|
-
membership.blackboardMessageIds = unique([...(membership.blackboardMessageIds || []), ...(input.blackboardMessageIds || [])]);
|
|
798
|
-
membership.blackboardArtifactRefIds = unique([...(membership.blackboardArtifactRefIds || []), ...(input.blackboardArtifactRefIds || [])]);
|
|
799
|
-
membership.lifecycle.push(lifecycleEvent(before, "reported", "worker output accepted"));
|
|
798
|
+
membership.evidenceRefs = (0, helpers_1.unique)([...membership.evidenceRefs, ...evidenceRefs]);
|
|
799
|
+
membership.artifactPaths = (0, helpers_1.unique)([...(membership.artifactPaths || []), ...(input.artifactPaths || [])]);
|
|
800
|
+
membership.blackboardMessageIds = (0, helpers_1.unique)([...(membership.blackboardMessageIds || []), ...(input.blackboardMessageIds || [])]);
|
|
801
|
+
membership.blackboardArtifactRefIds = (0, helpers_1.unique)([...(membership.blackboardArtifactRefIds || []), ...(input.blackboardArtifactRefIds || [])]);
|
|
802
|
+
membership.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "reported", "worker output accepted"));
|
|
800
803
|
appendMultiAgentNode(run, "agent-membership", membership.id, "completed", {
|
|
801
804
|
resultNodeId: membership.resultNodeId,
|
|
802
805
|
verifierNodeId: membership.verifierNodeId,
|
|
@@ -831,7 +834,7 @@ function summarizeMultiAgent(run) {
|
|
|
831
834
|
blockedReasons.push(`${membership.id}: failed membership`);
|
|
832
835
|
}
|
|
833
836
|
const groupsDetail = state.groups.map((group) => {
|
|
834
|
-
const roleIds = unique([...group.roleIds, ...state.memberships.filter((membership) => membership.groupId === group.id).map((membership) => membership.roleId)]);
|
|
837
|
+
const roleIds = (0, helpers_1.unique)([...group.roleIds, ...state.memberships.filter((membership) => membership.groupId === group.id).map((membership) => membership.roleId)]);
|
|
835
838
|
return {
|
|
836
839
|
id: group.id,
|
|
837
840
|
multiAgentRunId: group.multiAgentRunId,
|
|
@@ -840,7 +843,7 @@ function summarizeMultiAgent(run) {
|
|
|
840
843
|
roles: roleIds.map((roleId) => {
|
|
841
844
|
const role = state.roles.find((entry) => entry.id === roleId);
|
|
842
845
|
const memberships = state.memberships.filter((membership) => membership.groupId === group.id && membership.roleId === roleId);
|
|
843
|
-
const reported = memberships.filter(isMembershipReported).length;
|
|
846
|
+
const reported = memberships.filter(helpers_1.isMembershipReported).length;
|
|
844
847
|
return {
|
|
845
848
|
roleId,
|
|
846
849
|
requiredEvidence: role?.requiredEvidence.length || 0,
|
|
@@ -855,15 +858,15 @@ function summarizeMultiAgent(run) {
|
|
|
855
858
|
});
|
|
856
859
|
return {
|
|
857
860
|
totalRuns: state.runs.length,
|
|
858
|
-
runsByStatus: countBy(state.runs, (record) => record.status),
|
|
861
|
+
runsByStatus: (0, helpers_1.countBy)(state.runs, (record) => record.status),
|
|
859
862
|
roles: state.roles.length,
|
|
860
863
|
groups: state.groups.length,
|
|
861
864
|
memberships: state.memberships.length,
|
|
862
865
|
fanouts: state.fanouts.length,
|
|
863
866
|
fanins: state.fanins.length,
|
|
864
|
-
groupsByStatus: countBy(state.groups, (record) => record.status),
|
|
865
|
-
membershipsByStatus: countBy(state.memberships, (record) => record.status),
|
|
866
|
-
faninsByStatus: countBy(state.fanins, (record) => record.status),
|
|
867
|
+
groupsByStatus: (0, helpers_1.countBy)(state.groups, (record) => record.status),
|
|
868
|
+
membershipsByStatus: (0, helpers_1.countBy)(state.memberships, (record) => record.status),
|
|
869
|
+
faninsByStatus: (0, helpers_1.countBy)(state.fanins, (record) => record.status),
|
|
867
870
|
blockedReasons,
|
|
868
871
|
groupsDetail,
|
|
869
872
|
nextAction: nextMultiAgentAction(run, blockedReasons)
|
|
@@ -871,70 +874,7 @@ function summarizeMultiAgent(run) {
|
|
|
871
874
|
}
|
|
872
875
|
function buildMultiAgentGraph(run) {
|
|
873
876
|
const state = ensureMultiAgentState(run);
|
|
874
|
-
|
|
875
|
-
const nodes = [];
|
|
876
|
-
const edges = [];
|
|
877
|
-
for (const record of state.runs) {
|
|
878
|
-
nodes.push({ id: `${run.id}:multi-agent:${record.id}`, kind: "multi-agent-run", status: record.status, label: record.title || record.id, path: recordPath(run, "runs", record.id) });
|
|
879
|
-
edges.push({ from: `${run.id}:run`, to: `${run.id}:multi-agent:${record.id}` });
|
|
880
|
-
if (record.blackboardId)
|
|
881
|
-
edges.push({ from: `${run.id}:multi-agent:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
|
|
882
|
-
if (record.parentMultiAgentRunId)
|
|
883
|
-
edges.push({ from: `${run.id}:multi-agent:${record.parentMultiAgentRunId}`, to: `${run.id}:multi-agent:${record.id}`, label: "child" });
|
|
884
|
-
}
|
|
885
|
-
for (const record of state.roles) {
|
|
886
|
-
nodes.push({ id: `${run.id}:multi-agent:role:${record.id}`, kind: "agent-role", status: record.status, label: record.title, path: recordPath(run, "roles", record.id) });
|
|
887
|
-
edges.push({ from: `${run.id}:multi-agent:${record.multiAgentRunId}`, to: `${run.id}:multi-agent:role:${record.id}` });
|
|
888
|
-
if (record.blackboardId)
|
|
889
|
-
edges.push({ from: `${run.id}:multi-agent:role:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
|
|
890
|
-
}
|
|
891
|
-
for (const record of state.groups) {
|
|
892
|
-
nodes.push({ id: `${run.id}:multi-agent:group:${record.id}`, kind: "agent-group", status: record.status, label: record.title || record.id, path: recordPath(run, "groups", record.id) });
|
|
893
|
-
edges.push({ from: `${run.id}:multi-agent:${record.multiAgentRunId}`, to: `${run.id}:multi-agent:group:${record.id}` });
|
|
894
|
-
if (record.blackboardId)
|
|
895
|
-
edges.push({ from: `${run.id}:multi-agent:group:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
|
|
896
|
-
for (const taskId of record.taskIds)
|
|
897
|
-
edges.push({ from: `${run.id}:multi-agent:group:${record.id}`, to: `${run.id}:task:${taskId}`, label: "task" });
|
|
898
|
-
}
|
|
899
|
-
for (const record of state.fanouts) {
|
|
900
|
-
nodes.push({ id: `${run.id}:multi-agent:fanout:${record.id}`, kind: "agent-fanout", status: record.status, label: record.reason, path: recordPath(run, "fanouts", record.id) });
|
|
901
|
-
edges.push({ from: `${run.id}:multi-agent:group:${record.groupId}`, to: `${run.id}:multi-agent:fanout:${record.id}` });
|
|
902
|
-
for (const dispatchId of record.dispatchIds)
|
|
903
|
-
edges.push({ from: `${run.id}:multi-agent:fanout:${record.id}`, to: `${run.id}:dispatch:${dispatchId}`, label: "dispatch" });
|
|
904
|
-
}
|
|
905
|
-
for (const record of state.memberships) {
|
|
906
|
-
nodes.push({ id: `${run.id}:multi-agent:membership:${record.id}`, kind: "agent-membership", status: record.status, label: `${record.roleId}/${record.taskId}`, path: recordPath(run, "memberships", record.id) });
|
|
907
|
-
edges.push({ from: `${run.id}:multi-agent:group:${record.groupId}`, to: `${run.id}:multi-agent:membership:${record.id}` });
|
|
908
|
-
edges.push({ from: `${run.id}:multi-agent:role:${record.roleId}`, to: `${run.id}:multi-agent:membership:${record.id}` });
|
|
909
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: `${run.id}:task:${record.taskId}`, label: "task" });
|
|
910
|
-
if (record.workerId)
|
|
911
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: `${run.id}:worker:${record.workerId}`, label: "worker" });
|
|
912
|
-
if (record.resultNodeId)
|
|
913
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: record.resultNodeId, label: "result" });
|
|
914
|
-
if (record.verifierNodeId)
|
|
915
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: record.verifierNodeId, label: "verifier" });
|
|
916
|
-
if (record.blackboardId)
|
|
917
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
|
|
918
|
-
for (const artifactId of record.blackboardArtifactRefIds || [])
|
|
919
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: `${run.id}:blackboard:artifact:${artifactId}`, label: "evidence" });
|
|
920
|
-
for (const messageId of record.blackboardMessageIds || [])
|
|
921
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${record.id}`, to: `${run.id}:blackboard:message:${messageId}`, label: "message" });
|
|
922
|
-
}
|
|
923
|
-
for (const record of state.fanins) {
|
|
924
|
-
nodes.push({ id: `${run.id}:multi-agent:fanin:${record.id}`, kind: "agent-fanin", status: record.status, label: record.strategy, path: recordPath(run, "fanins", record.id) });
|
|
925
|
-
edges.push({ from: `${run.id}:multi-agent:group:${record.groupId}`, to: `${run.id}:multi-agent:fanin:${record.id}` });
|
|
926
|
-
if (record.fanoutId)
|
|
927
|
-
edges.push({ from: `${run.id}:multi-agent:fanout:${record.fanoutId}`, to: `${run.id}:multi-agent:fanin:${record.id}` });
|
|
928
|
-
for (const membershipId of record.reportedMembershipIds)
|
|
929
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${membershipId}`, to: `${run.id}:multi-agent:fanin:${record.id}`, label: "reported" });
|
|
930
|
-
for (const membershipId of record.missingMembershipIds)
|
|
931
|
-
edges.push({ from: `${run.id}:multi-agent:membership:${membershipId}`, to: `${run.id}:multi-agent:fanin:${record.id}`, label: "missing" });
|
|
932
|
-
if (record.blackboardId)
|
|
933
|
-
edges.push({ from: `${run.id}:multi-agent:fanin:${record.id}`, to: `${run.id}:blackboard:${record.blackboardId}`, label: "blackboard" });
|
|
934
|
-
}
|
|
935
|
-
if (!node_fs_1.default.existsSync(root))
|
|
936
|
-
node_fs_1.default.mkdirSync(root, { recursive: true });
|
|
937
|
-
return { nodes, edges: uniqueEdges(edges) };
|
|
877
|
+
return (0, graph_1.buildMultiAgentGraphFromState)(run, state);
|
|
938
878
|
}
|
|
939
879
|
function getMultiAgentRun(run, id) {
|
|
940
880
|
return ensureMultiAgentState(run).runs.find((record) => record.id === id);
|
|
@@ -984,31 +924,11 @@ function requireRunTask(run, id) {
|
|
|
984
924
|
throw new Error(`Unknown task id for multi-agent record: ${id}`);
|
|
985
925
|
return task;
|
|
986
926
|
}
|
|
987
|
-
function multiAgentRoot(run) {
|
|
988
|
-
return run.paths.multiAgentDir || node_path_1.default.join(run.paths.runDir, "multi-agent");
|
|
989
|
-
}
|
|
990
|
-
function recordPath(run, kind, id) {
|
|
991
|
-
return node_path_1.default.join(multiAgentRoot(run), kind, `${(0, state_1.safeFileName)(id)}.json`);
|
|
992
|
-
}
|
|
993
927
|
function fanoutTopicIds(group, multiAgentRun, input) {
|
|
994
928
|
return [...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])];
|
|
995
929
|
}
|
|
996
930
|
function writeRecord(run, kind, record) {
|
|
997
|
-
(0, state_1.writeJson)(recordPath(run, kind, record.id), record);
|
|
998
|
-
}
|
|
999
|
-
function assertNoRecordPathCollisions(label, records) {
|
|
1000
|
-
const seen = new Map();
|
|
1001
|
-
for (const record of records) {
|
|
1002
|
-
const safe = (0, state_1.safeFileName)(record.id);
|
|
1003
|
-
const existing = seen.get(safe);
|
|
1004
|
-
if (existing && existing !== record.id) {
|
|
1005
|
-
throw new Error(`${label} ids ${existing} and ${record.id} collide on safe file name ${safe}`);
|
|
1006
|
-
}
|
|
1007
|
-
seen.set(safe, record.id);
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
function indexRow(record) {
|
|
1011
|
-
return { id: record.id, status: record.status, updatedAt: record.updatedAt };
|
|
931
|
+
(0, state_1.writeJson)((0, paths_1.recordPath)(run, kind, record.id), record);
|
|
1012
932
|
}
|
|
1013
933
|
function appendMultiAgentNode(run, kind, id, status, metadata, parents = []) {
|
|
1014
934
|
const nodeId = kind === "multi-agent-run" ? `${run.id}:multi-agent:${id}` : `${run.id}:multi-agent:${kind.replace("agent-", "")}:${id}`;
|
|
@@ -1018,81 +938,12 @@ function appendMultiAgentNode(run, kind, id, status, metadata, parents = []) {
|
|
|
1018
938
|
status,
|
|
1019
939
|
loopStage: run.loopStage,
|
|
1020
940
|
outputs: metadata,
|
|
1021
|
-
artifacts: [{ id: kind, kind: "json", path: recordPath(run, pluralKind(kind), id) }],
|
|
941
|
+
artifacts: [{ id: kind, kind: "json", path: (0, paths_1.recordPath)(run, (0, helpers_1.pluralKind)(kind), id) }],
|
|
1022
942
|
parents,
|
|
1023
943
|
contractId: pipeline_contract_1.DEFAULT_PIPELINE_CONTRACT_ID,
|
|
1024
944
|
metadata
|
|
1025
945
|
}));
|
|
1026
946
|
}
|
|
1027
|
-
function pluralKind(kind) {
|
|
1028
|
-
switch (kind) {
|
|
1029
|
-
case "multi-agent-run":
|
|
1030
|
-
return "runs";
|
|
1031
|
-
case "agent-role":
|
|
1032
|
-
return "roles";
|
|
1033
|
-
case "agent-group":
|
|
1034
|
-
return "groups";
|
|
1035
|
-
case "agent-membership":
|
|
1036
|
-
return "memberships";
|
|
1037
|
-
case "agent-fanout":
|
|
1038
|
-
return "fanouts";
|
|
1039
|
-
case "agent-fanin":
|
|
1040
|
-
return "fanins";
|
|
1041
|
-
default:
|
|
1042
|
-
return `${kind}s`;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
function statusToNodeStatus(status) {
|
|
1046
|
-
switch (status) {
|
|
1047
|
-
case "completed":
|
|
1048
|
-
case "reported":
|
|
1049
|
-
case "ready":
|
|
1050
|
-
return "completed";
|
|
1051
|
-
case "running":
|
|
1052
|
-
case "forming":
|
|
1053
|
-
case "collecting":
|
|
1054
|
-
case "verifying":
|
|
1055
|
-
case "assigned":
|
|
1056
|
-
case "active":
|
|
1057
|
-
case "dispatched":
|
|
1058
|
-
return "running";
|
|
1059
|
-
case "blocked":
|
|
1060
|
-
return "blocked";
|
|
1061
|
-
case "failed":
|
|
1062
|
-
return "failed";
|
|
1063
|
-
case "cancelled":
|
|
1064
|
-
case "rejected":
|
|
1065
|
-
return "rejected";
|
|
1066
|
-
default:
|
|
1067
|
-
return "pending";
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
function assertLifecycleTransition(from, to) {
|
|
1071
|
-
const allowed = {
|
|
1072
|
-
planned: ["forming", "running", "failed", "cancelled"],
|
|
1073
|
-
forming: ["running", "failed", "cancelled"],
|
|
1074
|
-
running: ["collecting", "completed", "failed", "cancelled"],
|
|
1075
|
-
collecting: ["verifying", "completed", "failed", "cancelled"],
|
|
1076
|
-
verifying: ["completed", "failed", "cancelled"],
|
|
1077
|
-
completed: [],
|
|
1078
|
-
failed: [],
|
|
1079
|
-
cancelled: []
|
|
1080
|
-
};
|
|
1081
|
-
if (from === to)
|
|
1082
|
-
return;
|
|
1083
|
-
if (!allowed[from].includes(to))
|
|
1084
|
-
throw new Error(`Invalid MultiAgentRun lifecycle transition: ${from} -> ${to}`);
|
|
1085
|
-
}
|
|
1086
|
-
function lifecycleEvent(from, to, reason, actor = "cw", metadata) {
|
|
1087
|
-
return {
|
|
1088
|
-
at: new Date().toISOString(),
|
|
1089
|
-
from,
|
|
1090
|
-
to,
|
|
1091
|
-
actor,
|
|
1092
|
-
reason,
|
|
1093
|
-
metadata: compact(metadata)
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
947
|
function attachWorkerMetadata(run, membership) {
|
|
1097
948
|
const workers = run.workers || [];
|
|
1098
949
|
const index = workers.findIndex((worker) => worker.id === membership.workerId);
|
|
@@ -1117,9 +968,6 @@ function attachWorkerMetadata(run, membership) {
|
|
|
1117
968
|
};
|
|
1118
969
|
run.workers = workers.map((candidate) => (candidate.id === worker.id ? updated : candidate));
|
|
1119
970
|
}
|
|
1120
|
-
function isMembershipReported(membership) {
|
|
1121
|
-
return (membership.status === "reported" || membership.status === "verified") && membership.evidenceRefs.length > 0;
|
|
1122
|
-
}
|
|
1123
971
|
function nextMultiAgentAction(run, blockedReasons) {
|
|
1124
972
|
const state = ensureMultiAgentState(run);
|
|
1125
973
|
if (!state.runs.length)
|
|
@@ -1134,40 +982,3 @@ function nextMultiAgentAction(run, blockedReasons) {
|
|
|
1134
982
|
return `node scripts/cw.js multi-agent fanin ${run.id} --group ${groupWithoutFanin.id}`;
|
|
1135
983
|
return undefined;
|
|
1136
984
|
}
|
|
1137
|
-
function touch(record) {
|
|
1138
|
-
record.updatedAt = new Date().toISOString();
|
|
1139
|
-
return record;
|
|
1140
|
-
}
|
|
1141
|
-
function createId(prefix) {
|
|
1142
|
-
const stamp = new Date().toISOString().replace(/[-:]/g, "").replace(/\..+/, "Z");
|
|
1143
|
-
return `${prefix}-${stamp}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1144
|
-
}
|
|
1145
|
-
function compact(value) {
|
|
1146
|
-
if (!value)
|
|
1147
|
-
return undefined;
|
|
1148
|
-
const entries = Object.entries(value).filter(([, entry]) => entry !== undefined);
|
|
1149
|
-
return entries.length ? Object.fromEntries(entries) : undefined;
|
|
1150
|
-
}
|
|
1151
|
-
function unique(values) {
|
|
1152
|
-
return Array.from(new Set(values.filter(Boolean))).sort();
|
|
1153
|
-
}
|
|
1154
|
-
function countBy(items, key) {
|
|
1155
|
-
const counts = {};
|
|
1156
|
-
for (const item of items) {
|
|
1157
|
-
const value = key(item);
|
|
1158
|
-
counts[value] = (counts[value] || 0) + 1;
|
|
1159
|
-
}
|
|
1160
|
-
return counts;
|
|
1161
|
-
}
|
|
1162
|
-
function uniqueEdges(edges) {
|
|
1163
|
-
const seen = new Set();
|
|
1164
|
-
const result = [];
|
|
1165
|
-
for (const edge of edges) {
|
|
1166
|
-
const key = `${edge.from}\0${edge.to}\0${edge.label || ""}`;
|
|
1167
|
-
if (seen.has(key))
|
|
1168
|
-
continue;
|
|
1169
|
-
seen.add(key);
|
|
1170
|
-
result.push(edge);
|
|
1171
|
-
}
|
|
1172
|
-
return result;
|
|
1173
|
-
}
|