@tangle-network/agent-runtime 0.327.0 → 0.328.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.
Files changed (44) hide show
  1. package/dist/{activation-D4kme3Oh.d.ts → activation-CZRtcDPo.d.ts} +2 -2
  2. package/dist/agent.d.ts +1 -1
  3. package/dist/agent.js +1 -1
  4. package/dist/{coordination-driver-Cd0KpYoT.js → coordination-driver-B7Z9jgFr.js} +315 -7
  5. package/dist/coordination-driver-B7Z9jgFr.js.map +1 -0
  6. package/dist/{delegate-C6qiH8ti.js → delegate-By9tikQT.js} +2 -2
  7. package/dist/{delegate-C6qiH8ti.js.map → delegate-By9tikQT.js.map} +1 -1
  8. package/dist/durable.d.ts +1 -1
  9. package/dist/durable.js +2 -2
  10. package/dist/{graph-7DxUifPo.js → graph-0iL-4gj2.js} +12 -5
  11. package/dist/graph-0iL-4gj2.js.map +1 -0
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +3 -3
  14. package/dist/intelligence.d.ts +2 -2
  15. package/dist/kernel.d.ts +2 -2
  16. package/dist/kernel.js +6 -6
  17. package/dist/{loop-runner-bin-DLiEuQAt.js → loop-runner-bin-CNmBGFAu.js} +2 -2
  18. package/dist/{loop-runner-bin-DLiEuQAt.js.map → loop-runner-bin-CNmBGFAu.js.map} +1 -1
  19. package/dist/{loop-runner-bin-DKkrGTge.d.ts → loop-runner-bin-DDz4VTyE.d.ts} +2 -2
  20. package/dist/loop-runner-bin.d.ts +1 -1
  21. package/dist/loop-runner-bin.js +1 -1
  22. package/dist/mcp/bin.js +2 -2
  23. package/dist/mcp/index.d.ts +2 -2
  24. package/dist/mcp/index.js +3 -3
  25. package/dist/{openai-tools-BTq7nLhg.d.ts → openai-tools-B3Z4i5_B.d.ts} +2 -2
  26. package/dist/profiles.d.ts +1 -1
  27. package/dist/{provision-supervisor-BCpumw87.js → provision-supervisor-CCoerJyv.js} +2 -2
  28. package/dist/{provision-supervisor-BCpumw87.js.map → provision-supervisor-CCoerJyv.js.map} +1 -1
  29. package/dist/{runtime-CfBB9gRz.js → runtime-CYjHXjec.js} +6 -6
  30. package/dist/{runtime-CfBB9gRz.js.map → runtime-CYjHXjec.js.map} +1 -1
  31. package/dist/{server-vyi-BhWC.js → server-Czsqviqu.js} +2 -2
  32. package/dist/{server-vyi-BhWC.js.map → server-Czsqviqu.js.map} +1 -1
  33. package/dist/{supervise-Bso1hco7.js → supervise-9WPjMFrH.js} +195 -26
  34. package/dist/supervise-9WPjMFrH.js.map +1 -0
  35. package/dist/testing.d.ts +1 -1
  36. package/dist/testing.js +11 -11
  37. package/dist/tui/index.d.ts +1 -1
  38. package/dist/tui/index.js +1 -1
  39. package/dist/{types-loG2Pvmj.d.ts → types-0czU5q4A.d.ts} +168 -8
  40. package/package.json +1 -1
  41. package/skills/agent-graphs/references/authoring.md +12 -1
  42. package/dist/coordination-driver-Cd0KpYoT.js.map +0 -1
  43. package/dist/graph-7DxUifPo.js.map +0 -1
  44. package/dist/supervise-Bso1hco7.js.map +0 -1
