@cadenza.io/core 3.27.0 → 3.28.1

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/dist/index.mjs CHANGED
@@ -1241,6 +1241,7 @@ var SignalBroker = class _SignalBroker {
1241
1241
  this.signalObservers = /* @__PURE__ */ new Map();
1242
1242
  this.emittedSignalsRegistry = /* @__PURE__ */ new Set();
1243
1243
  this.signalMetadataRegistry = /* @__PURE__ */ new Map();
1244
+ this.passiveSignalListeners = /* @__PURE__ */ new Map();
1244
1245
  // ── Flush Strategy Management ───────────────────────────────────────
1245
1246
  this.flushStrategies = /* @__PURE__ */ new Map();
1246
1247
  this.strategyData = /* @__PURE__ */ new Map();
@@ -1321,6 +1322,20 @@ var SignalBroker = class _SignalBroker {
1321
1322
  console.log(
1322
1323
  ` \u2022 emittedSignalsRegistry size: ${this.emittedSignalsRegistry.size}`
1323
1324
  );
1325
+ const exactSignalEntries = Array.from(this.signalObservers.entries()).filter(([signal]) => signal.includes(":")).sort((left, right) => {
1326
+ const taskDelta = right[1].tasks.size - left[1].tasks.size;
1327
+ if (taskDelta !== 0) {
1328
+ return taskDelta;
1329
+ }
1330
+ return left[0].localeCompare(right[0]);
1331
+ });
1332
+ console.log(` \u2022 exact signal observer entries: ${exactSignalEntries.length}`);
1333
+ for (const [signal, observer] of exactSignalEntries.slice(0, 8)) {
1334
+ const sampleTaskNames = Array.from(observer.tasks).slice(0, 3).map((task) => task.name);
1335
+ console.log(
1336
+ ` - ${signal} (${observer.tasks.size} tasks) sample=${sampleTaskNames.join(", ")}`
1337
+ );
1338
+ }
1324
1339
  let totalSquashContexts = 0;
1325
1340
  let totalSquashGroups = 0;
1326
1341
  for (const groups of this.strategyData.values()) {
@@ -1734,7 +1749,7 @@ var SignalBroker = class _SignalBroker {
1734
1749
  this.schedule(signal, context, options);
1735
1750
  return;
1736
1751
  }
1737
- this.addSignal(signal);
1752
+ this.validateSignalName(signal);
1738
1753
  this.execute(signal, context);
1739
1754
  }
1740
1755
  /**
@@ -1813,6 +1828,7 @@ var SignalBroker = class _SignalBroker {
1813
1828
  ...context.__metadata,
1814
1829
  __executionTraceId: executionTraceId
1815
1830
  };
1831
+ this.notifyPassiveSignalListeners(signal, context);
1816
1832
  if (this.debug && (!isMetric && !isSubMeta || this.verbose)) {
1817
1833
  console.log(
1818
1834
  `EMITTING ${signal} to listeners ${this.signalObservers.get(signal)?.tasks.size ?? 0} with context ${this.verbose ? JSON.stringify(context) : JSON.stringify(context).slice(0, 100)}`
@@ -1910,11 +1926,37 @@ var SignalBroker = class _SignalBroker {
1910
1926
  this.addSignal(signal, metadata);
1911
1927
  this.signalObservers.get(signal).tasks.add(routineOrTask);
1912
1928
  }
1929
+ addPassiveSignalListener(listener) {
1930
+ const listenerId = uuid();
1931
+ this.passiveSignalListeners.set(listenerId, listener);
1932
+ return () => {
1933
+ this.passiveSignalListeners.delete(listenerId);
1934
+ };
1935
+ }
1936
+ notifyPassiveSignalListeners(signal, context) {
1937
+ if (this.passiveSignalListeners.size === 0) {
1938
+ return;
1939
+ }
1940
+ const metadata = this.getSignalMetadata(signal) ?? null;
1941
+ for (const listener of this.passiveSignalListeners.values()) {
1942
+ try {
1943
+ listener(signal, context, metadata);
1944
+ } catch (error) {
1945
+ if (this.debug) {
1946
+ console.error("Passive signal listener failed", error);
1947
+ }
1948
+ }
1949
+ }
1950
+ }
1913
1951
  registerEmittedSignal(signal, metadata) {
1952
+ const signalKey = this.resolveSignalMetadataKey(signal);
1953
+ if (!signalKey) {
1954
+ return;
1955
+ }
1914
1956
  if (metadata) {
1915
- this.setSignalMetadata(signal, metadata);
1957
+ this.setSignalMetadata(signalKey, metadata);
1916
1958
  }
1917
- this.emittedSignalsRegistry.add(signal);
1959
+ this.emittedSignalsRegistry.add(signalKey);
1918
1960
  }
1919
1961
  /**
1920
1962
  * Unsubscribes a routine/task from a signal.
@@ -2489,6 +2531,38 @@ var GraphNode = class _GraphNode extends SignalEmitter {
2489
2531
  getTag() {
2490
2532
  return this.task.getTag(this.context);
2491
2533
  }
2534
+ classifyBusinessRoutineLifecycle() {
2535
+ const fullContext = this.context?.getFullContext?.() ?? {};
2536
+ const metadata = fullContext.__metadata && typeof fullContext.__metadata === "object" ? fullContext.__metadata : {};
2537
+ if (this.task.isMeta || this.task.isSubMeta || this.task.isHidden) {
2538
+ return false;
2539
+ }
2540
+ if (fullContext.__isInquiry === true || fullContext.__isDeputy === true || metadata.__isInquiry === true || metadata.__isDeputy === true || metadata.__isSubMeta === true) {
2541
+ return false;
2542
+ }
2543
+ return true;
2544
+ }
2545
+ getBusinessRoutineLifecycleDecision() {
2546
+ const fullContext = this.context?.getFullContext?.() ?? {};
2547
+ const metadata = this.context?.getMetadata?.() ?? {};
2548
+ if (typeof metadata.__emitBusinessRoutineLifecycle === "boolean") {
2549
+ return metadata.__emitBusinessRoutineLifecycle;
2550
+ }
2551
+ if (typeof fullContext.__emitBusinessRoutineLifecycle === "boolean") {
2552
+ return fullContext.__emitBusinessRoutineLifecycle;
2553
+ }
2554
+ return this.classifyBusinessRoutineLifecycle();
2555
+ }
2556
+ rememberBusinessRoutineLifecycleDecision(value) {
2557
+ const fullContext = this.context?.getFullContext?.();
2558
+ const metadata = this.context?.getMetadata?.();
2559
+ if (fullContext && typeof fullContext === "object") {
2560
+ fullContext.__emitBusinessRoutineLifecycle = value;
2561
+ }
2562
+ if (metadata && typeof metadata === "object") {
2563
+ metadata.__emitBusinessRoutineLifecycle = value;
2564
+ }
2565
+ }
2492
2566
  /**
2493
2567
  * Schedules the current node/task on the specified graph layer if applicable.
2494
2568
  *
@@ -2614,17 +2688,23 @@ var GraphNode = class _GraphNode extends SignalEmitter {
2614
2688
  this.executionStart = Date.now();
2615
2689
  }
2616
2690
  if (this.previousNodes.length === 0) {
2617
- this.emitMetricsWithMetadata(
2618
- "meta.node.started_routine_execution",
2619
- {
2620
- data: {
2621
- isRunning: true,
2622
- started: formatTimestamp(this.executionStart)
2623
- },
2624
- filter: { uuid: this.routineExecId }
2625
- },
2626
- { squash: true, squashId: this.routineExecId }
2691
+ const shouldEmitBusinessRoutineLifecycle = this.getBusinessRoutineLifecycleDecision();
2692
+ this.rememberBusinessRoutineLifecycleDecision(
2693
+ shouldEmitBusinessRoutineLifecycle
2627
2694
  );
2695
+ if (shouldEmitBusinessRoutineLifecycle) {
2696
+ this.emitMetricsWithMetadata(
2697
+ "meta.node.started_routine_execution",
2698
+ {
2699
+ data: {
2700
+ isRunning: true,
2701
+ started: formatTimestamp(this.executionStart)
2702
+ },
2703
+ filter: { uuid: this.routineExecId }
2704
+ },
2705
+ { squash: true, squashId: this.routineExecId }
2706
+ );
2707
+ }
2628
2708
  }
2629
2709
  if (this.debug && !this.task.isSubMeta && !this.context.getMetadata().__isSubMeta || this.verbose) {
2630
2710
  this.log();
@@ -2693,21 +2773,23 @@ var GraphNode = class _GraphNode extends SignalEmitter {
2693
2773
  `meta.node.graph_completed:${this.routineExecId}`,
2694
2774
  context2
2695
2775
  );
2696
- this.emitMetricsWithMetadata(
2697
- "meta.node.ended_routine_execution",
2698
- {
2699
- data: {
2700
- isRunning: false,
2701
- isComplete: true,
2702
- resultContext: this.context.getContext(),
2703
- metaResultContext: this.context.getMetadata(),
2704
- progress: 1,
2705
- ended: formatTimestamp(end)
2776
+ if (this.getBusinessRoutineLifecycleDecision()) {
2777
+ this.emitMetricsWithMetadata(
2778
+ "meta.node.ended_routine_execution",
2779
+ {
2780
+ data: {
2781
+ isRunning: false,
2782
+ isComplete: true,
2783
+ resultContext: this.context.getContext(),
2784
+ metaResultContext: this.context.getMetadata(),
2785
+ progress: 1,
2786
+ ended: formatTimestamp(end)
2787
+ },
2788
+ filter: { uuid: this.routineExecId }
2706
2789
  },
2707
- filter: { uuid: this.routineExecId }
2708
- },
2709
- { squash: true, squashId: this.routineExecId }
2710
- );
2790
+ { squash: true, squashId: this.routineExecId }
2791
+ );
2792
+ }
2711
2793
  }
2712
2794
  return end;
2713
2795
  }
@@ -2974,16 +3056,17 @@ var GraphNode = class _GraphNode extends SignalEmitter {
2974
3056
  * @return {void} Does not return a value.
2975
3057
  */
2976
3058
  finalize() {
3059
+ const context = this.context?.getFullContext?.() ?? {};
2977
3060
  if (this.nextNodes.length === 0) {
2978
3061
  this.completeSubgraph();
2979
3062
  }
2980
3063
  if (this.errored || this.failed) {
2981
3064
  this.task.mapOnFailSignals(
2982
- (signal) => this.emitWithMetadata(signal, this.context.getFullContext())
3065
+ (signal) => this.emitWithMetadata(signal, { ...context })
2983
3066
  );
2984
3067
  } else if (this.result !== void 0 && this.result !== false) {
2985
3068
  this.task.mapSignals(
2986
- (signal) => this.emitWithMetadata(signal, this.context.getFullContext())
3069
+ (signal) => this.emitWithMetadata(signal, { ...context })
2987
3070
  );
2988
3071
  }
2989
3072
  this.end();
@@ -2997,8 +3080,9 @@ var GraphNode = class _GraphNode extends SignalEmitter {
2997
3080
  */
2998
3081
  onError(error, errorData = {}) {
2999
3082
  const normalizedError = normalizeGraphErrorMessage(error);
3083
+ const context = this.context?.getFullContext?.() ?? {};
3000
3084
  this.result = {
3001
- ...this.context.getFullContext(),
3085
+ ...context,
3002
3086
  __error: `Node error: ${normalizedError}`,
3003
3087
  __retries: this.retries,
3004
3088
  error: `Node error: ${normalizedError}`,
@@ -3592,7 +3676,7 @@ var GraphRunner = class extends SignalEmitter {
3592
3676
  allTasks
3593
3677
  );
3594
3678
  const ctx = new GraphContext(context || {});
3595
- if (!isSubMeta) {
3679
+ if (!isSubMeta && (!isMeta || this.debug)) {
3596
3680
  if (isNewTrace) {
3597
3681
  this.emitMetrics("meta.runner.new_trace", {
3598
3682
  data: {
@@ -3882,7 +3966,13 @@ var Actor = class {
3882
3966
  task(handler, bindingOptions = {}) {
3883
3967
  const mode = bindingOptions.mode ?? "read";
3884
3968
  const taskBindingId = `${this.spec.name}:${++this.nextTaskBindingIndex}`;
3885
- const wrapped = (context, emit, inquire, progressCallback) => {
3969
+ const wrapped = (context, emit, inquire, tools, progressCallback) => {
3970
+ const resolvedTools = tools && typeof tools === "object" && !Array.isArray(tools) && "helpers" in tools && "globals" in tools ? tools : {
3971
+ helpers: {},
3972
+ globals: {}
3973
+ };
3974
+ const resolvedProgressCallback = typeof progressCallback === "function" ? progressCallback : typeof tools === "function" ? tools : () => {
3975
+ };
3886
3976
  const normalizedInput = this.normalizeInputContext(context);
3887
3977
  const invocationOptions = this.resolveInvocationOptions(
3888
3978
  context,
@@ -4002,9 +4092,16 @@ var Actor = class {
4002
4092
  patchRuntimeState,
4003
4093
  reduceRuntimeState,
4004
4094
  emit: (signal, payload = {}) => emit(signal, payload),
4005
- inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options)
4095
+ inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options),
4096
+ tools: resolvedTools
4006
4097
  };
4007
- const handlerResult = await handler(actorContext);
4098
+ const handlerResult = await handler(
4099
+ actorContext,
4100
+ actorContext.emit,
4101
+ actorContext.inquire,
4102
+ resolvedTools,
4103
+ resolvedProgressCallback
4104
+ );
4008
4105
  if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
4009
4106
  reduceDurableState(handlerResult);
4010
4107
  }
@@ -4029,7 +4126,7 @@ var Actor = class {
4029
4126
  stateRecord.lastRuntimeWriteAt = writeTimestamp;
4030
4127
  }
4031
4128
  this.touchSession(actorKey, invocationOptions.touchSession, Date.now());
4032
- progressCallback(100);
4129
+ resolvedProgressCallback(100);
4033
4130
  if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
4034
4131
  return cloneForDurableState(stateRecord.durableState);
4035
4132
  }
@@ -4073,6 +4170,13 @@ var Actor = class {
4073
4170
  this.pruneExpiredActorKeys(Date.now());
4074
4171
  return this.ensureStateRecord(key).runtimeState;
4075
4172
  }
4173
+ /**
4174
+ * Lists all currently materialized actor keys.
4175
+ */
4176
+ listActorKeys() {
4177
+ this.pruneExpiredActorKeys(Date.now());
4178
+ return Array.from(this.stateByKey.keys()).sort();
4179
+ }
4076
4180
  /**
4077
4181
  * Alias of `getDurableVersion`.
4078
4182
  */
@@ -4482,6 +4586,176 @@ var Actor = class {
4482
4586
  }
4483
4587
  };
4484
4588
 
4589
+ // src/tools/definitions.ts
4590
+ function validateAlias(alias) {
4591
+ const normalized = String(alias ?? "").trim();
4592
+ if (!normalized) {
4593
+ throw new Error("Tool dependency alias must be a non-empty string");
4594
+ }
4595
+ return normalized;
4596
+ }
4597
+ function serializeGlobalValue(value) {
4598
+ if (value === void 0 || typeof value === "function") {
4599
+ throw new Error("Global values must be JSON-serializable");
4600
+ }
4601
+ try {
4602
+ return JSON.parse(JSON.stringify(value));
4603
+ } catch (error) {
4604
+ throw new Error(
4605
+ `Global values must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`
4606
+ );
4607
+ }
4608
+ }
4609
+ function deepFreeze(value) {
4610
+ if (!value || typeof value !== "object") {
4611
+ return value;
4612
+ }
4613
+ Object.freeze(value);
4614
+ for (const nested of Object.values(value)) {
4615
+ if (nested && typeof nested === "object" && !Object.isFrozen(nested)) {
4616
+ deepFreeze(nested);
4617
+ }
4618
+ }
4619
+ return value;
4620
+ }
4621
+ var GlobalDefinition = class {
4622
+ constructor(name, value, description = "", isMeta = false) {
4623
+ this.version = 1;
4624
+ this.destroyed = false;
4625
+ this.name = name;
4626
+ this.description = description;
4627
+ this.isMeta = isMeta;
4628
+ this.value = deepFreeze(serializeGlobalValue(value));
4629
+ }
4630
+ destroy() {
4631
+ this.destroyed = true;
4632
+ }
4633
+ export() {
4634
+ return {
4635
+ name: this.name,
4636
+ description: this.description,
4637
+ version: this.version,
4638
+ isMeta: this.isMeta,
4639
+ value: this.value
4640
+ };
4641
+ }
4642
+ };
4643
+ var HelperDefinition = class {
4644
+ constructor(name, helperFunction, description = "", isMeta = false) {
4645
+ this.version = 1;
4646
+ this.helperAliases = /* @__PURE__ */ new Map();
4647
+ this.globalAliases = /* @__PURE__ */ new Map();
4648
+ this.destroyed = false;
4649
+ this.name = name;
4650
+ this.description = description;
4651
+ this.isMeta = isMeta;
4652
+ this.helperFunction = helperFunction;
4653
+ }
4654
+ usesHelpers(helpers) {
4655
+ attachHelperDependency(
4656
+ this,
4657
+ this.name,
4658
+ this.version,
4659
+ helpers,
4660
+ "meta.helper.helper_associated"
4661
+ );
4662
+ return this;
4663
+ }
4664
+ usesGlobals(globals) {
4665
+ attachGlobalDependency(
4666
+ this,
4667
+ this.name,
4668
+ this.version,
4669
+ globals,
4670
+ "meta.helper.global_associated"
4671
+ );
4672
+ return this;
4673
+ }
4674
+ execute(context, emit, inquire, progressCallback) {
4675
+ return Cadenza.executeHelper(
4676
+ this,
4677
+ context,
4678
+ emit,
4679
+ inquire,
4680
+ progressCallback
4681
+ );
4682
+ }
4683
+ destroy() {
4684
+ this.destroyed = true;
4685
+ }
4686
+ export() {
4687
+ return {
4688
+ name: this.name,
4689
+ description: this.description,
4690
+ version: this.version,
4691
+ isMeta: this.isMeta,
4692
+ functionString: this.helperFunction.toString(),
4693
+ helperAliases: Object.fromEntries(this.helperAliases),
4694
+ globalAliases: Object.fromEntries(this.globalAliases)
4695
+ };
4696
+ }
4697
+ };
4698
+ function attachHelperDependency(owner, ownerName, ownerVersion, helpers, signalName) {
4699
+ for (const [alias, helper] of Object.entries(helpers)) {
4700
+ const normalizedAlias = validateAlias(alias);
4701
+ if (!helper) {
4702
+ throw new Error(
4703
+ `Helper dependency "${normalizedAlias}" must reference a helper definition`
4704
+ );
4705
+ }
4706
+ if (helper.isMeta !== owner.isMeta) {
4707
+ throw new Error(
4708
+ `${ownerName} cannot use ${helper.isMeta ? "meta" : "business"} helper "${helper.name}" across layer boundaries`
4709
+ );
4710
+ }
4711
+ owner.helperAliases.set(normalizedAlias, helper.name);
4712
+ Cadenza.emit(signalName, {
4713
+ data: {
4714
+ alias: normalizedAlias,
4715
+ ...signalName === "meta.task.helper_associated" ? {
4716
+ taskName: ownerName,
4717
+ taskVersion: ownerVersion
4718
+ } : {
4719
+ helperName: ownerName,
4720
+ helperVersion: ownerVersion
4721
+ },
4722
+ dependencyHelperName: helper.name,
4723
+ dependencyHelperVersion: helper.version
4724
+ }
4725
+ });
4726
+ }
4727
+ }
4728
+ function attachGlobalDependency(owner, ownerName, ownerVersion, globals, signalName) {
4729
+ for (const [alias, globalDefinition] of Object.entries(globals)) {
4730
+ const normalizedAlias = validateAlias(alias);
4731
+ if (!globalDefinition) {
4732
+ throw new Error(
4733
+ `Global dependency "${normalizedAlias}" must reference a global definition`
4734
+ );
4735
+ }
4736
+ if (globalDefinition.isMeta !== owner.isMeta) {
4737
+ throw new Error(
4738
+ `${ownerName} cannot use ${globalDefinition.isMeta ? "meta" : "business"} global "${globalDefinition.name}" across layer boundaries`
4739
+ );
4740
+ }
4741
+ owner.globalAliases.set(normalizedAlias, globalDefinition.name);
4742
+ Cadenza.emit(signalName, {
4743
+ data: {
4744
+ alias: normalizedAlias,
4745
+ ...signalName === "meta.task.global_associated" ? {
4746
+ taskName: ownerName,
4747
+ taskVersion: ownerVersion
4748
+ } : {
4749
+ helperName: ownerName,
4750
+ helperVersion: ownerVersion
4751
+ },
4752
+ globalName: globalDefinition.name,
4753
+ globalVersion: globalDefinition.version
4754
+ }
4755
+ });
4756
+ }
4757
+ }
4758
+
4485
4759
  // src/graph/definition/Task.ts
4486
4760
  function normalizeSignalDefinition(input) {
4487
4761
  if (typeof input === "string") {
@@ -4558,6 +4832,8 @@ var Task = class _Task extends SignalEmitter {
4558
4832
  this.observedSignals = /* @__PURE__ */ new Set();
4559
4833
  this.handlesIntents = /* @__PURE__ */ new Set();
4560
4834
  this.inquiresIntents = /* @__PURE__ */ new Set();
4835
+ this.helperAliases = /* @__PURE__ */ new Map();
4836
+ this.globalAliases = /* @__PURE__ */ new Map();
4561
4837
  this.name = name;
4562
4838
  this.taskFunction = task;
4563
4839
  this.description = description;
@@ -4593,6 +4869,8 @@ var Task = class _Task extends SignalEmitter {
4593
4869
  "meta.task.relationship_added",
4594
4870
  "meta.task.relationship_removed",
4595
4871
  "meta.task.intent_associated",
4872
+ "meta.task.helper_associated",
4873
+ "meta.task.global_associated",
4596
4874
  "meta.task.layer_index_changed",
4597
4875
  "meta.node.scheduled",
4598
4876
  "meta.node.mapped",
@@ -5106,10 +5384,18 @@ var Task = class _Task extends SignalEmitter {
5106
5384
  * @return {TaskResult} The result of the executed task.
5107
5385
  */
5108
5386
  execute(context, emit, inquire, progressCallback, nodeData) {
5387
+ const executionContext = this.isMeta ? context.getClonedFullContext() : context.getClonedContext();
5109
5388
  return this.taskFunction(
5110
- this.isMeta ? context.getClonedFullContext() : context.getClonedContext(),
5389
+ executionContext,
5111
5390
  emit,
5112
5391
  inquire,
5392
+ Cadenza.resolveToolsForOwner(
5393
+ this,
5394
+ executionContext,
5395
+ emit,
5396
+ inquire,
5397
+ progressCallback
5398
+ ),
5113
5399
  progressCallback
5114
5400
  );
5115
5401
  }
@@ -5123,6 +5409,7 @@ var Task = class _Task extends SignalEmitter {
5123
5409
  * @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
5124
5410
  */
5125
5411
  doAfter(...tasks) {
5412
+ Cadenza.assertGraphMutationAllowed("Task#doAfter");
5126
5413
  for (const pred of tasks) {
5127
5414
  if (!pred) continue;
5128
5415
  if (this.predecessorTasks.has(pred)) continue;
@@ -5154,6 +5441,7 @@ var Task = class _Task extends SignalEmitter {
5154
5441
  * @throws {Error} Throws an error if adding a task causes a cyclic dependency.
5155
5442
  */
5156
5443
  then(...tasks) {
5444
+ Cadenza.assertGraphMutationAllowed("Task#then");
5157
5445
  for (const next of tasks) {
5158
5446
  if (!next) continue;
5159
5447
  if (this.nextTasks.has(next)) continue;
@@ -5317,6 +5605,7 @@ var Task = class _Task extends SignalEmitter {
5317
5605
  * @return {this} The current instance after adding the specified signals.
5318
5606
  */
5319
5607
  doOn(...signals) {
5608
+ Cadenza.assertGraphMutationAllowed("Task#doOn");
5320
5609
  signals.forEach((input) => {
5321
5610
  const { name: signal, metadata } = normalizeSignalDefinition(input);
5322
5611
  if (this.observedSignals.has(signal)) return;
@@ -5341,6 +5630,7 @@ var Task = class _Task extends SignalEmitter {
5341
5630
  * @return {this} The current instance for method chaining.
5342
5631
  */
5343
5632
  emits(...signals) {
5633
+ Cadenza.assertGraphMutationAllowed("Task#emits");
5344
5634
  signals.forEach((input) => {
5345
5635
  const { name: signal } = normalizeSignalDefinition(input);
5346
5636
  if (this.observedSignals.has(signal))
@@ -5360,6 +5650,7 @@ var Task = class _Task extends SignalEmitter {
5360
5650
  * @return {this} Returns the current instance for chaining.
5361
5651
  */
5362
5652
  emitsOnFail(...signals) {
5653
+ Cadenza.assertGraphMutationAllowed("Task#emitsOnFail");
5363
5654
  signals.forEach((input) => {
5364
5655
  const { name: signal } = normalizeSignalDefinition(input);
5365
5656
  this.signalsToEmitOnFail.add(signal);
@@ -5374,6 +5665,7 @@ var Task = class _Task extends SignalEmitter {
5374
5665
  * @return {void} This method does not return a value.
5375
5666
  */
5376
5667
  attachSignal(...signals) {
5668
+ Cadenza.assertGraphMutationAllowed("Task#attachSignal");
5377
5669
  signals.forEach((input) => {
5378
5670
  const { name: signal, metadata } = normalizeSignalDefinition(input);
5379
5671
  this.emitsSignals.add(signal);
@@ -5470,6 +5762,7 @@ var Task = class _Task extends SignalEmitter {
5470
5762
  return this;
5471
5763
  }
5472
5764
  respondsTo(...inquires) {
5765
+ Cadenza.assertGraphMutationAllowed("Task#respondsTo");
5473
5766
  for (const intentName of inquires) {
5474
5767
  if (this.handlesIntents.has(intentName)) {
5475
5768
  continue;
@@ -5505,6 +5798,26 @@ var Task = class _Task extends SignalEmitter {
5505
5798
  }
5506
5799
  return this;
5507
5800
  }
5801
+ usesHelpers(helpers) {
5802
+ attachHelperDependency(
5803
+ this,
5804
+ this.name,
5805
+ this.version,
5806
+ helpers,
5807
+ "meta.task.helper_associated"
5808
+ );
5809
+ return this;
5810
+ }
5811
+ usesGlobals(globals) {
5812
+ attachGlobalDependency(
5813
+ this,
5814
+ this.name,
5815
+ this.version,
5816
+ globals,
5817
+ "meta.task.global_associated"
5818
+ );
5819
+ return this;
5820
+ }
5508
5821
  attachIntents(...intentNames) {
5509
5822
  for (const intent of intentNames) {
5510
5823
  this.inquiresIntents.add(intent);
@@ -5597,6 +5910,7 @@ var Task = class _Task extends SignalEmitter {
5597
5910
  this.nextTasks.clear();
5598
5911
  this.predecessorTasks.clear();
5599
5912
  this.destroyed = true;
5913
+ Cadenza.forgetTask(this.name);
5600
5914
  if (this.register) {
5601
5915
  Cadenza.registry.tasks.delete(this.name);
5602
5916
  this.emitMetricsWithMetadata("meta.task.destroyed", {
@@ -5638,6 +5952,8 @@ var Task = class _Task extends SignalEmitter {
5638
5952
  __validateInputContext: this.validateInputContext,
5639
5953
  __outputSchema: this.outputContextSchema,
5640
5954
  __validateOutputContext: this.validateOutputContext,
5955
+ __helperAliases: Object.fromEntries(this.helperAliases),
5956
+ __globalAliases: Object.fromEntries(this.globalAliases),
5641
5957
  __nextTasks: Array.from(this.nextTasks).map((t) => t.name),
5642
5958
  __previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
5643
5959
  };
@@ -5884,6 +6200,13 @@ var DebounceTask = class extends Task {
5884
6200
  this.lastContext.getClonedContext(),
5885
6201
  this.lastEmitFunction,
5886
6202
  this.lastInquireFunction,
6203
+ Cadenza.resolveToolsForOwner(
6204
+ this,
6205
+ this.lastContext.getClonedContext(),
6206
+ this.lastEmitFunction,
6207
+ this.lastInquireFunction,
6208
+ this.lastProgressCallback
6209
+ ),
5887
6210
  this.lastProgressCallback
5888
6211
  );
5889
6212
  } catch (error) {
@@ -6038,6 +6361,19 @@ var EphemeralTask = class extends Task {
6038
6361
  progressCallback,
6039
6362
  nodeData
6040
6363
  );
6364
+ if (result instanceof Promise) {
6365
+ return result.then((resolved) => {
6366
+ if (this.once || this.condition(resolved)) {
6367
+ this.destroy();
6368
+ }
6369
+ return resolved;
6370
+ }).catch((error) => {
6371
+ if (this.once || this.condition(error)) {
6372
+ this.destroy();
6373
+ }
6374
+ throw error;
6375
+ });
6376
+ }
6041
6377
  if (this.once || this.condition(result)) {
6042
6378
  this.destroy();
6043
6379
  }
@@ -7028,6 +7364,386 @@ var InquiryBroker = class _InquiryBroker extends SignalEmitter {
7028
7364
  }
7029
7365
  };
7030
7366
 
7367
+ // src/runtime/RuntimeDefinitionRegistry.ts
7368
+ function createLinkKey(predecessorTaskName, successorTaskName) {
7369
+ return `${predecessorTaskName}=>${successorTaskName}`;
7370
+ }
7371
+ function createTaskSignalKey(taskName, signalName) {
7372
+ return `${taskName}=>${signalName}`;
7373
+ }
7374
+ function createTaskIntentKey(taskName, intentName) {
7375
+ return `${taskName}=>${intentName}`;
7376
+ }
7377
+ function createRoutineSignalKey(routineName, signalName) {
7378
+ return `${routineName}=>${signalName}`;
7379
+ }
7380
+ var RuntimeDefinitionRegistry = class {
7381
+ constructor() {
7382
+ this.taskDefinitions = /* @__PURE__ */ new Map();
7383
+ this.helperDefinitions = /* @__PURE__ */ new Map();
7384
+ this.globalDefinitions = /* @__PURE__ */ new Map();
7385
+ this.routineDefinitions = /* @__PURE__ */ new Map();
7386
+ this.intentDefinitions = /* @__PURE__ */ new Map();
7387
+ this.actorDefinitions = /* @__PURE__ */ new Map();
7388
+ this.actorTaskDefinitions = /* @__PURE__ */ new Map();
7389
+ this.taskLinks = /* @__PURE__ */ new Map();
7390
+ this.taskSignalObservations = /* @__PURE__ */ new Map();
7391
+ this.taskSignalEmissions = /* @__PURE__ */ new Map();
7392
+ this.taskIntentBindings = /* @__PURE__ */ new Map();
7393
+ this.taskHelperBindings = /* @__PURE__ */ new Map();
7394
+ this.taskGlobalBindings = /* @__PURE__ */ new Map();
7395
+ this.helperHelperBindings = /* @__PURE__ */ new Map();
7396
+ this.helperGlobalBindings = /* @__PURE__ */ new Map();
7397
+ this.routineSignalObservations = /* @__PURE__ */ new Map();
7398
+ }
7399
+ reset() {
7400
+ this.taskDefinitions.clear();
7401
+ this.helperDefinitions.clear();
7402
+ this.globalDefinitions.clear();
7403
+ this.routineDefinitions.clear();
7404
+ this.intentDefinitions.clear();
7405
+ this.actorDefinitions.clear();
7406
+ this.actorTaskDefinitions.clear();
7407
+ this.taskLinks.clear();
7408
+ this.taskSignalObservations.clear();
7409
+ this.taskSignalEmissions.clear();
7410
+ this.taskIntentBindings.clear();
7411
+ this.taskHelperBindings.clear();
7412
+ this.taskGlobalBindings.clear();
7413
+ this.helperHelperBindings.clear();
7414
+ this.helperGlobalBindings.clear();
7415
+ this.routineSignalObservations.clear();
7416
+ }
7417
+ setTaskDefinition(definition) {
7418
+ this.taskDefinitions.set(definition.name, {
7419
+ ...definition,
7420
+ kind: definition.kind ?? "task",
7421
+ options: definition.options ? { ...definition.options } : void 0
7422
+ });
7423
+ }
7424
+ setHelperDefinition(definition) {
7425
+ this.helperDefinitions.set(definition.name, {
7426
+ ...definition,
7427
+ kind: definition.kind ?? "helper"
7428
+ });
7429
+ }
7430
+ setGlobalDefinition(definition) {
7431
+ this.globalDefinitions.set(definition.name, {
7432
+ ...definition,
7433
+ kind: definition.kind ?? "global",
7434
+ value: definition.value
7435
+ });
7436
+ }
7437
+ setRoutineDefinition(definition) {
7438
+ this.routineDefinitions.set(definition.name, {
7439
+ ...definition,
7440
+ startTaskNames: [...definition.startTaskNames],
7441
+ isMeta: definition.isMeta === true
7442
+ });
7443
+ }
7444
+ setIntentDefinition(definition) {
7445
+ this.intentDefinitions.set(definition.name, {
7446
+ ...definition,
7447
+ input: definition.input ? { ...definition.input } : void 0,
7448
+ output: definition.output ? { ...definition.output } : void 0
7449
+ });
7450
+ }
7451
+ setActorDefinition(definition) {
7452
+ this.actorDefinitions.set(definition.name, {
7453
+ ...definition,
7454
+ state: definition.state ? {
7455
+ ...definition.state,
7456
+ durable: definition.state.durable ? { ...definition.state.durable } : void 0,
7457
+ runtime: definition.state.runtime ? { ...definition.state.runtime } : void 0
7458
+ } : void 0,
7459
+ tasks: definition.tasks ? definition.tasks.map((task) => ({ ...task })) : void 0
7460
+ });
7461
+ }
7462
+ setActorTaskDefinition(definition) {
7463
+ this.actorTaskDefinitions.set(definition.taskName, {
7464
+ ...definition,
7465
+ mode: definition.mode ?? "read",
7466
+ options: definition.options ? { ...definition.options } : void 0
7467
+ });
7468
+ }
7469
+ setTaskLink(definition) {
7470
+ this.taskLinks.set(
7471
+ createLinkKey(
7472
+ definition.predecessorTaskName,
7473
+ definition.successorTaskName
7474
+ ),
7475
+ { ...definition }
7476
+ );
7477
+ }
7478
+ setTaskSignalObservation(definition) {
7479
+ const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
7480
+ this.taskSignalObservations.set(
7481
+ createTaskSignalKey(definition.taskName, signalName),
7482
+ {
7483
+ taskName: definition.taskName,
7484
+ signal: typeof definition.signal === "string" ? definition.signal : {
7485
+ name: definition.signal.name,
7486
+ deliveryMode: definition.signal.deliveryMode,
7487
+ broadcastFilter: definition.signal.broadcastFilter ?? null
7488
+ }
7489
+ }
7490
+ );
7491
+ }
7492
+ setTaskSignalEmission(definition) {
7493
+ const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
7494
+ this.taskSignalEmissions.set(
7495
+ `${definition.taskName}=>${definition.mode ?? "after"}=>${signalName}`,
7496
+ {
7497
+ taskName: definition.taskName,
7498
+ mode: definition.mode ?? "after",
7499
+ signal: typeof definition.signal === "string" ? definition.signal : {
7500
+ name: definition.signal.name,
7501
+ deliveryMode: definition.signal.deliveryMode,
7502
+ broadcastFilter: definition.signal.broadcastFilter ?? null
7503
+ }
7504
+ }
7505
+ );
7506
+ }
7507
+ setTaskIntentBinding(definition) {
7508
+ this.taskIntentBindings.set(
7509
+ createTaskIntentKey(definition.taskName, definition.intentName),
7510
+ { ...definition }
7511
+ );
7512
+ }
7513
+ setTaskHelperBinding(definition) {
7514
+ this.taskHelperBindings.set(
7515
+ `${definition.taskName}=>${definition.alias}`,
7516
+ { ...definition }
7517
+ );
7518
+ }
7519
+ setTaskGlobalBinding(definition) {
7520
+ this.taskGlobalBindings.set(
7521
+ `${definition.taskName}=>${definition.alias}`,
7522
+ { ...definition }
7523
+ );
7524
+ }
7525
+ setHelperHelperBinding(definition) {
7526
+ this.helperHelperBindings.set(
7527
+ `${definition.helperName}=>${definition.alias}`,
7528
+ { ...definition }
7529
+ );
7530
+ }
7531
+ setHelperGlobalBinding(definition) {
7532
+ this.helperGlobalBindings.set(
7533
+ `${definition.helperName}=>${definition.alias}`,
7534
+ { ...definition }
7535
+ );
7536
+ }
7537
+ setRoutineSignalObservation(definition) {
7538
+ this.routineSignalObservations.set(
7539
+ createRoutineSignalKey(definition.routineName, definition.signal),
7540
+ { ...definition }
7541
+ );
7542
+ }
7543
+ isRuntimeOwnedTask(taskName) {
7544
+ return this.taskDefinitions.has(taskName) || this.actorTaskDefinitions.has(taskName);
7545
+ }
7546
+ isRuntimeOwnedHelper(helperName) {
7547
+ return this.helperDefinitions.has(helperName);
7548
+ }
7549
+ isRuntimeOwnedGlobal(globalName) {
7550
+ return this.globalDefinitions.has(globalName);
7551
+ }
7552
+ isRuntimeOwnedRoutine(routineName) {
7553
+ return this.routineDefinitions.has(routineName);
7554
+ }
7555
+ isRuntimeOwnedActor(actorName) {
7556
+ return this.actorDefinitions.has(actorName);
7557
+ }
7558
+ };
7559
+ var runtimeDefinitionRegistry = new RuntimeDefinitionRegistry();
7560
+
7561
+ // src/runtime/sandbox.ts
7562
+ import vm from "vm";
7563
+ import ts from "typescript";
7564
+ var FORBIDDEN_SOURCE_PATTERNS = [
7565
+ {
7566
+ pattern: /\bimport\b/,
7567
+ message: "Runtime handler source must not contain import statements"
7568
+ },
7569
+ {
7570
+ pattern: /\bexport\b/,
7571
+ message: "Runtime handler source must not contain export statements"
7572
+ },
7573
+ {
7574
+ pattern: /\brequire\s*\(/,
7575
+ message: "Runtime handler source must not call require()"
7576
+ },
7577
+ {
7578
+ pattern: /\bprocess\b/,
7579
+ message: "Runtime handler source must not access process"
7580
+ },
7581
+ {
7582
+ pattern: /\bFunction\s*\(/,
7583
+ message: "Runtime handler source must not create dynamic functions"
7584
+ },
7585
+ {
7586
+ pattern: /\beval\s*\(/,
7587
+ message: "Runtime handler source must not call eval()"
7588
+ }
7589
+ ];
7590
+ function transpileIfNeeded(source, language, filename) {
7591
+ if (language === "js") {
7592
+ return source;
7593
+ }
7594
+ const result = ts.transpileModule(source, {
7595
+ compilerOptions: {
7596
+ target: ts.ScriptTarget.ES2020,
7597
+ module: ts.ModuleKind.ESNext
7598
+ },
7599
+ fileName: filename,
7600
+ reportDiagnostics: true
7601
+ });
7602
+ const diagnostics = result.diagnostics ?? [];
7603
+ const blockingDiagnostics = diagnostics.filter(
7604
+ (diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error
7605
+ );
7606
+ if (blockingDiagnostics.length > 0) {
7607
+ const message = blockingDiagnostics.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")).join("; ");
7608
+ throw new Error(`TypeScript transpile failed: ${message}`);
7609
+ }
7610
+ return result.outputText;
7611
+ }
7612
+ function createSandbox() {
7613
+ const sandbox = /* @__PURE__ */ Object.create(null);
7614
+ sandbox.global = void 0;
7615
+ sandbox.globalThis = sandbox;
7616
+ sandbox.process = void 0;
7617
+ sandbox.require = void 0;
7618
+ sandbox.module = void 0;
7619
+ sandbox.exports = void 0;
7620
+ sandbox.Buffer = void 0;
7621
+ sandbox.fetch = void 0;
7622
+ sandbox.WebSocket = void 0;
7623
+ sandbox.XMLHttpRequest = void 0;
7624
+ sandbox.setTimeout = void 0;
7625
+ sandbox.setInterval = void 0;
7626
+ sandbox.clearTimeout = void 0;
7627
+ sandbox.clearInterval = void 0;
7628
+ sandbox.queueMicrotask = void 0;
7629
+ return vm.createContext(sandbox);
7630
+ }
7631
+ function compileFunctionFromSource(source, language, filename, label) {
7632
+ const normalizedSource = String(source ?? "").trim();
7633
+ if (!normalizedSource) {
7634
+ throw new Error(`${label} source must be a non-empty string`);
7635
+ }
7636
+ for (const rule of FORBIDDEN_SOURCE_PATTERNS) {
7637
+ if (rule.pattern.test(normalizedSource)) {
7638
+ throw new Error(rule.message);
7639
+ }
7640
+ }
7641
+ const wrappedSource = `const __runtime_handler = ${normalizedSource};
7642
+ __runtime_handler;`;
7643
+ const transpiledSource = transpileIfNeeded(
7644
+ wrappedSource,
7645
+ language,
7646
+ filename
7647
+ ).trim();
7648
+ const sandbox = createSandbox();
7649
+ const script = new vm.Script(transpiledSource, {
7650
+ filename
7651
+ });
7652
+ const compiled = script.runInContext(sandbox, {
7653
+ timeout: 1e3,
7654
+ displayErrors: true,
7655
+ contextCodeGeneration: {
7656
+ strings: false,
7657
+ wasm: false
7658
+ }
7659
+ });
7660
+ if (typeof compiled !== "function") {
7661
+ throw new Error(`${label} source must evaluate to a function`);
7662
+ }
7663
+ return compiled;
7664
+ }
7665
+ function compileRuntimeTaskFunction(definition) {
7666
+ return compileFunctionFromSource(
7667
+ definition.handlerSource,
7668
+ definition.language,
7669
+ `${definition.name}.runtime-task.${definition.language}`,
7670
+ `Task "${definition.name}"`
7671
+ );
7672
+ }
7673
+ function compileRuntimeHelperFunction(definition) {
7674
+ return compileFunctionFromSource(
7675
+ definition.handlerSource,
7676
+ definition.language,
7677
+ `${definition.name}.runtime-helper.${definition.language}`,
7678
+ `Helper "${definition.name}"`
7679
+ );
7680
+ }
7681
+ function compileRuntimeActorTaskHandler(definition) {
7682
+ return compileFunctionFromSource(
7683
+ definition.handlerSource,
7684
+ definition.language,
7685
+ `${definition.actorName}.${definition.taskName}.runtime-actor-task.${definition.language}`,
7686
+ `Actor task "${definition.taskName}"`
7687
+ );
7688
+ }
7689
+
7690
+ // src/runtime/sanitize.ts
7691
+ function isPlainObject2(value) {
7692
+ return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
7693
+ }
7694
+ function sanitizeForJson(value, seen = /* @__PURE__ */ new WeakSet()) {
7695
+ if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
7696
+ return value ?? null;
7697
+ }
7698
+ if (typeof value === "bigint") {
7699
+ return value.toString();
7700
+ }
7701
+ if (typeof value === "function") {
7702
+ return `[Function ${value.name || "anonymous"}]`;
7703
+ }
7704
+ if (typeof value === "symbol") {
7705
+ return value.toString();
7706
+ }
7707
+ if (value instanceof Date) {
7708
+ return value.toISOString();
7709
+ }
7710
+ if (value instanceof Set) {
7711
+ return Array.from(value).map((entry) => sanitizeForJson(entry, seen));
7712
+ }
7713
+ if (value instanceof Map) {
7714
+ return Array.from(value.entries()).map(([key, entry]) => [
7715
+ sanitizeForJson(key, seen),
7716
+ sanitizeForJson(entry, seen)
7717
+ ]);
7718
+ }
7719
+ if (Array.isArray(value)) {
7720
+ return value.map((entry) => sanitizeForJson(entry, seen));
7721
+ }
7722
+ if (typeof value === "object") {
7723
+ if (seen.has(value)) {
7724
+ return "[Circular]";
7725
+ }
7726
+ seen.add(value);
7727
+ if (!isPlainObject2(value)) {
7728
+ const clone = {};
7729
+ for (const key of Object.keys(value)) {
7730
+ clone[key] = sanitizeForJson(
7731
+ value[key],
7732
+ seen
7733
+ );
7734
+ }
7735
+ clone.__type = value.constructor?.name ?? "Object";
7736
+ return clone;
7737
+ }
7738
+ const result = {};
7739
+ for (const [key, entry] of Object.entries(value)) {
7740
+ result[key] = sanitizeForJson(entry, seen);
7741
+ }
7742
+ return result;
7743
+ }
7744
+ return String(value);
7745
+ }
7746
+
7031
7747
  // src/Cadenza.ts
7032
7748
  var Cadenza = class {
7033
7749
  /**
@@ -7110,22 +7826,105 @@ var Cadenza = class {
7110
7826
  throw new Error("Task or Routine name must be a non-empty string.");
7111
7827
  }
7112
7828
  }
7113
- static resolveTaskOptionsForActorTask(func, options = {}) {
7114
- const metadata = getActorTaskRuntimeMetadata(func);
7115
- if (!metadata?.forceMeta) {
7116
- return options;
7117
- }
7118
- if (options.isMeta) {
7119
- return options;
7829
+ static assertGraphMutationAllowed(operationName) {
7830
+ if (this.helperExecutionDepth > 0) {
7831
+ throw new Error(
7832
+ `${operationName} is not allowed during helper execution`
7833
+ );
7120
7834
  }
7121
- return {
7122
- ...options,
7123
- isMeta: true
7835
+ }
7836
+ static executeHelper(helper, context, emit, inquire, progressCallback) {
7837
+ const helperContext = context && typeof context === "object" ? context : {};
7838
+ const tools = this.resolveToolsForOwner(
7839
+ helper,
7840
+ helperContext,
7841
+ emit,
7842
+ inquire,
7843
+ progressCallback
7844
+ );
7845
+ this.helperExecutionDepth += 1;
7846
+ try {
7847
+ return helper.helperFunction(
7848
+ helperContext,
7849
+ emit,
7850
+ inquire,
7851
+ tools,
7852
+ progressCallback
7853
+ );
7854
+ } finally {
7855
+ this.helperExecutionDepth = Math.max(0, this.helperExecutionDepth - 1);
7856
+ }
7857
+ }
7858
+ static resolveToolsForOwner(owner, context, emit, inquire, progressCallback) {
7859
+ const helpers = {};
7860
+ const globals = {};
7861
+ for (const [alias, helperName] of owner.helperAliases.entries()) {
7862
+ const helper = this.getHelper(helperName);
7863
+ if (!helper) {
7864
+ continue;
7865
+ }
7866
+ if (helper.isMeta !== owner.isMeta) {
7867
+ throw new Error(
7868
+ `Tool alias "${alias}" resolves across layer boundaries`
7869
+ );
7870
+ }
7871
+ helpers[alias] = (helperContext = context) => this.executeHelper(
7872
+ helper,
7873
+ helperContext,
7874
+ emit,
7875
+ inquire,
7876
+ progressCallback
7877
+ );
7878
+ }
7879
+ for (const [alias, globalName] of owner.globalAliases.entries()) {
7880
+ const globalDefinition = this.getGlobal(globalName);
7881
+ if (!globalDefinition) {
7882
+ continue;
7883
+ }
7884
+ if (globalDefinition.isMeta !== owner.isMeta) {
7885
+ throw new Error(
7886
+ `Global alias "${alias}" resolves across layer boundaries`
7887
+ );
7888
+ }
7889
+ globals[alias] = globalDefinition.value;
7890
+ }
7891
+ return {
7892
+ helpers,
7893
+ globals
7894
+ };
7895
+ }
7896
+ static resolveTaskOptionsForActorTask(func, options = {}) {
7897
+ const metadata = getActorTaskRuntimeMetadata(func);
7898
+ if (!metadata?.forceMeta) {
7899
+ return options;
7900
+ }
7901
+ if (options.isMeta) {
7902
+ return options;
7903
+ }
7904
+ return {
7905
+ ...options,
7906
+ isMeta: true
7124
7907
  };
7125
7908
  }
7126
7909
  static registerActor(actor) {
7127
7910
  this.actorCache.set(actor.spec.name, actor);
7128
7911
  }
7912
+ static getHelper(name) {
7913
+ return this.helperCache.get(name);
7914
+ }
7915
+ static getAllHelpers() {
7916
+ return Array.from(this.helperCache.values()).filter(
7917
+ (helper) => !helper.destroyed
7918
+ );
7919
+ }
7920
+ static getGlobal(name) {
7921
+ return this.globalCache.get(name);
7922
+ }
7923
+ static getAllGlobals() {
7924
+ return Array.from(this.globalCache.values()).filter(
7925
+ (globalDefinition) => !globalDefinition.destroyed
7926
+ );
7927
+ }
7129
7928
  /**
7130
7929
  * Executes the specified task or GraphRoutine with the given context using an internal runner.
7131
7930
  *
@@ -7188,6 +7987,9 @@ var Cadenza = class {
7188
7987
  static get(taskName) {
7189
7988
  return this.registry?.tasks.get(taskName) ?? this.taskCache.get(taskName);
7190
7989
  }
7990
+ static forgetTask(taskName) {
7991
+ this.taskCache.delete(taskName);
7992
+ }
7191
7993
  static getActor(actorName) {
7192
7994
  return this.actorCache.get(actorName);
7193
7995
  }
@@ -7195,9 +7997,10 @@ var Cadenza = class {
7195
7997
  return Array.from(this.actorCache.values());
7196
7998
  }
7197
7999
  static getRoutine(routineName) {
7198
- return this.registry?.routines.get(routineName);
8000
+ return this.registry?.routines.get(routineName) ?? this.routineCache.get(routineName);
7199
8001
  }
7200
8002
  static defineIntent(intent) {
8003
+ this.assertGraphMutationAllowed("Cadenza.defineIntent");
7201
8004
  this.inquiryBroker?.addIntent(intent);
7202
8005
  return intent;
7203
8006
  }
@@ -7351,6 +8154,7 @@ var Cadenza = class {
7351
8154
  * participate in the graph like any other task.
7352
8155
  */
7353
8156
  static createActor(spec, options = {}) {
8157
+ this.assertGraphMutationAllowed("Cadenza.createActor");
7354
8158
  this.bootstrap();
7355
8159
  const actor = new Actor(spec, options);
7356
8160
  this.registerActor(actor);
@@ -7466,6 +8270,7 @@ var Cadenza = class {
7466
8270
  * ```
7467
8271
  */
7468
8272
  static createTask(name, func, description, options = {}) {
8273
+ this.assertGraphMutationAllowed("Cadenza.createTask");
7469
8274
  this.bootstrap();
7470
8275
  this.validateName(name);
7471
8276
  const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
@@ -7515,6 +8320,164 @@ var Cadenza = class {
7515
8320
  this.taskCache.set(name, createdTask);
7516
8321
  return createdTask;
7517
8322
  }
8323
+ static createTaskFromDefinition(definition) {
8324
+ this.bootstrap();
8325
+ this.validateName(definition.name);
8326
+ const existing = this.get(definition.name);
8327
+ if (existing) {
8328
+ if (!runtimeDefinitionRegistry.isRuntimeOwnedTask(definition.name)) {
8329
+ throw new Error(
8330
+ `Task "${definition.name}" already exists and is not runtime-owned`
8331
+ );
8332
+ }
8333
+ existing.destroy();
8334
+ }
8335
+ const taskFunction = compileRuntimeTaskFunction(definition);
8336
+ const createdTask = definition.kind === "metaTask" ? this.createMetaTask(
8337
+ definition.name,
8338
+ taskFunction,
8339
+ definition.description ?? "",
8340
+ definition.options ?? {}
8341
+ ) : this.createTask(
8342
+ definition.name,
8343
+ taskFunction,
8344
+ definition.description ?? "",
8345
+ definition.options ?? {}
8346
+ );
8347
+ runtimeDefinitionRegistry.setTaskDefinition(definition);
8348
+ return createdTask;
8349
+ }
8350
+ static createHelper(name, func, description = "") {
8351
+ this.bootstrap();
8352
+ this.validateName(name);
8353
+ this.assertGraphMutationAllowed("Cadenza.createHelper");
8354
+ if (this.helperCache.has(name)) {
8355
+ throw new Error(`Helper "${name}" already exists`);
8356
+ }
8357
+ const helper = new HelperDefinition(name, func, description, false);
8358
+ this.helperCache.set(name, helper);
8359
+ this.emit("meta.helper.created", {
8360
+ data: {
8361
+ name,
8362
+ version: helper.version,
8363
+ description,
8364
+ functionString: func.toString(),
8365
+ isMeta: false
8366
+ }
8367
+ });
8368
+ return helper;
8369
+ }
8370
+ static createMetaHelper(name, func, description = "") {
8371
+ this.bootstrap();
8372
+ this.validateName(name);
8373
+ this.assertGraphMutationAllowed("Cadenza.createMetaHelper");
8374
+ if (this.helperCache.has(name)) {
8375
+ throw new Error(`Helper "${name}" already exists`);
8376
+ }
8377
+ const helper = new HelperDefinition(name, func, description, true);
8378
+ this.helperCache.set(name, helper);
8379
+ this.emit("meta.helper.created", {
8380
+ data: {
8381
+ name,
8382
+ version: helper.version,
8383
+ description,
8384
+ functionString: func.toString(),
8385
+ isMeta: true
8386
+ }
8387
+ });
8388
+ return helper;
8389
+ }
8390
+ static createHelperFromDefinition(definition) {
8391
+ this.bootstrap();
8392
+ this.validateName(definition.name);
8393
+ const existing = this.getHelper(definition.name);
8394
+ if (existing) {
8395
+ if (!runtimeDefinitionRegistry.isRuntimeOwnedHelper(definition.name)) {
8396
+ throw new Error(
8397
+ `Helper "${definition.name}" already exists and is not runtime-owned`
8398
+ );
8399
+ }
8400
+ existing.destroy();
8401
+ this.helperCache.delete(definition.name);
8402
+ }
8403
+ const helperFunction = compileRuntimeHelperFunction(definition);
8404
+ const helper = definition.kind === "metaHelper" ? this.createMetaHelper(
8405
+ definition.name,
8406
+ helperFunction,
8407
+ definition.description ?? ""
8408
+ ) : this.createHelper(
8409
+ definition.name,
8410
+ helperFunction,
8411
+ definition.description ?? ""
8412
+ );
8413
+ runtimeDefinitionRegistry.setHelperDefinition(definition);
8414
+ return helper;
8415
+ }
8416
+ static createGlobal(name, value, description = "") {
8417
+ this.bootstrap();
8418
+ this.validateName(name);
8419
+ this.assertGraphMutationAllowed("Cadenza.createGlobal");
8420
+ if (this.globalCache.has(name)) {
8421
+ throw new Error(`Global "${name}" already exists`);
8422
+ }
8423
+ const globalDefinition = new GlobalDefinition(name, value, description, false);
8424
+ this.globalCache.set(name, globalDefinition);
8425
+ this.emit("meta.global.created", {
8426
+ data: {
8427
+ name,
8428
+ version: globalDefinition.version,
8429
+ description,
8430
+ isMeta: false,
8431
+ value: globalDefinition.value
8432
+ }
8433
+ });
8434
+ return globalDefinition;
8435
+ }
8436
+ static createMetaGlobal(name, value, description = "") {
8437
+ this.bootstrap();
8438
+ this.validateName(name);
8439
+ this.assertGraphMutationAllowed("Cadenza.createMetaGlobal");
8440
+ if (this.globalCache.has(name)) {
8441
+ throw new Error(`Global "${name}" already exists`);
8442
+ }
8443
+ const globalDefinition = new GlobalDefinition(name, value, description, true);
8444
+ this.globalCache.set(name, globalDefinition);
8445
+ this.emit("meta.global.created", {
8446
+ data: {
8447
+ name,
8448
+ version: globalDefinition.version,
8449
+ description,
8450
+ isMeta: true,
8451
+ value: globalDefinition.value
8452
+ }
8453
+ });
8454
+ return globalDefinition;
8455
+ }
8456
+ static createGlobalFromDefinition(definition) {
8457
+ this.bootstrap();
8458
+ this.validateName(definition.name);
8459
+ const existing = this.getGlobal(definition.name);
8460
+ if (existing) {
8461
+ if (!runtimeDefinitionRegistry.isRuntimeOwnedGlobal(definition.name)) {
8462
+ throw new Error(
8463
+ `Global "${definition.name}" already exists and is not runtime-owned`
8464
+ );
8465
+ }
8466
+ existing.destroy();
8467
+ this.globalCache.delete(definition.name);
8468
+ }
8469
+ const globalDefinition = definition.kind === "metaGlobal" ? this.createMetaGlobal(
8470
+ definition.name,
8471
+ definition.value,
8472
+ definition.description ?? ""
8473
+ ) : this.createGlobal(
8474
+ definition.name,
8475
+ definition.value,
8476
+ definition.description ?? ""
8477
+ );
8478
+ runtimeDefinitionRegistry.setGlobalDefinition(definition);
8479
+ return globalDefinition;
8480
+ }
7518
8481
  /**
7519
8482
  * Creates a meta task with the specified name, functionality, description, and options.
7520
8483
  * This is used for creating tasks that lives on the meta layer.
@@ -7580,6 +8543,7 @@ var Cadenza = class {
7580
8543
  *
7581
8544
  */
7582
8545
  static createUniqueTask(name, func, description, options = {}) {
8546
+ this.assertGraphMutationAllowed("Cadenza.createUniqueTask");
7583
8547
  options.isUnique = true;
7584
8548
  return this.createTask(name, func, description, options);
7585
8549
  }
@@ -7628,6 +8592,7 @@ var Cadenza = class {
7628
8592
  * ```
7629
8593
  */
7630
8594
  static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
8595
+ this.assertGraphMutationAllowed("Cadenza.createThrottledTask");
7631
8596
  options.concurrency = 1;
7632
8597
  options.getTagCallback = throttledIdGetter;
7633
8598
  return this.createTask(name, func, description, options);
@@ -7687,6 +8652,7 @@ var Cadenza = class {
7687
8652
  * ```
7688
8653
  */
7689
8654
  static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
8655
+ this.assertGraphMutationAllowed("Cadenza.createDebounceTask");
7690
8656
  this.bootstrap();
7691
8657
  this.validateName(name);
7692
8658
  const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
@@ -7815,6 +8781,7 @@ var Cadenza = class {
7815
8781
  * ```
7816
8782
  */
7817
8783
  static createEphemeralTask(name, func, description, options = {}) {
8784
+ this.assertGraphMutationAllowed("Cadenza.createEphemeralTask");
7818
8785
  this.bootstrap();
7819
8786
  this.validateName(name);
7820
8787
  const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
@@ -7911,12 +8878,46 @@ var Cadenza = class {
7911
8878
  * ```
7912
8879
  */
7913
8880
  static createRoutine(name, tasks, description = "") {
8881
+ this.assertGraphMutationAllowed("Cadenza.createRoutine");
7914
8882
  this.bootstrap();
7915
8883
  this.validateName(name);
7916
8884
  if (tasks.length === 0) {
7917
8885
  throw new Error(`Routine '${name}' created with no starting tasks.`);
7918
8886
  }
7919
- return new GraphRoutine(name, tasks, description);
8887
+ const createdRoutine = new GraphRoutine(name, tasks, description);
8888
+ this.routineCache.set(name, createdRoutine);
8889
+ return createdRoutine;
8890
+ }
8891
+ static createRoutineFromDefinition(definition) {
8892
+ const existing = this.getRoutine(definition.name);
8893
+ if (existing) {
8894
+ if (!runtimeDefinitionRegistry.isRuntimeOwnedRoutine(definition.name)) {
8895
+ throw new Error(
8896
+ `Routine "${definition.name}" already exists and is not runtime-owned`
8897
+ );
8898
+ }
8899
+ existing.destroy();
8900
+ }
8901
+ const startTasks = definition.startTaskNames.map((taskName) => {
8902
+ const task = this.get(taskName);
8903
+ if (!task) {
8904
+ throw new Error(
8905
+ `Routine "${definition.name}" references missing task "${taskName}"`
8906
+ );
8907
+ }
8908
+ return task;
8909
+ });
8910
+ const routine = definition.isMeta === true ? this.createMetaRoutine(
8911
+ definition.name,
8912
+ startTasks,
8913
+ definition.description ?? ""
8914
+ ) : this.createRoutine(
8915
+ definition.name,
8916
+ startTasks,
8917
+ definition.description ?? ""
8918
+ );
8919
+ runtimeDefinitionRegistry.setRoutineDefinition(definition);
8920
+ return routine;
7920
8921
  }
7921
8922
  /**
7922
8923
  * Creates a meta routine with a given name, tasks, and optional description.
@@ -7931,47 +8932,1434 @@ var Cadenza = class {
7931
8932
  * @throws {Error} If no starting tasks are provided.
7932
8933
  */
7933
8934
  static createMetaRoutine(name, tasks, description = "") {
8935
+ this.assertGraphMutationAllowed("Cadenza.createMetaRoutine");
7934
8936
  this.bootstrap();
7935
8937
  this.validateName(name);
7936
8938
  if (tasks.length === 0) {
7937
8939
  throw new Error(`Routine '${name}' created with no starting tasks.`);
7938
8940
  }
7939
- return new GraphRoutine(name, tasks, description, true);
8941
+ const createdRoutine = new GraphRoutine(name, tasks, description, true);
8942
+ this.routineCache.set(name, createdRoutine);
8943
+ return createdRoutine;
8944
+ }
8945
+ static snapshotRuntime() {
8946
+ const taskMap = /* @__PURE__ */ new Map();
8947
+ for (const task of this.taskCache.values()) {
8948
+ taskMap.set(task.name, task);
8949
+ }
8950
+ for (const task of this.registry?.tasks.values() ?? []) {
8951
+ taskMap.set(task.name, task);
8952
+ }
8953
+ const tasks = Array.from(taskMap.values()).map((task) => {
8954
+ const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
8955
+ task.name
8956
+ );
8957
+ const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
8958
+ return {
8959
+ name: task.name,
8960
+ version: task.version,
8961
+ description: task.description,
8962
+ kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
8963
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name) === true,
8964
+ language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
8965
+ handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
8966
+ concurrency: task.concurrency,
8967
+ timeout: task.timeout,
8968
+ retryCount: task.retryCount,
8969
+ retryDelay: task.retryDelay,
8970
+ retryDelayMax: task.retryDelayMax,
8971
+ retryDelayFactor: task.retryDelayFactor,
8972
+ validateInputContext: task.validateInputContext,
8973
+ validateOutputContext: task.validateOutputContext,
8974
+ inputContextSchema: sanitizeForJson(task.inputContextSchema),
8975
+ outputContextSchema: sanitizeForJson(task.outputContextSchema),
8976
+ nextTaskNames: Array.from(task.nextTasks).map((nextTask) => nextTask.name),
8977
+ predecessorTaskNames: Array.from(task.predecessorTasks).map(
8978
+ (predecessorTask) => predecessorTask.name
8979
+ ),
8980
+ signals: {
8981
+ emits: Array.from(task.emitsSignals),
8982
+ emitsAfter: Array.from(task.signalsToEmitAfter),
8983
+ emitsOnFail: Array.from(task.signalsToEmitOnFail),
8984
+ observed: Array.from(task.observedSignals)
8985
+ },
8986
+ intents: {
8987
+ handles: Array.from(task.handlesIntents),
8988
+ inquires: Array.from(task.inquiresIntents)
8989
+ },
8990
+ tools: {
8991
+ helpers: Object.fromEntries(task.helperAliases),
8992
+ globals: Object.fromEntries(task.globalAliases)
8993
+ },
8994
+ actorName: runtimeActorTaskDefinition?.actorName ?? null,
8995
+ actorMode: runtimeActorTaskDefinition?.mode ?? null
8996
+ };
8997
+ });
8998
+ const helpers = this.getAllHelpers().map((helper) => {
8999
+ const runtimeHelperDefinition = runtimeDefinitionRegistry.helperDefinitions.get(helper.name);
9000
+ return {
9001
+ name: helper.name,
9002
+ version: helper.version,
9003
+ description: helper.description,
9004
+ kind: helper.isMeta ? "metaHelper" : "helper",
9005
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedHelper(helper.name),
9006
+ language: runtimeHelperDefinition?.language ?? null,
9007
+ handlerSource: runtimeHelperDefinition?.handlerSource ?? null,
9008
+ tools: {
9009
+ helpers: Object.fromEntries(helper.helperAliases),
9010
+ globals: Object.fromEntries(helper.globalAliases)
9011
+ }
9012
+ };
9013
+ });
9014
+ const globals = this.getAllGlobals().map((globalDefinition) => ({
9015
+ name: globalDefinition.name,
9016
+ version: globalDefinition.version,
9017
+ description: globalDefinition.description,
9018
+ kind: globalDefinition.isMeta ? "metaGlobal" : "global",
9019
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedGlobal(
9020
+ globalDefinition.name
9021
+ ),
9022
+ value: sanitizeForJson(globalDefinition.value)
9023
+ }));
9024
+ const routineMap = /* @__PURE__ */ new Map();
9025
+ for (const routine of this.routineCache.values()) {
9026
+ routineMap.set(routine.name, routine);
9027
+ }
9028
+ for (const routine of this.registry?.routines.values() ?? []) {
9029
+ routineMap.set(routine.name, routine);
9030
+ }
9031
+ const routines = Array.from(routineMap.values()).map(
9032
+ (routine) => ({
9033
+ name: routine.name,
9034
+ version: routine.version,
9035
+ description: routine.description,
9036
+ isMeta: routine.isMeta,
9037
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(routine.name) === true,
9038
+ startTaskNames: Array.from(routine.tasks).map((task) => task.name),
9039
+ observedSignals: Array.from(routine.observedSignals)
9040
+ })
9041
+ );
9042
+ const intents = Array.from(this.inquiryBroker?.intents.values() ?? []).map(
9043
+ (intent) => {
9044
+ const sanitizedIntent = sanitizeForJson(intent);
9045
+ return {
9046
+ ...sanitizedIntent,
9047
+ runtimeOwned: runtimeDefinitionRegistry.intentDefinitions.has(
9048
+ intent.name
9049
+ )
9050
+ };
9051
+ }
9052
+ );
9053
+ const signals = Array.from(
9054
+ this.signalBroker?.emittedSignalsRegistry.values() ?? []
9055
+ ).map((signalName) => ({
9056
+ name: signalName,
9057
+ metadata: sanitizeForJson(
9058
+ this.signalBroker?.signalMetadataRegistry.get(signalName) ?? null
9059
+ ) ?? null
9060
+ }));
9061
+ const actors = this.getAllActors().map((actor) => {
9062
+ const definition = actor.toDefinition();
9063
+ const actorKeys = actor.listActorKeys().map((actorKey) => ({
9064
+ actorKey,
9065
+ durableState: sanitizeForJson(actor.getDurableState(actorKey)),
9066
+ runtimeState: sanitizeForJson(actor.getRuntimeState(actorKey)),
9067
+ durableVersion: actor.getDurableVersion(actorKey),
9068
+ runtimeVersion: actor.getRuntimeVersion(actorKey)
9069
+ }));
9070
+ return {
9071
+ name: actor.spec.name,
9072
+ description: actor.spec.description ?? "",
9073
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedActor(
9074
+ actor.spec.name
9075
+ ),
9076
+ definition: sanitizeForJson(definition),
9077
+ actorKeys
9078
+ };
9079
+ });
9080
+ const actorTasks = Array.from(
9081
+ runtimeDefinitionRegistry.actorTaskDefinitions.values()
9082
+ ).map((definition) => ({
9083
+ actorName: definition.actorName,
9084
+ taskName: definition.taskName,
9085
+ description: definition.description ?? "",
9086
+ mode: definition.mode ?? "read",
9087
+ language: definition.language,
9088
+ handlerSource: definition.handlerSource,
9089
+ runtimeOwned: true
9090
+ }));
9091
+ const links = Array.from(runtimeDefinitionRegistry.taskLinks.values()).map(
9092
+ (link) => ({ ...link })
9093
+ );
9094
+ return {
9095
+ runtimeMode: "core",
9096
+ bootstrapped: this.isBootstrapped,
9097
+ mode: this.mode,
9098
+ tasks,
9099
+ helpers,
9100
+ globals,
9101
+ routines,
9102
+ intents,
9103
+ signals,
9104
+ actors,
9105
+ actorTasks,
9106
+ links
9107
+ };
7940
9108
  }
7941
9109
  static reset() {
7942
9110
  this.signalBroker?.reset();
7943
9111
  this.inquiryBroker?.reset();
7944
9112
  this.registry?.reset();
7945
9113
  this.taskCache.clear();
9114
+ this.routineCache.clear();
7946
9115
  this.actorCache.clear();
9116
+ this.helperCache.clear();
9117
+ this.globalCache.clear();
7947
9118
  this.runtimeInquiryDelegate = void 0;
7948
9119
  this.runtimeValidationPolicy = {};
7949
9120
  this.runtimeValidationScopes.clear();
7950
9121
  this.emittedMissingSchemaWarnings.clear();
9122
+ this.helperExecutionDepth = 0;
9123
+ runtimeDefinitionRegistry.reset();
7951
9124
  this.isBootstrapped = false;
7952
9125
  }
7953
9126
  };
7954
9127
  Cadenza.taskCache = /* @__PURE__ */ new Map();
9128
+ Cadenza.routineCache = /* @__PURE__ */ new Map();
7955
9129
  Cadenza.actorCache = /* @__PURE__ */ new Map();
9130
+ Cadenza.helperCache = /* @__PURE__ */ new Map();
9131
+ Cadenza.globalCache = /* @__PURE__ */ new Map();
7956
9132
  Cadenza.runtimeValidationPolicy = {};
7957
9133
  Cadenza.runtimeValidationScopes = /* @__PURE__ */ new Map();
7958
9134
  Cadenza.emittedMissingSchemaWarnings = /* @__PURE__ */ new Set();
9135
+ Cadenza.helperExecutionDepth = 0;
7959
9136
  Cadenza.isBootstrapped = false;
7960
9137
  Cadenza.mode = "production";
7961
9138
 
9139
+ // src/runtime/RuntimeSubscriptionManager.ts
9140
+ import { v4 as uuid8 } from "uuid";
9141
+ function isObject3(value) {
9142
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9143
+ }
9144
+ function asStringOrNull(value) {
9145
+ return typeof value === "string" && value.length > 0 ? value : null;
9146
+ }
9147
+ function asNumberOrNull(value) {
9148
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
9149
+ }
9150
+ function normalizeEventContext(context) {
9151
+ const sanitized = sanitizeForJson(context);
9152
+ return isObject3(sanitized) ? sanitized : { value: sanitized };
9153
+ }
9154
+ function matchesSignalPattern(fullSignal, signalName, patterns) {
9155
+ return patterns.some((pattern) => {
9156
+ if (pattern === "*") {
9157
+ return true;
9158
+ }
9159
+ if (pattern === fullSignal || pattern === signalName) {
9160
+ return true;
9161
+ }
9162
+ if (!pattern.endsWith(".*")) {
9163
+ return false;
9164
+ }
9165
+ const prefix = pattern.slice(0, -2);
9166
+ return signalName === prefix || signalName.startsWith(`${prefix}.`);
9167
+ });
9168
+ }
9169
+ var RuntimeSubscriptionManagerError = class extends Error {
9170
+ constructor(code, message) {
9171
+ super(message);
9172
+ this.code = code;
9173
+ this.name = "RuntimeSubscriptionManagerError";
9174
+ }
9175
+ };
9176
+ var RuntimeSubscriptionManager = class {
9177
+ constructor() {
9178
+ this.subscriptions = /* @__PURE__ */ new Map();
9179
+ this.removeBrokerListener = null;
9180
+ this.nextSequence = 0;
9181
+ this.attach();
9182
+ }
9183
+ dispose() {
9184
+ this.reset();
9185
+ this.removeBrokerListener?.();
9186
+ this.removeBrokerListener = null;
9187
+ }
9188
+ subscribe(signalPatterns, maxQueueSize) {
9189
+ this.attach();
9190
+ const descriptor = {
9191
+ subscriptionId: uuid8(),
9192
+ signalPatterns: [...signalPatterns],
9193
+ maxQueueSize,
9194
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
9195
+ pendingEvents: 0
9196
+ };
9197
+ this.subscriptions.set(descriptor.subscriptionId, {
9198
+ descriptor,
9199
+ events: [],
9200
+ nextWaiter: null
9201
+ });
9202
+ return { ...descriptor };
9203
+ }
9204
+ unsubscribe(subscriptionId) {
9205
+ const subscription = this.requireSubscription(subscriptionId);
9206
+ this.clearWaiter(
9207
+ subscription,
9208
+ new RuntimeSubscriptionManagerError(
9209
+ "not_found",
9210
+ `Subscription "${subscriptionId}" was closed`
9211
+ )
9212
+ );
9213
+ this.subscriptions.delete(subscriptionId);
9214
+ return { ...subscription.descriptor };
9215
+ }
9216
+ async nextEvent(subscriptionId, timeoutMs) {
9217
+ const subscription = this.requireSubscription(subscriptionId);
9218
+ if (subscription.events.length > 0) {
9219
+ const event = subscription.events.shift() ?? null;
9220
+ subscription.descriptor.pendingEvents = subscription.events.length;
9221
+ return {
9222
+ subscriptionId,
9223
+ event,
9224
+ timedOut: false,
9225
+ pendingEvents: subscription.events.length
9226
+ };
9227
+ }
9228
+ if (timeoutMs <= 0) {
9229
+ return {
9230
+ subscriptionId,
9231
+ event: null,
9232
+ timedOut: true,
9233
+ pendingEvents: 0
9234
+ };
9235
+ }
9236
+ if (subscription.nextWaiter) {
9237
+ throw new RuntimeSubscriptionManagerError(
9238
+ "conflict",
9239
+ `Subscription "${subscriptionId}" already has a pending nextEvent request`
9240
+ );
9241
+ }
9242
+ return new Promise((resolve, reject) => {
9243
+ const timer = setTimeout(() => {
9244
+ subscription.nextWaiter = null;
9245
+ resolve({
9246
+ subscriptionId,
9247
+ event: null,
9248
+ timedOut: true,
9249
+ pendingEvents: subscription.events.length
9250
+ });
9251
+ }, timeoutMs);
9252
+ subscription.nextWaiter = {
9253
+ resolve: (result) => {
9254
+ clearTimeout(timer);
9255
+ subscription.nextWaiter = null;
9256
+ resolve(result);
9257
+ },
9258
+ reject: (error) => {
9259
+ clearTimeout(timer);
9260
+ subscription.nextWaiter = null;
9261
+ reject(error);
9262
+ },
9263
+ timer
9264
+ };
9265
+ });
9266
+ }
9267
+ pollEvents(subscriptionId, limit) {
9268
+ const subscription = this.requireSubscription(subscriptionId);
9269
+ const events = subscription.events.splice(0, limit);
9270
+ subscription.descriptor.pendingEvents = subscription.events.length;
9271
+ return {
9272
+ subscriptionId,
9273
+ events,
9274
+ pendingEvents: subscription.events.length
9275
+ };
9276
+ }
9277
+ reset() {
9278
+ for (const subscription of this.subscriptions.values()) {
9279
+ this.clearWaiter(
9280
+ subscription,
9281
+ new RuntimeSubscriptionManagerError(
9282
+ "not_found",
9283
+ `Subscription "${subscription.descriptor.subscriptionId}" was reset`
9284
+ )
9285
+ );
9286
+ subscription.events.length = 0;
9287
+ subscription.descriptor.pendingEvents = 0;
9288
+ }
9289
+ this.subscriptions.clear();
9290
+ }
9291
+ attach() {
9292
+ if (this.removeBrokerListener) {
9293
+ return;
9294
+ }
9295
+ Cadenza.bootstrap();
9296
+ this.removeBrokerListener = Cadenza.signalBroker.addPassiveSignalListener(
9297
+ (signal, context, metadata) => this.captureSignal(signal, context, metadata)
9298
+ );
9299
+ }
9300
+ captureSignal(signal, context, metadata) {
9301
+ if (this.subscriptions.size === 0) {
9302
+ return;
9303
+ }
9304
+ const normalizedContext = normalizeEventContext(context);
9305
+ const emission = isObject3(normalizedContext.__signalEmission) ? normalizedContext.__signalEmission : {};
9306
+ const metadataObject = isObject3(normalizedContext.__metadata) ? normalizedContext.__metadata : {};
9307
+ const fullSignal = signal;
9308
+ const [baseSignalName, ...signalTagParts] = signal.split(":");
9309
+ const signalName = baseSignalName ?? signal;
9310
+ const signalTag = signalTagParts.length > 0 ? signalTagParts.join(":") : null;
9311
+ const eventTemplate = {
9312
+ type: "signal",
9313
+ signal: fullSignal,
9314
+ signalName,
9315
+ signalTag,
9316
+ emittedAt: asStringOrNull(emission.emittedAt),
9317
+ isMeta: emission.isMeta === true || signalName.startsWith("meta."),
9318
+ isSubMeta: normalizedContext.__isSubMeta === true || signalName.startsWith("sub_meta."),
9319
+ metadata: sanitizeForJson(metadata) ?? null,
9320
+ source: {
9321
+ taskName: asStringOrNull(emission.taskName),
9322
+ taskVersion: asNumberOrNull(emission.taskVersion),
9323
+ taskExecutionId: asStringOrNull(emission.taskExecutionId),
9324
+ routineName: asStringOrNull(normalizedContext.__routineName) ?? asStringOrNull(emission.routineName),
9325
+ routineVersion: asNumberOrNull(normalizedContext.__routineVersion) ?? asNumberOrNull(emission.routineVersion),
9326
+ routineExecutionId: asStringOrNull(normalizedContext.__routineExecId) ?? asStringOrNull(emission.routineExecutionId),
9327
+ executionTraceId: asStringOrNull(emission.executionTraceId) ?? asStringOrNull(normalizedContext.__executionTraceId) ?? asStringOrNull(metadataObject.__executionTraceId),
9328
+ consumed: emission.consumed === true,
9329
+ consumedBy: asStringOrNull(emission.consumedBy)
9330
+ },
9331
+ context: normalizedContext
9332
+ };
9333
+ for (const subscription of this.subscriptions.values()) {
9334
+ if (!matchesSignalPattern(
9335
+ fullSignal,
9336
+ signalName,
9337
+ subscription.descriptor.signalPatterns
9338
+ )) {
9339
+ continue;
9340
+ }
9341
+ const event = {
9342
+ id: uuid8(),
9343
+ subscriptionId: subscription.descriptor.subscriptionId,
9344
+ sequence: ++this.nextSequence,
9345
+ ...eventTemplate
9346
+ };
9347
+ if (subscription.nextWaiter) {
9348
+ subscription.nextWaiter.resolve({
9349
+ subscriptionId: subscription.descriptor.subscriptionId,
9350
+ event,
9351
+ timedOut: false,
9352
+ pendingEvents: subscription.events.length
9353
+ });
9354
+ continue;
9355
+ }
9356
+ subscription.events.push(event);
9357
+ if (subscription.events.length > subscription.descriptor.maxQueueSize) {
9358
+ subscription.events.shift();
9359
+ }
9360
+ subscription.descriptor.pendingEvents = subscription.events.length;
9361
+ }
9362
+ }
9363
+ clearWaiter(subscription, error) {
9364
+ if (!subscription.nextWaiter) {
9365
+ return;
9366
+ }
9367
+ if (subscription.nextWaiter.timer) {
9368
+ clearTimeout(subscription.nextWaiter.timer);
9369
+ }
9370
+ subscription.nextWaiter.reject(error);
9371
+ subscription.nextWaiter = null;
9372
+ }
9373
+ requireSubscription(subscriptionId) {
9374
+ const subscription = this.subscriptions.get(subscriptionId);
9375
+ if (!subscription) {
9376
+ throw new RuntimeSubscriptionManagerError(
9377
+ "not_found",
9378
+ `No subscription named "${subscriptionId}" exists`
9379
+ );
9380
+ }
9381
+ return subscription;
9382
+ }
9383
+ };
9384
+
9385
+ // src/runtime/RuntimeHost.ts
9386
+ var SUPPORTED_OPERATIONS = [
9387
+ "runtime.bootstrap",
9388
+ "runtime.info",
9389
+ "runtime.detach",
9390
+ "runtime.shutdown",
9391
+ "runtime.reset",
9392
+ "runtime.snapshot",
9393
+ "runtime.subscribe",
9394
+ "runtime.unsubscribe",
9395
+ "runtime.nextEvent",
9396
+ "runtime.pollEvents",
9397
+ "task.upsert",
9398
+ "helper.upsert",
9399
+ "global.upsert",
9400
+ "task.link",
9401
+ "task.observeSignal",
9402
+ "task.emitSignal",
9403
+ "task.respondToIntent",
9404
+ "task.useHelper",
9405
+ "task.useGlobal",
9406
+ "helper.useHelper",
9407
+ "helper.useGlobal",
9408
+ "routine.upsert",
9409
+ "routine.observeSignal",
9410
+ "intent.upsert",
9411
+ "actor.upsert",
9412
+ "actorTask.upsert",
9413
+ "run",
9414
+ "emit",
9415
+ "inquire"
9416
+ ];
9417
+ var RuntimeProtocolException = class extends Error {
9418
+ constructor(code, message, details) {
9419
+ super(message);
9420
+ this.code = code;
9421
+ this.details = details;
9422
+ this.name = "RuntimeProtocolException";
9423
+ }
9424
+ };
9425
+ function isObject4(value) {
9426
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9427
+ }
9428
+ function assertObject(value, message) {
9429
+ if (!isObject4(value)) {
9430
+ throw new RuntimeProtocolException("invalid_payload", message);
9431
+ }
9432
+ }
9433
+ function assertString(value, fieldName) {
9434
+ if (typeof value !== "string" || !value.trim()) {
9435
+ throw new RuntimeProtocolException(
9436
+ "invalid_payload",
9437
+ `${fieldName} must be a non-empty string`
9438
+ );
9439
+ }
9440
+ return value;
9441
+ }
9442
+ function assertStringArray(value, fieldName) {
9443
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
9444
+ throw new RuntimeProtocolException(
9445
+ "invalid_payload",
9446
+ `${fieldName} must be an array of strings`
9447
+ );
9448
+ }
9449
+ return value;
9450
+ }
9451
+ function normalizeSignalDefinition2(signal) {
9452
+ if (typeof signal === "string") {
9453
+ return signal;
9454
+ }
9455
+ if (isObject4(signal) && typeof signal.name === "string" && signal.name.trim().length > 0) {
9456
+ return {
9457
+ name: signal.name,
9458
+ deliveryMode: signal.deliveryMode === "single" || signal.deliveryMode === "broadcast" ? signal.deliveryMode : void 0,
9459
+ broadcastFilter: signal.broadcastFilter && isObject4(signal.broadcastFilter) ? signal.broadcastFilter : null
9460
+ };
9461
+ }
9462
+ throw new RuntimeProtocolException(
9463
+ "invalid_payload",
9464
+ "signal must be a signal string or structured signal definition"
9465
+ );
9466
+ }
9467
+ var RuntimeHost = class {
9468
+ constructor(options = {}) {
9469
+ this.pendingControlAction = null;
9470
+ this.subscriptionManager = new RuntimeSubscriptionManager();
9471
+ this.runtimeSharing = options.runtimeSharing ?? "isolated";
9472
+ this.runtimeName = options.runtimeName ?? null;
9473
+ this.sessionId = options.sessionId ?? null;
9474
+ this.sessionRole = options.sessionRole ?? null;
9475
+ this.activeSessionCountProvider = options.activeSessionCountProvider ?? (() => 1);
9476
+ this.daemonProcessId = options.daemonProcessId ?? null;
9477
+ this.onResetRuntime = options.onResetRuntime ?? null;
9478
+ }
9479
+ dispose() {
9480
+ this.subscriptionManager.dispose();
9481
+ }
9482
+ resetSubscriptions() {
9483
+ this.subscriptionManager.reset();
9484
+ }
9485
+ consumeControlAction() {
9486
+ const action = this.pendingControlAction;
9487
+ this.pendingControlAction = null;
9488
+ return action;
9489
+ }
9490
+ handshake() {
9491
+ return {
9492
+ ready: true,
9493
+ protocol: "cadenza-runtime-jsonl",
9494
+ protocolVersion: "1",
9495
+ runtimeMode: "core",
9496
+ runtimeSharing: this.runtimeSharing,
9497
+ runtimeName: this.runtimeName,
9498
+ sessionId: this.sessionId,
9499
+ sessionRole: this.sessionRole,
9500
+ supportedOperations: [...SUPPORTED_OPERATIONS]
9501
+ };
9502
+ }
9503
+ async handle(request) {
9504
+ try {
9505
+ if (!request || typeof request !== "object") {
9506
+ throw new RuntimeProtocolException(
9507
+ "invalid_request",
9508
+ "Request must be an object"
9509
+ );
9510
+ }
9511
+ if (typeof request.operation !== "string" || !SUPPORTED_OPERATIONS.includes(
9512
+ request.operation
9513
+ )) {
9514
+ throw new RuntimeProtocolException(
9515
+ "unsupported_operation",
9516
+ `Unsupported operation: ${String(request.operation ?? "")}`
9517
+ );
9518
+ }
9519
+ const operation = request.operation;
9520
+ this.assertOperationAllowed(operation);
9521
+ const result = await this.dispatch(operation, request.payload);
9522
+ return {
9523
+ id: request.id,
9524
+ operation,
9525
+ ok: true,
9526
+ result: sanitizeForJson(result)
9527
+ };
9528
+ } catch (error) {
9529
+ const normalizedError = this.normalizeError(error);
9530
+ return {
9531
+ id: request?.id,
9532
+ operation: typeof request?.operation === "string" ? request.operation : "runtime.snapshot",
9533
+ ok: false,
9534
+ error: normalizedError
9535
+ };
9536
+ }
9537
+ }
9538
+ normalizeError(error) {
9539
+ if (error instanceof RuntimeSubscriptionManagerError) {
9540
+ return {
9541
+ code: error.code,
9542
+ message: error.message
9543
+ };
9544
+ }
9545
+ if (error instanceof RuntimeProtocolException) {
9546
+ return {
9547
+ code: error.code,
9548
+ message: error.message,
9549
+ details: error.details ? sanitizeForJson(error.details) : void 0
9550
+ };
9551
+ }
9552
+ if (error instanceof Error) {
9553
+ return {
9554
+ code: "runtime_error",
9555
+ message: error.message
9556
+ };
9557
+ }
9558
+ return {
9559
+ code: "runtime_error",
9560
+ message: String(error)
9561
+ };
9562
+ }
9563
+ async dispatch(operation, payload) {
9564
+ switch (operation) {
9565
+ case "runtime.bootstrap":
9566
+ return this.bootstrapRuntime(payload);
9567
+ case "runtime.info":
9568
+ return this.runtimeInfo();
9569
+ case "runtime.detach":
9570
+ return this.detachRuntime();
9571
+ case "runtime.shutdown":
9572
+ return this.shutdownRuntime();
9573
+ case "runtime.reset":
9574
+ return this.resetRuntime();
9575
+ case "runtime.snapshot":
9576
+ return Cadenza.snapshotRuntime();
9577
+ case "runtime.subscribe":
9578
+ return this.subscribe(payload);
9579
+ case "runtime.unsubscribe":
9580
+ return this.unsubscribe(payload);
9581
+ case "runtime.nextEvent":
9582
+ return this.nextEvent(payload);
9583
+ case "runtime.pollEvents":
9584
+ return this.pollEvents(payload);
9585
+ case "task.upsert":
9586
+ return this.upsertTask(payload);
9587
+ case "helper.upsert":
9588
+ return this.upsertHelper(payload);
9589
+ case "global.upsert":
9590
+ return this.upsertGlobal(payload);
9591
+ case "task.link":
9592
+ return this.linkTasks(payload);
9593
+ case "task.observeSignal":
9594
+ return this.observeTaskSignal(payload);
9595
+ case "task.emitSignal":
9596
+ return this.emitTaskSignal(payload);
9597
+ case "task.respondToIntent":
9598
+ return this.bindTaskIntent(payload);
9599
+ case "task.useHelper":
9600
+ return this.bindTaskHelper(payload);
9601
+ case "task.useGlobal":
9602
+ return this.bindTaskGlobal(payload);
9603
+ case "helper.useHelper":
9604
+ return this.bindHelperHelper(payload);
9605
+ case "helper.useGlobal":
9606
+ return this.bindHelperGlobal(payload);
9607
+ case "routine.upsert":
9608
+ return this.upsertRoutine(payload);
9609
+ case "routine.observeSignal":
9610
+ return this.observeRoutineSignal(payload);
9611
+ case "intent.upsert":
9612
+ return this.upsertIntent(payload);
9613
+ case "actor.upsert":
9614
+ return this.upsertActor(payload);
9615
+ case "actorTask.upsert":
9616
+ return this.upsertActorTask(payload);
9617
+ case "run":
9618
+ return this.runTarget(payload);
9619
+ case "emit":
9620
+ return this.emitSignal(payload);
9621
+ case "inquire":
9622
+ return this.inquireIntent(payload);
9623
+ }
9624
+ }
9625
+ assertOperationAllowed(operation) {
9626
+ if (!this.sessionRole) {
9627
+ return;
9628
+ }
9629
+ if (this.sessionRole === "owner") {
9630
+ return;
9631
+ }
9632
+ if (this.sessionRole === "writer") {
9633
+ if (operation === "runtime.reset" || operation === "runtime.shutdown") {
9634
+ throw new RuntimeProtocolException(
9635
+ "forbidden",
9636
+ `Session role "${this.sessionRole}" cannot perform ${operation}`
9637
+ );
9638
+ }
9639
+ return;
9640
+ }
9641
+ const observerOperations = /* @__PURE__ */ new Set([
9642
+ "runtime.info",
9643
+ "runtime.detach",
9644
+ "runtime.snapshot",
9645
+ "runtime.subscribe",
9646
+ "runtime.unsubscribe",
9647
+ "runtime.nextEvent",
9648
+ "runtime.pollEvents",
9649
+ "inquire"
9650
+ ]);
9651
+ if (!observerOperations.has(operation)) {
9652
+ throw new RuntimeProtocolException(
9653
+ "forbidden",
9654
+ `Session role "${this.sessionRole}" cannot perform ${operation}`
9655
+ );
9656
+ }
9657
+ }
9658
+ bootstrapRuntime(payload) {
9659
+ const mode = isObject4(payload) && typeof payload.mode === "string" ? payload.mode : void 0;
9660
+ if (mode) {
9661
+ Cadenza.setMode(mode);
9662
+ } else {
9663
+ Cadenza.bootstrap();
9664
+ }
9665
+ return {
9666
+ bootstrapped: true,
9667
+ mode: Cadenza.mode
9668
+ };
9669
+ }
9670
+ runtimeInfo() {
9671
+ return {
9672
+ runtimeMode: "core",
9673
+ runtimeSharing: this.runtimeSharing,
9674
+ runtimeName: this.runtimeName,
9675
+ sessionId: this.sessionId,
9676
+ sessionRole: this.sessionRole,
9677
+ activeSessionCount: this.activeSessionCountProvider(),
9678
+ daemonProcessId: this.daemonProcessId,
9679
+ bootstrapped: Cadenza.isBootstrapped,
9680
+ mode: Cadenza.mode
9681
+ };
9682
+ }
9683
+ detachRuntime() {
9684
+ this.pendingControlAction = "detach";
9685
+ return {
9686
+ detached: true,
9687
+ runtimeName: this.runtimeName,
9688
+ sessionId: this.sessionId
9689
+ };
9690
+ }
9691
+ shutdownRuntime() {
9692
+ this.pendingControlAction = "shutdown";
9693
+ return {
9694
+ shutdown: true,
9695
+ runtimeName: this.runtimeName
9696
+ };
9697
+ }
9698
+ resetRuntime() {
9699
+ if (this.onResetRuntime) {
9700
+ this.onResetRuntime();
9701
+ } else {
9702
+ Cadenza.reset();
9703
+ this.subscriptionManager.reset();
9704
+ }
9705
+ return {
9706
+ reset: true,
9707
+ bootstrapped: false
9708
+ };
9709
+ }
9710
+ subscribe(payload) {
9711
+ assertObject(payload, "runtime.subscribe payload must be an object");
9712
+ const signalPatterns = this.parseSignalPatterns(payload.signalPatterns);
9713
+ const maxQueueSize = this.parsePositiveInteger(
9714
+ payload.maxQueueSize,
9715
+ "maxQueueSize",
9716
+ 100
9717
+ );
9718
+ return {
9719
+ subscription: this.subscriptionManager.subscribe(signalPatterns, maxQueueSize)
9720
+ };
9721
+ }
9722
+ unsubscribe(payload) {
9723
+ assertObject(payload, "runtime.unsubscribe payload must be an object");
9724
+ const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
9725
+ return {
9726
+ unsubscribed: true,
9727
+ subscription: this.subscriptionManager.unsubscribe(subscriptionId)
9728
+ };
9729
+ }
9730
+ async nextEvent(payload) {
9731
+ assertObject(payload, "runtime.nextEvent payload must be an object");
9732
+ const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
9733
+ const timeoutMs = this.parseNonNegativeInteger(
9734
+ payload.timeoutMs,
9735
+ "timeoutMs",
9736
+ 0
9737
+ );
9738
+ return this.subscriptionManager.nextEvent(subscriptionId, timeoutMs);
9739
+ }
9740
+ pollEvents(payload) {
9741
+ assertObject(payload, "runtime.pollEvents payload must be an object");
9742
+ const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
9743
+ const limit = this.parsePositiveInteger(payload.limit, "limit", 50);
9744
+ return this.subscriptionManager.pollEvents(subscriptionId, limit);
9745
+ }
9746
+ upsertTask(payload) {
9747
+ assertObject(payload, "task.upsert payload must be an object");
9748
+ const definition = payload;
9749
+ definition.name = assertString(definition.name, "name");
9750
+ definition.handlerSource = assertString(
9751
+ definition.handlerSource,
9752
+ "handlerSource"
9753
+ );
9754
+ definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
9755
+ throw new RuntimeProtocolException(
9756
+ "invalid_payload",
9757
+ "language must be 'js' or 'ts'"
9758
+ );
9759
+ })();
9760
+ definition.kind = definition.kind === "metaTask" ? "metaTask" : "task";
9761
+ runtimeDefinitionRegistry.setTaskDefinition(definition);
9762
+ const task = Cadenza.createTaskFromDefinition(definition);
9763
+ this.applyTaskDecorations(definition.name);
9764
+ this.applyAllTaskLinks();
9765
+ this.rematerializeRoutinesStartingWith(definition.name);
9766
+ return {
9767
+ task: this.snapshotTask(task)
9768
+ };
9769
+ }
9770
+ upsertHelper(payload) {
9771
+ assertObject(payload, "helper.upsert payload must be an object");
9772
+ const definition = payload;
9773
+ definition.name = assertString(definition.name, "name");
9774
+ definition.handlerSource = assertString(
9775
+ definition.handlerSource,
9776
+ "handlerSource"
9777
+ );
9778
+ definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
9779
+ throw new RuntimeProtocolException(
9780
+ "invalid_payload",
9781
+ "language must be 'js' or 'ts'"
9782
+ );
9783
+ })();
9784
+ definition.kind = definition.kind === "metaHelper" ? "metaHelper" : "helper";
9785
+ runtimeDefinitionRegistry.setHelperDefinition(definition);
9786
+ compileRuntimeHelperFunction(definition);
9787
+ Cadenza.createHelperFromDefinition(definition);
9788
+ this.applyHelperDecorations(definition.name);
9789
+ return {
9790
+ helper: this.snapshotHelper(definition.name)
9791
+ };
9792
+ }
9793
+ upsertGlobal(payload) {
9794
+ assertObject(payload, "global.upsert payload must be an object");
9795
+ const definition = {
9796
+ name: assertString(payload.name, "name"),
9797
+ description: typeof payload.description === "string" ? payload.description : "",
9798
+ kind: payload.kind === "metaGlobal" ? "metaGlobal" : "global",
9799
+ value: payload.value
9800
+ };
9801
+ runtimeDefinitionRegistry.setGlobalDefinition(definition);
9802
+ Cadenza.createGlobalFromDefinition(definition);
9803
+ return {
9804
+ global: this.snapshotGlobal(definition.name)
9805
+ };
9806
+ }
9807
+ linkTasks(payload) {
9808
+ assertObject(payload, "task.link payload must be an object");
9809
+ const definition = {
9810
+ predecessorTaskName: assertString(
9811
+ payload.predecessorTaskName,
9812
+ "predecessorTaskName"
9813
+ ),
9814
+ successorTaskName: assertString(
9815
+ payload.successorTaskName,
9816
+ "successorTaskName"
9817
+ )
9818
+ };
9819
+ runtimeDefinitionRegistry.setTaskLink(definition);
9820
+ this.applyAllTaskLinks();
9821
+ return {
9822
+ linked: true,
9823
+ ...definition
9824
+ };
9825
+ }
9826
+ observeTaskSignal(payload) {
9827
+ assertObject(payload, "task.observeSignal payload must be an object");
9828
+ const definition = {
9829
+ taskName: assertString(payload.taskName, "taskName"),
9830
+ signal: normalizeSignalDefinition2(payload.signal)
9831
+ };
9832
+ runtimeDefinitionRegistry.setTaskSignalObservation(definition);
9833
+ this.requireTask(definition.taskName).doOn(definition.signal);
9834
+ return {
9835
+ observed: true,
9836
+ taskName: definition.taskName,
9837
+ signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
9838
+ };
9839
+ }
9840
+ emitTaskSignal(payload) {
9841
+ assertObject(payload, "task.emitSignal payload must be an object");
9842
+ const mode = payload.mode === "attach" || payload.mode === "onFail" ? payload.mode : "after";
9843
+ const definition = {
9844
+ taskName: assertString(payload.taskName, "taskName"),
9845
+ signal: normalizeSignalDefinition2(payload.signal),
9846
+ mode
9847
+ };
9848
+ runtimeDefinitionRegistry.setTaskSignalEmission(definition);
9849
+ const task = this.requireTask(definition.taskName);
9850
+ if (definition.mode === "attach") {
9851
+ task.attachSignal(definition.signal);
9852
+ } else if (definition.mode === "onFail") {
9853
+ task.emitsOnFail(definition.signal);
9854
+ } else {
9855
+ task.emits(definition.signal);
9856
+ }
9857
+ return {
9858
+ attached: true,
9859
+ taskName: definition.taskName,
9860
+ mode: definition.mode,
9861
+ signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
9862
+ };
9863
+ }
9864
+ bindTaskIntent(payload) {
9865
+ assertObject(payload, "task.respondToIntent payload must be an object");
9866
+ const taskName = assertString(payload.taskName, "taskName");
9867
+ const intentName = assertString(payload.intentName, "intentName");
9868
+ runtimeDefinitionRegistry.setTaskIntentBinding({
9869
+ taskName,
9870
+ intentName
9871
+ });
9872
+ this.requireTask(taskName).respondsTo(intentName);
9873
+ return {
9874
+ bound: true,
9875
+ taskName,
9876
+ intentName
9877
+ };
9878
+ }
9879
+ bindTaskHelper(payload) {
9880
+ assertObject(payload, "task.useHelper payload must be an object");
9881
+ const definition = {
9882
+ taskName: assertString(payload.taskName, "taskName"),
9883
+ alias: assertString(payload.alias, "alias"),
9884
+ helperName: assertString(payload.helperName, "helperName")
9885
+ };
9886
+ runtimeDefinitionRegistry.setTaskHelperBinding(definition);
9887
+ this.requireTask(definition.taskName).usesHelpers({
9888
+ [definition.alias]: Cadenza.getHelper(definition.helperName)
9889
+ });
9890
+ return {
9891
+ bound: true,
9892
+ ...definition
9893
+ };
9894
+ }
9895
+ bindTaskGlobal(payload) {
9896
+ assertObject(payload, "task.useGlobal payload must be an object");
9897
+ const definition = {
9898
+ taskName: assertString(payload.taskName, "taskName"),
9899
+ alias: assertString(payload.alias, "alias"),
9900
+ globalName: assertString(payload.globalName, "globalName")
9901
+ };
9902
+ runtimeDefinitionRegistry.setTaskGlobalBinding(definition);
9903
+ this.requireTask(definition.taskName).usesGlobals({
9904
+ [definition.alias]: Cadenza.getGlobal(definition.globalName)
9905
+ });
9906
+ return {
9907
+ bound: true,
9908
+ ...definition
9909
+ };
9910
+ }
9911
+ bindHelperHelper(payload) {
9912
+ assertObject(payload, "helper.useHelper payload must be an object");
9913
+ const definition = {
9914
+ helperName: assertString(payload.helperName, "helperName"),
9915
+ alias: assertString(payload.alias, "alias"),
9916
+ dependencyHelperName: assertString(
9917
+ payload.dependencyHelperName,
9918
+ "dependencyHelperName"
9919
+ )
9920
+ };
9921
+ runtimeDefinitionRegistry.setHelperHelperBinding(definition);
9922
+ const helper = Cadenza.getHelper(definition.helperName);
9923
+ if (!helper) {
9924
+ throw new RuntimeProtocolException(
9925
+ "not_found",
9926
+ `No helper named "${definition.helperName}" exists`
9927
+ );
9928
+ }
9929
+ helper.usesHelpers({
9930
+ [definition.alias]: Cadenza.getHelper(definition.dependencyHelperName)
9931
+ });
9932
+ return {
9933
+ bound: true,
9934
+ ...definition
9935
+ };
9936
+ }
9937
+ bindHelperGlobal(payload) {
9938
+ assertObject(payload, "helper.useGlobal payload must be an object");
9939
+ const definition = {
9940
+ helperName: assertString(payload.helperName, "helperName"),
9941
+ alias: assertString(payload.alias, "alias"),
9942
+ globalName: assertString(payload.globalName, "globalName")
9943
+ };
9944
+ runtimeDefinitionRegistry.setHelperGlobalBinding(definition);
9945
+ const helper = Cadenza.getHelper(definition.helperName);
9946
+ if (!helper) {
9947
+ throw new RuntimeProtocolException(
9948
+ "not_found",
9949
+ `No helper named "${definition.helperName}" exists`
9950
+ );
9951
+ }
9952
+ helper.usesGlobals({
9953
+ [definition.alias]: Cadenza.getGlobal(definition.globalName)
9954
+ });
9955
+ return {
9956
+ bound: true,
9957
+ ...definition
9958
+ };
9959
+ }
9960
+ upsertRoutine(payload) {
9961
+ assertObject(payload, "routine.upsert payload must be an object");
9962
+ const definition = {
9963
+ name: assertString(payload.name, "name"),
9964
+ description: typeof payload.description === "string" ? payload.description : "",
9965
+ startTaskNames: assertStringArray(payload.startTaskNames, "startTaskNames"),
9966
+ isMeta: payload.isMeta === true
9967
+ };
9968
+ if (definition.startTaskNames.length === 0) {
9969
+ throw new RuntimeProtocolException(
9970
+ "invalid_payload",
9971
+ "startTaskNames must contain at least one task name"
9972
+ );
9973
+ }
9974
+ runtimeDefinitionRegistry.setRoutineDefinition(definition);
9975
+ const routine = Cadenza.createRoutineFromDefinition(definition);
9976
+ this.applyRoutineDecorations(definition.name);
9977
+ return {
9978
+ routine: this.snapshotRoutine(routine)
9979
+ };
9980
+ }
9981
+ observeRoutineSignal(payload) {
9982
+ assertObject(payload, "routine.observeSignal payload must be an object");
9983
+ const routineName = assertString(payload.routineName, "routineName");
9984
+ const signal = assertString(payload.signal, "signal");
9985
+ runtimeDefinitionRegistry.setRoutineSignalObservation({
9986
+ routineName,
9987
+ signal
9988
+ });
9989
+ this.requireRoutine(routineName).doOn(signal);
9990
+ return {
9991
+ observed: true,
9992
+ routineName,
9993
+ signal
9994
+ };
9995
+ }
9996
+ upsertIntent(payload) {
9997
+ assertObject(payload, "intent.upsert payload must be an object");
9998
+ const intent = {
9999
+ name: assertString(payload.name, "name"),
10000
+ description: typeof payload.description === "string" ? payload.description : "",
10001
+ input: isObject4(payload.input) ? payload.input : { type: "object" },
10002
+ output: isObject4(payload.output) ? payload.output : { type: "object" }
10003
+ };
10004
+ runtimeDefinitionRegistry.setIntentDefinition(intent);
10005
+ Cadenza.defineIntent(intent);
10006
+ return {
10007
+ intent: sanitizeForJson(intent)
10008
+ };
10009
+ }
10010
+ upsertActor(payload) {
10011
+ assertObject(payload, "actor.upsert payload must be an object");
10012
+ const definition = payload;
10013
+ definition.name = assertString(definition.name, "name");
10014
+ definition.description = assertString(definition.description, "description");
10015
+ definition.defaultKey = assertString(definition.defaultKey, "defaultKey");
10016
+ runtimeDefinitionRegistry.setActorDefinition(definition);
10017
+ const actor = Cadenza.createActorFromDefinition(definition);
10018
+ this.rematerializeActorTasksFor(definition.name);
10019
+ return {
10020
+ actor: sanitizeForJson({
10021
+ name: actor.spec.name,
10022
+ description: actor.spec.description ?? "",
10023
+ defaultKey: actor.spec.defaultKey
10024
+ })
10025
+ };
10026
+ }
10027
+ upsertActorTask(payload) {
10028
+ assertObject(payload, "actorTask.upsert payload must be an object");
10029
+ const definition = {
10030
+ actorName: assertString(payload.actorName, "actorName"),
10031
+ taskName: assertString(payload.taskName, "taskName"),
10032
+ description: typeof payload.description === "string" ? payload.description : "",
10033
+ mode: payload.mode === "write" || payload.mode === "meta" ? payload.mode : "read",
10034
+ handlerSource: assertString(payload.handlerSource, "handlerSource"),
10035
+ language: payload.language === "js" || payload.language === "ts" ? payload.language : (() => {
10036
+ throw new RuntimeProtocolException(
10037
+ "invalid_payload",
10038
+ "language must be 'js' or 'ts'"
10039
+ );
10040
+ })(),
10041
+ options: isObject4(payload.options) ? { ...payload.options } : void 0
10042
+ };
10043
+ runtimeDefinitionRegistry.setActorTaskDefinition(definition);
10044
+ const task = this.materializeActorTask(definition.taskName);
10045
+ this.applyTaskDecorations(definition.taskName);
10046
+ this.applyAllTaskLinks();
10047
+ this.rematerializeRoutinesStartingWith(definition.taskName);
10048
+ return {
10049
+ actorTask: this.snapshotTask(task)
10050
+ };
10051
+ }
10052
+ async runTarget(payload) {
10053
+ assertObject(payload, "run payload must be an object");
10054
+ const targetName = assertString(payload.targetName, "targetName");
10055
+ const context = isObject4(payload.context) ? payload.context : {};
10056
+ let target = Cadenza.getRoutine(targetName);
10057
+ if (!target) {
10058
+ const routineDefinition = runtimeDefinitionRegistry.routineDefinitions.get(targetName);
10059
+ if (routineDefinition) {
10060
+ target = Cadenza.createRoutineFromDefinition(routineDefinition);
10061
+ this.applyRoutineDecorations(targetName);
10062
+ }
10063
+ }
10064
+ target = target ?? Cadenza.get(targetName);
10065
+ if (!target) {
10066
+ throw new RuntimeProtocolException(
10067
+ "not_found",
10068
+ `No task or routine named "${targetName}" exists`
10069
+ );
10070
+ }
10071
+ const runner = "isMeta" in target && target.isMeta ? Cadenza.metaRunner : Cadenza.runner;
10072
+ const runResult = runner.run(target, context);
10073
+ const completedRun = await Promise.resolve(runResult);
10074
+ return {
10075
+ targetName,
10076
+ run: completedRun.export()
10077
+ };
10078
+ }
10079
+ emitSignal(payload) {
10080
+ assertObject(payload, "emit payload must be an object");
10081
+ const signal = assertString(payload.signal, "signal");
10082
+ const context = isObject4(payload.context) ? payload.context : {};
10083
+ const options = isObject4(payload.options) ? payload.options : {};
10084
+ Cadenza.emit(signal, context, options);
10085
+ return {
10086
+ emitted: true,
10087
+ signal
10088
+ };
10089
+ }
10090
+ async inquireIntent(payload) {
10091
+ assertObject(payload, "inquire payload must be an object");
10092
+ const inquiry = assertString(payload.intent, "intent");
10093
+ const context = isObject4(payload.context) ? payload.context : {};
10094
+ const options = isObject4(payload.options) ? payload.options : {};
10095
+ const response = await Cadenza.inquire(inquiry, context, options);
10096
+ return {
10097
+ inquiry,
10098
+ response
10099
+ };
10100
+ }
10101
+ requireTask(taskName) {
10102
+ const task = Cadenza.get(taskName);
10103
+ if (!task) {
10104
+ throw new RuntimeProtocolException(
10105
+ "not_found",
10106
+ `No task named "${taskName}" exists`
10107
+ );
10108
+ }
10109
+ return task;
10110
+ }
10111
+ requireRoutine(routineName) {
10112
+ const routine = Cadenza.getRoutine(routineName);
10113
+ if (!routine) {
10114
+ throw new RuntimeProtocolException(
10115
+ "not_found",
10116
+ `No routine named "${routineName}" exists`
10117
+ );
10118
+ }
10119
+ return routine;
10120
+ }
10121
+ applyTaskDecorations(taskName) {
10122
+ const task = this.requireTask(taskName);
10123
+ for (const observation of runtimeDefinitionRegistry.taskSignalObservations.values()) {
10124
+ if (observation.taskName !== taskName) {
10125
+ continue;
10126
+ }
10127
+ task.doOn(observation.signal);
10128
+ }
10129
+ for (const emission of runtimeDefinitionRegistry.taskSignalEmissions.values()) {
10130
+ if (emission.taskName !== taskName) {
10131
+ continue;
10132
+ }
10133
+ if (emission.mode === "attach") {
10134
+ task.attachSignal(emission.signal);
10135
+ } else if (emission.mode === "onFail") {
10136
+ task.emitsOnFail(emission.signal);
10137
+ } else {
10138
+ task.emits(emission.signal);
10139
+ }
10140
+ }
10141
+ for (const binding of runtimeDefinitionRegistry.taskIntentBindings.values()) {
10142
+ if (binding.taskName !== taskName) {
10143
+ continue;
10144
+ }
10145
+ task.respondsTo(binding.intentName);
10146
+ }
10147
+ for (const binding of runtimeDefinitionRegistry.taskHelperBindings.values()) {
10148
+ if (binding.taskName !== taskName) {
10149
+ continue;
10150
+ }
10151
+ task.usesHelpers({
10152
+ [binding.alias]: Cadenza.getHelper(binding.helperName)
10153
+ });
10154
+ }
10155
+ for (const binding of runtimeDefinitionRegistry.taskGlobalBindings.values()) {
10156
+ if (binding.taskName !== taskName) {
10157
+ continue;
10158
+ }
10159
+ task.usesGlobals({
10160
+ [binding.alias]: Cadenza.getGlobal(binding.globalName)
10161
+ });
10162
+ }
10163
+ }
10164
+ applyHelperDecorations(helperName) {
10165
+ const helper = Cadenza.getHelper(helperName);
10166
+ if (!helper) {
10167
+ throw new RuntimeProtocolException(
10168
+ "not_found",
10169
+ `No helper named "${helperName}" exists`
10170
+ );
10171
+ }
10172
+ for (const binding of runtimeDefinitionRegistry.helperHelperBindings.values()) {
10173
+ if (binding.helperName !== helperName) {
10174
+ continue;
10175
+ }
10176
+ helper.usesHelpers({
10177
+ [binding.alias]: Cadenza.getHelper(binding.dependencyHelperName)
10178
+ });
10179
+ }
10180
+ for (const binding of runtimeDefinitionRegistry.helperGlobalBindings.values()) {
10181
+ if (binding.helperName !== helperName) {
10182
+ continue;
10183
+ }
10184
+ helper.usesGlobals({
10185
+ [binding.alias]: Cadenza.getGlobal(binding.globalName)
10186
+ });
10187
+ }
10188
+ }
10189
+ applyAllTaskLinks() {
10190
+ for (const link of runtimeDefinitionRegistry.taskLinks.values()) {
10191
+ const predecessor = Cadenza.get(link.predecessorTaskName);
10192
+ const successor = Cadenza.get(link.successorTaskName);
10193
+ if (!predecessor || !successor) {
10194
+ continue;
10195
+ }
10196
+ predecessor.then(successor);
10197
+ }
10198
+ }
10199
+ applyRoutineDecorations(routineName) {
10200
+ const routine = this.requireRoutine(routineName);
10201
+ for (const observation of runtimeDefinitionRegistry.routineSignalObservations.values()) {
10202
+ if (observation.routineName !== routineName) {
10203
+ continue;
10204
+ }
10205
+ routine.doOn(observation.signal);
10206
+ }
10207
+ }
10208
+ rematerializeRoutinesStartingWith(taskName) {
10209
+ for (const definition of runtimeDefinitionRegistry.routineDefinitions.values()) {
10210
+ if (!definition.startTaskNames.includes(taskName)) {
10211
+ continue;
10212
+ }
10213
+ const recreated = Cadenza.createRoutineFromDefinition(definition);
10214
+ this.applyRoutineDecorations(recreated.name);
10215
+ }
10216
+ }
10217
+ rematerializeActorTasksFor(actorName) {
10218
+ for (const definition of runtimeDefinitionRegistry.actorTaskDefinitions.values()) {
10219
+ if (definition.actorName !== actorName) {
10220
+ continue;
10221
+ }
10222
+ this.materializeActorTask(definition.taskName);
10223
+ this.applyTaskDecorations(definition.taskName);
10224
+ this.applyAllTaskLinks();
10225
+ this.rematerializeRoutinesStartingWith(definition.taskName);
10226
+ }
10227
+ }
10228
+ materializeActorTask(taskName) {
10229
+ const definition = runtimeDefinitionRegistry.actorTaskDefinitions.get(taskName);
10230
+ if (!definition) {
10231
+ throw new RuntimeProtocolException(
10232
+ "not_found",
10233
+ `No actor task definition named "${taskName}" exists`
10234
+ );
10235
+ }
10236
+ const actor = Cadenza.getActor(definition.actorName);
10237
+ if (!actor) {
10238
+ throw new RuntimeProtocolException(
10239
+ "not_found",
10240
+ `No actor named "${definition.actorName}" exists`
10241
+ );
10242
+ }
10243
+ const existingTask = Cadenza.get(definition.taskName);
10244
+ if (existingTask && !runtimeDefinitionRegistry.isRuntimeOwnedTask(existingTask.name)) {
10245
+ throw new RuntimeProtocolException(
10246
+ "conflict",
10247
+ `Task "${definition.taskName}" already exists and is not runtime-owned`
10248
+ );
10249
+ }
10250
+ existingTask?.destroy();
10251
+ const handler = compileRuntimeActorTaskHandler(definition);
10252
+ return Cadenza.createTask(
10253
+ definition.taskName,
10254
+ actor.task(handler, { mode: definition.mode }),
10255
+ definition.description ?? "",
10256
+ definition.options ?? {}
10257
+ );
10258
+ }
10259
+ snapshotTask(task) {
10260
+ const snapshot = Cadenza.snapshotRuntime();
10261
+ const existing = snapshot.tasks.find((entry) => entry.name === task.name);
10262
+ if (existing) {
10263
+ return existing;
10264
+ }
10265
+ const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
10266
+ task.name
10267
+ );
10268
+ const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
10269
+ return {
10270
+ name: task.name,
10271
+ version: task.version,
10272
+ description: task.description,
10273
+ kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
10274
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name),
10275
+ language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
10276
+ handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
10277
+ tools: {
10278
+ helpers: Object.fromEntries(task.helperAliases),
10279
+ globals: Object.fromEntries(task.globalAliases)
10280
+ }
10281
+ };
10282
+ }
10283
+ snapshotHelper(helperName) {
10284
+ const snapshot = Cadenza.snapshotRuntime();
10285
+ return snapshot.helpers.find((entry) => entry.name === helperName) ?? {
10286
+ name: helperName
10287
+ };
10288
+ }
10289
+ snapshotGlobal(globalName) {
10290
+ const snapshot = Cadenza.snapshotRuntime();
10291
+ return snapshot.globals.find((entry) => entry.name === globalName) ?? {
10292
+ name: globalName
10293
+ };
10294
+ }
10295
+ snapshotRoutine(routine) {
10296
+ const snapshot = Cadenza.snapshotRuntime();
10297
+ return snapshot.routines.find((entry) => entry.name === routine.name) ?? {
10298
+ name: routine.name,
10299
+ version: routine.version,
10300
+ description: routine.description,
10301
+ isMeta: routine.isMeta,
10302
+ runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(
10303
+ routine.name
10304
+ ),
10305
+ startTaskNames: Array.from(routine.tasks).map((task) => task.name),
10306
+ observedSignals: Array.from(routine.observedSignals)
10307
+ };
10308
+ }
10309
+ parseSignalPatterns(value) {
10310
+ if (value === void 0) {
10311
+ return ["*"];
10312
+ }
10313
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
10314
+ throw new RuntimeProtocolException(
10315
+ "invalid_payload",
10316
+ "signalPatterns must be an array of non-empty strings"
10317
+ );
10318
+ }
10319
+ return Array.from(new Set(value.map((entry) => entry.trim())));
10320
+ }
10321
+ parsePositiveInteger(value, fieldName, fallback) {
10322
+ if (value === void 0) {
10323
+ return fallback;
10324
+ }
10325
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
10326
+ throw new RuntimeProtocolException(
10327
+ "invalid_payload",
10328
+ `${fieldName} must be a positive integer`
10329
+ );
10330
+ }
10331
+ return value;
10332
+ }
10333
+ parseNonNegativeInteger(value, fieldName, fallback) {
10334
+ if (value === void 0) {
10335
+ return fallback;
10336
+ }
10337
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
10338
+ throw new RuntimeProtocolException(
10339
+ "invalid_payload",
10340
+ `${fieldName} must be a non-negative integer`
10341
+ );
10342
+ }
10343
+ return value;
10344
+ }
10345
+ };
10346
+
7962
10347
  // src/index.ts
7963
10348
  var index_default = Cadenza;
7964
10349
  export {
7965
10350
  Actor,
7966
10351
  DebounceTask,
7967
10352
  EphemeralTask,
10353
+ GlobalDefinition,
7968
10354
  GraphContext,
7969
10355
  GraphRegistry,
7970
10356
  GraphRoutine,
7971
10357
  GraphRun,
7972
10358
  GraphRunner,
10359
+ HelperDefinition,
7973
10360
  InquiryBroker,
7974
10361
  META_ACTOR_SESSION_STATE_PERSIST_INTENT,
10362
+ RuntimeHost,
7975
10363
  SignalBroker,
7976
10364
  SignalEmitter,
7977
10365
  Task,