cool-workflow 0.1.98 → 0.2.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +11 -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/cli/dispatch.js +236 -0
- package/dist/cli/entry.js +120 -0
- package/dist/cli/io.js +21 -4
- package/dist/cli/parseargv.js +157 -0
- package/dist/cli.js +6 -33
- package/dist/core/capability-table.js +3534 -0
- package/dist/core/format/help.js +314 -0
- package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
- package/dist/core/hash.js +137 -0
- package/dist/core/multi-agent/candidate-scoring.js +219 -0
- package/dist/core/multi-agent/collaboration.js +481 -0
- package/dist/core/multi-agent/coordinator.js +515 -0
- package/dist/core/multi-agent/eval-replay.js +306 -0
- package/dist/core/multi-agent/runtime.js +929 -0
- package/dist/core/multi-agent/topology.js +298 -0
- package/dist/core/multi-agent/trust-policy.js +197 -0
- package/dist/core/pipeline/commit-gate.js +320 -0
- package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
- package/dist/core/pipeline/dispatch.js +103 -0
- package/dist/core/pipeline/drive-decide.js +227 -0
- package/dist/core/pipeline/error-feedback.js +161 -0
- package/dist/core/pipeline/loop-expansion.js +124 -0
- package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
- package/dist/core/pipeline/runner.js +230 -0
- package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
- package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
- package/dist/core/state/node-projection.js +95 -0
- package/dist/core/state/node-snapshot.js +230 -0
- package/dist/core/state/run-paths.js +93 -0
- package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
- package/dist/core/state/schema.js +50 -0
- package/dist/core/state/state-explosion/digest.js +243 -0
- package/dist/core/state/state-explosion/graph.js +527 -0
- package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
- package/dist/core/state/state-explosion/report.js +187 -0
- package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
- package/dist/{state-node.js → core/state/state-node.js} +90 -113
- package/dist/core/state/types.js +19 -0
- package/dist/{validation.js → core/state/validation.js} +64 -131
- package/dist/core/trust/evidence-grounding.js +134 -0
- package/dist/core/trust/ledger.js +199 -0
- package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
- package/dist/core/trust/telemetry-ledger.js +127 -0
- package/dist/core/types.js +20 -0
- package/dist/core/version.js +16 -0
- package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
- package/dist/mcp/dispatch.js +104 -0
- package/dist/mcp/server.js +144 -0
- package/dist/mcp-server.js +6 -84
- package/dist/{agent-config.js → shell/agent-config.js} +118 -71
- package/dist/shell/app-run-cli.js +88 -0
- package/dist/shell/audit-cli.js +259 -0
- package/dist/shell/audit-provenance.js +83 -0
- package/dist/shell/candidate-scoring-io.js +459 -0
- package/dist/shell/collaboration-io.js +264 -0
- package/dist/shell/commit-summary.js +104 -0
- package/dist/shell/commit.js +290 -0
- package/dist/shell/coordinator-io.js +476 -0
- package/dist/shell/demo-cli.js +19 -0
- package/dist/shell/dispatch.js +162 -0
- package/dist/{doctor.js → shell/doctor.js} +123 -56
- package/dist/shell/drive.js +873 -0
- package/dist/shell/error-feedback-io.js +305 -0
- package/dist/shell/eval-io.js +473 -0
- package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
- package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
- package/dist/shell/exec-backend-cli.js +88 -0
- package/dist/shell/execution-backend/agent.js +475 -0
- package/dist/shell/execution-backend/ci.js +15 -0
- package/dist/shell/execution-backend/container.js +69 -0
- package/dist/shell/execution-backend/envelopes.js +55 -0
- package/dist/shell/execution-backend/local.js +113 -0
- package/dist/shell/execution-backend/probes.js +175 -0
- package/dist/shell/execution-backend/registry.js +402 -0
- package/dist/shell/execution-backend/remote.js +128 -0
- package/dist/shell/execution-backend/types.js +11 -0
- package/dist/shell/feedback-cli.js +81 -0
- package/dist/shell/feedback-operations.js +48 -0
- package/dist/shell/fs-atomic.js +276 -0
- package/dist/shell/harness.js +98 -0
- package/dist/shell/ledger-cli.js +212 -0
- package/dist/shell/ledger-io.js +169 -0
- package/dist/shell/man-cli.js +89 -0
- package/dist/shell/metrics-cli.js +98 -0
- package/dist/shell/multi-agent-cli.js +1002 -0
- package/dist/shell/multi-agent-host.js +563 -0
- package/dist/shell/multi-agent-io.js +387 -0
- package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
- package/dist/shell/node-store.js +124 -0
- package/dist/{observability/format.js → shell/observability-format.js} +7 -1
- package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
- package/dist/{observability.js → shell/observability.js} +159 -332
- package/dist/{onramp.js → shell/onramp.js} +11 -0
- package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
- package/dist/shell/operator-ux.js +431 -0
- package/dist/shell/orchestrator.js +231 -0
- package/dist/shell/pipeline-cli.js +667 -0
- package/dist/shell/pipeline.js +217 -0
- package/dist/shell/reclamation-io.js +1366 -0
- package/dist/shell/registry-cli.js +329 -0
- package/dist/{remote-source.js → shell/remote-source.js} +2 -2
- package/dist/shell/report-cli.js +101 -0
- package/dist/shell/report-view-cli.js +117 -0
- package/dist/{orchestrator → shell}/report.js +289 -282
- package/dist/shell/reporter.js +62 -0
- package/dist/shell/run-export-cli.js +106 -0
- package/dist/shell/run-export.js +680 -0
- package/dist/shell/run-registry-io.js +1014 -0
- package/dist/shell/run-store.js +164 -0
- package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
- package/dist/{scheduler.js → shell/scheduler-io.js} +248 -48
- package/dist/shell/scheduling-io.js +311 -0
- package/dist/shell/state-cli.js +181 -0
- package/dist/shell/state-explosion-cli.js +197 -0
- package/dist/shell/telemetry-cli.js +85 -0
- package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
- package/dist/shell/telemetry-ledger-io.js +132 -0
- package/dist/{term.js → shell/term.js} +36 -46
- package/dist/shell/topology-io.js +361 -0
- package/dist/shell/trust-audit.js +471 -0
- package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
- package/dist/shell/verifier.js +48 -0
- package/dist/shell/workbench-host.js +250 -0
- package/dist/shell/workbench-text.js +18 -0
- package/dist/shell/workbench.js +175 -0
- package/dist/shell/worker-cli.js +124 -0
- package/dist/shell/worker-isolation.js +852 -0
- package/dist/shell/workflow-app-loader.js +650 -0
- package/docs/agent-delegation-drive.7.md +2 -0
- package/docs/cli-mcp-parity.7.md +280 -219
- package/docs/contract-migration-tooling.7.md +2 -0
- package/docs/control-plane-scheduling.7.md +2 -0
- package/docs/durable-state-and-locking.7.md +2 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
- package/docs/execution-backends.7.md +2 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +2 -0
- package/docs/multi-agent-eval-replay-harness.7.md +2 -0
- package/docs/multi-agent-operator-ux.7.md +2 -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 +132 -71
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +2 -0
- package/docs/release-tooling.7.md +2 -0
- package/docs/run-registry-control-plane.7.md +2 -0
- package/docs/run-retention-reclamation.7.md +23 -0
- package/docs/state-explosion-management.7.md +2 -0
- package/docs/team-collaboration.7.md +2 -0
- package/docs/web-desktop-workbench.7.md +2 -0
- package/manifest/plugin.manifest.json +1 -1
- package/manifest/source-context-profiles.json +9 -13
- package/package.json +1 -1
- package/scripts/agents/cw-attest-wrap.js +2 -2
- package/scripts/bump-version.js +4 -3
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-architecture-review.js +2 -3
- package/scripts/dogfood-release.js +3 -3
- package/scripts/gen-parity-doc.js +15 -2
- package/scripts/golden-path.js +4 -4
- package/scripts/onramp-check.js +1 -1
- package/scripts/parity-check.js +38 -21
- package/scripts/release-flow.js +2 -2
- package/scripts/sync-project-index.js +51 -27
- package/scripts/validate-run-state-schema.js +2 -2
- package/scripts/version-sync-check.js +30 -30
- package/dist/candidate-scoring.js +0 -729
- package/dist/capability-core.js +0 -1189
- package/dist/capability-registry.js +0 -885
- package/dist/cli/command-surface.js +0 -494
- package/dist/cli/format.js +0 -56
- package/dist/cli/handlers/audit.js +0 -82
- package/dist/cli/handlers/blackboard.js +0 -81
- package/dist/cli/handlers/candidate.js +0 -40
- package/dist/cli/handlers/clones.js +0 -34
- package/dist/cli/handlers/collaboration.js +0 -61
- package/dist/cli/handlers/eval.js +0 -40
- package/dist/cli/handlers/ledger.js +0 -169
- package/dist/cli/handlers/maintenance.js +0 -107
- package/dist/cli/handlers/multi-agent.js +0 -165
- package/dist/cli/handlers/node.js +0 -41
- package/dist/cli/handlers/operational.js +0 -155
- package/dist/cli/handlers/operator.js +0 -146
- package/dist/cli/handlers/registry.js +0 -68
- package/dist/cli/handlers/run.js +0 -153
- package/dist/cli/handlers/scheduling.js +0 -132
- package/dist/cli/handlers/workbench.js +0 -41
- package/dist/cli/handlers/worker.js +0 -45
- package/dist/cli/run-summary.js +0 -45
- package/dist/clones.js +0 -162
- package/dist/collaboration.js +0 -726
- package/dist/commit.js +0 -592
- package/dist/compare.js +0 -18
- package/dist/coordinator/classify.js +0 -45
- package/dist/coordinator/paths.js +0 -42
- package/dist/coordinator/util.js +0 -126
- package/dist/coordinator.js +0 -990
- package/dist/daemon.js +0 -44
- package/dist/dispatch.js +0 -250
- package/dist/drive.js +0 -864
- package/dist/error-feedback.js +0 -419
- package/dist/evidence-grounding.js +0 -184
- package/dist/execution-backend/agent.js +0 -354
- package/dist/execution-backend/probes.js +0 -112
- package/dist/execution-backend/util.js +0 -47
- package/dist/execution-backend.js +0 -961
- package/dist/gates.js +0 -48
- package/dist/harness.js +0 -61
- package/dist/ledger.js +0 -313
- package/dist/loop-expansion.js +0 -60
- package/dist/mcp/tool-call.js +0 -470
- package/dist/mcp/tool-definitions.js +0 -1066
- package/dist/mcp-surface.js +0 -30
- package/dist/multi-agent/graph.js +0 -84
- package/dist/multi-agent/helpers.js +0 -141
- package/dist/multi-agent/ids.js +0 -20
- package/dist/multi-agent/paths.js +0 -22
- package/dist/multi-agent-eval/normalize.js +0 -51
- package/dist/multi-agent-eval.js +0 -678
- package/dist/multi-agent-host.js +0 -777
- package/dist/multi-agent.js +0 -984
- package/dist/node-projection.js +0 -59
- package/dist/node-snapshot.js +0 -260
- package/dist/operator-ux.js +0 -631
- package/dist/orchestrator/app-operations.js +0 -211
- package/dist/orchestrator/audit-operations.js +0 -182
- package/dist/orchestrator/candidate-operations.js +0 -117
- package/dist/orchestrator/cli-options.js +0 -294
- package/dist/orchestrator/collaboration-operations.js +0 -86
- package/dist/orchestrator/feedback-operations.js +0 -81
- package/dist/orchestrator/host-operations.js +0 -78
- package/dist/orchestrator/lifecycle-operations.js +0 -650
- package/dist/orchestrator/migration-operations.js +0 -44
- package/dist/orchestrator/multi-agent-operations.js +0 -362
- package/dist/orchestrator/topology-operations.js +0 -84
- package/dist/orchestrator.js +0 -925
- package/dist/pipeline-runner.js +0 -285
- package/dist/reclamation/hash.js +0 -72
- package/dist/reclamation.js +0 -812
- package/dist/reporter.js +0 -67
- package/dist/run-export.js +0 -815
- package/dist/run-registry/derive.js +0 -175
- package/dist/run-registry/format.js +0 -124
- package/dist/run-registry/gc.js +0 -251
- package/dist/run-registry/policy.js +0 -16
- package/dist/run-registry/queue.js +0 -115
- package/dist/run-registry.js +0 -850
- package/dist/run-state-schema.js +0 -68
- package/dist/scheduling.js +0 -184
- package/dist/state-explosion.js +0 -1014
- package/dist/state.js +0 -367
- package/dist/telemetry-ledger.js +0 -196
- package/dist/topology.js +0 -565
- package/dist/triggers.js +0 -184
- package/dist/trust-audit.js +0 -644
- package/dist/types/blackboard.js +0 -2
- package/dist/types/candidate.js +0 -2
- package/dist/types/collaboration.js +0 -2
- package/dist/types/core.js +0 -2
- package/dist/types/drive.js +0 -10
- package/dist/types/error-feedback.js +0 -2
- package/dist/types/evidence-reasoning.js +0 -2
- package/dist/types/execution-backend.js +0 -2
- package/dist/types/multi-agent.js +0 -2
- package/dist/types/observability.js +0 -2
- package/dist/types/pipeline.js +0 -2
- package/dist/types/reclamation.js +0 -8
- package/dist/types/report-bundle.js +0 -6
- package/dist/types/result.js +0 -2
- package/dist/types/run-registry.js +0 -2
- package/dist/types/run.js +0 -2
- package/dist/types/sandbox.js +0 -2
- package/dist/types/schedule.js +0 -2
- package/dist/types/state-node.js +0 -2
- package/dist/types/topology.js +0 -2
- package/dist/types/trust.js +0 -2
- package/dist/types/workbench.js +0 -2
- package/dist/types/worker.js +0 -2
- package/dist/types/workflow-app.js +0 -2
- package/dist/types.js +0 -44
- package/dist/util/fingerprint.js +0 -19
- package/dist/util/fingerprint.test.js +0 -27
- package/dist/verifier.js +0 -78
- package/dist/version.js +0 -8
- package/dist/workbench-host.js +0 -192
- package/dist/workbench.js +0 -192
- package/dist/worker-accept/acceptance.js +0 -114
- package/dist/worker-accept/blackboard-fanout.js +0 -80
- package/dist/worker-accept/blackboard-linkage.js +0 -19
- package/dist/worker-accept/context.js +0 -2
- package/dist/worker-accept/telemetry-ledger.js +0 -126
- package/dist/worker-accept/validation.js +0 -77
- package/dist/worker-accept/verifier-completion.js +0 -73
- package/dist/worker-isolation/helpers.js +0 -51
- package/dist/worker-isolation/paths.js +0 -46
- package/dist/worker-isolation.js +0 -656
- package/dist/workflow-api.js +0 -131
- /package/dist/{types → core/types}/boundary.js +0 -0
package/dist/multi-agent.js
DELETED
|
@@ -1,984 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MULTI_AGENT_SCHEMA_VERSION = void 0;
|
|
7
|
-
exports.ensureMultiAgentState = ensureMultiAgentState;
|
|
8
|
-
exports.persistMultiAgentState = persistMultiAgentState;
|
|
9
|
-
exports.createMultiAgentRun = createMultiAgentRun;
|
|
10
|
-
exports.transitionMultiAgentRun = transitionMultiAgentRun;
|
|
11
|
-
exports.createAgentRole = createAgentRole;
|
|
12
|
-
exports.createAgentGroup = createAgentGroup;
|
|
13
|
-
exports.assignAgentMembership = assignAgentMembership;
|
|
14
|
-
exports.createAgentFanout = createAgentFanout;
|
|
15
|
-
exports.attachDispatchToMultiAgent = attachDispatchToMultiAgent;
|
|
16
|
-
exports.collectAgentFanin = collectAgentFanin;
|
|
17
|
-
exports.recordMultiAgentWorkerOutput = recordMultiAgentWorkerOutput;
|
|
18
|
-
exports.summarizeMultiAgent = summarizeMultiAgent;
|
|
19
|
-
exports.buildMultiAgentGraph = buildMultiAgentGraph;
|
|
20
|
-
exports.getMultiAgentRun = getMultiAgentRun;
|
|
21
|
-
exports.getAgentRole = getAgentRole;
|
|
22
|
-
exports.getAgentGroup = getAgentGroup;
|
|
23
|
-
exports.getAgentMembership = getAgentMembership;
|
|
24
|
-
exports.getAgentFanout = getAgentFanout;
|
|
25
|
-
exports.getAgentFanin = getAgentFanin;
|
|
26
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
27
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
28
|
-
const state_1 = require("./state");
|
|
29
|
-
const pipeline_contract_1 = require("./pipeline-contract");
|
|
30
|
-
const state_node_1 = require("./state-node");
|
|
31
|
-
const trust_audit_1 = require("./trust-audit");
|
|
32
|
-
const multi_agent_trust_1 = require("./multi-agent-trust");
|
|
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; } });
|
|
37
|
-
function ensureMultiAgentState(run) {
|
|
38
|
-
run.paths.multiAgentDir = (0, paths_1.multiAgentRoot)(run);
|
|
39
|
-
node_fs_1.default.mkdirSync(run.paths.multiAgentDir, { recursive: true });
|
|
40
|
-
for (const dir of ["runs", "roles", "groups", "memberships", "fanouts", "fanins"]) {
|
|
41
|
-
node_fs_1.default.mkdirSync(node_path_1.default.join(run.paths.multiAgentDir, dir), { recursive: true });
|
|
42
|
-
}
|
|
43
|
-
if (!run.multiAgent) {
|
|
44
|
-
run.multiAgent = {
|
|
45
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
46
|
-
runs: [],
|
|
47
|
-
roles: [],
|
|
48
|
-
groups: [],
|
|
49
|
-
memberships: [],
|
|
50
|
-
fanouts: [],
|
|
51
|
-
fanins: []
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
run.multiAgent.schemaVersion = helpers_1.MULTI_AGENT_SCHEMA_VERSION;
|
|
55
|
-
run.multiAgent.runs = run.multiAgent.runs || [];
|
|
56
|
-
run.multiAgent.roles = run.multiAgent.roles || [];
|
|
57
|
-
run.multiAgent.groups = run.multiAgent.groups || [];
|
|
58
|
-
run.multiAgent.memberships = run.multiAgent.memberships || [];
|
|
59
|
-
run.multiAgent.fanouts = run.multiAgent.fanouts || [];
|
|
60
|
-
run.multiAgent.fanins = run.multiAgent.fanins || [];
|
|
61
|
-
return run.multiAgent;
|
|
62
|
-
}
|
|
63
|
-
function persistMultiAgentState(run) {
|
|
64
|
-
const state = ensureMultiAgentState(run);
|
|
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);
|
|
72
|
-
(0, state_1.writeJson)(node_path_1.default.join(root, "index.json"), {
|
|
73
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
74
|
-
runId: run.id,
|
|
75
|
-
counts: {
|
|
76
|
-
runs: state.runs.length,
|
|
77
|
-
roles: state.roles.length,
|
|
78
|
-
groups: state.groups.length,
|
|
79
|
-
memberships: state.memberships.length,
|
|
80
|
-
fanouts: state.fanouts.length,
|
|
81
|
-
fanins: state.fanins.length
|
|
82
|
-
},
|
|
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)
|
|
89
|
-
});
|
|
90
|
-
for (const record of state.runs)
|
|
91
|
-
writeRecord(run, "runs", record);
|
|
92
|
-
for (const record of state.roles)
|
|
93
|
-
writeRecord(run, "roles", record);
|
|
94
|
-
for (const record of state.groups)
|
|
95
|
-
writeRecord(run, "groups", record);
|
|
96
|
-
for (const record of state.memberships)
|
|
97
|
-
writeRecord(run, "memberships", record);
|
|
98
|
-
for (const record of state.fanouts)
|
|
99
|
-
writeRecord(run, "fanouts", record);
|
|
100
|
-
for (const record of state.fanins)
|
|
101
|
-
writeRecord(run, "fanins", record);
|
|
102
|
-
}
|
|
103
|
-
function createMultiAgentRun(run, input = {}) {
|
|
104
|
-
const state = ensureMultiAgentState(run);
|
|
105
|
-
const id = input.id || (0, helpers_1.createId)("mar", state.runs.length + 1);
|
|
106
|
-
if (state.runs.some((record) => record.id === id))
|
|
107
|
-
throw new Error(`Duplicate MultiAgentRun id: ${id}`);
|
|
108
|
-
const now = new Date().toISOString();
|
|
109
|
-
const status = input.status || "planned";
|
|
110
|
-
const record = {
|
|
111
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
112
|
-
id,
|
|
113
|
-
runId: run.id,
|
|
114
|
-
createdAt: now,
|
|
115
|
-
updatedAt: now,
|
|
116
|
-
status,
|
|
117
|
-
title: input.title || id,
|
|
118
|
-
objective: input.objective,
|
|
119
|
-
parentMultiAgentRunId: input.parentMultiAgentRunId,
|
|
120
|
-
childMultiAgentRunIds: [],
|
|
121
|
-
roleIds: [],
|
|
122
|
-
groupIds: [],
|
|
123
|
-
fanoutIds: [],
|
|
124
|
-
faninIds: [],
|
|
125
|
-
blackboardId: input.blackboardId,
|
|
126
|
-
topicIds: (0, helpers_1.unique)(input.topicIds || []),
|
|
127
|
-
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, status, "created")],
|
|
128
|
-
links: {
|
|
129
|
-
workflowRunId: run.id,
|
|
130
|
-
phase: input.phase,
|
|
131
|
-
phaseId: input.phaseId,
|
|
132
|
-
blackboardId: input.blackboardId,
|
|
133
|
-
blackboardTopicIds: (0, helpers_1.unique)(input.topicIds || [])
|
|
134
|
-
},
|
|
135
|
-
policy: {
|
|
136
|
-
schemaVersion: 1,
|
|
137
|
-
id: `${id}-policy`,
|
|
138
|
-
policyRef: `multiAgent.runs.${id}.policy`,
|
|
139
|
-
subjectKind: "multi-agent-run",
|
|
140
|
-
subjectId: id,
|
|
141
|
-
allowedBlackboardTopicIds: (0, helpers_1.unique)(input.topicIds || ["*"]),
|
|
142
|
-
allowedWriteOperations: ["message", "context", "artifact", "snapshot", "topic", "coordinator-decision"],
|
|
143
|
-
allowedCandidateOperations: ["register", "score", "select"],
|
|
144
|
-
allowedJudgeOperations: ["verdict", "rationale", "panel-decision"],
|
|
145
|
-
sandboxProfileHints: [],
|
|
146
|
-
requiredEvidenceRefs: [],
|
|
147
|
-
deniedOperations: [],
|
|
148
|
-
metadata: { title: input.title }
|
|
149
|
-
},
|
|
150
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
151
|
-
};
|
|
152
|
-
if (record.parentMultiAgentRunId) {
|
|
153
|
-
const parent = requireMultiAgentRun(run, record.parentMultiAgentRunId);
|
|
154
|
-
parent.childMultiAgentRunIds = (0, helpers_1.unique)([...parent.childMultiAgentRunIds, record.id]);
|
|
155
|
-
(0, helpers_1.touch)(parent);
|
|
156
|
-
}
|
|
157
|
-
state.runs.push(record);
|
|
158
|
-
appendMultiAgentNode(run, "multi-agent-run", record.id, (0, helpers_1.statusToNodeStatus)(status), {
|
|
159
|
-
title: record.title,
|
|
160
|
-
objective: record.objective,
|
|
161
|
-
phase: record.links.phase
|
|
162
|
-
});
|
|
163
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
164
|
-
kind: "multi-agent.run",
|
|
165
|
-
decision: "recorded",
|
|
166
|
-
source: "runtime-derived",
|
|
167
|
-
multiAgentRunId: record.id,
|
|
168
|
-
metadata: { status: record.status, objective: record.objective }
|
|
169
|
-
});
|
|
170
|
-
persistMultiAgentState(run);
|
|
171
|
-
return record;
|
|
172
|
-
}
|
|
173
|
-
function transitionMultiAgentRun(run, multiAgentRunId, status, options = {}) {
|
|
174
|
-
ensureMultiAgentState(run);
|
|
175
|
-
const record = requireMultiAgentRun(run, multiAgentRunId);
|
|
176
|
-
(0, helpers_1.assertLifecycleTransition)(record.status, status);
|
|
177
|
-
if (status === "completed")
|
|
178
|
-
assertMultiAgentRunCompletionReady(run, record);
|
|
179
|
-
const before = record.status;
|
|
180
|
-
record.status = status;
|
|
181
|
-
record.updatedAt = new Date().toISOString();
|
|
182
|
-
record.lifecycle.push((0, helpers_1.lifecycleEvent)(before, status, options.reason, options.actor, options.metadata));
|
|
183
|
-
if (status === "completed")
|
|
184
|
-
completeOwnedMultiAgentRecords(run, record, options.reason);
|
|
185
|
-
appendMultiAgentNode(run, "multi-agent-run", record.id, (0, helpers_1.statusToNodeStatus)(status), {
|
|
186
|
-
status,
|
|
187
|
-
reason: options.reason
|
|
188
|
-
});
|
|
189
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
190
|
-
kind: "multi-agent.lifecycle",
|
|
191
|
-
decision: status === "failed" ? "failed" : "validated",
|
|
192
|
-
source: "cw-validated",
|
|
193
|
-
multiAgentRunId: record.id,
|
|
194
|
-
metadata: { from: before, to: status, reason: options.reason }
|
|
195
|
-
});
|
|
196
|
-
persistMultiAgentState(run);
|
|
197
|
-
return record;
|
|
198
|
-
}
|
|
199
|
-
function assertMultiAgentRunCompletionReady(run, multiAgentRun) {
|
|
200
|
-
const state = ensureMultiAgentState(run);
|
|
201
|
-
const groups = state.groups.filter((record) => record.multiAgentRunId === multiAgentRun.id);
|
|
202
|
-
const fanins = state.fanins.filter((record) => record.multiAgentRunId === multiAgentRun.id);
|
|
203
|
-
const blocked = fanins.flatMap((fanin) => {
|
|
204
|
-
const reasons = [...fanin.blockedReasons];
|
|
205
|
-
if (fanin.status === "blocked" || fanin.status === "failed")
|
|
206
|
-
reasons.push(`fanin ${fanin.id} status is ${fanin.status}`);
|
|
207
|
-
if (!fanin.verifierReady)
|
|
208
|
-
reasons.push(`fanin ${fanin.id} is not verifier-ready`);
|
|
209
|
-
return reasons.map((reason) => `${fanin.id}: ${reason}`);
|
|
210
|
-
});
|
|
211
|
-
for (const group of groups) {
|
|
212
|
-
if ((group.membershipIds.length || group.fanoutIds.length) && !group.faninIds.length) {
|
|
213
|
-
blocked.push(`group ${group.id} has no fanin record`);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
if (blocked.length) {
|
|
217
|
-
throw new Error(`Cannot complete MultiAgentRun ${multiAgentRun.id}: ${blocked.join("; ")}`);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function completeOwnedMultiAgentRecords(run, multiAgentRun, reason) {
|
|
221
|
-
const state = ensureMultiAgentState(run);
|
|
222
|
-
for (const role of state.roles.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
223
|
-
if (role.status === "completed" || role.status === "cancelled")
|
|
224
|
-
continue;
|
|
225
|
-
const before = role.status;
|
|
226
|
-
role.status = "completed";
|
|
227
|
-
role.updatedAt = multiAgentRun.updatedAt;
|
|
228
|
-
role.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
229
|
-
}
|
|
230
|
-
for (const group of state.groups.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
231
|
-
if (group.status === "completed" || group.status === "failed" || group.status === "cancelled")
|
|
232
|
-
continue;
|
|
233
|
-
const before = group.status;
|
|
234
|
-
group.status = "completed";
|
|
235
|
-
group.updatedAt = multiAgentRun.updatedAt;
|
|
236
|
-
group.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
237
|
-
}
|
|
238
|
-
for (const fanout of state.fanouts.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
239
|
-
if (fanout.status === "completed" || fanout.status === "failed" || fanout.status === "cancelled")
|
|
240
|
-
continue;
|
|
241
|
-
const before = fanout.status;
|
|
242
|
-
fanout.status = "completed";
|
|
243
|
-
fanout.updatedAt = multiAgentRun.updatedAt;
|
|
244
|
-
fanout.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
245
|
-
}
|
|
246
|
-
for (const fanin of state.fanins.filter((record) => record.multiAgentRunId === multiAgentRun.id)) {
|
|
247
|
-
if (fanin.status === "completed" || fanin.status === "failed")
|
|
248
|
-
continue;
|
|
249
|
-
const before = fanin.status;
|
|
250
|
-
fanin.status = "completed";
|
|
251
|
-
fanin.updatedAt = multiAgentRun.updatedAt;
|
|
252
|
-
fanin.lifecycle.push((0, helpers_1.lifecycleEvent)(before, "completed", reason || "multi-agent run completed"));
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
function createAgentRole(run, input) {
|
|
256
|
-
const state = ensureMultiAgentState(run);
|
|
257
|
-
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId);
|
|
258
|
-
const id = input.id || (0, helpers_1.createId)("role", state.roles.length + 1);
|
|
259
|
-
if (state.roles.some((record) => record.id === id))
|
|
260
|
-
throw new Error(`Duplicate AgentRole id: ${id}`);
|
|
261
|
-
if (input.parentRoleId)
|
|
262
|
-
requireAgentRole(run, input.parentRoleId);
|
|
263
|
-
const now = new Date().toISOString();
|
|
264
|
-
const role = {
|
|
265
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
266
|
-
id,
|
|
267
|
-
runId: run.id,
|
|
268
|
-
multiAgentRunId: multiAgentRun.id,
|
|
269
|
-
createdAt: now,
|
|
270
|
-
updatedAt: now,
|
|
271
|
-
status: "planned",
|
|
272
|
-
title: input.title || id,
|
|
273
|
-
responsibilities: input.responsibilities || [],
|
|
274
|
-
requiredEvidence: input.requiredEvidence || [],
|
|
275
|
-
sandboxProfileHints: input.sandboxProfileHints || [],
|
|
276
|
-
expectedArtifacts: input.expectedArtifacts || [],
|
|
277
|
-
faninObligations: input.faninObligations || [],
|
|
278
|
-
blackboardId: input.blackboardId || multiAgentRun.blackboardId,
|
|
279
|
-
topicIds: (0, helpers_1.unique)([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
280
|
-
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "planned", "created")],
|
|
281
|
-
parentRoleId: input.parentRoleId,
|
|
282
|
-
childRoleIds: [],
|
|
283
|
-
policy: undefined,
|
|
284
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
285
|
-
};
|
|
286
|
-
role.policy = (0, multi_agent_trust_1.policyForRole)(role);
|
|
287
|
-
if (role.parentRoleId) {
|
|
288
|
-
const parent = requireAgentRole(run, role.parentRoleId);
|
|
289
|
-
parent.childRoleIds = (0, helpers_1.unique)([...parent.childRoleIds, role.id]);
|
|
290
|
-
(0, helpers_1.touch)(parent);
|
|
291
|
-
}
|
|
292
|
-
state.roles.push(role);
|
|
293
|
-
multiAgentRun.roleIds = (0, helpers_1.unique)([...multiAgentRun.roleIds, role.id]);
|
|
294
|
-
(0, helpers_1.touch)(multiAgentRun);
|
|
295
|
-
appendMultiAgentNode(run, "agent-role", role.id, "pending", {
|
|
296
|
-
multiAgentRunId: role.multiAgentRunId,
|
|
297
|
-
title: role.title,
|
|
298
|
-
responsibilities: role.responsibilities,
|
|
299
|
-
requiredEvidence: role.requiredEvidence
|
|
300
|
-
}, [`${run.id}:multi-agent:${role.multiAgentRunId}`]);
|
|
301
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
302
|
-
kind: "multi-agent.role",
|
|
303
|
-
decision: "recorded",
|
|
304
|
-
source: "runtime-derived",
|
|
305
|
-
multiAgentRunId: role.multiAgentRunId,
|
|
306
|
-
agentRoleId: role.id,
|
|
307
|
-
metadata: {
|
|
308
|
-
responsibilities: role.responsibilities,
|
|
309
|
-
requiredEvidence: role.requiredEvidence,
|
|
310
|
-
sandboxProfileHints: role.sandboxProfileHints,
|
|
311
|
-
faninObligations: role.faninObligations
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
(0, multi_agent_trust_1.recordRolePolicyAudit)(run, role);
|
|
315
|
-
persistMultiAgentState(run);
|
|
316
|
-
return role;
|
|
317
|
-
}
|
|
318
|
-
function createAgentGroup(run, input) {
|
|
319
|
-
const state = ensureMultiAgentState(run);
|
|
320
|
-
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId);
|
|
321
|
-
const id = input.id || (0, helpers_1.createId)("group", state.groups.length + 1);
|
|
322
|
-
if (state.groups.some((record) => record.id === id))
|
|
323
|
-
throw new Error(`Duplicate AgentGroup id: ${id}`);
|
|
324
|
-
if (input.parentGroupId)
|
|
325
|
-
requireAgentGroup(run, input.parentGroupId);
|
|
326
|
-
for (const taskId of input.taskIds || [])
|
|
327
|
-
requireRunTask(run, taskId);
|
|
328
|
-
const now = new Date().toISOString();
|
|
329
|
-
const group = {
|
|
330
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
331
|
-
id,
|
|
332
|
-
runId: run.id,
|
|
333
|
-
multiAgentRunId: multiAgentRun.id,
|
|
334
|
-
createdAt: now,
|
|
335
|
-
updatedAt: now,
|
|
336
|
-
status: "forming",
|
|
337
|
-
title: input.title || id,
|
|
338
|
-
phase: input.phase,
|
|
339
|
-
phaseId: input.phaseId,
|
|
340
|
-
taskIds: (0, helpers_1.unique)(input.taskIds || []),
|
|
341
|
-
roleIds: [],
|
|
342
|
-
membershipIds: [],
|
|
343
|
-
workerIds: [],
|
|
344
|
-
fanoutIds: [],
|
|
345
|
-
faninIds: [],
|
|
346
|
-
blackboardId: input.blackboardId || multiAgentRun.blackboardId,
|
|
347
|
-
topicIds: (0, helpers_1.unique)([...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
348
|
-
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "forming", "created")],
|
|
349
|
-
parentGroupId: input.parentGroupId,
|
|
350
|
-
childGroupIds: [],
|
|
351
|
-
policy: undefined,
|
|
352
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
353
|
-
};
|
|
354
|
-
group.policy = (0, multi_agent_trust_1.policyForGroup)(group);
|
|
355
|
-
if (group.parentGroupId) {
|
|
356
|
-
const parent = requireAgentGroup(run, group.parentGroupId);
|
|
357
|
-
parent.childGroupIds = (0, helpers_1.unique)([...parent.childGroupIds, group.id]);
|
|
358
|
-
(0, helpers_1.touch)(parent);
|
|
359
|
-
}
|
|
360
|
-
state.groups.push(group);
|
|
361
|
-
multiAgentRun.groupIds = (0, helpers_1.unique)([...multiAgentRun.groupIds, group.id]);
|
|
362
|
-
(0, helpers_1.touch)(multiAgentRun);
|
|
363
|
-
appendMultiAgentNode(run, "agent-group", group.id, "running", {
|
|
364
|
-
multiAgentRunId: group.multiAgentRunId,
|
|
365
|
-
phase: group.phase,
|
|
366
|
-
taskIds: group.taskIds
|
|
367
|
-
}, [`${run.id}:multi-agent:${group.multiAgentRunId}`]);
|
|
368
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
369
|
-
kind: "multi-agent.group",
|
|
370
|
-
decision: "recorded",
|
|
371
|
-
source: "runtime-derived",
|
|
372
|
-
multiAgentRunId: group.multiAgentRunId,
|
|
373
|
-
agentGroupId: group.id,
|
|
374
|
-
metadata: { phase: group.phase, taskIds: group.taskIds }
|
|
375
|
-
});
|
|
376
|
-
persistMultiAgentState(run);
|
|
377
|
-
return group;
|
|
378
|
-
}
|
|
379
|
-
function assignAgentMembership(run, input) {
|
|
380
|
-
const state = ensureMultiAgentState(run);
|
|
381
|
-
const group = requireAgentGroup(run, input.groupId);
|
|
382
|
-
const role = requireAgentRole(run, input.roleId);
|
|
383
|
-
if (role.multiAgentRunId !== group.multiAgentRunId) {
|
|
384
|
-
throw new Error(`AgentRole ${role.id} belongs to ${role.multiAgentRunId}, not group run ${group.multiAgentRunId}`);
|
|
385
|
-
}
|
|
386
|
-
if (input.multiAgentRunId && input.multiAgentRunId !== group.multiAgentRunId) {
|
|
387
|
-
throw new Error(`Membership multiAgentRunId ${input.multiAgentRunId} does not match group ${group.id}`);
|
|
388
|
-
}
|
|
389
|
-
const task = requireRunTask(run, input.taskId);
|
|
390
|
-
if (input.workerId && !(run.workers || []).some((worker) => worker.id === input.workerId)) {
|
|
391
|
-
throw new Error(`Unknown worker id for membership: ${input.workerId}`);
|
|
392
|
-
}
|
|
393
|
-
const duplicate = state.memberships.find((membership) => membership.groupId === group.id &&
|
|
394
|
-
membership.roleId === role.id &&
|
|
395
|
-
membership.taskId === task.id &&
|
|
396
|
-
(input.workerId ? membership.workerId === input.workerId : !membership.workerId));
|
|
397
|
-
if (duplicate) {
|
|
398
|
-
throw new Error(`Duplicate AgentMembership for group=${group.id}, role=${role.id}, task=${task.id}, worker=${input.workerId || "none"}`);
|
|
399
|
-
}
|
|
400
|
-
const id = input.id || (0, helpers_1.createId)("membership", state.memberships.length + 1);
|
|
401
|
-
if (state.memberships.some((record) => record.id === id))
|
|
402
|
-
throw new Error(`Duplicate AgentMembership id: ${id}`);
|
|
403
|
-
const now = new Date().toISOString();
|
|
404
|
-
const status = input.status || (input.workerId ? "running" : "assigned");
|
|
405
|
-
const membership = {
|
|
406
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
407
|
-
id,
|
|
408
|
-
runId: run.id,
|
|
409
|
-
multiAgentRunId: group.multiAgentRunId,
|
|
410
|
-
groupId: group.id,
|
|
411
|
-
roleId: role.id,
|
|
412
|
-
taskId: task.id,
|
|
413
|
-
workerId: input.workerId,
|
|
414
|
-
dispatchId: input.dispatchId,
|
|
415
|
-
fanoutId: input.fanoutId,
|
|
416
|
-
createdAt: now,
|
|
417
|
-
updatedAt: now,
|
|
418
|
-
status,
|
|
419
|
-
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, status, "assigned")],
|
|
420
|
-
evidenceRefs: [],
|
|
421
|
-
artifactPaths: [],
|
|
422
|
-
blackboardId: input.blackboardId || group.blackboardId || role.blackboardId,
|
|
423
|
-
topicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(role.topicIds || []), ...(input.topicIds || [])]),
|
|
424
|
-
blackboardMessageIds: [],
|
|
425
|
-
blackboardArtifactRefIds: [],
|
|
426
|
-
policy: undefined,
|
|
427
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
428
|
-
};
|
|
429
|
-
membership.policy = (0, multi_agent_trust_1.policyForMembership)(membership, role);
|
|
430
|
-
state.memberships.push(membership);
|
|
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]);
|
|
434
|
-
if (membership.workerId)
|
|
435
|
-
group.workerIds = (0, helpers_1.unique)([...group.workerIds, membership.workerId]);
|
|
436
|
-
(0, helpers_1.touch)(group);
|
|
437
|
-
const roleStatusBefore = role.status;
|
|
438
|
-
role.status = "active";
|
|
439
|
-
role.updatedAt = now;
|
|
440
|
-
role.lifecycle.push((0, helpers_1.lifecycleEvent)(roleStatusBefore, "active", "membership assigned"));
|
|
441
|
-
if (membership.workerId)
|
|
442
|
-
attachWorkerMetadata(run, membership);
|
|
443
|
-
appendMultiAgentNode(run, "agent-membership", membership.id, (0, helpers_1.statusToNodeStatus)(membership.status), {
|
|
444
|
-
multiAgentRunId: membership.multiAgentRunId,
|
|
445
|
-
groupId: membership.groupId,
|
|
446
|
-
roleId: membership.roleId,
|
|
447
|
-
taskId: membership.taskId,
|
|
448
|
-
workerId: membership.workerId,
|
|
449
|
-
dispatchId: membership.dispatchId,
|
|
450
|
-
fanoutId: membership.fanoutId
|
|
451
|
-
}, [`${run.id}:multi-agent:group:${membership.groupId}`, `${run.id}:multi-agent:role:${membership.roleId}`]);
|
|
452
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
453
|
-
kind: "multi-agent.membership",
|
|
454
|
-
decision: "recorded",
|
|
455
|
-
source: "runtime-derived",
|
|
456
|
-
workerId: membership.workerId,
|
|
457
|
-
taskId: membership.taskId,
|
|
458
|
-
multiAgentRunId: membership.multiAgentRunId,
|
|
459
|
-
agentRoleId: membership.roleId,
|
|
460
|
-
agentGroupId: membership.groupId,
|
|
461
|
-
agentMembershipId: membership.id,
|
|
462
|
-
agentFanoutId: membership.fanoutId,
|
|
463
|
-
metadata: { status: membership.status, dispatchId: membership.dispatchId }
|
|
464
|
-
});
|
|
465
|
-
persistMultiAgentState(run);
|
|
466
|
-
return membership;
|
|
467
|
-
}
|
|
468
|
-
function createAgentFanout(run, input) {
|
|
469
|
-
const state = ensureMultiAgentState(run);
|
|
470
|
-
const group = requireAgentGroup(run, input.groupId);
|
|
471
|
-
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId || group.multiAgentRunId);
|
|
472
|
-
if (group.multiAgentRunId !== multiAgentRun.id)
|
|
473
|
-
throw new Error(`AgentGroup ${group.id} does not belong to ${multiAgentRun.id}`);
|
|
474
|
-
const id = input.id || (0, helpers_1.createId)("fanout", state.fanouts.length + 1);
|
|
475
|
-
if (state.fanouts.some((record) => record.id === id))
|
|
476
|
-
throw new Error(`Duplicate AgentFanout id: ${id}`);
|
|
477
|
-
for (const roleId of input.roleIds || [])
|
|
478
|
-
requireAgentRole(run, roleId);
|
|
479
|
-
for (const taskId of input.taskIds || [])
|
|
480
|
-
requireRunTask(run, taskId);
|
|
481
|
-
const now = new Date().toISOString();
|
|
482
|
-
const fanout = {
|
|
483
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
484
|
-
id,
|
|
485
|
-
runId: run.id,
|
|
486
|
-
multiAgentRunId: multiAgentRun.id,
|
|
487
|
-
groupId: group.id,
|
|
488
|
-
createdAt: now,
|
|
489
|
-
updatedAt: now,
|
|
490
|
-
status: "planned",
|
|
491
|
-
reason: input.reason,
|
|
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 || []),
|
|
497
|
-
concurrencyLimit: input.concurrencyLimit,
|
|
498
|
-
sandboxProfileChoices: input.sandboxProfileChoices || {},
|
|
499
|
-
expectedReturnShape: input.expectedReturnShape || "Each member writes a Markdown result with a cw:result JSON fence containing summary, findings, and evidence.",
|
|
500
|
-
blackboardId: input.blackboardId || group.blackboardId || multiAgentRun.blackboardId,
|
|
501
|
-
topicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
502
|
-
lifecycle: [(0, helpers_1.lifecycleEvent)(undefined, "planned", "created")],
|
|
503
|
-
policy: {
|
|
504
|
-
schemaVersion: 1,
|
|
505
|
-
id: `${id}-policy`,
|
|
506
|
-
policyRef: `multiAgent.fanouts.${id}.policy`,
|
|
507
|
-
subjectKind: "fanout",
|
|
508
|
-
subjectId: id,
|
|
509
|
-
allowedBlackboardTopicIds: (0, helpers_1.unique)(fanoutTopicIds(group, multiAgentRun, input)),
|
|
510
|
-
allowedWriteOperations: ["message", "context", "artifact"],
|
|
511
|
-
allowedCandidateOperations: ["register"],
|
|
512
|
-
allowedJudgeOperations: [],
|
|
513
|
-
sandboxProfileHints: (0, helpers_1.unique)(Object.values(input.sandboxProfileChoices || {}).map(String)),
|
|
514
|
-
requiredEvidenceRefs: [],
|
|
515
|
-
deniedOperations: [],
|
|
516
|
-
metadata: { reason: input.reason }
|
|
517
|
-
},
|
|
518
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
519
|
-
};
|
|
520
|
-
state.fanouts.push(fanout);
|
|
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);
|
|
527
|
-
appendMultiAgentNode(run, "agent-fanout", fanout.id, "pending", {
|
|
528
|
-
multiAgentRunId: fanout.multiAgentRunId,
|
|
529
|
-
groupId: fanout.groupId,
|
|
530
|
-
reason: fanout.reason,
|
|
531
|
-
roleIds: fanout.roleIds,
|
|
532
|
-
taskIds: fanout.taskIds,
|
|
533
|
-
concurrencyLimit: fanout.concurrencyLimit,
|
|
534
|
-
sandboxProfileChoices: fanout.sandboxProfileChoices
|
|
535
|
-
}, [`${run.id}:multi-agent:group:${fanout.groupId}`]);
|
|
536
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
537
|
-
kind: "multi-agent.fanout",
|
|
538
|
-
decision: "recorded",
|
|
539
|
-
source: "runtime-derived",
|
|
540
|
-
multiAgentRunId: fanout.multiAgentRunId,
|
|
541
|
-
agentGroupId: fanout.groupId,
|
|
542
|
-
agentFanoutId: fanout.id,
|
|
543
|
-
metadata: {
|
|
544
|
-
reason: fanout.reason,
|
|
545
|
-
roleIds: fanout.roleIds,
|
|
546
|
-
taskIds: fanout.taskIds,
|
|
547
|
-
concurrencyLimit: fanout.concurrencyLimit,
|
|
548
|
-
sandboxProfileChoices: fanout.sandboxProfileChoices
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
persistMultiAgentState(run);
|
|
552
|
-
return fanout;
|
|
553
|
-
}
|
|
554
|
-
function attachDispatchToMultiAgent(run, input) {
|
|
555
|
-
if (!input.multiAgentRunId && !input.groupId && !input.roleId && !input.fanoutId)
|
|
556
|
-
return { membershipIds: [] };
|
|
557
|
-
const state = ensureMultiAgentState(run);
|
|
558
|
-
let fanout = input.fanoutId ? requireAgentFanout(run, input.fanoutId) : undefined;
|
|
559
|
-
let group = input.groupId ? requireAgentGroup(run, input.groupId) : undefined;
|
|
560
|
-
if (!group && fanout)
|
|
561
|
-
group = requireAgentGroup(run, fanout.groupId);
|
|
562
|
-
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId || group?.multiAgentRunId || fanout?.multiAgentRunId || "");
|
|
563
|
-
if (!group)
|
|
564
|
-
throw new Error("Dispatch multi-agent attach requires --multi-agent-group or --multiAgentGroup");
|
|
565
|
-
if (group.multiAgentRunId !== multiAgentRun.id)
|
|
566
|
-
throw new Error(`Group ${group.id} does not belong to MultiAgentRun ${multiAgentRun.id}`);
|
|
567
|
-
const roleIds = input.roleId ? [input.roleId] : (0, helpers_1.unique)([...(fanout ? fanout.roleIds : [])]);
|
|
568
|
-
if (roleIds.length !== 1) {
|
|
569
|
-
throw new Error(`Dispatch multi-agent attach requires exactly one role for deterministic membership; found ${roleIds.length || 0}`);
|
|
570
|
-
}
|
|
571
|
-
const role = requireAgentRole(run, roleIds[0]);
|
|
572
|
-
if (role.multiAgentRunId !== multiAgentRun.id)
|
|
573
|
-
throw new Error(`Role ${role.id} does not belong to MultiAgentRun ${multiAgentRun.id}`);
|
|
574
|
-
if (!fanout) {
|
|
575
|
-
fanout = createAgentFanout(run, {
|
|
576
|
-
multiAgentRunId: multiAgentRun.id,
|
|
577
|
-
groupId: group.id,
|
|
578
|
-
reason: "dispatch attachment",
|
|
579
|
-
roleIds: [role.id],
|
|
580
|
-
taskIds: input.tasks.map((task) => task.id),
|
|
581
|
-
dispatchIds: [input.dispatchId],
|
|
582
|
-
concurrencyLimit: input.concurrencyLimit,
|
|
583
|
-
sandboxProfileChoices: input.sandboxProfileId ? { dispatch: input.sandboxProfileId } : {}
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
if (fanout.multiAgentRunId !== multiAgentRun.id || fanout.groupId !== group.id) {
|
|
587
|
-
throw new Error(`Fanout ${fanout.id} does not match MultiAgentRun ${multiAgentRun.id} and group ${group.id}`);
|
|
588
|
-
}
|
|
589
|
-
const membershipIds = [];
|
|
590
|
-
for (const task of input.tasks) {
|
|
591
|
-
if (!task.workerId)
|
|
592
|
-
throw new Error(`Task ${task.id} has no worker id for multi-agent membership`);
|
|
593
|
-
const membership = assignAgentMembership(run, {
|
|
594
|
-
multiAgentRunId: multiAgentRun.id,
|
|
595
|
-
groupId: group.id,
|
|
596
|
-
roleId: role.id,
|
|
597
|
-
taskId: task.id,
|
|
598
|
-
workerId: task.workerId,
|
|
599
|
-
dispatchId: input.dispatchId,
|
|
600
|
-
fanoutId: fanout.id,
|
|
601
|
-
status: "running"
|
|
602
|
-
});
|
|
603
|
-
task.multiAgent = {
|
|
604
|
-
runId: multiAgentRun.id,
|
|
605
|
-
groupId: group.id,
|
|
606
|
-
roleId: role.id,
|
|
607
|
-
membershipId: membership.id,
|
|
608
|
-
fanoutId: fanout.id
|
|
609
|
-
};
|
|
610
|
-
membershipIds.push(membership.id);
|
|
611
|
-
}
|
|
612
|
-
fanout.status = "dispatched";
|
|
613
|
-
fanout.updatedAt = new Date().toISOString();
|
|
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]);
|
|
619
|
-
if (input.sandboxProfileId)
|
|
620
|
-
fanout.sandboxProfileChoices.dispatch = input.sandboxProfileId;
|
|
621
|
-
const groupStatusBefore = group.status;
|
|
622
|
-
group.status = "running";
|
|
623
|
-
group.updatedAt = fanout.updatedAt;
|
|
624
|
-
group.lifecycle.push((0, helpers_1.lifecycleEvent)(groupStatusBefore, "running", "dispatch created"));
|
|
625
|
-
multiAgentRun.status = multiAgentRun.status === "planned" || multiAgentRun.status === "forming" ? "running" : multiAgentRun.status;
|
|
626
|
-
(0, helpers_1.touch)(multiAgentRun);
|
|
627
|
-
appendMultiAgentNode(run, "agent-fanout", fanout.id, "running", {
|
|
628
|
-
status: fanout.status,
|
|
629
|
-
dispatchIds: fanout.dispatchIds,
|
|
630
|
-
workerIds: fanout.workerIds,
|
|
631
|
-
membershipIds: fanout.membershipIds
|
|
632
|
-
}, [`${run.id}:dispatch:${input.dispatchId}`]);
|
|
633
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
634
|
-
kind: "multi-agent.fanout.dispatch",
|
|
635
|
-
decision: "validated",
|
|
636
|
-
source: "cw-validated",
|
|
637
|
-
multiAgentRunId: multiAgentRun.id,
|
|
638
|
-
agentRoleId: role.id,
|
|
639
|
-
agentGroupId: group.id,
|
|
640
|
-
agentFanoutId: fanout.id,
|
|
641
|
-
metadata: { dispatchId: input.dispatchId, membershipIds, workerIds: fanout.workerIds }
|
|
642
|
-
});
|
|
643
|
-
persistMultiAgentState(run);
|
|
644
|
-
return {
|
|
645
|
-
multiAgent: {
|
|
646
|
-
runId: multiAgentRun.id,
|
|
647
|
-
groupId: group.id,
|
|
648
|
-
roleId: role.id,
|
|
649
|
-
fanoutId: fanout.id
|
|
650
|
-
},
|
|
651
|
-
membershipIds
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
function collectAgentFanin(run, input) {
|
|
655
|
-
const state = ensureMultiAgentState(run);
|
|
656
|
-
const fanout = input.fanoutId ? requireAgentFanout(run, input.fanoutId) : undefined;
|
|
657
|
-
const group = requireAgentGroup(run, input.groupId || fanout?.groupId || "");
|
|
658
|
-
const multiAgentRun = requireMultiAgentRun(run, input.multiAgentRunId || group.multiAgentRunId);
|
|
659
|
-
if (group.multiAgentRunId !== multiAgentRun.id)
|
|
660
|
-
throw new Error(`Group ${group.id} does not belong to MultiAgentRun ${multiAgentRun.id}`);
|
|
661
|
-
if (fanout && fanout.groupId !== group.id)
|
|
662
|
-
throw new Error(`Fanout ${fanout.id} does not belong to group ${group.id}`);
|
|
663
|
-
const id = input.id || (0, helpers_1.createId)("fanin", state.fanins.length + 1);
|
|
664
|
-
if (state.fanins.some((record) => record.id === id))
|
|
665
|
-
throw new Error(`Duplicate AgentFanin id: ${id}`);
|
|
666
|
-
const requiredRoleIds = (0, helpers_1.unique)(input.requiredRoleIds?.length ? input.requiredRoleIds : group.roleIds);
|
|
667
|
-
for (const roleId of requiredRoleIds)
|
|
668
|
-
requireAgentRole(run, roleId);
|
|
669
|
-
const scopedMemberships = state.memberships.filter((membership) => membership.groupId === group.id && (!fanout || membership.fanoutId === fanout.id));
|
|
670
|
-
const coverage = scopedMemberships.map((membership) => ({
|
|
671
|
-
membershipId: membership.id,
|
|
672
|
-
roleId: membership.roleId,
|
|
673
|
-
taskId: membership.taskId,
|
|
674
|
-
workerId: membership.workerId,
|
|
675
|
-
evidenceRefs: membership.evidenceRefs,
|
|
676
|
-
blackboardMessageIds: membership.blackboardMessageIds || [],
|
|
677
|
-
blackboardArtifactRefIds: membership.blackboardArtifactRefIds || [],
|
|
678
|
-
resultNodeId: membership.resultNodeId,
|
|
679
|
-
verifierNodeId: membership.verifierNodeId,
|
|
680
|
-
complete: (0, helpers_1.isMembershipReported)(membership)
|
|
681
|
-
}));
|
|
682
|
-
const missingRoleIds = requiredRoleIds.filter((roleId) => !scopedMemberships.some((membership) => membership.roleId === roleId));
|
|
683
|
-
const missingMembershipIds = scopedMemberships
|
|
684
|
-
.filter((membership) => requiredRoleIds.includes(membership.roleId) && !(0, helpers_1.isMembershipReported)(membership))
|
|
685
|
-
.map((membership) => membership.id);
|
|
686
|
-
const blockedReasons = [
|
|
687
|
-
...missingRoleIds.map((roleId) => `required role ${roleId} has no membership`),
|
|
688
|
-
...missingMembershipIds.map((membershipId) => `membership ${membershipId} has not reported required evidence`)
|
|
689
|
-
];
|
|
690
|
-
const requiredMemberships = scopedMemberships.filter((membership) => requiredRoleIds.includes(membership.roleId));
|
|
691
|
-
const blackboardId = input.blackboardId || group.blackboardId || multiAgentRun.blackboardId;
|
|
692
|
-
const requiresBlackboardEvidence = Boolean(blackboardId || requiredMemberships.some((membership) => membership.blackboardId));
|
|
693
|
-
if (requiresBlackboardEvidence) {
|
|
694
|
-
for (const membership of requiredMemberships) {
|
|
695
|
-
const indexedEvidence = [
|
|
696
|
-
...((membership.blackboardArtifactRefIds || [])),
|
|
697
|
-
...((membership.blackboardMessageIds || []))
|
|
698
|
-
];
|
|
699
|
-
if (!indexedEvidence.length)
|
|
700
|
-
blockedReasons.push(`membership ${membership.id} has no indexed blackboard evidence`);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
const verifierReady = blockedReasons.length === 0;
|
|
704
|
-
const status = verifierReady ? "ready" : "blocked";
|
|
705
|
-
const now = new Date().toISOString();
|
|
706
|
-
const fanin = {
|
|
707
|
-
schemaVersion: helpers_1.MULTI_AGENT_SCHEMA_VERSION,
|
|
708
|
-
id,
|
|
709
|
-
runId: run.id,
|
|
710
|
-
multiAgentRunId: multiAgentRun.id,
|
|
711
|
-
groupId: group.id,
|
|
712
|
-
fanoutId: fanout?.id,
|
|
713
|
-
createdAt: now,
|
|
714
|
-
updatedAt: now,
|
|
715
|
-
status,
|
|
716
|
-
strategy: input.strategy || "required-role-evidence",
|
|
717
|
-
requiredRoleIds,
|
|
718
|
-
reportedMembershipIds: coverage.filter((entry) => entry.complete).map((entry) => entry.membershipId),
|
|
719
|
-
missingMembershipIds,
|
|
720
|
-
missingRoleIds,
|
|
721
|
-
evidenceCoverage: coverage,
|
|
722
|
-
verifierReady,
|
|
723
|
-
blockedReasons,
|
|
724
|
-
blackboardId,
|
|
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")],
|
|
729
|
-
policy: {
|
|
730
|
-
schemaVersion: 1,
|
|
731
|
-
id: `${id}-policy`,
|
|
732
|
-
policyRef: `multiAgent.fanins.${id}.policy`,
|
|
733
|
-
subjectKind: "fanin",
|
|
734
|
-
subjectId: id,
|
|
735
|
-
allowedBlackboardTopicIds: (0, helpers_1.unique)([...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])]),
|
|
736
|
-
allowedWriteOperations: ["message", "context", "artifact", "snapshot", "coordinator-decision"],
|
|
737
|
-
allowedCandidateOperations: verifierReady ? ["register", "score", "select"] : [],
|
|
738
|
-
allowedJudgeOperations: verifierReady ? ["panel-decision", "rationale"] : [],
|
|
739
|
-
sandboxProfileHints: [],
|
|
740
|
-
requiredEvidenceRefs: (0, helpers_1.unique)(coverage.flatMap((entry) => entry.evidenceRefs)),
|
|
741
|
-
deniedOperations: verifierReady ? [] : blockedReasons.map((reason) => ({ operation: "candidate.select", reason })),
|
|
742
|
-
metadata: { verifierReady, strategy: input.strategy || "required-role-evidence" }
|
|
743
|
-
},
|
|
744
|
-
metadata: (0, helpers_1.compact)(input.metadata)
|
|
745
|
-
};
|
|
746
|
-
state.fanins.push(fanin);
|
|
747
|
-
group.faninIds = (0, helpers_1.unique)([...group.faninIds, fanin.id]);
|
|
748
|
-
group.status = verifierReady ? "verifying" : "collecting";
|
|
749
|
-
(0, helpers_1.touch)(group);
|
|
750
|
-
multiAgentRun.faninIds = (0, helpers_1.unique)([...multiAgentRun.faninIds, fanin.id]);
|
|
751
|
-
multiAgentRun.status = verifierReady ? "verifying" : "collecting";
|
|
752
|
-
(0, helpers_1.touch)(multiAgentRun);
|
|
753
|
-
appendMultiAgentNode(run, "agent-fanin", fanin.id, verifierReady ? "verified" : "blocked", {
|
|
754
|
-
multiAgentRunId: fanin.multiAgentRunId,
|
|
755
|
-
groupId: fanin.groupId,
|
|
756
|
-
fanoutId: fanin.fanoutId,
|
|
757
|
-
requiredRoleIds,
|
|
758
|
-
missingRoleIds,
|
|
759
|
-
missingMembershipIds,
|
|
760
|
-
verifierReady
|
|
761
|
-
}, [
|
|
762
|
-
`${run.id}:multi-agent:group:${fanin.groupId}`,
|
|
763
|
-
...(fanin.fanoutId ? [`${run.id}:multi-agent:fanout:${fanin.fanoutId}`] : []),
|
|
764
|
-
...fanin.evidenceCoverage.map((entry) => `${run.id}:multi-agent:membership:${entry.membershipId}`)
|
|
765
|
-
]);
|
|
766
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
767
|
-
kind: "multi-agent.fanin",
|
|
768
|
-
decision: verifierReady ? "validated" : "failed",
|
|
769
|
-
source: "cw-validated",
|
|
770
|
-
multiAgentRunId: fanin.multiAgentRunId,
|
|
771
|
-
agentGroupId: fanin.groupId,
|
|
772
|
-
agentFanoutId: fanin.fanoutId,
|
|
773
|
-
agentFaninId: fanin.id,
|
|
774
|
-
evidenceRefs: fanin.evidenceCoverage.flatMap((entry) => entry.evidenceRefs),
|
|
775
|
-
metadata: {
|
|
776
|
-
verifierReady,
|
|
777
|
-
requiredRoleIds,
|
|
778
|
-
missingRoleIds,
|
|
779
|
-
missingMembershipIds,
|
|
780
|
-
blockedReasons
|
|
781
|
-
}
|
|
782
|
-
});
|
|
783
|
-
persistMultiAgentState(run);
|
|
784
|
-
return fanin;
|
|
785
|
-
}
|
|
786
|
-
function recordMultiAgentWorkerOutput(run, input) {
|
|
787
|
-
const state = ensureMultiAgentState(run);
|
|
788
|
-
const memberships = state.memberships.filter((membership) => membership.workerId === input.workerId && membership.taskId === input.taskId);
|
|
789
|
-
if (!memberships.length)
|
|
790
|
-
return [];
|
|
791
|
-
const evidenceRefs = input.evidence.map((entry) => entry.locator || entry.path || entry.summary || entry.id).filter(Boolean);
|
|
792
|
-
for (const membership of memberships) {
|
|
793
|
-
const before = membership.status;
|
|
794
|
-
membership.status = "reported";
|
|
795
|
-
membership.updatedAt = new Date().toISOString();
|
|
796
|
-
membership.resultNodeId = input.resultNodeId || membership.resultNodeId;
|
|
797
|
-
membership.verifierNodeId = input.verifierNodeId || membership.verifierNodeId;
|
|
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"));
|
|
803
|
-
appendMultiAgentNode(run, "agent-membership", membership.id, "completed", {
|
|
804
|
-
resultNodeId: membership.resultNodeId,
|
|
805
|
-
verifierNodeId: membership.verifierNodeId,
|
|
806
|
-
evidenceRefs: membership.evidenceRefs
|
|
807
|
-
}, [membership.resultNodeId, membership.verifierNodeId].filter(Boolean));
|
|
808
|
-
(0, trust_audit_1.recordTrustAuditEvent)(run, {
|
|
809
|
-
kind: "multi-agent.membership.output",
|
|
810
|
-
decision: "accepted",
|
|
811
|
-
source: "cw-validated",
|
|
812
|
-
workerId: input.workerId,
|
|
813
|
-
taskId: input.taskId,
|
|
814
|
-
nodeId: input.resultNodeId,
|
|
815
|
-
multiAgentRunId: membership.multiAgentRunId,
|
|
816
|
-
agentRoleId: membership.roleId,
|
|
817
|
-
agentGroupId: membership.groupId,
|
|
818
|
-
agentMembershipId: membership.id,
|
|
819
|
-
agentFanoutId: membership.fanoutId,
|
|
820
|
-
evidence: input.evidence,
|
|
821
|
-
metadata: { verifierNodeId: input.verifierNodeId }
|
|
822
|
-
});
|
|
823
|
-
}
|
|
824
|
-
persistMultiAgentState(run);
|
|
825
|
-
return memberships;
|
|
826
|
-
}
|
|
827
|
-
function summarizeMultiAgent(run) {
|
|
828
|
-
const state = ensureMultiAgentState(run);
|
|
829
|
-
const blockedReasons = [];
|
|
830
|
-
for (const fanin of state.fanins)
|
|
831
|
-
blockedReasons.push(...fanin.blockedReasons.map((reason) => `${fanin.id}: ${reason}`));
|
|
832
|
-
for (const membership of state.memberships) {
|
|
833
|
-
if (membership.status === "failed")
|
|
834
|
-
blockedReasons.push(`${membership.id}: failed membership`);
|
|
835
|
-
}
|
|
836
|
-
const groupsDetail = state.groups.map((group) => {
|
|
837
|
-
const roleIds = (0, helpers_1.unique)([...group.roleIds, ...state.memberships.filter((membership) => membership.groupId === group.id).map((membership) => membership.roleId)]);
|
|
838
|
-
return {
|
|
839
|
-
id: group.id,
|
|
840
|
-
multiAgentRunId: group.multiAgentRunId,
|
|
841
|
-
status: group.status,
|
|
842
|
-
phase: group.phase,
|
|
843
|
-
roles: roleIds.map((roleId) => {
|
|
844
|
-
const role = state.roles.find((entry) => entry.id === roleId);
|
|
845
|
-
const memberships = state.memberships.filter((membership) => membership.groupId === group.id && membership.roleId === roleId);
|
|
846
|
-
const reported = memberships.filter(helpers_1.isMembershipReported).length;
|
|
847
|
-
return {
|
|
848
|
-
roleId,
|
|
849
|
-
requiredEvidence: role?.requiredEvidence.length || 0,
|
|
850
|
-
memberships: memberships.length,
|
|
851
|
-
reported,
|
|
852
|
-
missing: Math.max(0, memberships.length - reported)
|
|
853
|
-
};
|
|
854
|
-
}),
|
|
855
|
-
fanouts: group.fanoutIds,
|
|
856
|
-
fanins: group.faninIds
|
|
857
|
-
};
|
|
858
|
-
});
|
|
859
|
-
return {
|
|
860
|
-
totalRuns: state.runs.length,
|
|
861
|
-
runsByStatus: (0, helpers_1.countBy)(state.runs, (record) => record.status),
|
|
862
|
-
roles: state.roles.length,
|
|
863
|
-
groups: state.groups.length,
|
|
864
|
-
memberships: state.memberships.length,
|
|
865
|
-
fanouts: state.fanouts.length,
|
|
866
|
-
fanins: state.fanins.length,
|
|
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),
|
|
870
|
-
blockedReasons,
|
|
871
|
-
groupsDetail,
|
|
872
|
-
nextAction: nextMultiAgentAction(run, blockedReasons)
|
|
873
|
-
};
|
|
874
|
-
}
|
|
875
|
-
function buildMultiAgentGraph(run) {
|
|
876
|
-
const state = ensureMultiAgentState(run);
|
|
877
|
-
return (0, graph_1.buildMultiAgentGraphFromState)(run, state);
|
|
878
|
-
}
|
|
879
|
-
function getMultiAgentRun(run, id) {
|
|
880
|
-
return ensureMultiAgentState(run).runs.find((record) => record.id === id);
|
|
881
|
-
}
|
|
882
|
-
function getAgentRole(run, id) {
|
|
883
|
-
return ensureMultiAgentState(run).roles.find((record) => record.id === id);
|
|
884
|
-
}
|
|
885
|
-
function getAgentGroup(run, id) {
|
|
886
|
-
return ensureMultiAgentState(run).groups.find((record) => record.id === id);
|
|
887
|
-
}
|
|
888
|
-
function getAgentMembership(run, id) {
|
|
889
|
-
return ensureMultiAgentState(run).memberships.find((record) => record.id === id);
|
|
890
|
-
}
|
|
891
|
-
function getAgentFanout(run, id) {
|
|
892
|
-
return ensureMultiAgentState(run).fanouts.find((record) => record.id === id);
|
|
893
|
-
}
|
|
894
|
-
function getAgentFanin(run, id) {
|
|
895
|
-
return ensureMultiAgentState(run).fanins.find((record) => record.id === id);
|
|
896
|
-
}
|
|
897
|
-
function requireMultiAgentRun(run, id) {
|
|
898
|
-
const record = getMultiAgentRun(run, id);
|
|
899
|
-
if (!record)
|
|
900
|
-
throw new Error(`Unknown MultiAgentRun id: ${id}`);
|
|
901
|
-
return record;
|
|
902
|
-
}
|
|
903
|
-
function requireAgentRole(run, id) {
|
|
904
|
-
const record = getAgentRole(run, id);
|
|
905
|
-
if (!record)
|
|
906
|
-
throw new Error(`Unknown AgentRole id: ${id}`);
|
|
907
|
-
return record;
|
|
908
|
-
}
|
|
909
|
-
function requireAgentGroup(run, id) {
|
|
910
|
-
const record = getAgentGroup(run, id);
|
|
911
|
-
if (!record)
|
|
912
|
-
throw new Error(`Unknown AgentGroup id: ${id}`);
|
|
913
|
-
return record;
|
|
914
|
-
}
|
|
915
|
-
function requireAgentFanout(run, id) {
|
|
916
|
-
const record = getAgentFanout(run, id);
|
|
917
|
-
if (!record)
|
|
918
|
-
throw new Error(`Unknown AgentFanout id: ${id}`);
|
|
919
|
-
return record;
|
|
920
|
-
}
|
|
921
|
-
function requireRunTask(run, id) {
|
|
922
|
-
const task = run.tasks.find((record) => record.id === id);
|
|
923
|
-
if (!task)
|
|
924
|
-
throw new Error(`Unknown task id for multi-agent record: ${id}`);
|
|
925
|
-
return task;
|
|
926
|
-
}
|
|
927
|
-
function fanoutTopicIds(group, multiAgentRun, input) {
|
|
928
|
-
return [...(group.topicIds || []), ...(multiAgentRun.topicIds || []), ...(input.topicIds || [])];
|
|
929
|
-
}
|
|
930
|
-
function writeRecord(run, kind, record) {
|
|
931
|
-
(0, state_1.writeJson)((0, paths_1.recordPath)(run, kind, record.id), record);
|
|
932
|
-
}
|
|
933
|
-
function appendMultiAgentNode(run, kind, id, status, metadata, parents = []) {
|
|
934
|
-
const nodeId = kind === "multi-agent-run" ? `${run.id}:multi-agent:${id}` : `${run.id}:multi-agent:${kind.replace("agent-", "")}:${id}`;
|
|
935
|
-
(0, state_node_1.appendRunNode)(run, (0, state_node_1.createStateNode)({
|
|
936
|
-
id: nodeId,
|
|
937
|
-
kind,
|
|
938
|
-
status,
|
|
939
|
-
loopStage: run.loopStage,
|
|
940
|
-
outputs: metadata,
|
|
941
|
-
artifacts: [{ id: kind, kind: "json", path: (0, paths_1.recordPath)(run, (0, helpers_1.pluralKind)(kind), id) }],
|
|
942
|
-
parents,
|
|
943
|
-
contractId: pipeline_contract_1.DEFAULT_PIPELINE_CONTRACT_ID,
|
|
944
|
-
metadata
|
|
945
|
-
}));
|
|
946
|
-
}
|
|
947
|
-
function attachWorkerMetadata(run, membership) {
|
|
948
|
-
const workers = run.workers || [];
|
|
949
|
-
const index = workers.findIndex((worker) => worker.id === membership.workerId);
|
|
950
|
-
if (index < 0)
|
|
951
|
-
return;
|
|
952
|
-
const worker = workers[index];
|
|
953
|
-
const multiAgent = {
|
|
954
|
-
runId: membership.multiAgentRunId,
|
|
955
|
-
groupId: membership.groupId,
|
|
956
|
-
roleId: membership.roleId,
|
|
957
|
-
membershipId: membership.id,
|
|
958
|
-
fanoutId: membership.fanoutId
|
|
959
|
-
};
|
|
960
|
-
const updated = {
|
|
961
|
-
...worker,
|
|
962
|
-
updatedAt: new Date().toISOString(),
|
|
963
|
-
multiAgent,
|
|
964
|
-
metadata: {
|
|
965
|
-
...(worker.metadata || {}),
|
|
966
|
-
multiAgent
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
run.workers = workers.map((candidate) => (candidate.id === worker.id ? updated : candidate));
|
|
970
|
-
}
|
|
971
|
-
function nextMultiAgentAction(run, blockedReasons) {
|
|
972
|
-
const state = ensureMultiAgentState(run);
|
|
973
|
-
if (!state.runs.length)
|
|
974
|
-
return `node scripts/cw.js multi-agent run ${run.id} --id <multi-agent-run-id>`;
|
|
975
|
-
if (blockedReasons.length)
|
|
976
|
-
return `node scripts/cw.js multi-agent fanin ${run.id} --group <group-id> --fanout <fanout-id>`;
|
|
977
|
-
const running = state.memberships.find((membership) => membership.status === "running");
|
|
978
|
-
if (running?.workerId)
|
|
979
|
-
return `node scripts/cw.js worker manifest ${run.id} ${running.workerId}`;
|
|
980
|
-
const groupWithoutFanin = state.groups.find((group) => group.membershipIds.length && !group.faninIds.length);
|
|
981
|
-
if (groupWithoutFanin)
|
|
982
|
-
return `node scripts/cw.js multi-agent fanin ${run.id} --group ${groupWithoutFanin.id}`;
|
|
983
|
-
return undefined;
|
|
984
|
-
}
|