@@ -5,7 +5,7 @@ import { $ as isAsyncIterable$1, Ot as teardownExecutor, U as addSpend, Y as err
5
5
  import { a as readCommittedJsonLines, n as isNoEntError, r as prepareJsonlAppend } from "./jsonl-file-DBv31uPi.js";
6
6
  import { _ as agentHarness, a as concreteProfileModel, c as profileModelExecutionSettings, n as assertModelAllowed, o as enforceTokenLimits, r as assertProfileModelsAllowed, s as profileBridgeWireModel, t as assertExecutableAgentProfile, v as harnessRunsAgent } from "./model-policy-CyCUwHed.js";
7
7
  import { t as composeRuntimeHooks } from "./runtime-hooks-tXpAarhW.js";
8
- import { C as createFileRunContext, F as createCoordinationToolsForManager, N as coordinationVerbNames, O as applyRunCancellation, T as withRunContext, c as refreshedWake, g as progressStop, h as plateau, k as watchRunCancellation, l as resolveWakePolicy, n as createSteerAcknowledger, o as composeWakeInput, p as createProgressTracker, r as driverAgent, s as deadlineWarningAt, t as createCancelAcknowledger, w as createInMemoryRunContext } from "./coordination-driver-Cd0KpYoT.js";
8
+ import { C as createFileRunContext, F as createCoordinationToolsForManager, N as coordinationVerbNames, O as applyRunCancellation, T as withRunContext, c as refreshedWake, g as progressStop, h as plateau, k as watchRunCancellation, l as resolveWakePolicy, n as createSteerAcknowledger, o as composeWakeInput, p as createProgressTracker, r as driverAgent, s as deadlineWarningAt, t as createCancelAcknowledger, w as createInMemoryRunContext } from "./coordination-driver-B7Z9jgFr.js";
9
9
  import { r as createStdioToolServer, t as PROTOCOL_VERSION } from "./tool-server-Dqer2M4_.js";
10
10
  import { c as loadGraph, i as graphRegistry } from "./graph-registry-DAI6KNXB.js";
11
11
  import { k as writeRunCancellation, o as readRunCancelRequest, s as readRunCancellation } from "./run-layout-Cu8H7aeh.js";
@@ -650,6 +650,7 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
650
650
  ...opts.onStop ? { onStop: opts.onStop } : {},
651
651
  ...opts.analysts ? { analysts: opts.analysts } : {},
652
652
  ...opts.analyzeOnSettle ? { analyzeOnSettle: opts.analyzeOnSettle } : {},
653
+ ...opts.mapOnSettle ? { mapOnSettle: opts.mapOnSettle } : {},
653
654
  ...opts.sourceEvidenceRefs ? { sourceEvidenceRefs: opts.sourceEvidenceRefs } : {},
654
655
  ...opts.peerAudit ? { peerAudit: opts.peerAudit } : {},
655
656
  ...opts.watchWorkers ? { watchWorkers: opts.watchWorkers } : {},
@@ -1059,14 +1060,19 @@ function kernelPromptRegistry() {
1059
1060
  * run as a subtask is one subtree of the caller's run, spending from the caller's conserved pool.
1060
1061
  *
1061
1062
  * Nothing here schedules anything. It produces the values a manager's construction takes
1062
- * (`authorizeSpawn`, `resolveSpawnProfile`, `analyzeOnSettle`, `continuityByProfile`) and
1063
- * observes what the kernel reports back (spawn bindings, steers, findings).
1063
+ * (`authorizeSpawn`, `resolveSpawnProfile`, `analyzeOnSettle`, `mapOnSettle`,
1064
+ * `continuityByProfile`) and observes what the kernel reports back (spawn bindings, steers,
1065
+ * findings, map steps).
1064
1066
  */
1065
1067
  /** Default per-edge traversal cap — the cyclic-graph backstop when an edge names none. */
1066
1068
  const defaultEdgeTraversalCap = 32;
1069
+ const mapItemFailurePolicies = ["all-or-refuse", "settled-subset"];
1067
1070
  function edgeId(edge) {
1068
- return edge.kind === "delegates" ? `delegates:${edge.from}->${edge.to}` : `analyzes:${edge.analyst}:${edge.over.join("+")}->${edge.to}`;
1071
+ if (edge.kind === "delegates") return `delegates:${edge.from}->${edge.to}`;
1072
+ if (edge.kind === "maps") return `maps:${edge.from}->${edge.to ?? "graph"}->${edge.join}`;
1073
+ return `analyzes:${edge.analyst}:${edge.over.join("+")}->${edge.to}`;
1069
1074
  }
1075
+ const isPositiveInteger = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
1070
1076
  /** Validate a topology and resolve every directive BEFORE any compute is spent — an invalid
1071
1077
  * topology or an unknown directive is a configuration fault, never a mid-run surprise. */
1072
1078
  function validateGraphTopology(nodes, edges, registry, analysts) {
@@ -1087,8 +1093,13 @@ function validateGraphTopology(nodes, edges, registry, analysts) {
1087
1093
  if (!node) throw new ValidationError(`runGraph: ${where} references unknown node '${id}'`);
1088
1094
  return node;
1089
1095
  };
1096
+ for (const edge of edges) {
1097
+ const kind = edge.kind;
1098
+ if (kind !== "delegates" && kind !== "analyzes" && kind !== "maps") throw new ValidationError(`runGraph: edge kind ${JSON.stringify(kind)} is not 'delegates', 'analyzes' or 'maps'`);
1099
+ }
1090
1100
  const delegates = edges.filter((edge) => edge.kind === "delegates");
1091
1101
  const analyzes = edges.filter((edge) => edge.kind === "analyzes");
1102
+ const maps = edges.filter((edge) => edge.kind === "maps");
1092
1103
  if (delegates.length === 0) throw new ValidationError("runGraph: at least one delegates edge is required (who spawns whom)");
1093
1104
  for (const edge of edges) registry.resolve(edge.directive);
1094
1105
  for (const edge of delegates) {
@@ -1133,31 +1144,101 @@ function validateGraphTopology(nodes, edges, registry, analysts) {
1133
1144
  delegatesByWorker.set(edge.to, edge);
1134
1145
  workers.set(edge.to, requireNode(edge.to, edgeId(edge)));
1135
1146
  }
1136
- for (const node of nodes) if (node.id !== root.id && !workers.has(node.id) && !analystNodes.has(node.id)) throw new ValidationError(`runGraph: node '${node.id}' has no delegates edge to it — an unreachable node never runs`);
1147
+ const { mapNodes, mapItemNames } = validateMaps(maps, {
1148
+ byId,
1149
+ root,
1150
+ workers,
1151
+ analystNodes,
1152
+ registry,
1153
+ analysts
1154
+ });
1155
+ for (const node of nodes) if (node.id !== root.id && !workers.has(node.id) && !analystNodes.has(node.id) && !mapNodes.has(node.id)) throw new ValidationError(`runGraph: node '${node.id}' has no delegates edge to it — an unreachable node never runs`);
1137
1156
  return {
1138
1157
  root,
1139
1158
  workers,
1140
1159
  delegatesByWorker,
1141
1160
  analyzes,
1142
- analystNodes
1161
+ analystNodes,
1162
+ maps,
1163
+ mapNodes,
1164
+ mapItemNames
1165
+ };
1166
+ }
1167
+ /**
1168
+ * Refuse a maps edge the runtime could not run as authored. A map's item and join nodes are the
1169
+ * runtime's to spawn, so neither may be the root, a delegates target, an analyst, or a node of
1170
+ * another map: a second way to reach the node would make its ledger rows and its pinning ambiguous.
1171
+ * The source must be a node that settles as a worker: a delegates target, or another map's join.
1172
+ */
1173
+ function validateMaps(maps, graph) {
1174
+ const mapNodes = /* @__PURE__ */ new Map();
1175
+ const mapItemNames = /* @__PURE__ */ new Map();
1176
+ const joins = /* @__PURE__ */ new Set();
1177
+ for (const edge of maps) {
1178
+ const id = edgeId(edge);
1179
+ const refuse = (why) => {
1180
+ throw new ValidationError(`runGraph: ${id} ${why}`);
1181
+ };
1182
+ if (edge.continuity !== void 0) refuse("carries continuity — every map item is a fresh session over its own element");
1183
+ if (typeof edge.pointer !== "string" || edge.pointer !== "" && !edge.pointer.startsWith("/")) refuse(`has pointer ${JSON.stringify(edge.pointer)} — a JSON pointer is '' or starts with '/'`);
1184
+ if (!isPositiveInteger(edge.maxItems)) refuse("needs maxItems as a positive integer");
1185
+ if (!isPositiveInteger(edge.concurrency)) refuse(`has concurrency ${JSON.stringify(edge.concurrency)} — it needs a positive integer; concurrency throttles the items, so a value below 1 could never start one`);
1186
+ if (!mapItemFailurePolicies.includes(edge.onItemFailure)) refuse(`needs onItemFailure 'all-or-refuse' or 'settled-subset'`);
1187
+ if (edge.itemBudget !== void 0 && (typeof edge.itemBudget !== "object" || edge.itemBudget === null || Array.isArray(edge.itemBudget))) refuse("has an itemBudget that is not a budget object");
1188
+ if (edge.to === void 0 === (edge.graph === void 0)) refuse("needs exactly one of to (an item node) or graph (a graph run per item)");
1189
+ if (typeof edge.join !== "string") refuse("needs a join node");
1190
+ if (edge.to !== void 0 && edge.to === edge.join) refuse("joins into its own item node");
1191
+ for (const nodeId of edge.to === void 0 ? [edge.join] : [edge.to, edge.join]) {
1192
+ const node = graph.byId.get(nodeId);
1193
+ if (!node) refuse(`references unknown node '${nodeId}'`);
1194
+ if (nodeId === graph.root.id || graph.workers.has(nodeId) || graph.analystNodes.has(nodeId) || mapNodes.has(nodeId)) refuse(`names node '${nodeId}', which the graph already reaches another way — a map's item and join nodes are spawned only by their maps edge, never as the root, a delegates target, an analyst, or a node of another map`);
1195
+ mapNodes.set(nodeId, node);
1196
+ }
1197
+ joins.add(edge.join);
1198
+ if (edge.to !== void 0) mapItemNames.set(id, edge.to);
1199
+ else try {
1200
+ const prepared = prepareGraphSubtask(parseGraphSubtaskTopology(edge.graph), {
1201
+ registry: graph.registry,
1202
+ ...graph.analysts ? { analysts: graph.analysts } : {}
1203
+ });
1204
+ mapItemNames.set(id, prepared.root);
1205
+ } catch (error) {
1206
+ refuse(`has a graph item that cannot run: ${errMessage(error)}`);
1207
+ }
1208
+ }
1209
+ for (const edge of maps) {
1210
+ if (!graph.byId.has(edge.from)) throw new ValidationError(`runGraph: ${edgeId(edge)} references unknown node '${edge.from}'`);
1211
+ if (!graph.workers.has(edge.from) && !joins.has(edge.from)) throw new ValidationError(`runGraph: ${edgeId(edge)} maps over '${edge.from}', which never settles as a worker — a map's source is a delegates target or another map's join`);
1212
+ if (edge.from === edge.join) throw new ValidationError(`runGraph: ${edgeId(edge)} maps over its own join`);
1213
+ }
1214
+ return {
1215
+ mapNodes,
1216
+ mapItemNames
1143
1217
  };
1144
1218
  }
1145
1219
  /** The root node's canonical profile with the graph brief appended: which nodes the driver may
1146
1220
  * spawn, by exact name, each with its delegation cap and continuity. */
1147
1221
  function graphRootProfile(validated, registry) {
1148
- const { root, workers, delegatesByWorker, analyzes, analystNodes } = validated;
1222
+ const { root, workers, delegatesByWorker, analyzes, analystNodes, maps, mapItemNames } = validated;
1149
1223
  const driverAnalyzesBriefs = analyzes.filter((edge) => edge.to === root.id).map((edge) => analystNodes.has(edge.analyst) ? `Findings from analyst '${edge.analyst}' (a tool-equipped analyst agent node, over: ${edge.over.join(", ")}) will arrive as finding events.` : `Findings from analyst '${edge.analyst}' (over: ${edge.over.join(", ")}) will arrive as finding events.\n${registry.resolve(edge.directive).text}`);
1224
+ const workerLines = [...workers.values()].map((node) => {
1225
+ const edge = delegatesByWorker.get(node.id);
1226
+ const cap = edge.maxTraversals ?? 32;
1227
+ const description = typeof node.profile.description === "string" && node.profile.description.length > 0 ? ` — ${node.profile.description}` : "";
1228
+ const continuityNote = edge.continuity === "resume" ? "; continuity: resume — each spawn after the first re-attaches to this node's latest settled session (spawn again to continue it; steer while it is live)" : "";
1229
+ return `- '${node.id}'${description} (delegation cap: ${cap} traversals${continuityNote})`;
1230
+ });
1231
+ const mapLines = maps.map((edge) => `- when '${edge.from}' settles, the runtime runs '${mapItemNames.get(edgeId(edge))}'${edge.to === void 0 ? " (a graph)" : ""} once per element of ${edge.pointer === "" ? "its result" : `${JSON.stringify(edge.pointer)} in its result`} (at most ${edge.maxItems} elements, ${edge.concurrency} at a time), then '${edge.join}' with the ordered results; '${edge.join}' settles to you like a worker, and a refused map arrives as a map event`);
1150
1232
  const graphBrief = [
1151
1233
  "AGENT GRAPH: you are the driver node of a fixed topology. You may spawn ONLY these worker",
1152
1234
  "nodes, by EXACT name (spawn_worker with profile: { name: '<node id>' }; the node's full",
1153
1235
  "profile is pinned by the graph — any other profile fields you author are ignored):",
1154
- ...[...workers.values()].map((node) => {
1155
- const edge = delegatesByWorker.get(node.id);
1156
- const cap = edge.maxTraversals ?? 32;
1157
- const description = typeof node.profile.description === "string" && node.profile.description.length > 0 ? ` — ${node.profile.description}` : "";
1158
- const continuityNote = edge.continuity === "resume" ? "; continuity: resume — each spawn after the first re-attaches to this node's latest settled session (spawn again to continue it; steer while it is live)" : "";
1159
- return `- '${node.id}'${description} (delegation cap: ${cap} traversals${continuityNote})`;
1160
- }),
1236
+ ...workerLines,
1237
+ ...mapLines.length > 0 ? [
1238
+ "",
1239
+ "MAPS (the runtime spawns these nodes; never spawn them yourself):",
1240
+ ...mapLines
1241
+ ] : [],
1161
1242
  ...driverAnalyzesBriefs.length > 0 ? ["", ...driverAnalyzesBriefs] : []
1162
1243
  ].join("\n");
1163
1244
  return {
@@ -1177,14 +1258,37 @@ function stringifyPayload(payload) {
1177
1258
  return String(payload);
1178
1259
  }
1179
1260
  }
1261
+ /** Each graph's pinning, mapped to the product authority it wraps. */
1262
+ const productAuthorities = /* @__PURE__ */ new WeakMap();
1263
+ /**
1264
+ * The product authority behind a spawn authority. A graph started inside a run composes its own
1265
+ * pinning with the run's product authority. When that run is itself a graph (`runGraph`), the run's
1266
+ * `authorizeSpawn` is the outer graph's pinning, which would refuse every node of the inner graph,
1267
+ * so the inner graph composes with the authority the outer pinning wraps instead.
1268
+ */
1269
+ function productSpawnAuthority(authorize) {
1270
+ return authorize !== void 0 && productAuthorities.has(authorize) ? productAuthorities.get(authorize) : authorize;
1271
+ }
1272
+ /** A node profile with an edge directive appended to its standing instructions. */
1273
+ function withDirective(profile, directiveText) {
1274
+ if (directiveText.length === 0) return profile;
1275
+ return {
1276
+ ...profile,
1277
+ prompt: {
1278
+ ...profile.prompt ?? {},
1279
+ instructions: [...profile.prompt?.instructions ?? [], directiveText]
1280
+ }
1281
+ };
1282
+ }
1180
1283
  /**
1181
1284
  * Build the graph layer for one validated graph. Each delegates directive is appended to the
1182
1285
  * worker profile's `prompt.instructions` per traversal, each analyzes edge becomes an
1183
1286
  * analyst-on-settle route with a real DESTINATION, and every traversal is ledgered and journaled.
1184
1287
  */
1185
1288
  function createGraphOverlay(validated, opts) {
1186
- const { root, workers, delegatesByWorker, analyzes, analystNodes } = validated;
1289
+ const { root, workers, delegatesByWorker, analyzes, analystNodes, maps, mapNodes, mapItemNames } = validated;
1187
1290
  const { registry, journal, runId, now } = opts;
1291
+ const mapsById = new Map(maps.map((edge) => [edgeId(edge), edge]));
1188
1292
  const ledger = [];
1189
1293
  const journaled = /* @__PURE__ */ new Set();
1190
1294
  const traversalCounts = /* @__PURE__ */ new Map();
@@ -1215,6 +1319,7 @@ function createGraphOverlay(validated, opts) {
1215
1319
  continuity: entry.continuity,
1216
1320
  bytes: entry.bytes,
1217
1321
  ...entry.reason !== void 0 ? { reason: entry.reason } : {},
1322
+ ...entry.map !== void 0 ? { map: entry.map } : {},
1218
1323
  seq: ledgerSeq++,
1219
1324
  at: new Date(now()).toISOString()
1220
1325
  });
@@ -1256,6 +1361,7 @@ function createGraphOverlay(validated, opts) {
1256
1361
  if (!analystNode || requested !== analystNode.id) throw new ValidationError(`runGraph: analyst run for ${JSON.stringify(input.analyst)} does not name an analyst node of this graph (analyst nodes: ${[...analystNodes.keys()].join(", ") || "none"})`);
1257
1362
  return analystNode.profile;
1258
1363
  }
1364
+ if (input.map !== void 0) return pinMapSpawn(input, requested);
1259
1365
  if (input.profile.metadata?.["agentRuntimeGraph"] !== void 0) throw new ValidationError("runGraph: a node of a graph cannot start another graph — run_graph inside a graph is refused; add the work as nodes of this graph instead");
1260
1366
  const node = requested !== void 0 ? workers.get(requested) : void 0;
1261
1367
  if (!node) throw new ValidationError(`runGraph: spawn_worker named profile ${JSON.stringify(requested)} which is not a worker node of this graph (nodes: ${[...workers.keys()].join(", ")}). Spawn by node id: profile.name selects the node; the node profile itself is pinned by the graph.`);
@@ -1298,18 +1404,31 @@ function createGraphOverlay(validated, opts) {
1298
1404
  const stale = pendingByAssignment.get(key);
1299
1405
  if (stale !== void 0) settleUnbound(stale);
1300
1406
  pendingByAssignment.set(key, row);
1301
- return directiveText.length === 0 ? node.profile : {
1302
- ...node.profile,
1303
- prompt: {
1304
- ...node.profile.prompt ?? {},
1305
- instructions: [...node.profile.prompt?.instructions ?? [], directiveText]
1306
- }
1407
+ return withDirective(node.profile, directiveText);
1408
+ };
1409
+ const pinMapSpawn = (input, requested) => {
1410
+ const marker = input.map;
1411
+ const edge = mapsById.get(marker.edge);
1412
+ const refuse = (why) => {
1413
+ throw new ValidationError(`runGraph: map spawn for ${JSON.stringify(marker.edge)} ${why}`);
1307
1414
  };
1415
+ if (edge === void 0) return refuse("names no maps edge of this graph");
1416
+ if (marker.role === "join") {
1417
+ if (requested !== edge.join) refuse(`names ${JSON.stringify(requested)}, not its join`);
1418
+ return mapNodes.get(edge.join).profile;
1419
+ }
1420
+ if (edge.to !== void 0) {
1421
+ if (requested !== edge.to) refuse(`names ${JSON.stringify(requested)}, not its item node`);
1422
+ return withDirective(mapNodes.get(edge.to).profile, registry.resolve(edge.directive).text);
1423
+ }
1424
+ const carried = graphSubtaskOf(input.profile);
1425
+ if (carried === void 0 || canonicalCandidateDigest(carried) !== canonicalCandidateDigest(parseGraphSubtaskTopology(edge.graph))) refuse("carries a graph other than its maps edge's");
1426
+ return input.profile;
1308
1427
  };
1309
1428
  const composeGuidance = (profile) => opts.guidance ? opts.guidance(profile) : profile;
1310
1429
  const resolveSpawnProfile = (authored) => {
1311
1430
  const requested = typeof authored.name === "string" ? authored.name : void 0;
1312
- const node = (requested !== void 0 ? workers.get(requested) : void 0) ?? (requested !== void 0 ? analystNodes.get(requested) : void 0);
1431
+ const node = requested === void 0 ? void 0 : workers.get(requested) ?? analystNodes.get(requested) ?? mapNodes.get(requested);
1313
1432
  return node ? composeGuidance(node.profile) : authored;
1314
1433
  };
1315
1434
  const authorizeSpawn = (input) => {
@@ -1320,6 +1439,7 @@ function createGraphOverlay(validated, opts) {
1320
1439
  profile: pinned
1321
1440
  });
1322
1441
  };
1442
+ productAuthorities.set(authorizeSpawn, opts.authorizeSpawn);
1323
1443
  const routes = analyzes.map((edge) => {
1324
1444
  const analystNode = analystNodes.get(edge.analyst);
1325
1445
  if (analystNode) return {
@@ -1339,6 +1459,17 @@ function createGraphOverlay(validated, opts) {
1339
1459
  directive: registry.resolve(edge.directive).text
1340
1460
  };
1341
1461
  });
1462
+ const mapRoutes = maps.map((edge) => ({
1463
+ edge: edgeId(edge),
1464
+ from: edge.from,
1465
+ pointer: edge.pointer,
1466
+ item: edge.to !== void 0 ? { profile: mapNodes.get(edge.to).profile } : { graph: edge.graph },
1467
+ join: mapNodes.get(edge.join).profile,
1468
+ maxItems: edge.maxItems,
1469
+ concurrency: edge.concurrency,
1470
+ onItemFailure: edge.onItemFailure,
1471
+ ...edge.itemBudget !== void 0 ? { itemBudget: edge.itemBudget } : {}
1472
+ }));
1342
1473
  const continuityByProfile = {};
1343
1474
  for (const [nodeId, edge] of delegatesByWorker) if (edge.continuity !== void 0) continuityByProfile[nodeId] = edge.continuity;
1344
1475
  const strippedByDigest = /* @__PURE__ */ new Map();
@@ -1374,6 +1505,31 @@ function createGraphOverlay(validated, opts) {
1374
1505
  }, true);
1375
1506
  };
1376
1507
  const onCoordinationEvent = (event) => {
1508
+ if (event.type === "map") {
1509
+ const step = event.map;
1510
+ const edge = mapsById.get(step.edge);
1511
+ if (!edge) return;
1512
+ const itemName = mapItemNames.get(step.edge);
1513
+ if (step.workerId !== void 0) nodeByWorkerId.set(step.workerId, step.phase === "join" ? edge.join : itemName);
1514
+ const directiveBytes = step.phase === "item" && step.workerId !== void 0 && edge.to !== void 0 ? byteLength(registry.resolve(edge.directive).text) : 0;
1515
+ record({
1516
+ edge: step.edge,
1517
+ kind: "maps",
1518
+ from: step.phase === "join" ? itemName : edge.from,
1519
+ to: step.phase === "join" ? edge.join : itemName,
1520
+ directive: formatPromptHandle(edge.directive),
1521
+ outcome: step.outcome,
1522
+ continuity: "fresh",
1523
+ bytes: step.bytes + directiveBytes,
1524
+ ...step.reason !== void 0 ? { reason: step.reason } : {},
1525
+ workerId: step.phase === "expand" ? step.sourceWorker : step.workerId,
1526
+ map: {
1527
+ phase: step.phase,
1528
+ ...step.index !== void 0 ? { index: step.index } : {}
1529
+ }
1530
+ }, true);
1531
+ return;
1532
+ }
1377
1533
  if (event.type === "finding") {
1378
1534
  const edge = driverAnalyzesByAnalyst.get(event.finding.analyst);
1379
1535
  if (!edge) return;
@@ -1438,6 +1594,7 @@ function createGraphOverlay(validated, opts) {
1438
1594
  };
1439
1595
  return {
1440
1596
  routes,
1597
+ maps: mapRoutes,
1441
1598
  continuityByProfile,
1442
1599
  authorizeSpawn,
1443
1600
  resolveSpawnProfile,
@@ -1491,7 +1648,11 @@ function parseGraphSubtaskTopology(raw) {
1491
1648
  ...edge,
1492
1649
  directive
1493
1650
  };
1494
- throw new ValidationError(`run_graph: ${where}.kind must be 'delegates' or 'analyzes'`);
1651
+ if (edge.kind === "maps") return {
1652
+ ...edge,
1653
+ directive
1654
+ };
1655
+ throw new ValidationError(`run_graph: ${where}.kind must be 'delegates', 'analyzes' or 'maps'`);
1495
1656
  })
1496
1657
  };
1497
1658
  }
@@ -2587,6 +2748,7 @@ function buildSupervisorAgent(profile, deps, testBrain) {
2587
2748
  ...deps.executeExtraTool ? { executeExtraTool: deps.executeExtraTool } : {},
2588
2749
  ...deps.analysts ? { analysts: deps.analysts } : {},
2589
2750
  ...deps.analyzeOnSettle ? { analyzeOnSettle: deps.analyzeOnSettle } : {},
2751
+ ...deps.mapOnSettle ? { mapOnSettle: deps.mapOnSettle } : {},
2590
2752
  ...deps.sourceEvidenceRefs ? { sourceEvidenceRefs: deps.sourceEvidenceRefs } : {},
2591
2753
  ...deps.peerAudit ? { peerAudit: deps.peerAudit } : {},
2592
2754
  ...deps.escalateQuestion ? { escalateQuestion: deps.escalateQuestion } : {},
@@ -2706,6 +2868,7 @@ function buildSupervisorAgent(profile, deps, testBrain) {
2706
2868
  },
2707
2869
  ...deps.analysts ? { analysts: deps.analysts } : {},
2708
2870
  ...deps.analyzeOnSettle ? { analyzeOnSettle: deps.analyzeOnSettle } : {},
2871
+ ...deps.mapOnSettle ? { mapOnSettle: deps.mapOnSettle } : {},
2709
2872
  ...deps.sourceEvidenceRefs ? { sourceEvidenceRefs: deps.sourceEvidenceRefs } : {},
2710
2873
  ...deps.peerAudit ? { peerAudit: deps.peerAudit } : {},
2711
2874
  ...deps.escalateQuestion ? { escalateQuestion: deps.escalateQuestion } : {},
@@ -4543,6 +4706,7 @@ const superviseOptionKeySet = /* @__PURE__ */ new Set([
4543
4706
  "allowedModels",
4544
4707
  "analysts",
4545
4708
  "analyzeOnSettle",
4709
+ "mapOnSettle",
4546
4710
  "authorizeMessage",
4547
4711
  "authorizeSpawn",
4548
4712
  "backend",
@@ -5311,6 +5475,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5311
5475
  };
5312
5476
  }
5313
5477
  } } : void 0;
5478
+ const productAuthority = productSpawnAuthority(options.authorizeSpawn);
5314
5479
  const graphOverlayFor = (topology) => {
5315
5480
  const registry = kernelPromptRegistry();
5316
5481
  const overlay = createGraphOverlay(validateGraphTopology(topology.nodes, topology.edges, registry, analysts), {
@@ -5319,7 +5484,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5319
5484
  runId,
5320
5485
  now,
5321
5486
  ...guidanceComposer ? { guidance: guidanceComposer } : {},
5322
- ...options.authorizeSpawn ? { authorizeSpawn: options.authorizeSpawn } : {},
5487
+ ...productAuthority ? { authorizeSpawn: productAuthority } : {},
5323
5488
  subtask: true
5324
5489
  });
5325
5490
  graphOverlays.add(overlay);
@@ -5347,6 +5512,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5347
5512
  ...spawnContext.key !== void 0 ? { key: spawnContext.key } : {},
5348
5513
  depth,
5349
5514
  ...spawnContext.analyst !== void 0 ? { analyst: spawnContext.analyst } : {},
5515
+ ...spawnContext.map !== void 0 ? { map: spawnContext.map } : {},
5350
5516
  ...spawnContext.continuity !== void 0 ? { continuity: spawnContext.continuity } : {}
5351
5517
  });
