@cadenza.io/core 3.26.1 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -0
- package/dist/cli.js +10908 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.mts +1475 -1075
- package/dist/index.d.ts +1475 -1075
- package/dist/index.js +2427 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2414 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
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.
|
|
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(
|
|
1957
|
+
this.setSignalMetadata(signalKey, metadata);
|
|
1916
1958
|
}
|
|
1917
|
-
this.emittedSignalsRegistry.add(
|
|
1959
|
+
this.emittedSignalsRegistry.add(signalKey);
|
|
1918
1960
|
}
|
|
1919
1961
|
/**
|
|
1920
1962
|
* Unsubscribes a routine/task from a signal.
|
|
@@ -2974,16 +3016,17 @@ var GraphNode = class _GraphNode extends SignalEmitter {
|
|
|
2974
3016
|
* @return {void} Does not return a value.
|
|
2975
3017
|
*/
|
|
2976
3018
|
finalize() {
|
|
3019
|
+
const context = this.context?.getFullContext?.() ?? {};
|
|
2977
3020
|
if (this.nextNodes.length === 0) {
|
|
2978
3021
|
this.completeSubgraph();
|
|
2979
3022
|
}
|
|
2980
3023
|
if (this.errored || this.failed) {
|
|
2981
3024
|
this.task.mapOnFailSignals(
|
|
2982
|
-
(signal) => this.emitWithMetadata(signal,
|
|
3025
|
+
(signal) => this.emitWithMetadata(signal, { ...context })
|
|
2983
3026
|
);
|
|
2984
3027
|
} else if (this.result !== void 0 && this.result !== false) {
|
|
2985
3028
|
this.task.mapSignals(
|
|
2986
|
-
(signal) => this.emitWithMetadata(signal,
|
|
3029
|
+
(signal) => this.emitWithMetadata(signal, { ...context })
|
|
2987
3030
|
);
|
|
2988
3031
|
}
|
|
2989
3032
|
this.end();
|
|
@@ -2997,8 +3040,9 @@ var GraphNode = class _GraphNode extends SignalEmitter {
|
|
|
2997
3040
|
*/
|
|
2998
3041
|
onError(error, errorData = {}) {
|
|
2999
3042
|
const normalizedError = normalizeGraphErrorMessage(error);
|
|
3043
|
+
const context = this.context?.getFullContext?.() ?? {};
|
|
3000
3044
|
this.result = {
|
|
3001
|
-
...
|
|
3045
|
+
...context,
|
|
3002
3046
|
__error: `Node error: ${normalizedError}`,
|
|
3003
3047
|
__retries: this.retries,
|
|
3004
3048
|
error: `Node error: ${normalizedError}`,
|
|
@@ -3853,6 +3897,7 @@ var Actor = class {
|
|
|
3853
3897
|
this.stateByKey = /* @__PURE__ */ new Map();
|
|
3854
3898
|
this.sessionByKey = /* @__PURE__ */ new Map();
|
|
3855
3899
|
this.idempotencyByKey = /* @__PURE__ */ new Map();
|
|
3900
|
+
this.pendingHydrationByKey = /* @__PURE__ */ new Map();
|
|
3856
3901
|
this.writeQueueByKey = /* @__PURE__ */ new Map();
|
|
3857
3902
|
this.nextTaskBindingIndex = 0;
|
|
3858
3903
|
if (!spec.name || typeof spec.name !== "string") {
|
|
@@ -3864,6 +3909,7 @@ var Actor = class {
|
|
|
3864
3909
|
}
|
|
3865
3910
|
this.kind = options.isMeta || spec.kind === "meta" ? "meta" : "standard";
|
|
3866
3911
|
this.sourceDefinition = options.definitionSource;
|
|
3912
|
+
this.hydrateDurableState = options.hydrateDurableState;
|
|
3867
3913
|
this.spec = {
|
|
3868
3914
|
...spec,
|
|
3869
3915
|
defaultKey: normalizedDefaultKey,
|
|
@@ -3880,7 +3926,13 @@ var Actor = class {
|
|
|
3880
3926
|
task(handler, bindingOptions = {}) {
|
|
3881
3927
|
const mode = bindingOptions.mode ?? "read";
|
|
3882
3928
|
const taskBindingId = `${this.spec.name}:${++this.nextTaskBindingIndex}`;
|
|
3883
|
-
const wrapped = (context, emit, inquire, progressCallback) => {
|
|
3929
|
+
const wrapped = (context, emit, inquire, tools, progressCallback) => {
|
|
3930
|
+
const resolvedTools = tools && typeof tools === "object" && !Array.isArray(tools) && "helpers" in tools && "globals" in tools ? tools : {
|
|
3931
|
+
helpers: {},
|
|
3932
|
+
globals: {}
|
|
3933
|
+
};
|
|
3934
|
+
const resolvedProgressCallback = typeof progressCallback === "function" ? progressCallback : typeof tools === "function" ? tools : () => {
|
|
3935
|
+
};
|
|
3884
3936
|
const normalizedInput = this.normalizeInputContext(context);
|
|
3885
3937
|
const invocationOptions = this.resolveInvocationOptions(
|
|
3886
3938
|
context,
|
|
@@ -3891,7 +3943,7 @@ var Actor = class {
|
|
|
3891
3943
|
this.pruneExpiredActorKeys(now2);
|
|
3892
3944
|
this.touchSession(actorKey, invocationOptions.touchSession, now2);
|
|
3893
3945
|
const runTask = async () => {
|
|
3894
|
-
const stateRecord = this.
|
|
3946
|
+
const stateRecord = await this.maybeHydrateStateRecord(actorKey);
|
|
3895
3947
|
stateRecord.lastReadAt = Date.now();
|
|
3896
3948
|
let durableStateChanged = false;
|
|
3897
3949
|
let runtimeStateChanged = false;
|
|
@@ -4000,7 +4052,8 @@ var Actor = class {
|
|
|
4000
4052
|
patchRuntimeState,
|
|
4001
4053
|
reduceRuntimeState,
|
|
4002
4054
|
emit: (signal, payload = {}) => emit(signal, payload),
|
|
4003
|
-
inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options)
|
|
4055
|
+
inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options),
|
|
4056
|
+
tools: resolvedTools
|
|
4004
4057
|
};
|
|
4005
4058
|
const handlerResult = await handler(actorContext);
|
|
4006
4059
|
if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
|
|
@@ -4027,7 +4080,7 @@ var Actor = class {
|
|
|
4027
4080
|
stateRecord.lastRuntimeWriteAt = writeTimestamp;
|
|
4028
4081
|
}
|
|
4029
4082
|
this.touchSession(actorKey, invocationOptions.touchSession, Date.now());
|
|
4030
|
-
|
|
4083
|
+
resolvedProgressCallback(100);
|
|
4031
4084
|
if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
|
|
4032
4085
|
return cloneForDurableState(stateRecord.durableState);
|
|
4033
4086
|
}
|
|
@@ -4071,6 +4124,13 @@ var Actor = class {
|
|
|
4071
4124
|
this.pruneExpiredActorKeys(Date.now());
|
|
4072
4125
|
return this.ensureStateRecord(key).runtimeState;
|
|
4073
4126
|
}
|
|
4127
|
+
/**
|
|
4128
|
+
* Lists all currently materialized actor keys.
|
|
4129
|
+
*/
|
|
4130
|
+
listActorKeys() {
|
|
4131
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4132
|
+
return Array.from(this.stateByKey.keys()).sort();
|
|
4133
|
+
}
|
|
4074
4134
|
/**
|
|
4075
4135
|
* Alias of `getDurableVersion`.
|
|
4076
4136
|
*/
|
|
@@ -4133,6 +4193,7 @@ var Actor = class {
|
|
|
4133
4193
|
this.stateByKey.clear();
|
|
4134
4194
|
this.sessionByKey.clear();
|
|
4135
4195
|
this.idempotencyByKey.clear();
|
|
4196
|
+
this.pendingHydrationByKey.clear();
|
|
4136
4197
|
if ((this.spec.loadPolicy ?? "eager") === "eager") {
|
|
4137
4198
|
this.ensureStateRecord(this.spec.defaultKey);
|
|
4138
4199
|
}
|
|
@@ -4144,6 +4205,7 @@ var Actor = class {
|
|
|
4144
4205
|
}
|
|
4145
4206
|
this.stateByKey.delete(normalizedKey);
|
|
4146
4207
|
this.sessionByKey.delete(normalizedKey);
|
|
4208
|
+
this.pendingHydrationByKey.delete(normalizedKey);
|
|
4147
4209
|
for (const key of this.idempotencyByKey.keys()) {
|
|
4148
4210
|
if (key.startsWith(`${normalizedKey}:`)) {
|
|
4149
4211
|
this.idempotencyByKey.delete(key);
|
|
@@ -4229,6 +4291,7 @@ var Actor = class {
|
|
|
4229
4291
|
runtimeState: this.resolveInitialRuntimeState(),
|
|
4230
4292
|
version: 0,
|
|
4231
4293
|
runtimeVersion: 0,
|
|
4294
|
+
hydrationResolved: this.hydrateDurableState === void 0,
|
|
4232
4295
|
createdAt: now2,
|
|
4233
4296
|
lastReadAt: now2,
|
|
4234
4297
|
lastDurableWriteAt: now2,
|
|
@@ -4238,6 +4301,54 @@ var Actor = class {
|
|
|
4238
4301
|
this.touchSession(actorKey, true, now2);
|
|
4239
4302
|
return record;
|
|
4240
4303
|
}
|
|
4304
|
+
async maybeHydrateStateRecord(actorKey) {
|
|
4305
|
+
const record = this.ensureStateRecord(actorKey);
|
|
4306
|
+
if (record.hydrationResolved || !this.hydrateDurableState) {
|
|
4307
|
+
return record;
|
|
4308
|
+
}
|
|
4309
|
+
const pending = this.pendingHydrationByKey.get(actorKey);
|
|
4310
|
+
if (pending) {
|
|
4311
|
+
return pending;
|
|
4312
|
+
}
|
|
4313
|
+
let hydrationPromise;
|
|
4314
|
+
hydrationPromise = (async () => {
|
|
4315
|
+
const current = this.ensureStateRecord(actorKey);
|
|
4316
|
+
if (current.hydrationResolved || !this.hydrateDurableState) {
|
|
4317
|
+
return current;
|
|
4318
|
+
}
|
|
4319
|
+
const snapshot = await this.hydrateDurableState(actorKey);
|
|
4320
|
+
const latest = this.ensureStateRecord(actorKey);
|
|
4321
|
+
if (latest.hydrationResolved) {
|
|
4322
|
+
return latest;
|
|
4323
|
+
}
|
|
4324
|
+
if (snapshot) {
|
|
4325
|
+
const durableVersion = Number(snapshot.durableVersion);
|
|
4326
|
+
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
4327
|
+
throw new Error(
|
|
4328
|
+
`Actor "${this.spec.name}" received invalid hydrated durable version for key "${actorKey}"`
|
|
4329
|
+
);
|
|
4330
|
+
}
|
|
4331
|
+
if (!isObject2(snapshot.durableState) || Array.isArray(snapshot.durableState)) {
|
|
4332
|
+
throw new Error(
|
|
4333
|
+
`Actor "${this.spec.name}" received invalid hydrated durable state for key "${actorKey}"`
|
|
4334
|
+
);
|
|
4335
|
+
}
|
|
4336
|
+
const hydratedAt = Date.now();
|
|
4337
|
+
latest.durableState = cloneForDurableState(snapshot.durableState);
|
|
4338
|
+
latest.version = durableVersion;
|
|
4339
|
+
latest.lastReadAt = hydratedAt;
|
|
4340
|
+
latest.lastDurableWriteAt = hydratedAt;
|
|
4341
|
+
}
|
|
4342
|
+
latest.hydrationResolved = true;
|
|
4343
|
+
return latest;
|
|
4344
|
+
})().finally(() => {
|
|
4345
|
+
if (this.pendingHydrationByKey.get(actorKey) === hydrationPromise) {
|
|
4346
|
+
this.pendingHydrationByKey.delete(actorKey);
|
|
4347
|
+
}
|
|
4348
|
+
});
|
|
4349
|
+
this.pendingHydrationByKey.set(actorKey, hydrationPromise);
|
|
4350
|
+
return hydrationPromise;
|
|
4351
|
+
}
|
|
4241
4352
|
touchSession(actorKey, shouldTouch, touchedAt) {
|
|
4242
4353
|
if (!this.spec.session?.enabled || !shouldTouch) {
|
|
4243
4354
|
return;
|
|
@@ -4429,6 +4540,176 @@ var Actor = class {
|
|
|
4429
4540
|
}
|
|
4430
4541
|
};
|
|
4431
4542
|
|
|
4543
|
+
// src/tools/definitions.ts
|
|
4544
|
+
function validateAlias(alias) {
|
|
4545
|
+
const normalized = String(alias ?? "").trim();
|
|
4546
|
+
if (!normalized) {
|
|
4547
|
+
throw new Error("Tool dependency alias must be a non-empty string");
|
|
4548
|
+
}
|
|
4549
|
+
return normalized;
|
|
4550
|
+
}
|
|
4551
|
+
function serializeGlobalValue(value) {
|
|
4552
|
+
if (value === void 0 || typeof value === "function") {
|
|
4553
|
+
throw new Error("Global values must be JSON-serializable");
|
|
4554
|
+
}
|
|
4555
|
+
try {
|
|
4556
|
+
return JSON.parse(JSON.stringify(value));
|
|
4557
|
+
} catch (error) {
|
|
4558
|
+
throw new Error(
|
|
4559
|
+
`Global values must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`
|
|
4560
|
+
);
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
function deepFreeze(value) {
|
|
4564
|
+
if (!value || typeof value !== "object") {
|
|
4565
|
+
return value;
|
|
4566
|
+
}
|
|
4567
|
+
Object.freeze(value);
|
|
4568
|
+
for (const nested of Object.values(value)) {
|
|
4569
|
+
if (nested && typeof nested === "object" && !Object.isFrozen(nested)) {
|
|
4570
|
+
deepFreeze(nested);
|
|
4571
|
+
}
|
|
4572
|
+
}
|
|
4573
|
+
return value;
|
|
4574
|
+
}
|
|
4575
|
+
var GlobalDefinition = class {
|
|
4576
|
+
constructor(name, value, description = "", isMeta = false) {
|
|
4577
|
+
this.version = 1;
|
|
4578
|
+
this.destroyed = false;
|
|
4579
|
+
this.name = name;
|
|
4580
|
+
this.description = description;
|
|
4581
|
+
this.isMeta = isMeta;
|
|
4582
|
+
this.value = deepFreeze(serializeGlobalValue(value));
|
|
4583
|
+
}
|
|
4584
|
+
destroy() {
|
|
4585
|
+
this.destroyed = true;
|
|
4586
|
+
}
|
|
4587
|
+
export() {
|
|
4588
|
+
return {
|
|
4589
|
+
name: this.name,
|
|
4590
|
+
description: this.description,
|
|
4591
|
+
version: this.version,
|
|
4592
|
+
isMeta: this.isMeta,
|
|
4593
|
+
value: this.value
|
|
4594
|
+
};
|
|
4595
|
+
}
|
|
4596
|
+
};
|
|
4597
|
+
var HelperDefinition = class {
|
|
4598
|
+
constructor(name, helperFunction, description = "", isMeta = false) {
|
|
4599
|
+
this.version = 1;
|
|
4600
|
+
this.helperAliases = /* @__PURE__ */ new Map();
|
|
4601
|
+
this.globalAliases = /* @__PURE__ */ new Map();
|
|
4602
|
+
this.destroyed = false;
|
|
4603
|
+
this.name = name;
|
|
4604
|
+
this.description = description;
|
|
4605
|
+
this.isMeta = isMeta;
|
|
4606
|
+
this.helperFunction = helperFunction;
|
|
4607
|
+
}
|
|
4608
|
+
usesHelpers(helpers) {
|
|
4609
|
+
attachHelperDependency(
|
|
4610
|
+
this,
|
|
4611
|
+
this.name,
|
|
4612
|
+
this.version,
|
|
4613
|
+
helpers,
|
|
4614
|
+
"meta.helper.helper_associated"
|
|
4615
|
+
);
|
|
4616
|
+
return this;
|
|
4617
|
+
}
|
|
4618
|
+
usesGlobals(globals) {
|
|
4619
|
+
attachGlobalDependency(
|
|
4620
|
+
this,
|
|
4621
|
+
this.name,
|
|
4622
|
+
this.version,
|
|
4623
|
+
globals,
|
|
4624
|
+
"meta.helper.global_associated"
|
|
4625
|
+
);
|
|
4626
|
+
return this;
|
|
4627
|
+
}
|
|
4628
|
+
execute(context, emit, inquire, progressCallback) {
|
|
4629
|
+
return Cadenza.executeHelper(
|
|
4630
|
+
this,
|
|
4631
|
+
context,
|
|
4632
|
+
emit,
|
|
4633
|
+
inquire,
|
|
4634
|
+
progressCallback
|
|
4635
|
+
);
|
|
4636
|
+
}
|
|
4637
|
+
destroy() {
|
|
4638
|
+
this.destroyed = true;
|
|
4639
|
+
}
|
|
4640
|
+
export() {
|
|
4641
|
+
return {
|
|
4642
|
+
name: this.name,
|
|
4643
|
+
description: this.description,
|
|
4644
|
+
version: this.version,
|
|
4645
|
+
isMeta: this.isMeta,
|
|
4646
|
+
functionString: this.helperFunction.toString(),
|
|
4647
|
+
helperAliases: Object.fromEntries(this.helperAliases),
|
|
4648
|
+
globalAliases: Object.fromEntries(this.globalAliases)
|
|
4649
|
+
};
|
|
4650
|
+
}
|
|
4651
|
+
};
|
|
4652
|
+
function attachHelperDependency(owner, ownerName, ownerVersion, helpers, signalName) {
|
|
4653
|
+
for (const [alias, helper] of Object.entries(helpers)) {
|
|
4654
|
+
const normalizedAlias = validateAlias(alias);
|
|
4655
|
+
if (!helper) {
|
|
4656
|
+
throw new Error(
|
|
4657
|
+
`Helper dependency "${normalizedAlias}" must reference a helper definition`
|
|
4658
|
+
);
|
|
4659
|
+
}
|
|
4660
|
+
if (helper.isMeta !== owner.isMeta) {
|
|
4661
|
+
throw new Error(
|
|
4662
|
+
`${ownerName} cannot use ${helper.isMeta ? "meta" : "business"} helper "${helper.name}" across layer boundaries`
|
|
4663
|
+
);
|
|
4664
|
+
}
|
|
4665
|
+
owner.helperAliases.set(normalizedAlias, helper.name);
|
|
4666
|
+
Cadenza.emit(signalName, {
|
|
4667
|
+
data: {
|
|
4668
|
+
alias: normalizedAlias,
|
|
4669
|
+
...signalName === "meta.task.helper_associated" ? {
|
|
4670
|
+
taskName: ownerName,
|
|
4671
|
+
taskVersion: ownerVersion
|
|
4672
|
+
} : {
|
|
4673
|
+
helperName: ownerName,
|
|
4674
|
+
helperVersion: ownerVersion
|
|
4675
|
+
},
|
|
4676
|
+
dependencyHelperName: helper.name,
|
|
4677
|
+
dependencyHelperVersion: helper.version
|
|
4678
|
+
}
|
|
4679
|
+
});
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
function attachGlobalDependency(owner, ownerName, ownerVersion, globals, signalName) {
|
|
4683
|
+
for (const [alias, globalDefinition] of Object.entries(globals)) {
|
|
4684
|
+
const normalizedAlias = validateAlias(alias);
|
|
4685
|
+
if (!globalDefinition) {
|
|
4686
|
+
throw new Error(
|
|
4687
|
+
`Global dependency "${normalizedAlias}" must reference a global definition`
|
|
4688
|
+
);
|
|
4689
|
+
}
|
|
4690
|
+
if (globalDefinition.isMeta !== owner.isMeta) {
|
|
4691
|
+
throw new Error(
|
|
4692
|
+
`${ownerName} cannot use ${globalDefinition.isMeta ? "meta" : "business"} global "${globalDefinition.name}" across layer boundaries`
|
|
4693
|
+
);
|
|
4694
|
+
}
|
|
4695
|
+
owner.globalAliases.set(normalizedAlias, globalDefinition.name);
|
|
4696
|
+
Cadenza.emit(signalName, {
|
|
4697
|
+
data: {
|
|
4698
|
+
alias: normalizedAlias,
|
|
4699
|
+
...signalName === "meta.task.global_associated" ? {
|
|
4700
|
+
taskName: ownerName,
|
|
4701
|
+
taskVersion: ownerVersion
|
|
4702
|
+
} : {
|
|
4703
|
+
helperName: ownerName,
|
|
4704
|
+
helperVersion: ownerVersion
|
|
4705
|
+
},
|
|
4706
|
+
globalName: globalDefinition.name,
|
|
4707
|
+
globalVersion: globalDefinition.version
|
|
4708
|
+
}
|
|
4709
|
+
});
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
|
|
4432
4713
|
// src/graph/definition/Task.ts
|
|
4433
4714
|
function normalizeSignalDefinition(input) {
|
|
4434
4715
|
if (typeof input === "string") {
|
|
@@ -4505,6 +4786,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
4505
4786
|
this.observedSignals = /* @__PURE__ */ new Set();
|
|
4506
4787
|
this.handlesIntents = /* @__PURE__ */ new Set();
|
|
4507
4788
|
this.inquiresIntents = /* @__PURE__ */ new Set();
|
|
4789
|
+
this.helperAliases = /* @__PURE__ */ new Map();
|
|
4790
|
+
this.globalAliases = /* @__PURE__ */ new Map();
|
|
4508
4791
|
this.name = name;
|
|
4509
4792
|
this.taskFunction = task;
|
|
4510
4793
|
this.description = description;
|
|
@@ -4540,6 +4823,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
4540
4823
|
"meta.task.relationship_added",
|
|
4541
4824
|
"meta.task.relationship_removed",
|
|
4542
4825
|
"meta.task.intent_associated",
|
|
4826
|
+
"meta.task.helper_associated",
|
|
4827
|
+
"meta.task.global_associated",
|
|
4543
4828
|
"meta.task.layer_index_changed",
|
|
4544
4829
|
"meta.node.scheduled",
|
|
4545
4830
|
"meta.node.mapped",
|
|
@@ -5053,10 +5338,18 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5053
5338
|
* @return {TaskResult} The result of the executed task.
|
|
5054
5339
|
*/
|
|
5055
5340
|
execute(context, emit, inquire, progressCallback, nodeData) {
|
|
5341
|
+
const executionContext = this.isMeta ? context.getClonedFullContext() : context.getClonedContext();
|
|
5056
5342
|
return this.taskFunction(
|
|
5057
|
-
|
|
5343
|
+
executionContext,
|
|
5058
5344
|
emit,
|
|
5059
5345
|
inquire,
|
|
5346
|
+
Cadenza.resolveToolsForOwner(
|
|
5347
|
+
this,
|
|
5348
|
+
executionContext,
|
|
5349
|
+
emit,
|
|
5350
|
+
inquire,
|
|
5351
|
+
progressCallback
|
|
5352
|
+
),
|
|
5060
5353
|
progressCallback
|
|
5061
5354
|
);
|
|
5062
5355
|
}
|
|
@@ -5070,6 +5363,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5070
5363
|
* @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
|
|
5071
5364
|
*/
|
|
5072
5365
|
doAfter(...tasks) {
|
|
5366
|
+
Cadenza.assertGraphMutationAllowed("Task#doAfter");
|
|
5073
5367
|
for (const pred of tasks) {
|
|
5074
5368
|
if (!pred) continue;
|
|
5075
5369
|
if (this.predecessorTasks.has(pred)) continue;
|
|
@@ -5101,6 +5395,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5101
5395
|
* @throws {Error} Throws an error if adding a task causes a cyclic dependency.
|
|
5102
5396
|
*/
|
|
5103
5397
|
then(...tasks) {
|
|
5398
|
+
Cadenza.assertGraphMutationAllowed("Task#then");
|
|
5104
5399
|
for (const next of tasks) {
|
|
5105
5400
|
if (!next) continue;
|
|
5106
5401
|
if (this.nextTasks.has(next)) continue;
|
|
@@ -5264,6 +5559,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5264
5559
|
* @return {this} The current instance after adding the specified signals.
|
|
5265
5560
|
*/
|
|
5266
5561
|
doOn(...signals) {
|
|
5562
|
+
Cadenza.assertGraphMutationAllowed("Task#doOn");
|
|
5267
5563
|
signals.forEach((input) => {
|
|
5268
5564
|
const { name: signal, metadata } = normalizeSignalDefinition(input);
|
|
5269
5565
|
if (this.observedSignals.has(signal)) return;
|
|
@@ -5288,6 +5584,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5288
5584
|
* @return {this} The current instance for method chaining.
|
|
5289
5585
|
*/
|
|
5290
5586
|
emits(...signals) {
|
|
5587
|
+
Cadenza.assertGraphMutationAllowed("Task#emits");
|
|
5291
5588
|
signals.forEach((input) => {
|
|
5292
5589
|
const { name: signal } = normalizeSignalDefinition(input);
|
|
5293
5590
|
if (this.observedSignals.has(signal))
|
|
@@ -5307,6 +5604,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5307
5604
|
* @return {this} Returns the current instance for chaining.
|
|
5308
5605
|
*/
|
|
5309
5606
|
emitsOnFail(...signals) {
|
|
5607
|
+
Cadenza.assertGraphMutationAllowed("Task#emitsOnFail");
|
|
5310
5608
|
signals.forEach((input) => {
|
|
5311
5609
|
const { name: signal } = normalizeSignalDefinition(input);
|
|
5312
5610
|
this.signalsToEmitOnFail.add(signal);
|
|
@@ -5321,6 +5619,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5321
5619
|
* @return {void} This method does not return a value.
|
|
5322
5620
|
*/
|
|
5323
5621
|
attachSignal(...signals) {
|
|
5622
|
+
Cadenza.assertGraphMutationAllowed("Task#attachSignal");
|
|
5324
5623
|
signals.forEach((input) => {
|
|
5325
5624
|
const { name: signal, metadata } = normalizeSignalDefinition(input);
|
|
5326
5625
|
this.emitsSignals.add(signal);
|
|
@@ -5417,6 +5716,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5417
5716
|
return this;
|
|
5418
5717
|
}
|
|
5419
5718
|
respondsTo(...inquires) {
|
|
5719
|
+
Cadenza.assertGraphMutationAllowed("Task#respondsTo");
|
|
5420
5720
|
for (const intentName of inquires) {
|
|
5421
5721
|
if (this.handlesIntents.has(intentName)) {
|
|
5422
5722
|
continue;
|
|
@@ -5452,6 +5752,26 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5452
5752
|
}
|
|
5453
5753
|
return this;
|
|
5454
5754
|
}
|
|
5755
|
+
usesHelpers(helpers) {
|
|
5756
|
+
attachHelperDependency(
|
|
5757
|
+
this,
|
|
5758
|
+
this.name,
|
|
5759
|
+
this.version,
|
|
5760
|
+
helpers,
|
|
5761
|
+
"meta.task.helper_associated"
|
|
5762
|
+
);
|
|
5763
|
+
return this;
|
|
5764
|
+
}
|
|
5765
|
+
usesGlobals(globals) {
|
|
5766
|
+
attachGlobalDependency(
|
|
5767
|
+
this,
|
|
5768
|
+
this.name,
|
|
5769
|
+
this.version,
|
|
5770
|
+
globals,
|
|
5771
|
+
"meta.task.global_associated"
|
|
5772
|
+
);
|
|
5773
|
+
return this;
|
|
5774
|
+
}
|
|
5455
5775
|
attachIntents(...intentNames) {
|
|
5456
5776
|
for (const intent of intentNames) {
|
|
5457
5777
|
this.inquiresIntents.add(intent);
|
|
@@ -5544,6 +5864,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5544
5864
|
this.nextTasks.clear();
|
|
5545
5865
|
this.predecessorTasks.clear();
|
|
5546
5866
|
this.destroyed = true;
|
|
5867
|
+
Cadenza.forgetTask(this.name);
|
|
5547
5868
|
if (this.register) {
|
|
5548
5869
|
Cadenza.registry.tasks.delete(this.name);
|
|
5549
5870
|
this.emitMetricsWithMetadata("meta.task.destroyed", {
|
|
@@ -5585,6 +5906,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5585
5906
|
__validateInputContext: this.validateInputContext,
|
|
5586
5907
|
__outputSchema: this.outputContextSchema,
|
|
5587
5908
|
__validateOutputContext: this.validateOutputContext,
|
|
5909
|
+
__helperAliases: Object.fromEntries(this.helperAliases),
|
|
5910
|
+
__globalAliases: Object.fromEntries(this.globalAliases),
|
|
5588
5911
|
__nextTasks: Array.from(this.nextTasks).map((t) => t.name),
|
|
5589
5912
|
__previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
|
|
5590
5913
|
};
|
|
@@ -5831,6 +6154,13 @@ var DebounceTask = class extends Task {
|
|
|
5831
6154
|
this.lastContext.getClonedContext(),
|
|
5832
6155
|
this.lastEmitFunction,
|
|
5833
6156
|
this.lastInquireFunction,
|
|
6157
|
+
Cadenza.resolveToolsForOwner(
|
|
6158
|
+
this,
|
|
6159
|
+
this.lastContext.getClonedContext(),
|
|
6160
|
+
this.lastEmitFunction,
|
|
6161
|
+
this.lastInquireFunction,
|
|
6162
|
+
this.lastProgressCallback
|
|
6163
|
+
),
|
|
5834
6164
|
this.lastProgressCallback
|
|
5835
6165
|
);
|
|
5836
6166
|
} catch (error) {
|
|
@@ -5985,6 +6315,19 @@ var EphemeralTask = class extends Task {
|
|
|
5985
6315
|
progressCallback,
|
|
5986
6316
|
nodeData
|
|
5987
6317
|
);
|
|
6318
|
+
if (result instanceof Promise) {
|
|
6319
|
+
return result.then((resolved) => {
|
|
6320
|
+
if (this.once || this.condition(resolved)) {
|
|
6321
|
+
this.destroy();
|
|
6322
|
+
}
|
|
6323
|
+
return resolved;
|
|
6324
|
+
}).catch((error) => {
|
|
6325
|
+
if (this.once || this.condition(error)) {
|
|
6326
|
+
this.destroy();
|
|
6327
|
+
}
|
|
6328
|
+
throw error;
|
|
6329
|
+
});
|
|
6330
|
+
}
|
|
5988
6331
|
if (this.once || this.condition(result)) {
|
|
5989
6332
|
this.destroy();
|
|
5990
6333
|
}
|
|
@@ -6975,6 +7318,386 @@ var InquiryBroker = class _InquiryBroker extends SignalEmitter {
|
|
|
6975
7318
|
}
|
|
6976
7319
|
};
|
|
6977
7320
|
|
|
7321
|
+
// src/runtime/RuntimeDefinitionRegistry.ts
|
|
7322
|
+
function createLinkKey(predecessorTaskName, successorTaskName) {
|
|
7323
|
+
return `${predecessorTaskName}=>${successorTaskName}`;
|
|
7324
|
+
}
|
|
7325
|
+
function createTaskSignalKey(taskName, signalName) {
|
|
7326
|
+
return `${taskName}=>${signalName}`;
|
|
7327
|
+
}
|
|
7328
|
+
function createTaskIntentKey(taskName, intentName) {
|
|
7329
|
+
return `${taskName}=>${intentName}`;
|
|
7330
|
+
}
|
|
7331
|
+
function createRoutineSignalKey(routineName, signalName) {
|
|
7332
|
+
return `${routineName}=>${signalName}`;
|
|
7333
|
+
}
|
|
7334
|
+
var RuntimeDefinitionRegistry = class {
|
|
7335
|
+
constructor() {
|
|
7336
|
+
this.taskDefinitions = /* @__PURE__ */ new Map();
|
|
7337
|
+
this.helperDefinitions = /* @__PURE__ */ new Map();
|
|
7338
|
+
this.globalDefinitions = /* @__PURE__ */ new Map();
|
|
7339
|
+
this.routineDefinitions = /* @__PURE__ */ new Map();
|
|
7340
|
+
this.intentDefinitions = /* @__PURE__ */ new Map();
|
|
7341
|
+
this.actorDefinitions = /* @__PURE__ */ new Map();
|
|
7342
|
+
this.actorTaskDefinitions = /* @__PURE__ */ new Map();
|
|
7343
|
+
this.taskLinks = /* @__PURE__ */ new Map();
|
|
7344
|
+
this.taskSignalObservations = /* @__PURE__ */ new Map();
|
|
7345
|
+
this.taskSignalEmissions = /* @__PURE__ */ new Map();
|
|
7346
|
+
this.taskIntentBindings = /* @__PURE__ */ new Map();
|
|
7347
|
+
this.taskHelperBindings = /* @__PURE__ */ new Map();
|
|
7348
|
+
this.taskGlobalBindings = /* @__PURE__ */ new Map();
|
|
7349
|
+
this.helperHelperBindings = /* @__PURE__ */ new Map();
|
|
7350
|
+
this.helperGlobalBindings = /* @__PURE__ */ new Map();
|
|
7351
|
+
this.routineSignalObservations = /* @__PURE__ */ new Map();
|
|
7352
|
+
}
|
|
7353
|
+
reset() {
|
|
7354
|
+
this.taskDefinitions.clear();
|
|
7355
|
+
this.helperDefinitions.clear();
|
|
7356
|
+
this.globalDefinitions.clear();
|
|
7357
|
+
this.routineDefinitions.clear();
|
|
7358
|
+
this.intentDefinitions.clear();
|
|
7359
|
+
this.actorDefinitions.clear();
|
|
7360
|
+
this.actorTaskDefinitions.clear();
|
|
7361
|
+
this.taskLinks.clear();
|
|
7362
|
+
this.taskSignalObservations.clear();
|
|
7363
|
+
this.taskSignalEmissions.clear();
|
|
7364
|
+
this.taskIntentBindings.clear();
|
|
7365
|
+
this.taskHelperBindings.clear();
|
|
7366
|
+
this.taskGlobalBindings.clear();
|
|
7367
|
+
this.helperHelperBindings.clear();
|
|
7368
|
+
this.helperGlobalBindings.clear();
|
|
7369
|
+
this.routineSignalObservations.clear();
|
|
7370
|
+
}
|
|
7371
|
+
setTaskDefinition(definition) {
|
|
7372
|
+
this.taskDefinitions.set(definition.name, {
|
|
7373
|
+
...definition,
|
|
7374
|
+
kind: definition.kind ?? "task",
|
|
7375
|
+
options: definition.options ? { ...definition.options } : void 0
|
|
7376
|
+
});
|
|
7377
|
+
}
|
|
7378
|
+
setHelperDefinition(definition) {
|
|
7379
|
+
this.helperDefinitions.set(definition.name, {
|
|
7380
|
+
...definition,
|
|
7381
|
+
kind: definition.kind ?? "helper"
|
|
7382
|
+
});
|
|
7383
|
+
}
|
|
7384
|
+
setGlobalDefinition(definition) {
|
|
7385
|
+
this.globalDefinitions.set(definition.name, {
|
|
7386
|
+
...definition,
|
|
7387
|
+
kind: definition.kind ?? "global",
|
|
7388
|
+
value: definition.value
|
|
7389
|
+
});
|
|
7390
|
+
}
|
|
7391
|
+
setRoutineDefinition(definition) {
|
|
7392
|
+
this.routineDefinitions.set(definition.name, {
|
|
7393
|
+
...definition,
|
|
7394
|
+
startTaskNames: [...definition.startTaskNames],
|
|
7395
|
+
isMeta: definition.isMeta === true
|
|
7396
|
+
});
|
|
7397
|
+
}
|
|
7398
|
+
setIntentDefinition(definition) {
|
|
7399
|
+
this.intentDefinitions.set(definition.name, {
|
|
7400
|
+
...definition,
|
|
7401
|
+
input: definition.input ? { ...definition.input } : void 0,
|
|
7402
|
+
output: definition.output ? { ...definition.output } : void 0
|
|
7403
|
+
});
|
|
7404
|
+
}
|
|
7405
|
+
setActorDefinition(definition) {
|
|
7406
|
+
this.actorDefinitions.set(definition.name, {
|
|
7407
|
+
...definition,
|
|
7408
|
+
state: definition.state ? {
|
|
7409
|
+
...definition.state,
|
|
7410
|
+
durable: definition.state.durable ? { ...definition.state.durable } : void 0,
|
|
7411
|
+
runtime: definition.state.runtime ? { ...definition.state.runtime } : void 0
|
|
7412
|
+
} : void 0,
|
|
7413
|
+
tasks: definition.tasks ? definition.tasks.map((task) => ({ ...task })) : void 0
|
|
7414
|
+
});
|
|
7415
|
+
}
|
|
7416
|
+
setActorTaskDefinition(definition) {
|
|
7417
|
+
this.actorTaskDefinitions.set(definition.taskName, {
|
|
7418
|
+
...definition,
|
|
7419
|
+
mode: definition.mode ?? "read",
|
|
7420
|
+
options: definition.options ? { ...definition.options } : void 0
|
|
7421
|
+
});
|
|
7422
|
+
}
|
|
7423
|
+
setTaskLink(definition) {
|
|
7424
|
+
this.taskLinks.set(
|
|
7425
|
+
createLinkKey(
|
|
7426
|
+
definition.predecessorTaskName,
|
|
7427
|
+
definition.successorTaskName
|
|
7428
|
+
),
|
|
7429
|
+
{ ...definition }
|
|
7430
|
+
);
|
|
7431
|
+
}
|
|
7432
|
+
setTaskSignalObservation(definition) {
|
|
7433
|
+
const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
|
|
7434
|
+
this.taskSignalObservations.set(
|
|
7435
|
+
createTaskSignalKey(definition.taskName, signalName),
|
|
7436
|
+
{
|
|
7437
|
+
taskName: definition.taskName,
|
|
7438
|
+
signal: typeof definition.signal === "string" ? definition.signal : {
|
|
7439
|
+
name: definition.signal.name,
|
|
7440
|
+
deliveryMode: definition.signal.deliveryMode,
|
|
7441
|
+
broadcastFilter: definition.signal.broadcastFilter ?? null
|
|
7442
|
+
}
|
|
7443
|
+
}
|
|
7444
|
+
);
|
|
7445
|
+
}
|
|
7446
|
+
setTaskSignalEmission(definition) {
|
|
7447
|
+
const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
|
|
7448
|
+
this.taskSignalEmissions.set(
|
|
7449
|
+
`${definition.taskName}=>${definition.mode ?? "after"}=>${signalName}`,
|
|
7450
|
+
{
|
|
7451
|
+
taskName: definition.taskName,
|
|
7452
|
+
mode: definition.mode ?? "after",
|
|
7453
|
+
signal: typeof definition.signal === "string" ? definition.signal : {
|
|
7454
|
+
name: definition.signal.name,
|
|
7455
|
+
deliveryMode: definition.signal.deliveryMode,
|
|
7456
|
+
broadcastFilter: definition.signal.broadcastFilter ?? null
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
);
|
|
7460
|
+
}
|
|
7461
|
+
setTaskIntentBinding(definition) {
|
|
7462
|
+
this.taskIntentBindings.set(
|
|
7463
|
+
createTaskIntentKey(definition.taskName, definition.intentName),
|
|
7464
|
+
{ ...definition }
|
|
7465
|
+
);
|
|
7466
|
+
}
|
|
7467
|
+
setTaskHelperBinding(definition) {
|
|
7468
|
+
this.taskHelperBindings.set(
|
|
7469
|
+
`${definition.taskName}=>${definition.alias}`,
|
|
7470
|
+
{ ...definition }
|
|
7471
|
+
);
|
|
7472
|
+
}
|
|
7473
|
+
setTaskGlobalBinding(definition) {
|
|
7474
|
+
this.taskGlobalBindings.set(
|
|
7475
|
+
`${definition.taskName}=>${definition.alias}`,
|
|
7476
|
+
{ ...definition }
|
|
7477
|
+
);
|
|
7478
|
+
}
|
|
7479
|
+
setHelperHelperBinding(definition) {
|
|
7480
|
+
this.helperHelperBindings.set(
|
|
7481
|
+
`${definition.helperName}=>${definition.alias}`,
|
|
7482
|
+
{ ...definition }
|
|
7483
|
+
);
|
|
7484
|
+
}
|
|
7485
|
+
setHelperGlobalBinding(definition) {
|
|
7486
|
+
this.helperGlobalBindings.set(
|
|
7487
|
+
`${definition.helperName}=>${definition.alias}`,
|
|
7488
|
+
{ ...definition }
|
|
7489
|
+
);
|
|
7490
|
+
}
|
|
7491
|
+
setRoutineSignalObservation(definition) {
|
|
7492
|
+
this.routineSignalObservations.set(
|
|
7493
|
+
createRoutineSignalKey(definition.routineName, definition.signal),
|
|
7494
|
+
{ ...definition }
|
|
7495
|
+
);
|
|
7496
|
+
}
|
|
7497
|
+
isRuntimeOwnedTask(taskName) {
|
|
7498
|
+
return this.taskDefinitions.has(taskName) || this.actorTaskDefinitions.has(taskName);
|
|
7499
|
+
}
|
|
7500
|
+
isRuntimeOwnedHelper(helperName) {
|
|
7501
|
+
return this.helperDefinitions.has(helperName);
|
|
7502
|
+
}
|
|
7503
|
+
isRuntimeOwnedGlobal(globalName) {
|
|
7504
|
+
return this.globalDefinitions.has(globalName);
|
|
7505
|
+
}
|
|
7506
|
+
isRuntimeOwnedRoutine(routineName) {
|
|
7507
|
+
return this.routineDefinitions.has(routineName);
|
|
7508
|
+
}
|
|
7509
|
+
isRuntimeOwnedActor(actorName) {
|
|
7510
|
+
return this.actorDefinitions.has(actorName);
|
|
7511
|
+
}
|
|
7512
|
+
};
|
|
7513
|
+
var runtimeDefinitionRegistry = new RuntimeDefinitionRegistry();
|
|
7514
|
+
|
|
7515
|
+
// src/runtime/sandbox.ts
|
|
7516
|
+
import vm from "vm";
|
|
7517
|
+
import ts from "typescript";
|
|
7518
|
+
var FORBIDDEN_SOURCE_PATTERNS = [
|
|
7519
|
+
{
|
|
7520
|
+
pattern: /\bimport\b/,
|
|
7521
|
+
message: "Runtime handler source must not contain import statements"
|
|
7522
|
+
},
|
|
7523
|
+
{
|
|
7524
|
+
pattern: /\bexport\b/,
|
|
7525
|
+
message: "Runtime handler source must not contain export statements"
|
|
7526
|
+
},
|
|
7527
|
+
{
|
|
7528
|
+
pattern: /\brequire\s*\(/,
|
|
7529
|
+
message: "Runtime handler source must not call require()"
|
|
7530
|
+
},
|
|
7531
|
+
{
|
|
7532
|
+
pattern: /\bprocess\b/,
|
|
7533
|
+
message: "Runtime handler source must not access process"
|
|
7534
|
+
},
|
|
7535
|
+
{
|
|
7536
|
+
pattern: /\bFunction\s*\(/,
|
|
7537
|
+
message: "Runtime handler source must not create dynamic functions"
|
|
7538
|
+
},
|
|
7539
|
+
{
|
|
7540
|
+
pattern: /\beval\s*\(/,
|
|
7541
|
+
message: "Runtime handler source must not call eval()"
|
|
7542
|
+
}
|
|
7543
|
+
];
|
|
7544
|
+
function transpileIfNeeded(source, language, filename) {
|
|
7545
|
+
if (language === "js") {
|
|
7546
|
+
return source;
|
|
7547
|
+
}
|
|
7548
|
+
const result = ts.transpileModule(source, {
|
|
7549
|
+
compilerOptions: {
|
|
7550
|
+
target: ts.ScriptTarget.ES2020,
|
|
7551
|
+
module: ts.ModuleKind.ESNext
|
|
7552
|
+
},
|
|
7553
|
+
fileName: filename,
|
|
7554
|
+
reportDiagnostics: true
|
|
7555
|
+
});
|
|
7556
|
+
const diagnostics = result.diagnostics ?? [];
|
|
7557
|
+
const blockingDiagnostics = diagnostics.filter(
|
|
7558
|
+
(diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error
|
|
7559
|
+
);
|
|
7560
|
+
if (blockingDiagnostics.length > 0) {
|
|
7561
|
+
const message = blockingDiagnostics.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")).join("; ");
|
|
7562
|
+
throw new Error(`TypeScript transpile failed: ${message}`);
|
|
7563
|
+
}
|
|
7564
|
+
return result.outputText;
|
|
7565
|
+
}
|
|
7566
|
+
function createSandbox() {
|
|
7567
|
+
const sandbox = /* @__PURE__ */ Object.create(null);
|
|
7568
|
+
sandbox.global = void 0;
|
|
7569
|
+
sandbox.globalThis = sandbox;
|
|
7570
|
+
sandbox.process = void 0;
|
|
7571
|
+
sandbox.require = void 0;
|
|
7572
|
+
sandbox.module = void 0;
|
|
7573
|
+
sandbox.exports = void 0;
|
|
7574
|
+
sandbox.Buffer = void 0;
|
|
7575
|
+
sandbox.fetch = void 0;
|
|
7576
|
+
sandbox.WebSocket = void 0;
|
|
7577
|
+
sandbox.XMLHttpRequest = void 0;
|
|
7578
|
+
sandbox.setTimeout = void 0;
|
|
7579
|
+
sandbox.setInterval = void 0;
|
|
7580
|
+
sandbox.clearTimeout = void 0;
|
|
7581
|
+
sandbox.clearInterval = void 0;
|
|
7582
|
+
sandbox.queueMicrotask = void 0;
|
|
7583
|
+
return vm.createContext(sandbox);
|
|
7584
|
+
}
|
|
7585
|
+
function compileFunctionFromSource(source, language, filename, label) {
|
|
7586
|
+
const normalizedSource = String(source ?? "").trim();
|
|
7587
|
+
if (!normalizedSource) {
|
|
7588
|
+
throw new Error(`${label} source must be a non-empty string`);
|
|
7589
|
+
}
|
|
7590
|
+
for (const rule of FORBIDDEN_SOURCE_PATTERNS) {
|
|
7591
|
+
if (rule.pattern.test(normalizedSource)) {
|
|
7592
|
+
throw new Error(rule.message);
|
|
7593
|
+
}
|
|
7594
|
+
}
|
|
7595
|
+
const wrappedSource = `const __runtime_handler = ${normalizedSource};
|
|
7596
|
+
__runtime_handler;`;
|
|
7597
|
+
const transpiledSource = transpileIfNeeded(
|
|
7598
|
+
wrappedSource,
|
|
7599
|
+
language,
|
|
7600
|
+
filename
|
|
7601
|
+
).trim();
|
|
7602
|
+
const sandbox = createSandbox();
|
|
7603
|
+
const script = new vm.Script(transpiledSource, {
|
|
7604
|
+
filename
|
|
7605
|
+
});
|
|
7606
|
+
const compiled = script.runInContext(sandbox, {
|
|
7607
|
+
timeout: 1e3,
|
|
7608
|
+
displayErrors: true,
|
|
7609
|
+
contextCodeGeneration: {
|
|
7610
|
+
strings: false,
|
|
7611
|
+
wasm: false
|
|
7612
|
+
}
|
|
7613
|
+
});
|
|
7614
|
+
if (typeof compiled !== "function") {
|
|
7615
|
+
throw new Error(`${label} source must evaluate to a function`);
|
|
7616
|
+
}
|
|
7617
|
+
return compiled;
|
|
7618
|
+
}
|
|
7619
|
+
function compileRuntimeTaskFunction(definition) {
|
|
7620
|
+
return compileFunctionFromSource(
|
|
7621
|
+
definition.handlerSource,
|
|
7622
|
+
definition.language,
|
|
7623
|
+
`${definition.name}.runtime-task.${definition.language}`,
|
|
7624
|
+
`Task "${definition.name}"`
|
|
7625
|
+
);
|
|
7626
|
+
}
|
|
7627
|
+
function compileRuntimeHelperFunction(definition) {
|
|
7628
|
+
return compileFunctionFromSource(
|
|
7629
|
+
definition.handlerSource,
|
|
7630
|
+
definition.language,
|
|
7631
|
+
`${definition.name}.runtime-helper.${definition.language}`,
|
|
7632
|
+
`Helper "${definition.name}"`
|
|
7633
|
+
);
|
|
7634
|
+
}
|
|
7635
|
+
function compileRuntimeActorTaskHandler(definition) {
|
|
7636
|
+
return compileFunctionFromSource(
|
|
7637
|
+
definition.handlerSource,
|
|
7638
|
+
definition.language,
|
|
7639
|
+
`${definition.actorName}.${definition.taskName}.runtime-actor-task.${definition.language}`,
|
|
7640
|
+
`Actor task "${definition.taskName}"`
|
|
7641
|
+
);
|
|
7642
|
+
}
|
|
7643
|
+
|
|
7644
|
+
// src/runtime/sanitize.ts
|
|
7645
|
+
function isPlainObject2(value) {
|
|
7646
|
+
return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
|
|
7647
|
+
}
|
|
7648
|
+
function sanitizeForJson(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
7649
|
+
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
7650
|
+
return value ?? null;
|
|
7651
|
+
}
|
|
7652
|
+
if (typeof value === "bigint") {
|
|
7653
|
+
return value.toString();
|
|
7654
|
+
}
|
|
7655
|
+
if (typeof value === "function") {
|
|
7656
|
+
return `[Function ${value.name || "anonymous"}]`;
|
|
7657
|
+
}
|
|
7658
|
+
if (typeof value === "symbol") {
|
|
7659
|
+
return value.toString();
|
|
7660
|
+
}
|
|
7661
|
+
if (value instanceof Date) {
|
|
7662
|
+
return value.toISOString();
|
|
7663
|
+
}
|
|
7664
|
+
if (value instanceof Set) {
|
|
7665
|
+
return Array.from(value).map((entry) => sanitizeForJson(entry, seen));
|
|
7666
|
+
}
|
|
7667
|
+
if (value instanceof Map) {
|
|
7668
|
+
return Array.from(value.entries()).map(([key, entry]) => [
|
|
7669
|
+
sanitizeForJson(key, seen),
|
|
7670
|
+
sanitizeForJson(entry, seen)
|
|
7671
|
+
]);
|
|
7672
|
+
}
|
|
7673
|
+
if (Array.isArray(value)) {
|
|
7674
|
+
return value.map((entry) => sanitizeForJson(entry, seen));
|
|
7675
|
+
}
|
|
7676
|
+
if (typeof value === "object") {
|
|
7677
|
+
if (seen.has(value)) {
|
|
7678
|
+
return "[Circular]";
|
|
7679
|
+
}
|
|
7680
|
+
seen.add(value);
|
|
7681
|
+
if (!isPlainObject2(value)) {
|
|
7682
|
+
const clone = {};
|
|
7683
|
+
for (const key of Object.keys(value)) {
|
|
7684
|
+
clone[key] = sanitizeForJson(
|
|
7685
|
+
value[key],
|
|
7686
|
+
seen
|
|
7687
|
+
);
|
|
7688
|
+
}
|
|
7689
|
+
clone.__type = value.constructor?.name ?? "Object";
|
|
7690
|
+
return clone;
|
|
7691
|
+
}
|
|
7692
|
+
const result = {};
|
|
7693
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
7694
|
+
result[key] = sanitizeForJson(entry, seen);
|
|
7695
|
+
}
|
|
7696
|
+
return result;
|
|
7697
|
+
}
|
|
7698
|
+
return String(value);
|
|
7699
|
+
}
|
|
7700
|
+
|
|
6978
7701
|
// src/Cadenza.ts
|
|
6979
7702
|
var Cadenza = class {
|
|
6980
7703
|
/**
|
|
@@ -7057,6 +7780,73 @@ var Cadenza = class {
|
|
|
7057
7780
|
throw new Error("Task or Routine name must be a non-empty string.");
|
|
7058
7781
|
}
|
|
7059
7782
|
}
|
|
7783
|
+
static assertGraphMutationAllowed(operationName) {
|
|
7784
|
+
if (this.helperExecutionDepth > 0) {
|
|
7785
|
+
throw new Error(
|
|
7786
|
+
`${operationName} is not allowed during helper execution`
|
|
7787
|
+
);
|
|
7788
|
+
}
|
|
7789
|
+
}
|
|
7790
|
+
static executeHelper(helper, context, emit, inquire, progressCallback) {
|
|
7791
|
+
const helperContext = context && typeof context === "object" ? context : {};
|
|
7792
|
+
const tools = this.resolveToolsForOwner(
|
|
7793
|
+
helper,
|
|
7794
|
+
helperContext,
|
|
7795
|
+
emit,
|
|
7796
|
+
inquire,
|
|
7797
|
+
progressCallback
|
|
7798
|
+
);
|
|
7799
|
+
this.helperExecutionDepth += 1;
|
|
7800
|
+
try {
|
|
7801
|
+
return helper.helperFunction(
|
|
7802
|
+
helperContext,
|
|
7803
|
+
emit,
|
|
7804
|
+
inquire,
|
|
7805
|
+
tools,
|
|
7806
|
+
progressCallback
|
|
7807
|
+
);
|
|
7808
|
+
} finally {
|
|
7809
|
+
this.helperExecutionDepth = Math.max(0, this.helperExecutionDepth - 1);
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
static resolveToolsForOwner(owner, context, emit, inquire, progressCallback) {
|
|
7813
|
+
const helpers = {};
|
|
7814
|
+
const globals = {};
|
|
7815
|
+
for (const [alias, helperName] of owner.helperAliases.entries()) {
|
|
7816
|
+
const helper = this.getHelper(helperName);
|
|
7817
|
+
if (!helper) {
|
|
7818
|
+
continue;
|
|
7819
|
+
}
|
|
7820
|
+
if (helper.isMeta !== owner.isMeta) {
|
|
7821
|
+
throw new Error(
|
|
7822
|
+
`Tool alias "${alias}" resolves across layer boundaries`
|
|
7823
|
+
);
|
|
7824
|
+
}
|
|
7825
|
+
helpers[alias] = (helperContext = context) => this.executeHelper(
|
|
7826
|
+
helper,
|
|
7827
|
+
helperContext,
|
|
7828
|
+
emit,
|
|
7829
|
+
inquire,
|
|
7830
|
+
progressCallback
|
|
7831
|
+
);
|
|
7832
|
+
}
|
|
7833
|
+
for (const [alias, globalName] of owner.globalAliases.entries()) {
|
|
7834
|
+
const globalDefinition = this.getGlobal(globalName);
|
|
7835
|
+
if (!globalDefinition) {
|
|
7836
|
+
continue;
|
|
7837
|
+
}
|
|
7838
|
+
if (globalDefinition.isMeta !== owner.isMeta) {
|
|
7839
|
+
throw new Error(
|
|
7840
|
+
`Global alias "${alias}" resolves across layer boundaries`
|
|
7841
|
+
);
|
|
7842
|
+
}
|
|
7843
|
+
globals[alias] = globalDefinition.value;
|
|
7844
|
+
}
|
|
7845
|
+
return {
|
|
7846
|
+
helpers,
|
|
7847
|
+
globals
|
|
7848
|
+
};
|
|
7849
|
+
}
|
|
7060
7850
|
static resolveTaskOptionsForActorTask(func, options = {}) {
|
|
7061
7851
|
const metadata = getActorTaskRuntimeMetadata(func);
|
|
7062
7852
|
if (!metadata?.forceMeta) {
|
|
@@ -7073,9 +7863,25 @@ var Cadenza = class {
|
|
|
7073
7863
|
static registerActor(actor) {
|
|
7074
7864
|
this.actorCache.set(actor.spec.name, actor);
|
|
7075
7865
|
}
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7866
|
+
static getHelper(name) {
|
|
7867
|
+
return this.helperCache.get(name);
|
|
7868
|
+
}
|
|
7869
|
+
static getAllHelpers() {
|
|
7870
|
+
return Array.from(this.helperCache.values()).filter(
|
|
7871
|
+
(helper) => !helper.destroyed
|
|
7872
|
+
);
|
|
7873
|
+
}
|
|
7874
|
+
static getGlobal(name) {
|
|
7875
|
+
return this.globalCache.get(name);
|
|
7876
|
+
}
|
|
7877
|
+
static getAllGlobals() {
|
|
7878
|
+
return Array.from(this.globalCache.values()).filter(
|
|
7879
|
+
(globalDefinition) => !globalDefinition.destroyed
|
|
7880
|
+
);
|
|
7881
|
+
}
|
|
7882
|
+
/**
|
|
7883
|
+
* Executes the specified task or GraphRoutine with the given context using an internal runner.
|
|
7884
|
+
*
|
|
7079
7885
|
* @param {Task | GraphRoutine} task - The task or GraphRoutine to be executed.
|
|
7080
7886
|
* @param {AnyObject} context - The context in which the task or GraphRoutine should be executed.
|
|
7081
7887
|
* @return {void}
|
|
@@ -7135,6 +7941,9 @@ var Cadenza = class {
|
|
|
7135
7941
|
static get(taskName) {
|
|
7136
7942
|
return this.registry?.tasks.get(taskName) ?? this.taskCache.get(taskName);
|
|
7137
7943
|
}
|
|
7944
|
+
static forgetTask(taskName) {
|
|
7945
|
+
this.taskCache.delete(taskName);
|
|
7946
|
+
}
|
|
7138
7947
|
static getActor(actorName) {
|
|
7139
7948
|
return this.actorCache.get(actorName);
|
|
7140
7949
|
}
|
|
@@ -7142,9 +7951,10 @@ var Cadenza = class {
|
|
|
7142
7951
|
return Array.from(this.actorCache.values());
|
|
7143
7952
|
}
|
|
7144
7953
|
static getRoutine(routineName) {
|
|
7145
|
-
return this.registry?.routines.get(routineName);
|
|
7954
|
+
return this.registry?.routines.get(routineName) ?? this.routineCache.get(routineName);
|
|
7146
7955
|
}
|
|
7147
7956
|
static defineIntent(intent) {
|
|
7957
|
+
this.assertGraphMutationAllowed("Cadenza.defineIntent");
|
|
7148
7958
|
this.inquiryBroker?.addIntent(intent);
|
|
7149
7959
|
return intent;
|
|
7150
7960
|
}
|
|
@@ -7298,6 +8108,7 @@ var Cadenza = class {
|
|
|
7298
8108
|
* participate in the graph like any other task.
|
|
7299
8109
|
*/
|
|
7300
8110
|
static createActor(spec, options = {}) {
|
|
8111
|
+
this.assertGraphMutationAllowed("Cadenza.createActor");
|
|
7301
8112
|
this.bootstrap();
|
|
7302
8113
|
const actor = new Actor(spec, options);
|
|
7303
8114
|
this.registerActor(actor);
|
|
@@ -7335,7 +8146,8 @@ var Cadenza = class {
|
|
|
7335
8146
|
};
|
|
7336
8147
|
const actorOptions = {
|
|
7337
8148
|
isMeta: options.isMeta,
|
|
7338
|
-
definitionSource: definition
|
|
8149
|
+
definitionSource: definition,
|
|
8150
|
+
hydrateDurableState: options.hydrateDurableState
|
|
7339
8151
|
};
|
|
7340
8152
|
return this.createActor(spec, actorOptions);
|
|
7341
8153
|
}
|
|
@@ -7412,6 +8224,7 @@ var Cadenza = class {
|
|
|
7412
8224
|
* ```
|
|
7413
8225
|
*/
|
|
7414
8226
|
static createTask(name, func, description, options = {}) {
|
|
8227
|
+
this.assertGraphMutationAllowed("Cadenza.createTask");
|
|
7415
8228
|
this.bootstrap();
|
|
7416
8229
|
this.validateName(name);
|
|
7417
8230
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7461,6 +8274,164 @@ var Cadenza = class {
|
|
|
7461
8274
|
this.taskCache.set(name, createdTask);
|
|
7462
8275
|
return createdTask;
|
|
7463
8276
|
}
|
|
8277
|
+
static createTaskFromDefinition(definition) {
|
|
8278
|
+
this.bootstrap();
|
|
8279
|
+
this.validateName(definition.name);
|
|
8280
|
+
const existing = this.get(definition.name);
|
|
8281
|
+
if (existing) {
|
|
8282
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedTask(definition.name)) {
|
|
8283
|
+
throw new Error(
|
|
8284
|
+
`Task "${definition.name}" already exists and is not runtime-owned`
|
|
8285
|
+
);
|
|
8286
|
+
}
|
|
8287
|
+
existing.destroy();
|
|
8288
|
+
}
|
|
8289
|
+
const taskFunction = compileRuntimeTaskFunction(definition);
|
|
8290
|
+
const createdTask = definition.kind === "metaTask" ? this.createMetaTask(
|
|
8291
|
+
definition.name,
|
|
8292
|
+
taskFunction,
|
|
8293
|
+
definition.description ?? "",
|
|
8294
|
+
definition.options ?? {}
|
|
8295
|
+
) : this.createTask(
|
|
8296
|
+
definition.name,
|
|
8297
|
+
taskFunction,
|
|
8298
|
+
definition.description ?? "",
|
|
8299
|
+
definition.options ?? {}
|
|
8300
|
+
);
|
|
8301
|
+
runtimeDefinitionRegistry.setTaskDefinition(definition);
|
|
8302
|
+
return createdTask;
|
|
8303
|
+
}
|
|
8304
|
+
static createHelper(name, func, description = "") {
|
|
8305
|
+
this.bootstrap();
|
|
8306
|
+
this.validateName(name);
|
|
8307
|
+
this.assertGraphMutationAllowed("Cadenza.createHelper");
|
|
8308
|
+
if (this.helperCache.has(name)) {
|
|
8309
|
+
throw new Error(`Helper "${name}" already exists`);
|
|
8310
|
+
}
|
|
8311
|
+
const helper = new HelperDefinition(name, func, description, false);
|
|
8312
|
+
this.helperCache.set(name, helper);
|
|
8313
|
+
this.emit("meta.helper.created", {
|
|
8314
|
+
data: {
|
|
8315
|
+
name,
|
|
8316
|
+
version: helper.version,
|
|
8317
|
+
description,
|
|
8318
|
+
functionString: func.toString(),
|
|
8319
|
+
isMeta: false
|
|
8320
|
+
}
|
|
8321
|
+
});
|
|
8322
|
+
return helper;
|
|
8323
|
+
}
|
|
8324
|
+
static createMetaHelper(name, func, description = "") {
|
|
8325
|
+
this.bootstrap();
|
|
8326
|
+
this.validateName(name);
|
|
8327
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaHelper");
|
|
8328
|
+
if (this.helperCache.has(name)) {
|
|
8329
|
+
throw new Error(`Helper "${name}" already exists`);
|
|
8330
|
+
}
|
|
8331
|
+
const helper = new HelperDefinition(name, func, description, true);
|
|
8332
|
+
this.helperCache.set(name, helper);
|
|
8333
|
+
this.emit("meta.helper.created", {
|
|
8334
|
+
data: {
|
|
8335
|
+
name,
|
|
8336
|
+
version: helper.version,
|
|
8337
|
+
description,
|
|
8338
|
+
functionString: func.toString(),
|
|
8339
|
+
isMeta: true
|
|
8340
|
+
}
|
|
8341
|
+
});
|
|
8342
|
+
return helper;
|
|
8343
|
+
}
|
|
8344
|
+
static createHelperFromDefinition(definition) {
|
|
8345
|
+
this.bootstrap();
|
|
8346
|
+
this.validateName(definition.name);
|
|
8347
|
+
const existing = this.getHelper(definition.name);
|
|
8348
|
+
if (existing) {
|
|
8349
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedHelper(definition.name)) {
|
|
8350
|
+
throw new Error(
|
|
8351
|
+
`Helper "${definition.name}" already exists and is not runtime-owned`
|
|
8352
|
+
);
|
|
8353
|
+
}
|
|
8354
|
+
existing.destroy();
|
|
8355
|
+
this.helperCache.delete(definition.name);
|
|
8356
|
+
}
|
|
8357
|
+
const helperFunction = compileRuntimeHelperFunction(definition);
|
|
8358
|
+
const helper = definition.kind === "metaHelper" ? this.createMetaHelper(
|
|
8359
|
+
definition.name,
|
|
8360
|
+
helperFunction,
|
|
8361
|
+
definition.description ?? ""
|
|
8362
|
+
) : this.createHelper(
|
|
8363
|
+
definition.name,
|
|
8364
|
+
helperFunction,
|
|
8365
|
+
definition.description ?? ""
|
|
8366
|
+
);
|
|
8367
|
+
runtimeDefinitionRegistry.setHelperDefinition(definition);
|
|
8368
|
+
return helper;
|
|
8369
|
+
}
|
|
8370
|
+
static createGlobal(name, value, description = "") {
|
|
8371
|
+
this.bootstrap();
|
|
8372
|
+
this.validateName(name);
|
|
8373
|
+
this.assertGraphMutationAllowed("Cadenza.createGlobal");
|
|
8374
|
+
if (this.globalCache.has(name)) {
|
|
8375
|
+
throw new Error(`Global "${name}" already exists`);
|
|
8376
|
+
}
|
|
8377
|
+
const globalDefinition = new GlobalDefinition(name, value, description, false);
|
|
8378
|
+
this.globalCache.set(name, globalDefinition);
|
|
8379
|
+
this.emit("meta.global.created", {
|
|
8380
|
+
data: {
|
|
8381
|
+
name,
|
|
8382
|
+
version: globalDefinition.version,
|
|
8383
|
+
description,
|
|
8384
|
+
isMeta: false,
|
|
8385
|
+
value: globalDefinition.value
|
|
8386
|
+
}
|
|
8387
|
+
});
|
|
8388
|
+
return globalDefinition;
|
|
8389
|
+
}
|
|
8390
|
+
static createMetaGlobal(name, value, description = "") {
|
|
8391
|
+
this.bootstrap();
|
|
8392
|
+
this.validateName(name);
|
|
8393
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaGlobal");
|
|
8394
|
+
if (this.globalCache.has(name)) {
|
|
8395
|
+
throw new Error(`Global "${name}" already exists`);
|
|
8396
|
+
}
|
|
8397
|
+
const globalDefinition = new GlobalDefinition(name, value, description, true);
|
|
8398
|
+
this.globalCache.set(name, globalDefinition);
|
|
8399
|
+
this.emit("meta.global.created", {
|
|
8400
|
+
data: {
|
|
8401
|
+
name,
|
|
8402
|
+
version: globalDefinition.version,
|
|
8403
|
+
description,
|
|
8404
|
+
isMeta: true,
|
|
8405
|
+
value: globalDefinition.value
|
|
8406
|
+
}
|
|
8407
|
+
});
|
|
8408
|
+
return globalDefinition;
|
|
8409
|
+
}
|
|
8410
|
+
static createGlobalFromDefinition(definition) {
|
|
8411
|
+
this.bootstrap();
|
|
8412
|
+
this.validateName(definition.name);
|
|
8413
|
+
const existing = this.getGlobal(definition.name);
|
|
8414
|
+
if (existing) {
|
|
8415
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedGlobal(definition.name)) {
|
|
8416
|
+
throw new Error(
|
|
8417
|
+
`Global "${definition.name}" already exists and is not runtime-owned`
|
|
8418
|
+
);
|
|
8419
|
+
}
|
|
8420
|
+
existing.destroy();
|
|
8421
|
+
this.globalCache.delete(definition.name);
|
|
8422
|
+
}
|
|
8423
|
+
const globalDefinition = definition.kind === "metaGlobal" ? this.createMetaGlobal(
|
|
8424
|
+
definition.name,
|
|
8425
|
+
definition.value,
|
|
8426
|
+
definition.description ?? ""
|
|
8427
|
+
) : this.createGlobal(
|
|
8428
|
+
definition.name,
|
|
8429
|
+
definition.value,
|
|
8430
|
+
definition.description ?? ""
|
|
8431
|
+
);
|
|
8432
|
+
runtimeDefinitionRegistry.setGlobalDefinition(definition);
|
|
8433
|
+
return globalDefinition;
|
|
8434
|
+
}
|
|
7464
8435
|
/**
|
|
7465
8436
|
* Creates a meta task with the specified name, functionality, description, and options.
|
|
7466
8437
|
* This is used for creating tasks that lives on the meta layer.
|
|
@@ -7526,6 +8497,7 @@ var Cadenza = class {
|
|
|
7526
8497
|
*
|
|
7527
8498
|
*/
|
|
7528
8499
|
static createUniqueTask(name, func, description, options = {}) {
|
|
8500
|
+
this.assertGraphMutationAllowed("Cadenza.createUniqueTask");
|
|
7529
8501
|
options.isUnique = true;
|
|
7530
8502
|
return this.createTask(name, func, description, options);
|
|
7531
8503
|
}
|
|
@@ -7574,6 +8546,7 @@ var Cadenza = class {
|
|
|
7574
8546
|
* ```
|
|
7575
8547
|
*/
|
|
7576
8548
|
static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
|
|
8549
|
+
this.assertGraphMutationAllowed("Cadenza.createThrottledTask");
|
|
7577
8550
|
options.concurrency = 1;
|
|
7578
8551
|
options.getTagCallback = throttledIdGetter;
|
|
7579
8552
|
return this.createTask(name, func, description, options);
|
|
@@ -7633,6 +8606,7 @@ var Cadenza = class {
|
|
|
7633
8606
|
* ```
|
|
7634
8607
|
*/
|
|
7635
8608
|
static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
|
|
8609
|
+
this.assertGraphMutationAllowed("Cadenza.createDebounceTask");
|
|
7636
8610
|
this.bootstrap();
|
|
7637
8611
|
this.validateName(name);
|
|
7638
8612
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7761,6 +8735,7 @@ var Cadenza = class {
|
|
|
7761
8735
|
* ```
|
|
7762
8736
|
*/
|
|
7763
8737
|
static createEphemeralTask(name, func, description, options = {}) {
|
|
8738
|
+
this.assertGraphMutationAllowed("Cadenza.createEphemeralTask");
|
|
7764
8739
|
this.bootstrap();
|
|
7765
8740
|
this.validateName(name);
|
|
7766
8741
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7857,12 +8832,46 @@ var Cadenza = class {
|
|
|
7857
8832
|
* ```
|
|
7858
8833
|
*/
|
|
7859
8834
|
static createRoutine(name, tasks, description = "") {
|
|
8835
|
+
this.assertGraphMutationAllowed("Cadenza.createRoutine");
|
|
7860
8836
|
this.bootstrap();
|
|
7861
8837
|
this.validateName(name);
|
|
7862
8838
|
if (tasks.length === 0) {
|
|
7863
8839
|
throw new Error(`Routine '${name}' created with no starting tasks.`);
|
|
7864
8840
|
}
|
|
7865
|
-
|
|
8841
|
+
const createdRoutine = new GraphRoutine(name, tasks, description);
|
|
8842
|
+
this.routineCache.set(name, createdRoutine);
|
|
8843
|
+
return createdRoutine;
|
|
8844
|
+
}
|
|
8845
|
+
static createRoutineFromDefinition(definition) {
|
|
8846
|
+
const existing = this.getRoutine(definition.name);
|
|
8847
|
+
if (existing) {
|
|
8848
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedRoutine(definition.name)) {
|
|
8849
|
+
throw new Error(
|
|
8850
|
+
`Routine "${definition.name}" already exists and is not runtime-owned`
|
|
8851
|
+
);
|
|
8852
|
+
}
|
|
8853
|
+
existing.destroy();
|
|
8854
|
+
}
|
|
8855
|
+
const startTasks = definition.startTaskNames.map((taskName) => {
|
|
8856
|
+
const task = this.get(taskName);
|
|
8857
|
+
if (!task) {
|
|
8858
|
+
throw new Error(
|
|
8859
|
+
`Routine "${definition.name}" references missing task "${taskName}"`
|
|
8860
|
+
);
|
|
8861
|
+
}
|
|
8862
|
+
return task;
|
|
8863
|
+
});
|
|
8864
|
+
const routine = definition.isMeta === true ? this.createMetaRoutine(
|
|
8865
|
+
definition.name,
|
|
8866
|
+
startTasks,
|
|
8867
|
+
definition.description ?? ""
|
|
8868
|
+
) : this.createRoutine(
|
|
8869
|
+
definition.name,
|
|
8870
|
+
startTasks,
|
|
8871
|
+
definition.description ?? ""
|
|
8872
|
+
);
|
|
8873
|
+
runtimeDefinitionRegistry.setRoutineDefinition(definition);
|
|
8874
|
+
return routine;
|
|
7866
8875
|
}
|
|
7867
8876
|
/**
|
|
7868
8877
|
* Creates a meta routine with a given name, tasks, and optional description.
|
|
@@ -7877,47 +8886,1434 @@ var Cadenza = class {
|
|
|
7877
8886
|
* @throws {Error} If no starting tasks are provided.
|
|
7878
8887
|
*/
|
|
7879
8888
|
static createMetaRoutine(name, tasks, description = "") {
|
|
8889
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaRoutine");
|
|
7880
8890
|
this.bootstrap();
|
|
7881
8891
|
this.validateName(name);
|
|
7882
8892
|
if (tasks.length === 0) {
|
|
7883
8893
|
throw new Error(`Routine '${name}' created with no starting tasks.`);
|
|
7884
8894
|
}
|
|
7885
|
-
|
|
8895
|
+
const createdRoutine = new GraphRoutine(name, tasks, description, true);
|
|
8896
|
+
this.routineCache.set(name, createdRoutine);
|
|
8897
|
+
return createdRoutine;
|
|
8898
|
+
}
|
|
8899
|
+
static snapshotRuntime() {
|
|
8900
|
+
const taskMap = /* @__PURE__ */ new Map();
|
|
8901
|
+
for (const task of this.taskCache.values()) {
|
|
8902
|
+
taskMap.set(task.name, task);
|
|
8903
|
+
}
|
|
8904
|
+
for (const task of this.registry?.tasks.values() ?? []) {
|
|
8905
|
+
taskMap.set(task.name, task);
|
|
8906
|
+
}
|
|
8907
|
+
const tasks = Array.from(taskMap.values()).map((task) => {
|
|
8908
|
+
const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
|
|
8909
|
+
task.name
|
|
8910
|
+
);
|
|
8911
|
+
const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
|
|
8912
|
+
return {
|
|
8913
|
+
name: task.name,
|
|
8914
|
+
version: task.version,
|
|
8915
|
+
description: task.description,
|
|
8916
|
+
kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
|
|
8917
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name) === true,
|
|
8918
|
+
language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
|
|
8919
|
+
handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
|
|
8920
|
+
concurrency: task.concurrency,
|
|
8921
|
+
timeout: task.timeout,
|
|
8922
|
+
retryCount: task.retryCount,
|
|
8923
|
+
retryDelay: task.retryDelay,
|
|
8924
|
+
retryDelayMax: task.retryDelayMax,
|
|
8925
|
+
retryDelayFactor: task.retryDelayFactor,
|
|
8926
|
+
validateInputContext: task.validateInputContext,
|
|
8927
|
+
validateOutputContext: task.validateOutputContext,
|
|
8928
|
+
inputContextSchema: sanitizeForJson(task.inputContextSchema),
|
|
8929
|
+
outputContextSchema: sanitizeForJson(task.outputContextSchema),
|
|
8930
|
+
nextTaskNames: Array.from(task.nextTasks).map((nextTask) => nextTask.name),
|
|
8931
|
+
predecessorTaskNames: Array.from(task.predecessorTasks).map(
|
|
8932
|
+
(predecessorTask) => predecessorTask.name
|
|
8933
|
+
),
|
|
8934
|
+
signals: {
|
|
8935
|
+
emits: Array.from(task.emitsSignals),
|
|
8936
|
+
emitsAfter: Array.from(task.signalsToEmitAfter),
|
|
8937
|
+
emitsOnFail: Array.from(task.signalsToEmitOnFail),
|
|
8938
|
+
observed: Array.from(task.observedSignals)
|
|
8939
|
+
},
|
|
8940
|
+
intents: {
|
|
8941
|
+
handles: Array.from(task.handlesIntents),
|
|
8942
|
+
inquires: Array.from(task.inquiresIntents)
|
|
8943
|
+
},
|
|
8944
|
+
tools: {
|
|
8945
|
+
helpers: Object.fromEntries(task.helperAliases),
|
|
8946
|
+
globals: Object.fromEntries(task.globalAliases)
|
|
8947
|
+
},
|
|
8948
|
+
actorName: runtimeActorTaskDefinition?.actorName ?? null,
|
|
8949
|
+
actorMode: runtimeActorTaskDefinition?.mode ?? null
|
|
8950
|
+
};
|
|
8951
|
+
});
|
|
8952
|
+
const helpers = this.getAllHelpers().map((helper) => {
|
|
8953
|
+
const runtimeHelperDefinition = runtimeDefinitionRegistry.helperDefinitions.get(helper.name);
|
|
8954
|
+
return {
|
|
8955
|
+
name: helper.name,
|
|
8956
|
+
version: helper.version,
|
|
8957
|
+
description: helper.description,
|
|
8958
|
+
kind: helper.isMeta ? "metaHelper" : "helper",
|
|
8959
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedHelper(helper.name),
|
|
8960
|
+
language: runtimeHelperDefinition?.language ?? null,
|
|
8961
|
+
handlerSource: runtimeHelperDefinition?.handlerSource ?? null,
|
|
8962
|
+
tools: {
|
|
8963
|
+
helpers: Object.fromEntries(helper.helperAliases),
|
|
8964
|
+
globals: Object.fromEntries(helper.globalAliases)
|
|
8965
|
+
}
|
|
8966
|
+
};
|
|
8967
|
+
});
|
|
8968
|
+
const globals = this.getAllGlobals().map((globalDefinition) => ({
|
|
8969
|
+
name: globalDefinition.name,
|
|
8970
|
+
version: globalDefinition.version,
|
|
8971
|
+
description: globalDefinition.description,
|
|
8972
|
+
kind: globalDefinition.isMeta ? "metaGlobal" : "global",
|
|
8973
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedGlobal(
|
|
8974
|
+
globalDefinition.name
|
|
8975
|
+
),
|
|
8976
|
+
value: sanitizeForJson(globalDefinition.value)
|
|
8977
|
+
}));
|
|
8978
|
+
const routineMap = /* @__PURE__ */ new Map();
|
|
8979
|
+
for (const routine of this.routineCache.values()) {
|
|
8980
|
+
routineMap.set(routine.name, routine);
|
|
8981
|
+
}
|
|
8982
|
+
for (const routine of this.registry?.routines.values() ?? []) {
|
|
8983
|
+
routineMap.set(routine.name, routine);
|
|
8984
|
+
}
|
|
8985
|
+
const routines = Array.from(routineMap.values()).map(
|
|
8986
|
+
(routine) => ({
|
|
8987
|
+
name: routine.name,
|
|
8988
|
+
version: routine.version,
|
|
8989
|
+
description: routine.description,
|
|
8990
|
+
isMeta: routine.isMeta,
|
|
8991
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(routine.name) === true,
|
|
8992
|
+
startTaskNames: Array.from(routine.tasks).map((task) => task.name),
|
|
8993
|
+
observedSignals: Array.from(routine.observedSignals)
|
|
8994
|
+
})
|
|
8995
|
+
);
|
|
8996
|
+
const intents = Array.from(this.inquiryBroker?.intents.values() ?? []).map(
|
|
8997
|
+
(intent) => {
|
|
8998
|
+
const sanitizedIntent = sanitizeForJson(intent);
|
|
8999
|
+
return {
|
|
9000
|
+
...sanitizedIntent,
|
|
9001
|
+
runtimeOwned: runtimeDefinitionRegistry.intentDefinitions.has(
|
|
9002
|
+
intent.name
|
|
9003
|
+
)
|
|
9004
|
+
};
|
|
9005
|
+
}
|
|
9006
|
+
);
|
|
9007
|
+
const signals = Array.from(
|
|
9008
|
+
this.signalBroker?.emittedSignalsRegistry.values() ?? []
|
|
9009
|
+
).map((signalName) => ({
|
|
9010
|
+
name: signalName,
|
|
9011
|
+
metadata: sanitizeForJson(
|
|
9012
|
+
this.signalBroker?.signalMetadataRegistry.get(signalName) ?? null
|
|
9013
|
+
) ?? null
|
|
9014
|
+
}));
|
|
9015
|
+
const actors = this.getAllActors().map((actor) => {
|
|
9016
|
+
const definition = actor.toDefinition();
|
|
9017
|
+
const actorKeys = actor.listActorKeys().map((actorKey) => ({
|
|
9018
|
+
actorKey,
|
|
9019
|
+
durableState: sanitizeForJson(actor.getDurableState(actorKey)),
|
|
9020
|
+
runtimeState: sanitizeForJson(actor.getRuntimeState(actorKey)),
|
|
9021
|
+
durableVersion: actor.getDurableVersion(actorKey),
|
|
9022
|
+
runtimeVersion: actor.getRuntimeVersion(actorKey)
|
|
9023
|
+
}));
|
|
9024
|
+
return {
|
|
9025
|
+
name: actor.spec.name,
|
|
9026
|
+
description: actor.spec.description ?? "",
|
|
9027
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedActor(
|
|
9028
|
+
actor.spec.name
|
|
9029
|
+
),
|
|
9030
|
+
definition: sanitizeForJson(definition),
|
|
9031
|
+
actorKeys
|
|
9032
|
+
};
|
|
9033
|
+
});
|
|
9034
|
+
const actorTasks = Array.from(
|
|
9035
|
+
runtimeDefinitionRegistry.actorTaskDefinitions.values()
|
|
9036
|
+
).map((definition) => ({
|
|
9037
|
+
actorName: definition.actorName,
|
|
9038
|
+
taskName: definition.taskName,
|
|
9039
|
+
description: definition.description ?? "",
|
|
9040
|
+
mode: definition.mode ?? "read",
|
|
9041
|
+
language: definition.language,
|
|
9042
|
+
handlerSource: definition.handlerSource,
|
|
9043
|
+
runtimeOwned: true
|
|
9044
|
+
}));
|
|
9045
|
+
const links = Array.from(runtimeDefinitionRegistry.taskLinks.values()).map(
|
|
9046
|
+
(link) => ({ ...link })
|
|
9047
|
+
);
|
|
9048
|
+
return {
|
|
9049
|
+
runtimeMode: "core",
|
|
9050
|
+
bootstrapped: this.isBootstrapped,
|
|
9051
|
+
mode: this.mode,
|
|
9052
|
+
tasks,
|
|
9053
|
+
helpers,
|
|
9054
|
+
globals,
|
|
9055
|
+
routines,
|
|
9056
|
+
intents,
|
|
9057
|
+
signals,
|
|
9058
|
+
actors,
|
|
9059
|
+
actorTasks,
|
|
9060
|
+
links
|
|
9061
|
+
};
|
|
7886
9062
|
}
|
|
7887
9063
|
static reset() {
|
|
7888
9064
|
this.signalBroker?.reset();
|
|
7889
9065
|
this.inquiryBroker?.reset();
|
|
7890
9066
|
this.registry?.reset();
|
|
7891
9067
|
this.taskCache.clear();
|
|
9068
|
+
this.routineCache.clear();
|
|
7892
9069
|
this.actorCache.clear();
|
|
9070
|
+
this.helperCache.clear();
|
|
9071
|
+
this.globalCache.clear();
|
|
7893
9072
|
this.runtimeInquiryDelegate = void 0;
|
|
7894
9073
|
this.runtimeValidationPolicy = {};
|
|
7895
9074
|
this.runtimeValidationScopes.clear();
|
|
7896
9075
|
this.emittedMissingSchemaWarnings.clear();
|
|
9076
|
+
this.helperExecutionDepth = 0;
|
|
9077
|
+
runtimeDefinitionRegistry.reset();
|
|
7897
9078
|
this.isBootstrapped = false;
|
|
7898
9079
|
}
|
|
7899
9080
|
};
|
|
7900
9081
|
Cadenza.taskCache = /* @__PURE__ */ new Map();
|
|
9082
|
+
Cadenza.routineCache = /* @__PURE__ */ new Map();
|
|
7901
9083
|
Cadenza.actorCache = /* @__PURE__ */ new Map();
|
|
9084
|
+
Cadenza.helperCache = /* @__PURE__ */ new Map();
|
|
9085
|
+
Cadenza.globalCache = /* @__PURE__ */ new Map();
|
|
7902
9086
|
Cadenza.runtimeValidationPolicy = {};
|
|
7903
9087
|
Cadenza.runtimeValidationScopes = /* @__PURE__ */ new Map();
|
|
7904
9088
|
Cadenza.emittedMissingSchemaWarnings = /* @__PURE__ */ new Set();
|
|
9089
|
+
Cadenza.helperExecutionDepth = 0;
|
|
7905
9090
|
Cadenza.isBootstrapped = false;
|
|
7906
9091
|
Cadenza.mode = "production";
|
|
7907
9092
|
|
|
9093
|
+
// src/runtime/RuntimeSubscriptionManager.ts
|
|
9094
|
+
import { v4 as uuid8 } from "uuid";
|
|
9095
|
+
function isObject3(value) {
|
|
9096
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9097
|
+
}
|
|
9098
|
+
function asStringOrNull(value) {
|
|
9099
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
9100
|
+
}
|
|
9101
|
+
function asNumberOrNull(value) {
|
|
9102
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
9103
|
+
}
|
|
9104
|
+
function normalizeEventContext(context) {
|
|
9105
|
+
const sanitized = sanitizeForJson(context);
|
|
9106
|
+
return isObject3(sanitized) ? sanitized : { value: sanitized };
|
|
9107
|
+
}
|
|
9108
|
+
function matchesSignalPattern(fullSignal, signalName, patterns) {
|
|
9109
|
+
return patterns.some((pattern) => {
|
|
9110
|
+
if (pattern === "*") {
|
|
9111
|
+
return true;
|
|
9112
|
+
}
|
|
9113
|
+
if (pattern === fullSignal || pattern === signalName) {
|
|
9114
|
+
return true;
|
|
9115
|
+
}
|
|
9116
|
+
if (!pattern.endsWith(".*")) {
|
|
9117
|
+
return false;
|
|
9118
|
+
}
|
|
9119
|
+
const prefix = pattern.slice(0, -2);
|
|
9120
|
+
return signalName === prefix || signalName.startsWith(`${prefix}.`);
|
|
9121
|
+
});
|
|
9122
|
+
}
|
|
9123
|
+
var RuntimeSubscriptionManagerError = class extends Error {
|
|
9124
|
+
constructor(code, message) {
|
|
9125
|
+
super(message);
|
|
9126
|
+
this.code = code;
|
|
9127
|
+
this.name = "RuntimeSubscriptionManagerError";
|
|
9128
|
+
}
|
|
9129
|
+
};
|
|
9130
|
+
var RuntimeSubscriptionManager = class {
|
|
9131
|
+
constructor() {
|
|
9132
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
9133
|
+
this.removeBrokerListener = null;
|
|
9134
|
+
this.nextSequence = 0;
|
|
9135
|
+
this.attach();
|
|
9136
|
+
}
|
|
9137
|
+
dispose() {
|
|
9138
|
+
this.reset();
|
|
9139
|
+
this.removeBrokerListener?.();
|
|
9140
|
+
this.removeBrokerListener = null;
|
|
9141
|
+
}
|
|
9142
|
+
subscribe(signalPatterns, maxQueueSize) {
|
|
9143
|
+
this.attach();
|
|
9144
|
+
const descriptor = {
|
|
9145
|
+
subscriptionId: uuid8(),
|
|
9146
|
+
signalPatterns: [...signalPatterns],
|
|
9147
|
+
maxQueueSize,
|
|
9148
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9149
|
+
pendingEvents: 0
|
|
9150
|
+
};
|
|
9151
|
+
this.subscriptions.set(descriptor.subscriptionId, {
|
|
9152
|
+
descriptor,
|
|
9153
|
+
events: [],
|
|
9154
|
+
nextWaiter: null
|
|
9155
|
+
});
|
|
9156
|
+
return { ...descriptor };
|
|
9157
|
+
}
|
|
9158
|
+
unsubscribe(subscriptionId) {
|
|
9159
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9160
|
+
this.clearWaiter(
|
|
9161
|
+
subscription,
|
|
9162
|
+
new RuntimeSubscriptionManagerError(
|
|
9163
|
+
"not_found",
|
|
9164
|
+
`Subscription "${subscriptionId}" was closed`
|
|
9165
|
+
)
|
|
9166
|
+
);
|
|
9167
|
+
this.subscriptions.delete(subscriptionId);
|
|
9168
|
+
return { ...subscription.descriptor };
|
|
9169
|
+
}
|
|
9170
|
+
async nextEvent(subscriptionId, timeoutMs) {
|
|
9171
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9172
|
+
if (subscription.events.length > 0) {
|
|
9173
|
+
const event = subscription.events.shift() ?? null;
|
|
9174
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9175
|
+
return {
|
|
9176
|
+
subscriptionId,
|
|
9177
|
+
event,
|
|
9178
|
+
timedOut: false,
|
|
9179
|
+
pendingEvents: subscription.events.length
|
|
9180
|
+
};
|
|
9181
|
+
}
|
|
9182
|
+
if (timeoutMs <= 0) {
|
|
9183
|
+
return {
|
|
9184
|
+
subscriptionId,
|
|
9185
|
+
event: null,
|
|
9186
|
+
timedOut: true,
|
|
9187
|
+
pendingEvents: 0
|
|
9188
|
+
};
|
|
9189
|
+
}
|
|
9190
|
+
if (subscription.nextWaiter) {
|
|
9191
|
+
throw new RuntimeSubscriptionManagerError(
|
|
9192
|
+
"conflict",
|
|
9193
|
+
`Subscription "${subscriptionId}" already has a pending nextEvent request`
|
|
9194
|
+
);
|
|
9195
|
+
}
|
|
9196
|
+
return new Promise((resolve, reject) => {
|
|
9197
|
+
const timer = setTimeout(() => {
|
|
9198
|
+
subscription.nextWaiter = null;
|
|
9199
|
+
resolve({
|
|
9200
|
+
subscriptionId,
|
|
9201
|
+
event: null,
|
|
9202
|
+
timedOut: true,
|
|
9203
|
+
pendingEvents: subscription.events.length
|
|
9204
|
+
});
|
|
9205
|
+
}, timeoutMs);
|
|
9206
|
+
subscription.nextWaiter = {
|
|
9207
|
+
resolve: (result) => {
|
|
9208
|
+
clearTimeout(timer);
|
|
9209
|
+
subscription.nextWaiter = null;
|
|
9210
|
+
resolve(result);
|
|
9211
|
+
},
|
|
9212
|
+
reject: (error) => {
|
|
9213
|
+
clearTimeout(timer);
|
|
9214
|
+
subscription.nextWaiter = null;
|
|
9215
|
+
reject(error);
|
|
9216
|
+
},
|
|
9217
|
+
timer
|
|
9218
|
+
};
|
|
9219
|
+
});
|
|
9220
|
+
}
|
|
9221
|
+
pollEvents(subscriptionId, limit) {
|
|
9222
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9223
|
+
const events = subscription.events.splice(0, limit);
|
|
9224
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9225
|
+
return {
|
|
9226
|
+
subscriptionId,
|
|
9227
|
+
events,
|
|
9228
|
+
pendingEvents: subscription.events.length
|
|
9229
|
+
};
|
|
9230
|
+
}
|
|
9231
|
+
reset() {
|
|
9232
|
+
for (const subscription of this.subscriptions.values()) {
|
|
9233
|
+
this.clearWaiter(
|
|
9234
|
+
subscription,
|
|
9235
|
+
new RuntimeSubscriptionManagerError(
|
|
9236
|
+
"not_found",
|
|
9237
|
+
`Subscription "${subscription.descriptor.subscriptionId}" was reset`
|
|
9238
|
+
)
|
|
9239
|
+
);
|
|
9240
|
+
subscription.events.length = 0;
|
|
9241
|
+
subscription.descriptor.pendingEvents = 0;
|
|
9242
|
+
}
|
|
9243
|
+
this.subscriptions.clear();
|
|
9244
|
+
}
|
|
9245
|
+
attach() {
|
|
9246
|
+
if (this.removeBrokerListener) {
|
|
9247
|
+
return;
|
|
9248
|
+
}
|
|
9249
|
+
Cadenza.bootstrap();
|
|
9250
|
+
this.removeBrokerListener = Cadenza.signalBroker.addPassiveSignalListener(
|
|
9251
|
+
(signal, context, metadata) => this.captureSignal(signal, context, metadata)
|
|
9252
|
+
);
|
|
9253
|
+
}
|
|
9254
|
+
captureSignal(signal, context, metadata) {
|
|
9255
|
+
if (this.subscriptions.size === 0) {
|
|
9256
|
+
return;
|
|
9257
|
+
}
|
|
9258
|
+
const normalizedContext = normalizeEventContext(context);
|
|
9259
|
+
const emission = isObject3(normalizedContext.__signalEmission) ? normalizedContext.__signalEmission : {};
|
|
9260
|
+
const metadataObject = isObject3(normalizedContext.__metadata) ? normalizedContext.__metadata : {};
|
|
9261
|
+
const fullSignal = signal;
|
|
9262
|
+
const [baseSignalName, ...signalTagParts] = signal.split(":");
|
|
9263
|
+
const signalName = baseSignalName ?? signal;
|
|
9264
|
+
const signalTag = signalTagParts.length > 0 ? signalTagParts.join(":") : null;
|
|
9265
|
+
const eventTemplate = {
|
|
9266
|
+
type: "signal",
|
|
9267
|
+
signal: fullSignal,
|
|
9268
|
+
signalName,
|
|
9269
|
+
signalTag,
|
|
9270
|
+
emittedAt: asStringOrNull(emission.emittedAt),
|
|
9271
|
+
isMeta: emission.isMeta === true || signalName.startsWith("meta."),
|
|
9272
|
+
isSubMeta: normalizedContext.__isSubMeta === true || signalName.startsWith("sub_meta."),
|
|
9273
|
+
metadata: sanitizeForJson(metadata) ?? null,
|
|
9274
|
+
source: {
|
|
9275
|
+
taskName: asStringOrNull(emission.taskName),
|
|
9276
|
+
taskVersion: asNumberOrNull(emission.taskVersion),
|
|
9277
|
+
taskExecutionId: asStringOrNull(emission.taskExecutionId),
|
|
9278
|
+
routineName: asStringOrNull(normalizedContext.__routineName) ?? asStringOrNull(emission.routineName),
|
|
9279
|
+
routineVersion: asNumberOrNull(normalizedContext.__routineVersion) ?? asNumberOrNull(emission.routineVersion),
|
|
9280
|
+
routineExecutionId: asStringOrNull(normalizedContext.__routineExecId) ?? asStringOrNull(emission.routineExecutionId),
|
|
9281
|
+
executionTraceId: asStringOrNull(emission.executionTraceId) ?? asStringOrNull(normalizedContext.__executionTraceId) ?? asStringOrNull(metadataObject.__executionTraceId),
|
|
9282
|
+
consumed: emission.consumed === true,
|
|
9283
|
+
consumedBy: asStringOrNull(emission.consumedBy)
|
|
9284
|
+
},
|
|
9285
|
+
context: normalizedContext
|
|
9286
|
+
};
|
|
9287
|
+
for (const subscription of this.subscriptions.values()) {
|
|
9288
|
+
if (!matchesSignalPattern(
|
|
9289
|
+
fullSignal,
|
|
9290
|
+
signalName,
|
|
9291
|
+
subscription.descriptor.signalPatterns
|
|
9292
|
+
)) {
|
|
9293
|
+
continue;
|
|
9294
|
+
}
|
|
9295
|
+
const event = {
|
|
9296
|
+
id: uuid8(),
|
|
9297
|
+
subscriptionId: subscription.descriptor.subscriptionId,
|
|
9298
|
+
sequence: ++this.nextSequence,
|
|
9299
|
+
...eventTemplate
|
|
9300
|
+
};
|
|
9301
|
+
if (subscription.nextWaiter) {
|
|
9302
|
+
subscription.nextWaiter.resolve({
|
|
9303
|
+
subscriptionId: subscription.descriptor.subscriptionId,
|
|
9304
|
+
event,
|
|
9305
|
+
timedOut: false,
|
|
9306
|
+
pendingEvents: subscription.events.length
|
|
9307
|
+
});
|
|
9308
|
+
continue;
|
|
9309
|
+
}
|
|
9310
|
+
subscription.events.push(event);
|
|
9311
|
+
if (subscription.events.length > subscription.descriptor.maxQueueSize) {
|
|
9312
|
+
subscription.events.shift();
|
|
9313
|
+
}
|
|
9314
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9315
|
+
}
|
|
9316
|
+
}
|
|
9317
|
+
clearWaiter(subscription, error) {
|
|
9318
|
+
if (!subscription.nextWaiter) {
|
|
9319
|
+
return;
|
|
9320
|
+
}
|
|
9321
|
+
if (subscription.nextWaiter.timer) {
|
|
9322
|
+
clearTimeout(subscription.nextWaiter.timer);
|
|
9323
|
+
}
|
|
9324
|
+
subscription.nextWaiter.reject(error);
|
|
9325
|
+
subscription.nextWaiter = null;
|
|
9326
|
+
}
|
|
9327
|
+
requireSubscription(subscriptionId) {
|
|
9328
|
+
const subscription = this.subscriptions.get(subscriptionId);
|
|
9329
|
+
if (!subscription) {
|
|
9330
|
+
throw new RuntimeSubscriptionManagerError(
|
|
9331
|
+
"not_found",
|
|
9332
|
+
`No subscription named "${subscriptionId}" exists`
|
|
9333
|
+
);
|
|
9334
|
+
}
|
|
9335
|
+
return subscription;
|
|
9336
|
+
}
|
|
9337
|
+
};
|
|
9338
|
+
|
|
9339
|
+
// src/runtime/RuntimeHost.ts
|
|
9340
|
+
var SUPPORTED_OPERATIONS = [
|
|
9341
|
+
"runtime.bootstrap",
|
|
9342
|
+
"runtime.info",
|
|
9343
|
+
"runtime.detach",
|
|
9344
|
+
"runtime.shutdown",
|
|
9345
|
+
"runtime.reset",
|
|
9346
|
+
"runtime.snapshot",
|
|
9347
|
+
"runtime.subscribe",
|
|
9348
|
+
"runtime.unsubscribe",
|
|
9349
|
+
"runtime.nextEvent",
|
|
9350
|
+
"runtime.pollEvents",
|
|
9351
|
+
"task.upsert",
|
|
9352
|
+
"helper.upsert",
|
|
9353
|
+
"global.upsert",
|
|
9354
|
+
"task.link",
|
|
9355
|
+
"task.observeSignal",
|
|
9356
|
+
"task.emitSignal",
|
|
9357
|
+
"task.respondToIntent",
|
|
9358
|
+
"task.useHelper",
|
|
9359
|
+
"task.useGlobal",
|
|
9360
|
+
"helper.useHelper",
|
|
9361
|
+
"helper.useGlobal",
|
|
9362
|
+
"routine.upsert",
|
|
9363
|
+
"routine.observeSignal",
|
|
9364
|
+
"intent.upsert",
|
|
9365
|
+
"actor.upsert",
|
|
9366
|
+
"actorTask.upsert",
|
|
9367
|
+
"run",
|
|
9368
|
+
"emit",
|
|
9369
|
+
"inquire"
|
|
9370
|
+
];
|
|
9371
|
+
var RuntimeProtocolException = class extends Error {
|
|
9372
|
+
constructor(code, message, details) {
|
|
9373
|
+
super(message);
|
|
9374
|
+
this.code = code;
|
|
9375
|
+
this.details = details;
|
|
9376
|
+
this.name = "RuntimeProtocolException";
|
|
9377
|
+
}
|
|
9378
|
+
};
|
|
9379
|
+
function isObject4(value) {
|
|
9380
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9381
|
+
}
|
|
9382
|
+
function assertObject(value, message) {
|
|
9383
|
+
if (!isObject4(value)) {
|
|
9384
|
+
throw new RuntimeProtocolException("invalid_payload", message);
|
|
9385
|
+
}
|
|
9386
|
+
}
|
|
9387
|
+
function assertString(value, fieldName) {
|
|
9388
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
9389
|
+
throw new RuntimeProtocolException(
|
|
9390
|
+
"invalid_payload",
|
|
9391
|
+
`${fieldName} must be a non-empty string`
|
|
9392
|
+
);
|
|
9393
|
+
}
|
|
9394
|
+
return value;
|
|
9395
|
+
}
|
|
9396
|
+
function assertStringArray(value, fieldName) {
|
|
9397
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
9398
|
+
throw new RuntimeProtocolException(
|
|
9399
|
+
"invalid_payload",
|
|
9400
|
+
`${fieldName} must be an array of strings`
|
|
9401
|
+
);
|
|
9402
|
+
}
|
|
9403
|
+
return value;
|
|
9404
|
+
}
|
|
9405
|
+
function normalizeSignalDefinition2(signal) {
|
|
9406
|
+
if (typeof signal === "string") {
|
|
9407
|
+
return signal;
|
|
9408
|
+
}
|
|
9409
|
+
if (isObject4(signal) && typeof signal.name === "string" && signal.name.trim().length > 0) {
|
|
9410
|
+
return {
|
|
9411
|
+
name: signal.name,
|
|
9412
|
+
deliveryMode: signal.deliveryMode === "single" || signal.deliveryMode === "broadcast" ? signal.deliveryMode : void 0,
|
|
9413
|
+
broadcastFilter: signal.broadcastFilter && isObject4(signal.broadcastFilter) ? signal.broadcastFilter : null
|
|
9414
|
+
};
|
|
9415
|
+
}
|
|
9416
|
+
throw new RuntimeProtocolException(
|
|
9417
|
+
"invalid_payload",
|
|
9418
|
+
"signal must be a signal string or structured signal definition"
|
|
9419
|
+
);
|
|
9420
|
+
}
|
|
9421
|
+
var RuntimeHost = class {
|
|
9422
|
+
constructor(options = {}) {
|
|
9423
|
+
this.pendingControlAction = null;
|
|
9424
|
+
this.subscriptionManager = new RuntimeSubscriptionManager();
|
|
9425
|
+
this.runtimeSharing = options.runtimeSharing ?? "isolated";
|
|
9426
|
+
this.runtimeName = options.runtimeName ?? null;
|
|
9427
|
+
this.sessionId = options.sessionId ?? null;
|
|
9428
|
+
this.sessionRole = options.sessionRole ?? null;
|
|
9429
|
+
this.activeSessionCountProvider = options.activeSessionCountProvider ?? (() => 1);
|
|
9430
|
+
this.daemonProcessId = options.daemonProcessId ?? null;
|
|
9431
|
+
this.onResetRuntime = options.onResetRuntime ?? null;
|
|
9432
|
+
}
|
|
9433
|
+
dispose() {
|
|
9434
|
+
this.subscriptionManager.dispose();
|
|
9435
|
+
}
|
|
9436
|
+
resetSubscriptions() {
|
|
9437
|
+
this.subscriptionManager.reset();
|
|
9438
|
+
}
|
|
9439
|
+
consumeControlAction() {
|
|
9440
|
+
const action = this.pendingControlAction;
|
|
9441
|
+
this.pendingControlAction = null;
|
|
9442
|
+
return action;
|
|
9443
|
+
}
|
|
9444
|
+
handshake() {
|
|
9445
|
+
return {
|
|
9446
|
+
ready: true,
|
|
9447
|
+
protocol: "cadenza-runtime-jsonl",
|
|
9448
|
+
protocolVersion: "1",
|
|
9449
|
+
runtimeMode: "core",
|
|
9450
|
+
runtimeSharing: this.runtimeSharing,
|
|
9451
|
+
runtimeName: this.runtimeName,
|
|
9452
|
+
sessionId: this.sessionId,
|
|
9453
|
+
sessionRole: this.sessionRole,
|
|
9454
|
+
supportedOperations: [...SUPPORTED_OPERATIONS]
|
|
9455
|
+
};
|
|
9456
|
+
}
|
|
9457
|
+
async handle(request) {
|
|
9458
|
+
try {
|
|
9459
|
+
if (!request || typeof request !== "object") {
|
|
9460
|
+
throw new RuntimeProtocolException(
|
|
9461
|
+
"invalid_request",
|
|
9462
|
+
"Request must be an object"
|
|
9463
|
+
);
|
|
9464
|
+
}
|
|
9465
|
+
if (typeof request.operation !== "string" || !SUPPORTED_OPERATIONS.includes(
|
|
9466
|
+
request.operation
|
|
9467
|
+
)) {
|
|
9468
|
+
throw new RuntimeProtocolException(
|
|
9469
|
+
"unsupported_operation",
|
|
9470
|
+
`Unsupported operation: ${String(request.operation ?? "")}`
|
|
9471
|
+
);
|
|
9472
|
+
}
|
|
9473
|
+
const operation = request.operation;
|
|
9474
|
+
this.assertOperationAllowed(operation);
|
|
9475
|
+
const result = await this.dispatch(operation, request.payload);
|
|
9476
|
+
return {
|
|
9477
|
+
id: request.id,
|
|
9478
|
+
operation,
|
|
9479
|
+
ok: true,
|
|
9480
|
+
result: sanitizeForJson(result)
|
|
9481
|
+
};
|
|
9482
|
+
} catch (error) {
|
|
9483
|
+
const normalizedError = this.normalizeError(error);
|
|
9484
|
+
return {
|
|
9485
|
+
id: request?.id,
|
|
9486
|
+
operation: typeof request?.operation === "string" ? request.operation : "runtime.snapshot",
|
|
9487
|
+
ok: false,
|
|
9488
|
+
error: normalizedError
|
|
9489
|
+
};
|
|
9490
|
+
}
|
|
9491
|
+
}
|
|
9492
|
+
normalizeError(error) {
|
|
9493
|
+
if (error instanceof RuntimeSubscriptionManagerError) {
|
|
9494
|
+
return {
|
|
9495
|
+
code: error.code,
|
|
9496
|
+
message: error.message
|
|
9497
|
+
};
|
|
9498
|
+
}
|
|
9499
|
+
if (error instanceof RuntimeProtocolException) {
|
|
9500
|
+
return {
|
|
9501
|
+
code: error.code,
|
|
9502
|
+
message: error.message,
|
|
9503
|
+
details: error.details ? sanitizeForJson(error.details) : void 0
|
|
9504
|
+
};
|
|
9505
|
+
}
|
|
9506
|
+
if (error instanceof Error) {
|
|
9507
|
+
return {
|
|
9508
|
+
code: "runtime_error",
|
|
9509
|
+
message: error.message
|
|
9510
|
+
};
|
|
9511
|
+
}
|
|
9512
|
+
return {
|
|
9513
|
+
code: "runtime_error",
|
|
9514
|
+
message: String(error)
|
|
9515
|
+
};
|
|
9516
|
+
}
|
|
9517
|
+
async dispatch(operation, payload) {
|
|
9518
|
+
switch (operation) {
|
|
9519
|
+
case "runtime.bootstrap":
|
|
9520
|
+
return this.bootstrapRuntime(payload);
|
|
9521
|
+
case "runtime.info":
|
|
9522
|
+
return this.runtimeInfo();
|
|
9523
|
+
case "runtime.detach":
|
|
9524
|
+
return this.detachRuntime();
|
|
9525
|
+
case "runtime.shutdown":
|
|
9526
|
+
return this.shutdownRuntime();
|
|
9527
|
+
case "runtime.reset":
|
|
9528
|
+
return this.resetRuntime();
|
|
9529
|
+
case "runtime.snapshot":
|
|
9530
|
+
return Cadenza.snapshotRuntime();
|
|
9531
|
+
case "runtime.subscribe":
|
|
9532
|
+
return this.subscribe(payload);
|
|
9533
|
+
case "runtime.unsubscribe":
|
|
9534
|
+
return this.unsubscribe(payload);
|
|
9535
|
+
case "runtime.nextEvent":
|
|
9536
|
+
return this.nextEvent(payload);
|
|
9537
|
+
case "runtime.pollEvents":
|
|
9538
|
+
return this.pollEvents(payload);
|
|
9539
|
+
case "task.upsert":
|
|
9540
|
+
return this.upsertTask(payload);
|
|
9541
|
+
case "helper.upsert":
|
|
9542
|
+
return this.upsertHelper(payload);
|
|
9543
|
+
case "global.upsert":
|
|
9544
|
+
return this.upsertGlobal(payload);
|
|
9545
|
+
case "task.link":
|
|
9546
|
+
return this.linkTasks(payload);
|
|
9547
|
+
case "task.observeSignal":
|
|
9548
|
+
return this.observeTaskSignal(payload);
|
|
9549
|
+
case "task.emitSignal":
|
|
9550
|
+
return this.emitTaskSignal(payload);
|
|
9551
|
+
case "task.respondToIntent":
|
|
9552
|
+
return this.bindTaskIntent(payload);
|
|
9553
|
+
case "task.useHelper":
|
|
9554
|
+
return this.bindTaskHelper(payload);
|
|
9555
|
+
case "task.useGlobal":
|
|
9556
|
+
return this.bindTaskGlobal(payload);
|
|
9557
|
+
case "helper.useHelper":
|
|
9558
|
+
return this.bindHelperHelper(payload);
|
|
9559
|
+
case "helper.useGlobal":
|
|
9560
|
+
return this.bindHelperGlobal(payload);
|
|
9561
|
+
case "routine.upsert":
|
|
9562
|
+
return this.upsertRoutine(payload);
|
|
9563
|
+
case "routine.observeSignal":
|
|
9564
|
+
return this.observeRoutineSignal(payload);
|
|
9565
|
+
case "intent.upsert":
|
|
9566
|
+
return this.upsertIntent(payload);
|
|
9567
|
+
case "actor.upsert":
|
|
9568
|
+
return this.upsertActor(payload);
|
|
9569
|
+
case "actorTask.upsert":
|
|
9570
|
+
return this.upsertActorTask(payload);
|
|
9571
|
+
case "run":
|
|
9572
|
+
return this.runTarget(payload);
|
|
9573
|
+
case "emit":
|
|
9574
|
+
return this.emitSignal(payload);
|
|
9575
|
+
case "inquire":
|
|
9576
|
+
return this.inquireIntent(payload);
|
|
9577
|
+
}
|
|
9578
|
+
}
|
|
9579
|
+
assertOperationAllowed(operation) {
|
|
9580
|
+
if (!this.sessionRole) {
|
|
9581
|
+
return;
|
|
9582
|
+
}
|
|
9583
|
+
if (this.sessionRole === "owner") {
|
|
9584
|
+
return;
|
|
9585
|
+
}
|
|
9586
|
+
if (this.sessionRole === "writer") {
|
|
9587
|
+
if (operation === "runtime.reset" || operation === "runtime.shutdown") {
|
|
9588
|
+
throw new RuntimeProtocolException(
|
|
9589
|
+
"forbidden",
|
|
9590
|
+
`Session role "${this.sessionRole}" cannot perform ${operation}`
|
|
9591
|
+
);
|
|
9592
|
+
}
|
|
9593
|
+
return;
|
|
9594
|
+
}
|
|
9595
|
+
const observerOperations = /* @__PURE__ */ new Set([
|
|
9596
|
+
"runtime.info",
|
|
9597
|
+
"runtime.detach",
|
|
9598
|
+
"runtime.snapshot",
|
|
9599
|
+
"runtime.subscribe",
|
|
9600
|
+
"runtime.unsubscribe",
|
|
9601
|
+
"runtime.nextEvent",
|
|
9602
|
+
"runtime.pollEvents",
|
|
9603
|
+
"inquire"
|
|
9604
|
+
]);
|
|
9605
|
+
if (!observerOperations.has(operation)) {
|
|
9606
|
+
throw new RuntimeProtocolException(
|
|
9607
|
+
"forbidden",
|
|
9608
|
+
`Session role "${this.sessionRole}" cannot perform ${operation}`
|
|
9609
|
+
);
|
|
9610
|
+
}
|
|
9611
|
+
}
|
|
9612
|
+
bootstrapRuntime(payload) {
|
|
9613
|
+
const mode = isObject4(payload) && typeof payload.mode === "string" ? payload.mode : void 0;
|
|
9614
|
+
if (mode) {
|
|
9615
|
+
Cadenza.setMode(mode);
|
|
9616
|
+
} else {
|
|
9617
|
+
Cadenza.bootstrap();
|
|
9618
|
+
}
|
|
9619
|
+
return {
|
|
9620
|
+
bootstrapped: true,
|
|
9621
|
+
mode: Cadenza.mode
|
|
9622
|
+
};
|
|
9623
|
+
}
|
|
9624
|
+
runtimeInfo() {
|
|
9625
|
+
return {
|
|
9626
|
+
runtimeMode: "core",
|
|
9627
|
+
runtimeSharing: this.runtimeSharing,
|
|
9628
|
+
runtimeName: this.runtimeName,
|
|
9629
|
+
sessionId: this.sessionId,
|
|
9630
|
+
sessionRole: this.sessionRole,
|
|
9631
|
+
activeSessionCount: this.activeSessionCountProvider(),
|
|
9632
|
+
daemonProcessId: this.daemonProcessId,
|
|
9633
|
+
bootstrapped: Cadenza.isBootstrapped,
|
|
9634
|
+
mode: Cadenza.mode
|
|
9635
|
+
};
|
|
9636
|
+
}
|
|
9637
|
+
detachRuntime() {
|
|
9638
|
+
this.pendingControlAction = "detach";
|
|
9639
|
+
return {
|
|
9640
|
+
detached: true,
|
|
9641
|
+
runtimeName: this.runtimeName,
|
|
9642
|
+
sessionId: this.sessionId
|
|
9643
|
+
};
|
|
9644
|
+
}
|
|
9645
|
+
shutdownRuntime() {
|
|
9646
|
+
this.pendingControlAction = "shutdown";
|
|
9647
|
+
return {
|
|
9648
|
+
shutdown: true,
|
|
9649
|
+
runtimeName: this.runtimeName
|
|
9650
|
+
};
|
|
9651
|
+
}
|
|
9652
|
+
resetRuntime() {
|
|
9653
|
+
if (this.onResetRuntime) {
|
|
9654
|
+
this.onResetRuntime();
|
|
9655
|
+
} else {
|
|
9656
|
+
Cadenza.reset();
|
|
9657
|
+
this.subscriptionManager.reset();
|
|
9658
|
+
}
|
|
9659
|
+
return {
|
|
9660
|
+
reset: true,
|
|
9661
|
+
bootstrapped: false
|
|
9662
|
+
};
|
|
9663
|
+
}
|
|
9664
|
+
subscribe(payload) {
|
|
9665
|
+
assertObject(payload, "runtime.subscribe payload must be an object");
|
|
9666
|
+
const signalPatterns = this.parseSignalPatterns(payload.signalPatterns);
|
|
9667
|
+
const maxQueueSize = this.parsePositiveInteger(
|
|
9668
|
+
payload.maxQueueSize,
|
|
9669
|
+
"maxQueueSize",
|
|
9670
|
+
100
|
|
9671
|
+
);
|
|
9672
|
+
return {
|
|
9673
|
+
subscription: this.subscriptionManager.subscribe(signalPatterns, maxQueueSize)
|
|
9674
|
+
};
|
|
9675
|
+
}
|
|
9676
|
+
unsubscribe(payload) {
|
|
9677
|
+
assertObject(payload, "runtime.unsubscribe payload must be an object");
|
|
9678
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9679
|
+
return {
|
|
9680
|
+
unsubscribed: true,
|
|
9681
|
+
subscription: this.subscriptionManager.unsubscribe(subscriptionId)
|
|
9682
|
+
};
|
|
9683
|
+
}
|
|
9684
|
+
async nextEvent(payload) {
|
|
9685
|
+
assertObject(payload, "runtime.nextEvent payload must be an object");
|
|
9686
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9687
|
+
const timeoutMs = this.parseNonNegativeInteger(
|
|
9688
|
+
payload.timeoutMs,
|
|
9689
|
+
"timeoutMs",
|
|
9690
|
+
0
|
|
9691
|
+
);
|
|
9692
|
+
return this.subscriptionManager.nextEvent(subscriptionId, timeoutMs);
|
|
9693
|
+
}
|
|
9694
|
+
pollEvents(payload) {
|
|
9695
|
+
assertObject(payload, "runtime.pollEvents payload must be an object");
|
|
9696
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9697
|
+
const limit = this.parsePositiveInteger(payload.limit, "limit", 50);
|
|
9698
|
+
return this.subscriptionManager.pollEvents(subscriptionId, limit);
|
|
9699
|
+
}
|
|
9700
|
+
upsertTask(payload) {
|
|
9701
|
+
assertObject(payload, "task.upsert payload must be an object");
|
|
9702
|
+
const definition = payload;
|
|
9703
|
+
definition.name = assertString(definition.name, "name");
|
|
9704
|
+
definition.handlerSource = assertString(
|
|
9705
|
+
definition.handlerSource,
|
|
9706
|
+
"handlerSource"
|
|
9707
|
+
);
|
|
9708
|
+
definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
|
|
9709
|
+
throw new RuntimeProtocolException(
|
|
9710
|
+
"invalid_payload",
|
|
9711
|
+
"language must be 'js' or 'ts'"
|
|
9712
|
+
);
|
|
9713
|
+
})();
|
|
9714
|
+
definition.kind = definition.kind === "metaTask" ? "metaTask" : "task";
|
|
9715
|
+
runtimeDefinitionRegistry.setTaskDefinition(definition);
|
|
9716
|
+
const task = Cadenza.createTaskFromDefinition(definition);
|
|
9717
|
+
this.applyTaskDecorations(definition.name);
|
|
9718
|
+
this.applyAllTaskLinks();
|
|
9719
|
+
this.rematerializeRoutinesStartingWith(definition.name);
|
|
9720
|
+
return {
|
|
9721
|
+
task: this.snapshotTask(task)
|
|
9722
|
+
};
|
|
9723
|
+
}
|
|
9724
|
+
upsertHelper(payload) {
|
|
9725
|
+
assertObject(payload, "helper.upsert payload must be an object");
|
|
9726
|
+
const definition = payload;
|
|
9727
|
+
definition.name = assertString(definition.name, "name");
|
|
9728
|
+
definition.handlerSource = assertString(
|
|
9729
|
+
definition.handlerSource,
|
|
9730
|
+
"handlerSource"
|
|
9731
|
+
);
|
|
9732
|
+
definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
|
|
9733
|
+
throw new RuntimeProtocolException(
|
|
9734
|
+
"invalid_payload",
|
|
9735
|
+
"language must be 'js' or 'ts'"
|
|
9736
|
+
);
|
|
9737
|
+
})();
|
|
9738
|
+
definition.kind = definition.kind === "metaHelper" ? "metaHelper" : "helper";
|
|
9739
|
+
runtimeDefinitionRegistry.setHelperDefinition(definition);
|
|
9740
|
+
compileRuntimeHelperFunction(definition);
|
|
9741
|
+
Cadenza.createHelperFromDefinition(definition);
|
|
9742
|
+
this.applyHelperDecorations(definition.name);
|
|
9743
|
+
return {
|
|
9744
|
+
helper: this.snapshotHelper(definition.name)
|
|
9745
|
+
};
|
|
9746
|
+
}
|
|
9747
|
+
upsertGlobal(payload) {
|
|
9748
|
+
assertObject(payload, "global.upsert payload must be an object");
|
|
9749
|
+
const definition = {
|
|
9750
|
+
name: assertString(payload.name, "name"),
|
|
9751
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9752
|
+
kind: payload.kind === "metaGlobal" ? "metaGlobal" : "global",
|
|
9753
|
+
value: payload.value
|
|
9754
|
+
};
|
|
9755
|
+
runtimeDefinitionRegistry.setGlobalDefinition(definition);
|
|
9756
|
+
Cadenza.createGlobalFromDefinition(definition);
|
|
9757
|
+
return {
|
|
9758
|
+
global: this.snapshotGlobal(definition.name)
|
|
9759
|
+
};
|
|
9760
|
+
}
|
|
9761
|
+
linkTasks(payload) {
|
|
9762
|
+
assertObject(payload, "task.link payload must be an object");
|
|
9763
|
+
const definition = {
|
|
9764
|
+
predecessorTaskName: assertString(
|
|
9765
|
+
payload.predecessorTaskName,
|
|
9766
|
+
"predecessorTaskName"
|
|
9767
|
+
),
|
|
9768
|
+
successorTaskName: assertString(
|
|
9769
|
+
payload.successorTaskName,
|
|
9770
|
+
"successorTaskName"
|
|
9771
|
+
)
|
|
9772
|
+
};
|
|
9773
|
+
runtimeDefinitionRegistry.setTaskLink(definition);
|
|
9774
|
+
this.applyAllTaskLinks();
|
|
9775
|
+
return {
|
|
9776
|
+
linked: true,
|
|
9777
|
+
...definition
|
|
9778
|
+
};
|
|
9779
|
+
}
|
|
9780
|
+
observeTaskSignal(payload) {
|
|
9781
|
+
assertObject(payload, "task.observeSignal payload must be an object");
|
|
9782
|
+
const definition = {
|
|
9783
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9784
|
+
signal: normalizeSignalDefinition2(payload.signal)
|
|
9785
|
+
};
|
|
9786
|
+
runtimeDefinitionRegistry.setTaskSignalObservation(definition);
|
|
9787
|
+
this.requireTask(definition.taskName).doOn(definition.signal);
|
|
9788
|
+
return {
|
|
9789
|
+
observed: true,
|
|
9790
|
+
taskName: definition.taskName,
|
|
9791
|
+
signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
|
|
9792
|
+
};
|
|
9793
|
+
}
|
|
9794
|
+
emitTaskSignal(payload) {
|
|
9795
|
+
assertObject(payload, "task.emitSignal payload must be an object");
|
|
9796
|
+
const mode = payload.mode === "attach" || payload.mode === "onFail" ? payload.mode : "after";
|
|
9797
|
+
const definition = {
|
|
9798
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9799
|
+
signal: normalizeSignalDefinition2(payload.signal),
|
|
9800
|
+
mode
|
|
9801
|
+
};
|
|
9802
|
+
runtimeDefinitionRegistry.setTaskSignalEmission(definition);
|
|
9803
|
+
const task = this.requireTask(definition.taskName);
|
|
9804
|
+
if (definition.mode === "attach") {
|
|
9805
|
+
task.attachSignal(definition.signal);
|
|
9806
|
+
} else if (definition.mode === "onFail") {
|
|
9807
|
+
task.emitsOnFail(definition.signal);
|
|
9808
|
+
} else {
|
|
9809
|
+
task.emits(definition.signal);
|
|
9810
|
+
}
|
|
9811
|
+
return {
|
|
9812
|
+
attached: true,
|
|
9813
|
+
taskName: definition.taskName,
|
|
9814
|
+
mode: definition.mode,
|
|
9815
|
+
signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
|
|
9816
|
+
};
|
|
9817
|
+
}
|
|
9818
|
+
bindTaskIntent(payload) {
|
|
9819
|
+
assertObject(payload, "task.respondToIntent payload must be an object");
|
|
9820
|
+
const taskName = assertString(payload.taskName, "taskName");
|
|
9821
|
+
const intentName = assertString(payload.intentName, "intentName");
|
|
9822
|
+
runtimeDefinitionRegistry.setTaskIntentBinding({
|
|
9823
|
+
taskName,
|
|
9824
|
+
intentName
|
|
9825
|
+
});
|
|
9826
|
+
this.requireTask(taskName).respondsTo(intentName);
|
|
9827
|
+
return {
|
|
9828
|
+
bound: true,
|
|
9829
|
+
taskName,
|
|
9830
|
+
intentName
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
bindTaskHelper(payload) {
|
|
9834
|
+
assertObject(payload, "task.useHelper payload must be an object");
|
|
9835
|
+
const definition = {
|
|
9836
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9837
|
+
alias: assertString(payload.alias, "alias"),
|
|
9838
|
+
helperName: assertString(payload.helperName, "helperName")
|
|
9839
|
+
};
|
|
9840
|
+
runtimeDefinitionRegistry.setTaskHelperBinding(definition);
|
|
9841
|
+
this.requireTask(definition.taskName).usesHelpers({
|
|
9842
|
+
[definition.alias]: Cadenza.getHelper(definition.helperName)
|
|
9843
|
+
});
|
|
9844
|
+
return {
|
|
9845
|
+
bound: true,
|
|
9846
|
+
...definition
|
|
9847
|
+
};
|
|
9848
|
+
}
|
|
9849
|
+
bindTaskGlobal(payload) {
|
|
9850
|
+
assertObject(payload, "task.useGlobal payload must be an object");
|
|
9851
|
+
const definition = {
|
|
9852
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9853
|
+
alias: assertString(payload.alias, "alias"),
|
|
9854
|
+
globalName: assertString(payload.globalName, "globalName")
|
|
9855
|
+
};
|
|
9856
|
+
runtimeDefinitionRegistry.setTaskGlobalBinding(definition);
|
|
9857
|
+
this.requireTask(definition.taskName).usesGlobals({
|
|
9858
|
+
[definition.alias]: Cadenza.getGlobal(definition.globalName)
|
|
9859
|
+
});
|
|
9860
|
+
return {
|
|
9861
|
+
bound: true,
|
|
9862
|
+
...definition
|
|
9863
|
+
};
|
|
9864
|
+
}
|
|
9865
|
+
bindHelperHelper(payload) {
|
|
9866
|
+
assertObject(payload, "helper.useHelper payload must be an object");
|
|
9867
|
+
const definition = {
|
|
9868
|
+
helperName: assertString(payload.helperName, "helperName"),
|
|
9869
|
+
alias: assertString(payload.alias, "alias"),
|
|
9870
|
+
dependencyHelperName: assertString(
|
|
9871
|
+
payload.dependencyHelperName,
|
|
9872
|
+
"dependencyHelperName"
|
|
9873
|
+
)
|
|
9874
|
+
};
|
|
9875
|
+
runtimeDefinitionRegistry.setHelperHelperBinding(definition);
|
|
9876
|
+
const helper = Cadenza.getHelper(definition.helperName);
|
|
9877
|
+
if (!helper) {
|
|
9878
|
+
throw new RuntimeProtocolException(
|
|
9879
|
+
"not_found",
|
|
9880
|
+
`No helper named "${definition.helperName}" exists`
|
|
9881
|
+
);
|
|
9882
|
+
}
|
|
9883
|
+
helper.usesHelpers({
|
|
9884
|
+
[definition.alias]: Cadenza.getHelper(definition.dependencyHelperName)
|
|
9885
|
+
});
|
|
9886
|
+
return {
|
|
9887
|
+
bound: true,
|
|
9888
|
+
...definition
|
|
9889
|
+
};
|
|
9890
|
+
}
|
|
9891
|
+
bindHelperGlobal(payload) {
|
|
9892
|
+
assertObject(payload, "helper.useGlobal payload must be an object");
|
|
9893
|
+
const definition = {
|
|
9894
|
+
helperName: assertString(payload.helperName, "helperName"),
|
|
9895
|
+
alias: assertString(payload.alias, "alias"),
|
|
9896
|
+
globalName: assertString(payload.globalName, "globalName")
|
|
9897
|
+
};
|
|
9898
|
+
runtimeDefinitionRegistry.setHelperGlobalBinding(definition);
|
|
9899
|
+
const helper = Cadenza.getHelper(definition.helperName);
|
|
9900
|
+
if (!helper) {
|
|
9901
|
+
throw new RuntimeProtocolException(
|
|
9902
|
+
"not_found",
|
|
9903
|
+
`No helper named "${definition.helperName}" exists`
|
|
9904
|
+
);
|
|
9905
|
+
}
|
|
9906
|
+
helper.usesGlobals({
|
|
9907
|
+
[definition.alias]: Cadenza.getGlobal(definition.globalName)
|
|
9908
|
+
});
|
|
9909
|
+
return {
|
|
9910
|
+
bound: true,
|
|
9911
|
+
...definition
|
|
9912
|
+
};
|
|
9913
|
+
}
|
|
9914
|
+
upsertRoutine(payload) {
|
|
9915
|
+
assertObject(payload, "routine.upsert payload must be an object");
|
|
9916
|
+
const definition = {
|
|
9917
|
+
name: assertString(payload.name, "name"),
|
|
9918
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9919
|
+
startTaskNames: assertStringArray(payload.startTaskNames, "startTaskNames"),
|
|
9920
|
+
isMeta: payload.isMeta === true
|
|
9921
|
+
};
|
|
9922
|
+
if (definition.startTaskNames.length === 0) {
|
|
9923
|
+
throw new RuntimeProtocolException(
|
|
9924
|
+
"invalid_payload",
|
|
9925
|
+
"startTaskNames must contain at least one task name"
|
|
9926
|
+
);
|
|
9927
|
+
}
|
|
9928
|
+
runtimeDefinitionRegistry.setRoutineDefinition(definition);
|
|
9929
|
+
const routine = Cadenza.createRoutineFromDefinition(definition);
|
|
9930
|
+
this.applyRoutineDecorations(definition.name);
|
|
9931
|
+
return {
|
|
9932
|
+
routine: this.snapshotRoutine(routine)
|
|
9933
|
+
};
|
|
9934
|
+
}
|
|
9935
|
+
observeRoutineSignal(payload) {
|
|
9936
|
+
assertObject(payload, "routine.observeSignal payload must be an object");
|
|
9937
|
+
const routineName = assertString(payload.routineName, "routineName");
|
|
9938
|
+
const signal = assertString(payload.signal, "signal");
|
|
9939
|
+
runtimeDefinitionRegistry.setRoutineSignalObservation({
|
|
9940
|
+
routineName,
|
|
9941
|
+
signal
|
|
9942
|
+
});
|
|
9943
|
+
this.requireRoutine(routineName).doOn(signal);
|
|
9944
|
+
return {
|
|
9945
|
+
observed: true,
|
|
9946
|
+
routineName,
|
|
9947
|
+
signal
|
|
9948
|
+
};
|
|
9949
|
+
}
|
|
9950
|
+
upsertIntent(payload) {
|
|
9951
|
+
assertObject(payload, "intent.upsert payload must be an object");
|
|
9952
|
+
const intent = {
|
|
9953
|
+
name: assertString(payload.name, "name"),
|
|
9954
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9955
|
+
input: isObject4(payload.input) ? payload.input : { type: "object" },
|
|
9956
|
+
output: isObject4(payload.output) ? payload.output : { type: "object" }
|
|
9957
|
+
};
|
|
9958
|
+
runtimeDefinitionRegistry.setIntentDefinition(intent);
|
|
9959
|
+
Cadenza.defineIntent(intent);
|
|
9960
|
+
return {
|
|
9961
|
+
intent: sanitizeForJson(intent)
|
|
9962
|
+
};
|
|
9963
|
+
}
|
|
9964
|
+
upsertActor(payload) {
|
|
9965
|
+
assertObject(payload, "actor.upsert payload must be an object");
|
|
9966
|
+
const definition = payload;
|
|
9967
|
+
definition.name = assertString(definition.name, "name");
|
|
9968
|
+
definition.description = assertString(definition.description, "description");
|
|
9969
|
+
definition.defaultKey = assertString(definition.defaultKey, "defaultKey");
|
|
9970
|
+
runtimeDefinitionRegistry.setActorDefinition(definition);
|
|
9971
|
+
const actor = Cadenza.createActorFromDefinition(definition);
|
|
9972
|
+
this.rematerializeActorTasksFor(definition.name);
|
|
9973
|
+
return {
|
|
9974
|
+
actor: sanitizeForJson({
|
|
9975
|
+
name: actor.spec.name,
|
|
9976
|
+
description: actor.spec.description ?? "",
|
|
9977
|
+
defaultKey: actor.spec.defaultKey
|
|
9978
|
+
})
|
|
9979
|
+
};
|
|
9980
|
+
}
|
|
9981
|
+
upsertActorTask(payload) {
|
|
9982
|
+
assertObject(payload, "actorTask.upsert payload must be an object");
|
|
9983
|
+
const definition = {
|
|
9984
|
+
actorName: assertString(payload.actorName, "actorName"),
|
|
9985
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9986
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9987
|
+
mode: payload.mode === "write" || payload.mode === "meta" ? payload.mode : "read",
|
|
9988
|
+
handlerSource: assertString(payload.handlerSource, "handlerSource"),
|
|
9989
|
+
language: payload.language === "js" || payload.language === "ts" ? payload.language : (() => {
|
|
9990
|
+
throw new RuntimeProtocolException(
|
|
9991
|
+
"invalid_payload",
|
|
9992
|
+
"language must be 'js' or 'ts'"
|
|
9993
|
+
);
|
|
9994
|
+
})(),
|
|
9995
|
+
options: isObject4(payload.options) ? { ...payload.options } : void 0
|
|
9996
|
+
};
|
|
9997
|
+
runtimeDefinitionRegistry.setActorTaskDefinition(definition);
|
|
9998
|
+
const task = this.materializeActorTask(definition.taskName);
|
|
9999
|
+
this.applyTaskDecorations(definition.taskName);
|
|
10000
|
+
this.applyAllTaskLinks();
|
|
10001
|
+
this.rematerializeRoutinesStartingWith(definition.taskName);
|
|
10002
|
+
return {
|
|
10003
|
+
actorTask: this.snapshotTask(task)
|
|
10004
|
+
};
|
|
10005
|
+
}
|
|
10006
|
+
async runTarget(payload) {
|
|
10007
|
+
assertObject(payload, "run payload must be an object");
|
|
10008
|
+
const targetName = assertString(payload.targetName, "targetName");
|
|
10009
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10010
|
+
let target = Cadenza.getRoutine(targetName);
|
|
10011
|
+
if (!target) {
|
|
10012
|
+
const routineDefinition = runtimeDefinitionRegistry.routineDefinitions.get(targetName);
|
|
10013
|
+
if (routineDefinition) {
|
|
10014
|
+
target = Cadenza.createRoutineFromDefinition(routineDefinition);
|
|
10015
|
+
this.applyRoutineDecorations(targetName);
|
|
10016
|
+
}
|
|
10017
|
+
}
|
|
10018
|
+
target = target ?? Cadenza.get(targetName);
|
|
10019
|
+
if (!target) {
|
|
10020
|
+
throw new RuntimeProtocolException(
|
|
10021
|
+
"not_found",
|
|
10022
|
+
`No task or routine named "${targetName}" exists`
|
|
10023
|
+
);
|
|
10024
|
+
}
|
|
10025
|
+
const runner = "isMeta" in target && target.isMeta ? Cadenza.metaRunner : Cadenza.runner;
|
|
10026
|
+
const runResult = runner.run(target, context);
|
|
10027
|
+
const completedRun = await Promise.resolve(runResult);
|
|
10028
|
+
return {
|
|
10029
|
+
targetName,
|
|
10030
|
+
run: completedRun.export()
|
|
10031
|
+
};
|
|
10032
|
+
}
|
|
10033
|
+
emitSignal(payload) {
|
|
10034
|
+
assertObject(payload, "emit payload must be an object");
|
|
10035
|
+
const signal = assertString(payload.signal, "signal");
|
|
10036
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10037
|
+
const options = isObject4(payload.options) ? payload.options : {};
|
|
10038
|
+
Cadenza.emit(signal, context, options);
|
|
10039
|
+
return {
|
|
10040
|
+
emitted: true,
|
|
10041
|
+
signal
|
|
10042
|
+
};
|
|
10043
|
+
}
|
|
10044
|
+
async inquireIntent(payload) {
|
|
10045
|
+
assertObject(payload, "inquire payload must be an object");
|
|
10046
|
+
const inquiry = assertString(payload.intent, "intent");
|
|
10047
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10048
|
+
const options = isObject4(payload.options) ? payload.options : {};
|
|
10049
|
+
const response = await Cadenza.inquire(inquiry, context, options);
|
|
10050
|
+
return {
|
|
10051
|
+
inquiry,
|
|
10052
|
+
response
|
|
10053
|
+
};
|
|
10054
|
+
}
|
|
10055
|
+
requireTask(taskName) {
|
|
10056
|
+
const task = Cadenza.get(taskName);
|
|
10057
|
+
if (!task) {
|
|
10058
|
+
throw new RuntimeProtocolException(
|
|
10059
|
+
"not_found",
|
|
10060
|
+
`No task named "${taskName}" exists`
|
|
10061
|
+
);
|
|
10062
|
+
}
|
|
10063
|
+
return task;
|
|
10064
|
+
}
|
|
10065
|
+
requireRoutine(routineName) {
|
|
10066
|
+
const routine = Cadenza.getRoutine(routineName);
|
|
10067
|
+
if (!routine) {
|
|
10068
|
+
throw new RuntimeProtocolException(
|
|
10069
|
+
"not_found",
|
|
10070
|
+
`No routine named "${routineName}" exists`
|
|
10071
|
+
);
|
|
10072
|
+
}
|
|
10073
|
+
return routine;
|
|
10074
|
+
}
|
|
10075
|
+
applyTaskDecorations(taskName) {
|
|
10076
|
+
const task = this.requireTask(taskName);
|
|
10077
|
+
for (const observation of runtimeDefinitionRegistry.taskSignalObservations.values()) {
|
|
10078
|
+
if (observation.taskName !== taskName) {
|
|
10079
|
+
continue;
|
|
10080
|
+
}
|
|
10081
|
+
task.doOn(observation.signal);
|
|
10082
|
+
}
|
|
10083
|
+
for (const emission of runtimeDefinitionRegistry.taskSignalEmissions.values()) {
|
|
10084
|
+
if (emission.taskName !== taskName) {
|
|
10085
|
+
continue;
|
|
10086
|
+
}
|
|
10087
|
+
if (emission.mode === "attach") {
|
|
10088
|
+
task.attachSignal(emission.signal);
|
|
10089
|
+
} else if (emission.mode === "onFail") {
|
|
10090
|
+
task.emitsOnFail(emission.signal);
|
|
10091
|
+
} else {
|
|
10092
|
+
task.emits(emission.signal);
|
|
10093
|
+
}
|
|
10094
|
+
}
|
|
10095
|
+
for (const binding of runtimeDefinitionRegistry.taskIntentBindings.values()) {
|
|
10096
|
+
if (binding.taskName !== taskName) {
|
|
10097
|
+
continue;
|
|
10098
|
+
}
|
|
10099
|
+
task.respondsTo(binding.intentName);
|
|
10100
|
+
}
|
|
10101
|
+
for (const binding of runtimeDefinitionRegistry.taskHelperBindings.values()) {
|
|
10102
|
+
if (binding.taskName !== taskName) {
|
|
10103
|
+
continue;
|
|
10104
|
+
}
|
|
10105
|
+
task.usesHelpers({
|
|
10106
|
+
[binding.alias]: Cadenza.getHelper(binding.helperName)
|
|
10107
|
+
});
|
|
10108
|
+
}
|
|
10109
|
+
for (const binding of runtimeDefinitionRegistry.taskGlobalBindings.values()) {
|
|
10110
|
+
if (binding.taskName !== taskName) {
|
|
10111
|
+
continue;
|
|
10112
|
+
}
|
|
10113
|
+
task.usesGlobals({
|
|
10114
|
+
[binding.alias]: Cadenza.getGlobal(binding.globalName)
|
|
10115
|
+
});
|
|
10116
|
+
}
|
|
10117
|
+
}
|
|
10118
|
+
applyHelperDecorations(helperName) {
|
|
10119
|
+
const helper = Cadenza.getHelper(helperName);
|
|
10120
|
+
if (!helper) {
|
|
10121
|
+
throw new RuntimeProtocolException(
|
|
10122
|
+
"not_found",
|
|
10123
|
+
`No helper named "${helperName}" exists`
|
|
10124
|
+
);
|
|
10125
|
+
}
|
|
10126
|
+
for (const binding of runtimeDefinitionRegistry.helperHelperBindings.values()) {
|
|
10127
|
+
if (binding.helperName !== helperName) {
|
|
10128
|
+
continue;
|
|
10129
|
+
}
|
|
10130
|
+
helper.usesHelpers({
|
|
10131
|
+
[binding.alias]: Cadenza.getHelper(binding.dependencyHelperName)
|
|
10132
|
+
});
|
|
10133
|
+
}
|
|
10134
|
+
for (const binding of runtimeDefinitionRegistry.helperGlobalBindings.values()) {
|
|
10135
|
+
if (binding.helperName !== helperName) {
|
|
10136
|
+
continue;
|
|
10137
|
+
}
|
|
10138
|
+
helper.usesGlobals({
|
|
10139
|
+
[binding.alias]: Cadenza.getGlobal(binding.globalName)
|
|
10140
|
+
});
|
|
10141
|
+
}
|
|
10142
|
+
}
|
|
10143
|
+
applyAllTaskLinks() {
|
|
10144
|
+
for (const link of runtimeDefinitionRegistry.taskLinks.values()) {
|
|
10145
|
+
const predecessor = Cadenza.get(link.predecessorTaskName);
|
|
10146
|
+
const successor = Cadenza.get(link.successorTaskName);
|
|
10147
|
+
if (!predecessor || !successor) {
|
|
10148
|
+
continue;
|
|
10149
|
+
}
|
|
10150
|
+
predecessor.then(successor);
|
|
10151
|
+
}
|
|
10152
|
+
}
|
|
10153
|
+
applyRoutineDecorations(routineName) {
|
|
10154
|
+
const routine = this.requireRoutine(routineName);
|
|
10155
|
+
for (const observation of runtimeDefinitionRegistry.routineSignalObservations.values()) {
|
|
10156
|
+
if (observation.routineName !== routineName) {
|
|
10157
|
+
continue;
|
|
10158
|
+
}
|
|
10159
|
+
routine.doOn(observation.signal);
|
|
10160
|
+
}
|
|
10161
|
+
}
|
|
10162
|
+
rematerializeRoutinesStartingWith(taskName) {
|
|
10163
|
+
for (const definition of runtimeDefinitionRegistry.routineDefinitions.values()) {
|
|
10164
|
+
if (!definition.startTaskNames.includes(taskName)) {
|
|
10165
|
+
continue;
|
|
10166
|
+
}
|
|
10167
|
+
const recreated = Cadenza.createRoutineFromDefinition(definition);
|
|
10168
|
+
this.applyRoutineDecorations(recreated.name);
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10171
|
+
rematerializeActorTasksFor(actorName) {
|
|
10172
|
+
for (const definition of runtimeDefinitionRegistry.actorTaskDefinitions.values()) {
|
|
10173
|
+
if (definition.actorName !== actorName) {
|
|
10174
|
+
continue;
|
|
10175
|
+
}
|
|
10176
|
+
this.materializeActorTask(definition.taskName);
|
|
10177
|
+
this.applyTaskDecorations(definition.taskName);
|
|
10178
|
+
this.applyAllTaskLinks();
|
|
10179
|
+
this.rematerializeRoutinesStartingWith(definition.taskName);
|
|
10180
|
+
}
|
|
10181
|
+
}
|
|
10182
|
+
materializeActorTask(taskName) {
|
|
10183
|
+
const definition = runtimeDefinitionRegistry.actorTaskDefinitions.get(taskName);
|
|
10184
|
+
if (!definition) {
|
|
10185
|
+
throw new RuntimeProtocolException(
|
|
10186
|
+
"not_found",
|
|
10187
|
+
`No actor task definition named "${taskName}" exists`
|
|
10188
|
+
);
|
|
10189
|
+
}
|
|
10190
|
+
const actor = Cadenza.getActor(definition.actorName);
|
|
10191
|
+
if (!actor) {
|
|
10192
|
+
throw new RuntimeProtocolException(
|
|
10193
|
+
"not_found",
|
|
10194
|
+
`No actor named "${definition.actorName}" exists`
|
|
10195
|
+
);
|
|
10196
|
+
}
|
|
10197
|
+
const existingTask = Cadenza.get(definition.taskName);
|
|
10198
|
+
if (existingTask && !runtimeDefinitionRegistry.isRuntimeOwnedTask(existingTask.name)) {
|
|
10199
|
+
throw new RuntimeProtocolException(
|
|
10200
|
+
"conflict",
|
|
10201
|
+
`Task "${definition.taskName}" already exists and is not runtime-owned`
|
|
10202
|
+
);
|
|
10203
|
+
}
|
|
10204
|
+
existingTask?.destroy();
|
|
10205
|
+
const handler = compileRuntimeActorTaskHandler(definition);
|
|
10206
|
+
return Cadenza.createTask(
|
|
10207
|
+
definition.taskName,
|
|
10208
|
+
actor.task(handler, { mode: definition.mode }),
|
|
10209
|
+
definition.description ?? "",
|
|
10210
|
+
definition.options ?? {}
|
|
10211
|
+
);
|
|
10212
|
+
}
|
|
10213
|
+
snapshotTask(task) {
|
|
10214
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10215
|
+
const existing = snapshot.tasks.find((entry) => entry.name === task.name);
|
|
10216
|
+
if (existing) {
|
|
10217
|
+
return existing;
|
|
10218
|
+
}
|
|
10219
|
+
const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
|
|
10220
|
+
task.name
|
|
10221
|
+
);
|
|
10222
|
+
const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
|
|
10223
|
+
return {
|
|
10224
|
+
name: task.name,
|
|
10225
|
+
version: task.version,
|
|
10226
|
+
description: task.description,
|
|
10227
|
+
kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
|
|
10228
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name),
|
|
10229
|
+
language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
|
|
10230
|
+
handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
|
|
10231
|
+
tools: {
|
|
10232
|
+
helpers: Object.fromEntries(task.helperAliases),
|
|
10233
|
+
globals: Object.fromEntries(task.globalAliases)
|
|
10234
|
+
}
|
|
10235
|
+
};
|
|
10236
|
+
}
|
|
10237
|
+
snapshotHelper(helperName) {
|
|
10238
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10239
|
+
return snapshot.helpers.find((entry) => entry.name === helperName) ?? {
|
|
10240
|
+
name: helperName
|
|
10241
|
+
};
|
|
10242
|
+
}
|
|
10243
|
+
snapshotGlobal(globalName) {
|
|
10244
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10245
|
+
return snapshot.globals.find((entry) => entry.name === globalName) ?? {
|
|
10246
|
+
name: globalName
|
|
10247
|
+
};
|
|
10248
|
+
}
|
|
10249
|
+
snapshotRoutine(routine) {
|
|
10250
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10251
|
+
return snapshot.routines.find((entry) => entry.name === routine.name) ?? {
|
|
10252
|
+
name: routine.name,
|
|
10253
|
+
version: routine.version,
|
|
10254
|
+
description: routine.description,
|
|
10255
|
+
isMeta: routine.isMeta,
|
|
10256
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(
|
|
10257
|
+
routine.name
|
|
10258
|
+
),
|
|
10259
|
+
startTaskNames: Array.from(routine.tasks).map((task) => task.name),
|
|
10260
|
+
observedSignals: Array.from(routine.observedSignals)
|
|
10261
|
+
};
|
|
10262
|
+
}
|
|
10263
|
+
parseSignalPatterns(value) {
|
|
10264
|
+
if (value === void 0) {
|
|
10265
|
+
return ["*"];
|
|
10266
|
+
}
|
|
10267
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
|
|
10268
|
+
throw new RuntimeProtocolException(
|
|
10269
|
+
"invalid_payload",
|
|
10270
|
+
"signalPatterns must be an array of non-empty strings"
|
|
10271
|
+
);
|
|
10272
|
+
}
|
|
10273
|
+
return Array.from(new Set(value.map((entry) => entry.trim())));
|
|
10274
|
+
}
|
|
10275
|
+
parsePositiveInteger(value, fieldName, fallback) {
|
|
10276
|
+
if (value === void 0) {
|
|
10277
|
+
return fallback;
|
|
10278
|
+
}
|
|
10279
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
10280
|
+
throw new RuntimeProtocolException(
|
|
10281
|
+
"invalid_payload",
|
|
10282
|
+
`${fieldName} must be a positive integer`
|
|
10283
|
+
);
|
|
10284
|
+
}
|
|
10285
|
+
return value;
|
|
10286
|
+
}
|
|
10287
|
+
parseNonNegativeInteger(value, fieldName, fallback) {
|
|
10288
|
+
if (value === void 0) {
|
|
10289
|
+
return fallback;
|
|
10290
|
+
}
|
|
10291
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
10292
|
+
throw new RuntimeProtocolException(
|
|
10293
|
+
"invalid_payload",
|
|
10294
|
+
`${fieldName} must be a non-negative integer`
|
|
10295
|
+
);
|
|
10296
|
+
}
|
|
10297
|
+
return value;
|
|
10298
|
+
}
|
|
10299
|
+
};
|
|
10300
|
+
|
|
7908
10301
|
// src/index.ts
|
|
7909
10302
|
var index_default = Cadenza;
|
|
7910
10303
|
export {
|
|
7911
10304
|
Actor,
|
|
7912
10305
|
DebounceTask,
|
|
7913
10306
|
EphemeralTask,
|
|
10307
|
+
GlobalDefinition,
|
|
7914
10308
|
GraphContext,
|
|
7915
10309
|
GraphRegistry,
|
|
7916
10310
|
GraphRoutine,
|
|
7917
10311
|
GraphRun,
|
|
7918
10312
|
GraphRunner,
|
|
10313
|
+
HelperDefinition,
|
|
7919
10314
|
InquiryBroker,
|
|
7920
10315
|
META_ACTOR_SESSION_STATE_PERSIST_INTENT,
|
|
10316
|
+
RuntimeHost,
|
|
7921
10317
|
SignalBroker,
|
|
7922
10318
|
SignalEmitter,
|
|
7923
10319
|
Task,
|