5352
5518
  const authorize = graph?.authorizeSpawn ?? options.authorizeSpawn;
@@ -5389,7 +5555,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5389
5555
  }
5390
5556
  const ownerId = childCoordinationOwner(parentOwnerId, childExecution.identity, spawnContext, depth);
5391
5557
  const subtask = graphSubtaskOf(authorized);
5392
- if (subtask !== void 0 && graph !== void 0) throw new ValidationError("supervise: a node of a graph cannot start another graph; add the work as nodes");
5558
+ if (subtask !== void 0 && graph !== void 0 && spawnContext.map === void 0) throw new ValidationError("supervise: a node of a graph cannot start another graph; add the work as nodes");
5393
5559
  const ownGraph = subtask === void 0 ? void 0 : graphOverlayFor(subtask);
5394
5560
  const subtreeGraph = ownGraph ?? graph;
5395
5561
  const ownSubmission = selectedDeliverable === void 0 && (subtreeGraph !== void 0 || deliverable !== void 0);
@@ -5413,6 +5579,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5413
5579
  const runMessageAuthority = authorizeDownFor(authorized, depth + 1);
5414
5580
  const authorizeNestedMessage = subtreeGraph && runMessageAuthority ? subtreeGraph.observeMessages(runMessageAuthority) : runMessageAuthority;
5415
5581
  const nestedAnalyzeOnSettle = subtreeGraph ? subtreeGraph.routes.length > 0 ? subtreeGraph.routes : void 0 : options.analyzeOnSettle;
5582
+ const nestedMapOnSettle = subtreeGraph ? subtreeGraph.maps.length > 0 ? subtreeGraph.maps : void 0 : options.mapOnSettle;
5416
5583
  const nestedContinuity = subtreeGraph ? Object.keys(subtreeGraph.continuityByProfile).length > 0 ? subtreeGraph.continuityByProfile : void 0 : options.continuityByProfile;
5417
5584
  const runResolveSpawnProfile = options.resolveSpawnProfile;
5418
5585
  const nestedResolveSpawnProfile = subtreeGraph ? (authored) => {
@@ -5464,6 +5631,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5464
5631
  ...options.watchWorkers ? { watchWorkers: options.watchWorkers } : {},
5465
5632
  ...options.stallAfterMs !== void 0 ? { stallAfterMs: options.stallAfterMs } : {},
5466
5633
  ...options.wake !== void 0 ? { wake: options.wake } : {},
5634
+ ...nestedMapOnSettle ? { mapOnSettle: nestedMapOnSettle } : {},
5467
5635
  ...nestedContinuity ? { continuityByProfile: nestedContinuity } : {},
5468
5636
  ...spawnPreflight ? { preflightSpawn: spawnPreflight } : {},
5469
5637
  ...nestedResolveSpawnProfile ? { resolveSpawnProfile: nestedResolveSpawnProfile } : {},
@@ -5590,6 +5758,7 @@ function superviseInternal(profile, task, opts, testBrain) {
5590
5758
  ...options.watchWorkers ? { watchWorkers: options.watchWorkers } : {},
5591
5759
  ...options.stallAfterMs !== void 0 ? { stallAfterMs: options.stallAfterMs } : {},
5592
5760
  ...options.wake !== void 0 ? { wake: options.wake } : {},
5761
+ ...options.mapOnSettle ? { mapOnSettle: options.mapOnSettle } : {},
5593
5762
  ...options.continuityByProfile ? { continuityByProfile: options.continuityByProfile } : {},
5594
5763
  ...options.stopRule ? { stopRule: stopRuleOf(options.stopRule) } : {},
5595
5764
  ...options.onProgressStop ? { onProgressStop: options.onProgressStop } : {},
@@ -5756,4 +5925,4 @@ function rootProviderModelEvidenceFromExecution(evidence) {
5756
5925
  //#endregion
5757
5926
  export { dumbContinuationPassPrompt as A, defaultEdgeTraversalCap as C, createPromptRegistry as D, analyzesFindingsReportPrompt as E, serveCoordinationMcp as F, kernelPromptRegistry as M, naiveContinuationPrompt as N, delegatesWorkerBriefPrompt as O, promptHandle as P, createGraphOverlay as S, validateGraphTopology as T, readRootStream as _, superviseRootProfile as a, composeReentryTask as b, isPreSpawnExecutorFailure as c, withWorkerSpawnRetry as d, assertCoordinationBinding as f, ROOT_STREAM_FILE as g, supervisorAgentWithTestBrain as h, superviseFleetCapabilities as i, formatPromptHandle as j, dumbContinuationFailPrompt as k, resolveWorkerSpawnRetry as l, supervisorAgent as m, profileGuidanceComposer as n, superviseWithTestBrain as o, resolveSupervisorProfile as p, supervise as r, workerFromBackend as s, DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY as t, retryPreSpawnRefusals as u, readRootStreamReceipt as v, graphRootProfile as w, createSupervisorSpanRecorder as x, UNPROVEN_CONTINUITY as y };
5758
5927
 
5759
- //# sourceMappingURL=supervise-Bso1hco7.js.map
5928
+ //# sourceMappingURL=supervise-9WPjMFrH.js.map