@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.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -23,13 +33,16 @@ __export(index_exports, {
|
|
|
23
33
|
Actor: () => Actor,
|
|
24
34
|
DebounceTask: () => DebounceTask,
|
|
25
35
|
EphemeralTask: () => EphemeralTask,
|
|
36
|
+
GlobalDefinition: () => GlobalDefinition,
|
|
26
37
|
GraphContext: () => GraphContext,
|
|
27
38
|
GraphRegistry: () => GraphRegistry,
|
|
28
39
|
GraphRoutine: () => GraphRoutine,
|
|
29
40
|
GraphRun: () => GraphRun,
|
|
30
41
|
GraphRunner: () => GraphRunner,
|
|
42
|
+
HelperDefinition: () => HelperDefinition,
|
|
31
43
|
InquiryBroker: () => InquiryBroker,
|
|
32
44
|
META_ACTOR_SESSION_STATE_PERSIST_INTENT: () => META_ACTOR_SESSION_STATE_PERSIST_INTENT,
|
|
45
|
+
RuntimeHost: () => RuntimeHost,
|
|
33
46
|
SignalBroker: () => SignalBroker,
|
|
34
47
|
SignalEmitter: () => SignalEmitter,
|
|
35
48
|
Task: () => Task,
|
|
@@ -1281,6 +1294,7 @@ var SignalBroker = class _SignalBroker {
|
|
|
1281
1294
|
this.signalObservers = /* @__PURE__ */ new Map();
|
|
1282
1295
|
this.emittedSignalsRegistry = /* @__PURE__ */ new Set();
|
|
1283
1296
|
this.signalMetadataRegistry = /* @__PURE__ */ new Map();
|
|
1297
|
+
this.passiveSignalListeners = /* @__PURE__ */ new Map();
|
|
1284
1298
|
// ── Flush Strategy Management ───────────────────────────────────────
|
|
1285
1299
|
this.flushStrategies = /* @__PURE__ */ new Map();
|
|
1286
1300
|
this.strategyData = /* @__PURE__ */ new Map();
|
|
@@ -1361,6 +1375,20 @@ var SignalBroker = class _SignalBroker {
|
|
|
1361
1375
|
console.log(
|
|
1362
1376
|
` \u2022 emittedSignalsRegistry size: ${this.emittedSignalsRegistry.size}`
|
|
1363
1377
|
);
|
|
1378
|
+
const exactSignalEntries = Array.from(this.signalObservers.entries()).filter(([signal]) => signal.includes(":")).sort((left, right) => {
|
|
1379
|
+
const taskDelta = right[1].tasks.size - left[1].tasks.size;
|
|
1380
|
+
if (taskDelta !== 0) {
|
|
1381
|
+
return taskDelta;
|
|
1382
|
+
}
|
|
1383
|
+
return left[0].localeCompare(right[0]);
|
|
1384
|
+
});
|
|
1385
|
+
console.log(` \u2022 exact signal observer entries: ${exactSignalEntries.length}`);
|
|
1386
|
+
for (const [signal, observer] of exactSignalEntries.slice(0, 8)) {
|
|
1387
|
+
const sampleTaskNames = Array.from(observer.tasks).slice(0, 3).map((task) => task.name);
|
|
1388
|
+
console.log(
|
|
1389
|
+
` - ${signal} (${observer.tasks.size} tasks) sample=${sampleTaskNames.join(", ")}`
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1364
1392
|
let totalSquashContexts = 0;
|
|
1365
1393
|
let totalSquashGroups = 0;
|
|
1366
1394
|
for (const groups of this.strategyData.values()) {
|
|
@@ -1774,7 +1802,7 @@ var SignalBroker = class _SignalBroker {
|
|
|
1774
1802
|
this.schedule(signal, context, options);
|
|
1775
1803
|
return;
|
|
1776
1804
|
}
|
|
1777
|
-
this.
|
|
1805
|
+
this.validateSignalName(signal);
|
|
1778
1806
|
this.execute(signal, context);
|
|
1779
1807
|
}
|
|
1780
1808
|
/**
|
|
@@ -1853,6 +1881,7 @@ var SignalBroker = class _SignalBroker {
|
|
|
1853
1881
|
...context.__metadata,
|
|
1854
1882
|
__executionTraceId: executionTraceId
|
|
1855
1883
|
};
|
|
1884
|
+
this.notifyPassiveSignalListeners(signal, context);
|
|
1856
1885
|
if (this.debug && (!isMetric && !isSubMeta || this.verbose)) {
|
|
1857
1886
|
console.log(
|
|
1858
1887
|
`EMITTING ${signal} to listeners ${this.signalObservers.get(signal)?.tasks.size ?? 0} with context ${this.verbose ? JSON.stringify(context) : JSON.stringify(context).slice(0, 100)}`
|
|
@@ -1950,11 +1979,37 @@ var SignalBroker = class _SignalBroker {
|
|
|
1950
1979
|
this.addSignal(signal, metadata);
|
|
1951
1980
|
this.signalObservers.get(signal).tasks.add(routineOrTask);
|
|
1952
1981
|
}
|
|
1982
|
+
addPassiveSignalListener(listener) {
|
|
1983
|
+
const listenerId = (0, import_uuid.v4)();
|
|
1984
|
+
this.passiveSignalListeners.set(listenerId, listener);
|
|
1985
|
+
return () => {
|
|
1986
|
+
this.passiveSignalListeners.delete(listenerId);
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
notifyPassiveSignalListeners(signal, context) {
|
|
1990
|
+
if (this.passiveSignalListeners.size === 0) {
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
const metadata = this.getSignalMetadata(signal) ?? null;
|
|
1994
|
+
for (const listener of this.passiveSignalListeners.values()) {
|
|
1995
|
+
try {
|
|
1996
|
+
listener(signal, context, metadata);
|
|
1997
|
+
} catch (error) {
|
|
1998
|
+
if (this.debug) {
|
|
1999
|
+
console.error("Passive signal listener failed", error);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
1953
2004
|
registerEmittedSignal(signal, metadata) {
|
|
2005
|
+
const signalKey = this.resolveSignalMetadataKey(signal);
|
|
2006
|
+
if (!signalKey) {
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
1954
2009
|
if (metadata) {
|
|
1955
|
-
this.setSignalMetadata(
|
|
2010
|
+
this.setSignalMetadata(signalKey, metadata);
|
|
1956
2011
|
}
|
|
1957
|
-
this.emittedSignalsRegistry.add(
|
|
2012
|
+
this.emittedSignalsRegistry.add(signalKey);
|
|
1958
2013
|
}
|
|
1959
2014
|
/**
|
|
1960
2015
|
* Unsubscribes a routine/task from a signal.
|
|
@@ -3014,16 +3069,17 @@ var GraphNode = class _GraphNode extends SignalEmitter {
|
|
|
3014
3069
|
* @return {void} Does not return a value.
|
|
3015
3070
|
*/
|
|
3016
3071
|
finalize() {
|
|
3072
|
+
const context = this.context?.getFullContext?.() ?? {};
|
|
3017
3073
|
if (this.nextNodes.length === 0) {
|
|
3018
3074
|
this.completeSubgraph();
|
|
3019
3075
|
}
|
|
3020
3076
|
if (this.errored || this.failed) {
|
|
3021
3077
|
this.task.mapOnFailSignals(
|
|
3022
|
-
(signal) => this.emitWithMetadata(signal,
|
|
3078
|
+
(signal) => this.emitWithMetadata(signal, { ...context })
|
|
3023
3079
|
);
|
|
3024
3080
|
} else if (this.result !== void 0 && this.result !== false) {
|
|
3025
3081
|
this.task.mapSignals(
|
|
3026
|
-
(signal) => this.emitWithMetadata(signal,
|
|
3082
|
+
(signal) => this.emitWithMetadata(signal, { ...context })
|
|
3027
3083
|
);
|
|
3028
3084
|
}
|
|
3029
3085
|
this.end();
|
|
@@ -3037,8 +3093,9 @@ var GraphNode = class _GraphNode extends SignalEmitter {
|
|
|
3037
3093
|
*/
|
|
3038
3094
|
onError(error, errorData = {}) {
|
|
3039
3095
|
const normalizedError = normalizeGraphErrorMessage(error);
|
|
3096
|
+
const context = this.context?.getFullContext?.() ?? {};
|
|
3040
3097
|
this.result = {
|
|
3041
|
-
...
|
|
3098
|
+
...context,
|
|
3042
3099
|
__error: `Node error: ${normalizedError}`,
|
|
3043
3100
|
__retries: this.retries,
|
|
3044
3101
|
error: `Node error: ${normalizedError}`,
|
|
@@ -3893,6 +3950,7 @@ var Actor = class {
|
|
|
3893
3950
|
this.stateByKey = /* @__PURE__ */ new Map();
|
|
3894
3951
|
this.sessionByKey = /* @__PURE__ */ new Map();
|
|
3895
3952
|
this.idempotencyByKey = /* @__PURE__ */ new Map();
|
|
3953
|
+
this.pendingHydrationByKey = /* @__PURE__ */ new Map();
|
|
3896
3954
|
this.writeQueueByKey = /* @__PURE__ */ new Map();
|
|
3897
3955
|
this.nextTaskBindingIndex = 0;
|
|
3898
3956
|
if (!spec.name || typeof spec.name !== "string") {
|
|
@@ -3904,6 +3962,7 @@ var Actor = class {
|
|
|
3904
3962
|
}
|
|
3905
3963
|
this.kind = options.isMeta || spec.kind === "meta" ? "meta" : "standard";
|
|
3906
3964
|
this.sourceDefinition = options.definitionSource;
|
|
3965
|
+
this.hydrateDurableState = options.hydrateDurableState;
|
|
3907
3966
|
this.spec = {
|
|
3908
3967
|
...spec,
|
|
3909
3968
|
defaultKey: normalizedDefaultKey,
|
|
@@ -3920,7 +3979,13 @@ var Actor = class {
|
|
|
3920
3979
|
task(handler, bindingOptions = {}) {
|
|
3921
3980
|
const mode = bindingOptions.mode ?? "read";
|
|
3922
3981
|
const taskBindingId = `${this.spec.name}:${++this.nextTaskBindingIndex}`;
|
|
3923
|
-
const wrapped = (context, emit, inquire, progressCallback) => {
|
|
3982
|
+
const wrapped = (context, emit, inquire, tools, progressCallback) => {
|
|
3983
|
+
const resolvedTools = tools && typeof tools === "object" && !Array.isArray(tools) && "helpers" in tools && "globals" in tools ? tools : {
|
|
3984
|
+
helpers: {},
|
|
3985
|
+
globals: {}
|
|
3986
|
+
};
|
|
3987
|
+
const resolvedProgressCallback = typeof progressCallback === "function" ? progressCallback : typeof tools === "function" ? tools : () => {
|
|
3988
|
+
};
|
|
3924
3989
|
const normalizedInput = this.normalizeInputContext(context);
|
|
3925
3990
|
const invocationOptions = this.resolveInvocationOptions(
|
|
3926
3991
|
context,
|
|
@@ -3931,7 +3996,7 @@ var Actor = class {
|
|
|
3931
3996
|
this.pruneExpiredActorKeys(now2);
|
|
3932
3997
|
this.touchSession(actorKey, invocationOptions.touchSession, now2);
|
|
3933
3998
|
const runTask = async () => {
|
|
3934
|
-
const stateRecord = this.
|
|
3999
|
+
const stateRecord = await this.maybeHydrateStateRecord(actorKey);
|
|
3935
4000
|
stateRecord.lastReadAt = Date.now();
|
|
3936
4001
|
let durableStateChanged = false;
|
|
3937
4002
|
let runtimeStateChanged = false;
|
|
@@ -4040,7 +4105,8 @@ var Actor = class {
|
|
|
4040
4105
|
patchRuntimeState,
|
|
4041
4106
|
reduceRuntimeState,
|
|
4042
4107
|
emit: (signal, payload = {}) => emit(signal, payload),
|
|
4043
|
-
inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options)
|
|
4108
|
+
inquire: (inquiryName, inquiryContext = {}, options = {}) => inquire(inquiryName, inquiryContext, options),
|
|
4109
|
+
tools: resolvedTools
|
|
4044
4110
|
};
|
|
4045
4111
|
const handlerResult = await handler(actorContext);
|
|
4046
4112
|
if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
|
|
@@ -4067,7 +4133,7 @@ var Actor = class {
|
|
|
4067
4133
|
stateRecord.lastRuntimeWriteAt = writeTimestamp;
|
|
4068
4134
|
}
|
|
4069
4135
|
this.touchSession(actorKey, invocationOptions.touchSession, Date.now());
|
|
4070
|
-
|
|
4136
|
+
resolvedProgressCallback(100);
|
|
4071
4137
|
if (invocationOptions.writeContract === "reducer" && typeof handlerResult === "function") {
|
|
4072
4138
|
return cloneForDurableState(stateRecord.durableState);
|
|
4073
4139
|
}
|
|
@@ -4111,6 +4177,13 @@ var Actor = class {
|
|
|
4111
4177
|
this.pruneExpiredActorKeys(Date.now());
|
|
4112
4178
|
return this.ensureStateRecord(key).runtimeState;
|
|
4113
4179
|
}
|
|
4180
|
+
/**
|
|
4181
|
+
* Lists all currently materialized actor keys.
|
|
4182
|
+
*/
|
|
4183
|
+
listActorKeys() {
|
|
4184
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4185
|
+
return Array.from(this.stateByKey.keys()).sort();
|
|
4186
|
+
}
|
|
4114
4187
|
/**
|
|
4115
4188
|
* Alias of `getDurableVersion`.
|
|
4116
4189
|
*/
|
|
@@ -4173,6 +4246,7 @@ var Actor = class {
|
|
|
4173
4246
|
this.stateByKey.clear();
|
|
4174
4247
|
this.sessionByKey.clear();
|
|
4175
4248
|
this.idempotencyByKey.clear();
|
|
4249
|
+
this.pendingHydrationByKey.clear();
|
|
4176
4250
|
if ((this.spec.loadPolicy ?? "eager") === "eager") {
|
|
4177
4251
|
this.ensureStateRecord(this.spec.defaultKey);
|
|
4178
4252
|
}
|
|
@@ -4184,6 +4258,7 @@ var Actor = class {
|
|
|
4184
4258
|
}
|
|
4185
4259
|
this.stateByKey.delete(normalizedKey);
|
|
4186
4260
|
this.sessionByKey.delete(normalizedKey);
|
|
4261
|
+
this.pendingHydrationByKey.delete(normalizedKey);
|
|
4187
4262
|
for (const key of this.idempotencyByKey.keys()) {
|
|
4188
4263
|
if (key.startsWith(`${normalizedKey}:`)) {
|
|
4189
4264
|
this.idempotencyByKey.delete(key);
|
|
@@ -4269,6 +4344,7 @@ var Actor = class {
|
|
|
4269
4344
|
runtimeState: this.resolveInitialRuntimeState(),
|
|
4270
4345
|
version: 0,
|
|
4271
4346
|
runtimeVersion: 0,
|
|
4347
|
+
hydrationResolved: this.hydrateDurableState === void 0,
|
|
4272
4348
|
createdAt: now2,
|
|
4273
4349
|
lastReadAt: now2,
|
|
4274
4350
|
lastDurableWriteAt: now2,
|
|
@@ -4278,6 +4354,54 @@ var Actor = class {
|
|
|
4278
4354
|
this.touchSession(actorKey, true, now2);
|
|
4279
4355
|
return record;
|
|
4280
4356
|
}
|
|
4357
|
+
async maybeHydrateStateRecord(actorKey) {
|
|
4358
|
+
const record = this.ensureStateRecord(actorKey);
|
|
4359
|
+
if (record.hydrationResolved || !this.hydrateDurableState) {
|
|
4360
|
+
return record;
|
|
4361
|
+
}
|
|
4362
|
+
const pending = this.pendingHydrationByKey.get(actorKey);
|
|
4363
|
+
if (pending) {
|
|
4364
|
+
return pending;
|
|
4365
|
+
}
|
|
4366
|
+
let hydrationPromise;
|
|
4367
|
+
hydrationPromise = (async () => {
|
|
4368
|
+
const current = this.ensureStateRecord(actorKey);
|
|
4369
|
+
if (current.hydrationResolved || !this.hydrateDurableState) {
|
|
4370
|
+
return current;
|
|
4371
|
+
}
|
|
4372
|
+
const snapshot = await this.hydrateDurableState(actorKey);
|
|
4373
|
+
const latest = this.ensureStateRecord(actorKey);
|
|
4374
|
+
if (latest.hydrationResolved) {
|
|
4375
|
+
return latest;
|
|
4376
|
+
}
|
|
4377
|
+
if (snapshot) {
|
|
4378
|
+
const durableVersion = Number(snapshot.durableVersion);
|
|
4379
|
+
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
4380
|
+
throw new Error(
|
|
4381
|
+
`Actor "${this.spec.name}" received invalid hydrated durable version for key "${actorKey}"`
|
|
4382
|
+
);
|
|
4383
|
+
}
|
|
4384
|
+
if (!isObject2(snapshot.durableState) || Array.isArray(snapshot.durableState)) {
|
|
4385
|
+
throw new Error(
|
|
4386
|
+
`Actor "${this.spec.name}" received invalid hydrated durable state for key "${actorKey}"`
|
|
4387
|
+
);
|
|
4388
|
+
}
|
|
4389
|
+
const hydratedAt = Date.now();
|
|
4390
|
+
latest.durableState = cloneForDurableState(snapshot.durableState);
|
|
4391
|
+
latest.version = durableVersion;
|
|
4392
|
+
latest.lastReadAt = hydratedAt;
|
|
4393
|
+
latest.lastDurableWriteAt = hydratedAt;
|
|
4394
|
+
}
|
|
4395
|
+
latest.hydrationResolved = true;
|
|
4396
|
+
return latest;
|
|
4397
|
+
})().finally(() => {
|
|
4398
|
+
if (this.pendingHydrationByKey.get(actorKey) === hydrationPromise) {
|
|
4399
|
+
this.pendingHydrationByKey.delete(actorKey);
|
|
4400
|
+
}
|
|
4401
|
+
});
|
|
4402
|
+
this.pendingHydrationByKey.set(actorKey, hydrationPromise);
|
|
4403
|
+
return hydrationPromise;
|
|
4404
|
+
}
|
|
4281
4405
|
touchSession(actorKey, shouldTouch, touchedAt) {
|
|
4282
4406
|
if (!this.spec.session?.enabled || !shouldTouch) {
|
|
4283
4407
|
return;
|
|
@@ -4469,6 +4593,176 @@ var Actor = class {
|
|
|
4469
4593
|
}
|
|
4470
4594
|
};
|
|
4471
4595
|
|
|
4596
|
+
// src/tools/definitions.ts
|
|
4597
|
+
function validateAlias(alias) {
|
|
4598
|
+
const normalized = String(alias ?? "").trim();
|
|
4599
|
+
if (!normalized) {
|
|
4600
|
+
throw new Error("Tool dependency alias must be a non-empty string");
|
|
4601
|
+
}
|
|
4602
|
+
return normalized;
|
|
4603
|
+
}
|
|
4604
|
+
function serializeGlobalValue(value) {
|
|
4605
|
+
if (value === void 0 || typeof value === "function") {
|
|
4606
|
+
throw new Error("Global values must be JSON-serializable");
|
|
4607
|
+
}
|
|
4608
|
+
try {
|
|
4609
|
+
return JSON.parse(JSON.stringify(value));
|
|
4610
|
+
} catch (error) {
|
|
4611
|
+
throw new Error(
|
|
4612
|
+
`Global values must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`
|
|
4613
|
+
);
|
|
4614
|
+
}
|
|
4615
|
+
}
|
|
4616
|
+
function deepFreeze(value) {
|
|
4617
|
+
if (!value || typeof value !== "object") {
|
|
4618
|
+
return value;
|
|
4619
|
+
}
|
|
4620
|
+
Object.freeze(value);
|
|
4621
|
+
for (const nested of Object.values(value)) {
|
|
4622
|
+
if (nested && typeof nested === "object" && !Object.isFrozen(nested)) {
|
|
4623
|
+
deepFreeze(nested);
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
return value;
|
|
4627
|
+
}
|
|
4628
|
+
var GlobalDefinition = class {
|
|
4629
|
+
constructor(name, value, description = "", isMeta = false) {
|
|
4630
|
+
this.version = 1;
|
|
4631
|
+
this.destroyed = false;
|
|
4632
|
+
this.name = name;
|
|
4633
|
+
this.description = description;
|
|
4634
|
+
this.isMeta = isMeta;
|
|
4635
|
+
this.value = deepFreeze(serializeGlobalValue(value));
|
|
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
|
+
value: this.value
|
|
4647
|
+
};
|
|
4648
|
+
}
|
|
4649
|
+
};
|
|
4650
|
+
var HelperDefinition = class {
|
|
4651
|
+
constructor(name, helperFunction, description = "", isMeta = false) {
|
|
4652
|
+
this.version = 1;
|
|
4653
|
+
this.helperAliases = /* @__PURE__ */ new Map();
|
|
4654
|
+
this.globalAliases = /* @__PURE__ */ new Map();
|
|
4655
|
+
this.destroyed = false;
|
|
4656
|
+
this.name = name;
|
|
4657
|
+
this.description = description;
|
|
4658
|
+
this.isMeta = isMeta;
|
|
4659
|
+
this.helperFunction = helperFunction;
|
|
4660
|
+
}
|
|
4661
|
+
usesHelpers(helpers) {
|
|
4662
|
+
attachHelperDependency(
|
|
4663
|
+
this,
|
|
4664
|
+
this.name,
|
|
4665
|
+
this.version,
|
|
4666
|
+
helpers,
|
|
4667
|
+
"meta.helper.helper_associated"
|
|
4668
|
+
);
|
|
4669
|
+
return this;
|
|
4670
|
+
}
|
|
4671
|
+
usesGlobals(globals) {
|
|
4672
|
+
attachGlobalDependency(
|
|
4673
|
+
this,
|
|
4674
|
+
this.name,
|
|
4675
|
+
this.version,
|
|
4676
|
+
globals,
|
|
4677
|
+
"meta.helper.global_associated"
|
|
4678
|
+
);
|
|
4679
|
+
return this;
|
|
4680
|
+
}
|
|
4681
|
+
execute(context, emit, inquire, progressCallback) {
|
|
4682
|
+
return Cadenza.executeHelper(
|
|
4683
|
+
this,
|
|
4684
|
+
context,
|
|
4685
|
+
emit,
|
|
4686
|
+
inquire,
|
|
4687
|
+
progressCallback
|
|
4688
|
+
);
|
|
4689
|
+
}
|
|
4690
|
+
destroy() {
|
|
4691
|
+
this.destroyed = true;
|
|
4692
|
+
}
|
|
4693
|
+
export() {
|
|
4694
|
+
return {
|
|
4695
|
+
name: this.name,
|
|
4696
|
+
description: this.description,
|
|
4697
|
+
version: this.version,
|
|
4698
|
+
isMeta: this.isMeta,
|
|
4699
|
+
functionString: this.helperFunction.toString(),
|
|
4700
|
+
helperAliases: Object.fromEntries(this.helperAliases),
|
|
4701
|
+
globalAliases: Object.fromEntries(this.globalAliases)
|
|
4702
|
+
};
|
|
4703
|
+
}
|
|
4704
|
+
};
|
|
4705
|
+
function attachHelperDependency(owner, ownerName, ownerVersion, helpers, signalName) {
|
|
4706
|
+
for (const [alias, helper] of Object.entries(helpers)) {
|
|
4707
|
+
const normalizedAlias = validateAlias(alias);
|
|
4708
|
+
if (!helper) {
|
|
4709
|
+
throw new Error(
|
|
4710
|
+
`Helper dependency "${normalizedAlias}" must reference a helper definition`
|
|
4711
|
+
);
|
|
4712
|
+
}
|
|
4713
|
+
if (helper.isMeta !== owner.isMeta) {
|
|
4714
|
+
throw new Error(
|
|
4715
|
+
`${ownerName} cannot use ${helper.isMeta ? "meta" : "business"} helper "${helper.name}" across layer boundaries`
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
owner.helperAliases.set(normalizedAlias, helper.name);
|
|
4719
|
+
Cadenza.emit(signalName, {
|
|
4720
|
+
data: {
|
|
4721
|
+
alias: normalizedAlias,
|
|
4722
|
+
...signalName === "meta.task.helper_associated" ? {
|
|
4723
|
+
taskName: ownerName,
|
|
4724
|
+
taskVersion: ownerVersion
|
|
4725
|
+
} : {
|
|
4726
|
+
helperName: ownerName,
|
|
4727
|
+
helperVersion: ownerVersion
|
|
4728
|
+
},
|
|
4729
|
+
dependencyHelperName: helper.name,
|
|
4730
|
+
dependencyHelperVersion: helper.version
|
|
4731
|
+
}
|
|
4732
|
+
});
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
function attachGlobalDependency(owner, ownerName, ownerVersion, globals, signalName) {
|
|
4736
|
+
for (const [alias, globalDefinition] of Object.entries(globals)) {
|
|
4737
|
+
const normalizedAlias = validateAlias(alias);
|
|
4738
|
+
if (!globalDefinition) {
|
|
4739
|
+
throw new Error(
|
|
4740
|
+
`Global dependency "${normalizedAlias}" must reference a global definition`
|
|
4741
|
+
);
|
|
4742
|
+
}
|
|
4743
|
+
if (globalDefinition.isMeta !== owner.isMeta) {
|
|
4744
|
+
throw new Error(
|
|
4745
|
+
`${ownerName} cannot use ${globalDefinition.isMeta ? "meta" : "business"} global "${globalDefinition.name}" across layer boundaries`
|
|
4746
|
+
);
|
|
4747
|
+
}
|
|
4748
|
+
owner.globalAliases.set(normalizedAlias, globalDefinition.name);
|
|
4749
|
+
Cadenza.emit(signalName, {
|
|
4750
|
+
data: {
|
|
4751
|
+
alias: normalizedAlias,
|
|
4752
|
+
...signalName === "meta.task.global_associated" ? {
|
|
4753
|
+
taskName: ownerName,
|
|
4754
|
+
taskVersion: ownerVersion
|
|
4755
|
+
} : {
|
|
4756
|
+
helperName: ownerName,
|
|
4757
|
+
helperVersion: ownerVersion
|
|
4758
|
+
},
|
|
4759
|
+
globalName: globalDefinition.name,
|
|
4760
|
+
globalVersion: globalDefinition.version
|
|
4761
|
+
}
|
|
4762
|
+
});
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
|
|
4472
4766
|
// src/graph/definition/Task.ts
|
|
4473
4767
|
function normalizeSignalDefinition(input) {
|
|
4474
4768
|
if (typeof input === "string") {
|
|
@@ -4545,6 +4839,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
4545
4839
|
this.observedSignals = /* @__PURE__ */ new Set();
|
|
4546
4840
|
this.handlesIntents = /* @__PURE__ */ new Set();
|
|
4547
4841
|
this.inquiresIntents = /* @__PURE__ */ new Set();
|
|
4842
|
+
this.helperAliases = /* @__PURE__ */ new Map();
|
|
4843
|
+
this.globalAliases = /* @__PURE__ */ new Map();
|
|
4548
4844
|
this.name = name;
|
|
4549
4845
|
this.taskFunction = task;
|
|
4550
4846
|
this.description = description;
|
|
@@ -4580,6 +4876,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
4580
4876
|
"meta.task.relationship_added",
|
|
4581
4877
|
"meta.task.relationship_removed",
|
|
4582
4878
|
"meta.task.intent_associated",
|
|
4879
|
+
"meta.task.helper_associated",
|
|
4880
|
+
"meta.task.global_associated",
|
|
4583
4881
|
"meta.task.layer_index_changed",
|
|
4584
4882
|
"meta.node.scheduled",
|
|
4585
4883
|
"meta.node.mapped",
|
|
@@ -5093,10 +5391,18 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5093
5391
|
* @return {TaskResult} The result of the executed task.
|
|
5094
5392
|
*/
|
|
5095
5393
|
execute(context, emit, inquire, progressCallback, nodeData) {
|
|
5394
|
+
const executionContext = this.isMeta ? context.getClonedFullContext() : context.getClonedContext();
|
|
5096
5395
|
return this.taskFunction(
|
|
5097
|
-
|
|
5396
|
+
executionContext,
|
|
5098
5397
|
emit,
|
|
5099
5398
|
inquire,
|
|
5399
|
+
Cadenza.resolveToolsForOwner(
|
|
5400
|
+
this,
|
|
5401
|
+
executionContext,
|
|
5402
|
+
emit,
|
|
5403
|
+
inquire,
|
|
5404
|
+
progressCallback
|
|
5405
|
+
),
|
|
5100
5406
|
progressCallback
|
|
5101
5407
|
);
|
|
5102
5408
|
}
|
|
@@ -5110,6 +5416,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5110
5416
|
* @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
|
|
5111
5417
|
*/
|
|
5112
5418
|
doAfter(...tasks) {
|
|
5419
|
+
Cadenza.assertGraphMutationAllowed("Task#doAfter");
|
|
5113
5420
|
for (const pred of tasks) {
|
|
5114
5421
|
if (!pred) continue;
|
|
5115
5422
|
if (this.predecessorTasks.has(pred)) continue;
|
|
@@ -5141,6 +5448,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5141
5448
|
* @throws {Error} Throws an error if adding a task causes a cyclic dependency.
|
|
5142
5449
|
*/
|
|
5143
5450
|
then(...tasks) {
|
|
5451
|
+
Cadenza.assertGraphMutationAllowed("Task#then");
|
|
5144
5452
|
for (const next of tasks) {
|
|
5145
5453
|
if (!next) continue;
|
|
5146
5454
|
if (this.nextTasks.has(next)) continue;
|
|
@@ -5304,6 +5612,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5304
5612
|
* @return {this} The current instance after adding the specified signals.
|
|
5305
5613
|
*/
|
|
5306
5614
|
doOn(...signals) {
|
|
5615
|
+
Cadenza.assertGraphMutationAllowed("Task#doOn");
|
|
5307
5616
|
signals.forEach((input) => {
|
|
5308
5617
|
const { name: signal, metadata } = normalizeSignalDefinition(input);
|
|
5309
5618
|
if (this.observedSignals.has(signal)) return;
|
|
@@ -5328,6 +5637,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5328
5637
|
* @return {this} The current instance for method chaining.
|
|
5329
5638
|
*/
|
|
5330
5639
|
emits(...signals) {
|
|
5640
|
+
Cadenza.assertGraphMutationAllowed("Task#emits");
|
|
5331
5641
|
signals.forEach((input) => {
|
|
5332
5642
|
const { name: signal } = normalizeSignalDefinition(input);
|
|
5333
5643
|
if (this.observedSignals.has(signal))
|
|
@@ -5347,6 +5657,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5347
5657
|
* @return {this} Returns the current instance for chaining.
|
|
5348
5658
|
*/
|
|
5349
5659
|
emitsOnFail(...signals) {
|
|
5660
|
+
Cadenza.assertGraphMutationAllowed("Task#emitsOnFail");
|
|
5350
5661
|
signals.forEach((input) => {
|
|
5351
5662
|
const { name: signal } = normalizeSignalDefinition(input);
|
|
5352
5663
|
this.signalsToEmitOnFail.add(signal);
|
|
@@ -5361,6 +5672,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5361
5672
|
* @return {void} This method does not return a value.
|
|
5362
5673
|
*/
|
|
5363
5674
|
attachSignal(...signals) {
|
|
5675
|
+
Cadenza.assertGraphMutationAllowed("Task#attachSignal");
|
|
5364
5676
|
signals.forEach((input) => {
|
|
5365
5677
|
const { name: signal, metadata } = normalizeSignalDefinition(input);
|
|
5366
5678
|
this.emitsSignals.add(signal);
|
|
@@ -5457,6 +5769,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5457
5769
|
return this;
|
|
5458
5770
|
}
|
|
5459
5771
|
respondsTo(...inquires) {
|
|
5772
|
+
Cadenza.assertGraphMutationAllowed("Task#respondsTo");
|
|
5460
5773
|
for (const intentName of inquires) {
|
|
5461
5774
|
if (this.handlesIntents.has(intentName)) {
|
|
5462
5775
|
continue;
|
|
@@ -5492,6 +5805,26 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5492
5805
|
}
|
|
5493
5806
|
return this;
|
|
5494
5807
|
}
|
|
5808
|
+
usesHelpers(helpers) {
|
|
5809
|
+
attachHelperDependency(
|
|
5810
|
+
this,
|
|
5811
|
+
this.name,
|
|
5812
|
+
this.version,
|
|
5813
|
+
helpers,
|
|
5814
|
+
"meta.task.helper_associated"
|
|
5815
|
+
);
|
|
5816
|
+
return this;
|
|
5817
|
+
}
|
|
5818
|
+
usesGlobals(globals) {
|
|
5819
|
+
attachGlobalDependency(
|
|
5820
|
+
this,
|
|
5821
|
+
this.name,
|
|
5822
|
+
this.version,
|
|
5823
|
+
globals,
|
|
5824
|
+
"meta.task.global_associated"
|
|
5825
|
+
);
|
|
5826
|
+
return this;
|
|
5827
|
+
}
|
|
5495
5828
|
attachIntents(...intentNames) {
|
|
5496
5829
|
for (const intent of intentNames) {
|
|
5497
5830
|
this.inquiresIntents.add(intent);
|
|
@@ -5584,6 +5917,7 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5584
5917
|
this.nextTasks.clear();
|
|
5585
5918
|
this.predecessorTasks.clear();
|
|
5586
5919
|
this.destroyed = true;
|
|
5920
|
+
Cadenza.forgetTask(this.name);
|
|
5587
5921
|
if (this.register) {
|
|
5588
5922
|
Cadenza.registry.tasks.delete(this.name);
|
|
5589
5923
|
this.emitMetricsWithMetadata("meta.task.destroyed", {
|
|
@@ -5625,6 +5959,8 @@ var Task = class _Task extends SignalEmitter {
|
|
|
5625
5959
|
__validateInputContext: this.validateInputContext,
|
|
5626
5960
|
__outputSchema: this.outputContextSchema,
|
|
5627
5961
|
__validateOutputContext: this.validateOutputContext,
|
|
5962
|
+
__helperAliases: Object.fromEntries(this.helperAliases),
|
|
5963
|
+
__globalAliases: Object.fromEntries(this.globalAliases),
|
|
5628
5964
|
__nextTasks: Array.from(this.nextTasks).map((t) => t.name),
|
|
5629
5965
|
__previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
|
|
5630
5966
|
};
|
|
@@ -5871,6 +6207,13 @@ var DebounceTask = class extends Task {
|
|
|
5871
6207
|
this.lastContext.getClonedContext(),
|
|
5872
6208
|
this.lastEmitFunction,
|
|
5873
6209
|
this.lastInquireFunction,
|
|
6210
|
+
Cadenza.resolveToolsForOwner(
|
|
6211
|
+
this,
|
|
6212
|
+
this.lastContext.getClonedContext(),
|
|
6213
|
+
this.lastEmitFunction,
|
|
6214
|
+
this.lastInquireFunction,
|
|
6215
|
+
this.lastProgressCallback
|
|
6216
|
+
),
|
|
5874
6217
|
this.lastProgressCallback
|
|
5875
6218
|
);
|
|
5876
6219
|
} catch (error) {
|
|
@@ -6025,6 +6368,19 @@ var EphemeralTask = class extends Task {
|
|
|
6025
6368
|
progressCallback,
|
|
6026
6369
|
nodeData
|
|
6027
6370
|
);
|
|
6371
|
+
if (result instanceof Promise) {
|
|
6372
|
+
return result.then((resolved) => {
|
|
6373
|
+
if (this.once || this.condition(resolved)) {
|
|
6374
|
+
this.destroy();
|
|
6375
|
+
}
|
|
6376
|
+
return resolved;
|
|
6377
|
+
}).catch((error) => {
|
|
6378
|
+
if (this.once || this.condition(error)) {
|
|
6379
|
+
this.destroy();
|
|
6380
|
+
}
|
|
6381
|
+
throw error;
|
|
6382
|
+
});
|
|
6383
|
+
}
|
|
6028
6384
|
if (this.once || this.condition(result)) {
|
|
6029
6385
|
this.destroy();
|
|
6030
6386
|
}
|
|
@@ -7015,6 +7371,386 @@ var InquiryBroker = class _InquiryBroker extends SignalEmitter {
|
|
|
7015
7371
|
}
|
|
7016
7372
|
};
|
|
7017
7373
|
|
|
7374
|
+
// src/runtime/RuntimeDefinitionRegistry.ts
|
|
7375
|
+
function createLinkKey(predecessorTaskName, successorTaskName) {
|
|
7376
|
+
return `${predecessorTaskName}=>${successorTaskName}`;
|
|
7377
|
+
}
|
|
7378
|
+
function createTaskSignalKey(taskName, signalName) {
|
|
7379
|
+
return `${taskName}=>${signalName}`;
|
|
7380
|
+
}
|
|
7381
|
+
function createTaskIntentKey(taskName, intentName) {
|
|
7382
|
+
return `${taskName}=>${intentName}`;
|
|
7383
|
+
}
|
|
7384
|
+
function createRoutineSignalKey(routineName, signalName) {
|
|
7385
|
+
return `${routineName}=>${signalName}`;
|
|
7386
|
+
}
|
|
7387
|
+
var RuntimeDefinitionRegistry = class {
|
|
7388
|
+
constructor() {
|
|
7389
|
+
this.taskDefinitions = /* @__PURE__ */ new Map();
|
|
7390
|
+
this.helperDefinitions = /* @__PURE__ */ new Map();
|
|
7391
|
+
this.globalDefinitions = /* @__PURE__ */ new Map();
|
|
7392
|
+
this.routineDefinitions = /* @__PURE__ */ new Map();
|
|
7393
|
+
this.intentDefinitions = /* @__PURE__ */ new Map();
|
|
7394
|
+
this.actorDefinitions = /* @__PURE__ */ new Map();
|
|
7395
|
+
this.actorTaskDefinitions = /* @__PURE__ */ new Map();
|
|
7396
|
+
this.taskLinks = /* @__PURE__ */ new Map();
|
|
7397
|
+
this.taskSignalObservations = /* @__PURE__ */ new Map();
|
|
7398
|
+
this.taskSignalEmissions = /* @__PURE__ */ new Map();
|
|
7399
|
+
this.taskIntentBindings = /* @__PURE__ */ new Map();
|
|
7400
|
+
this.taskHelperBindings = /* @__PURE__ */ new Map();
|
|
7401
|
+
this.taskGlobalBindings = /* @__PURE__ */ new Map();
|
|
7402
|
+
this.helperHelperBindings = /* @__PURE__ */ new Map();
|
|
7403
|
+
this.helperGlobalBindings = /* @__PURE__ */ new Map();
|
|
7404
|
+
this.routineSignalObservations = /* @__PURE__ */ new Map();
|
|
7405
|
+
}
|
|
7406
|
+
reset() {
|
|
7407
|
+
this.taskDefinitions.clear();
|
|
7408
|
+
this.helperDefinitions.clear();
|
|
7409
|
+
this.globalDefinitions.clear();
|
|
7410
|
+
this.routineDefinitions.clear();
|
|
7411
|
+
this.intentDefinitions.clear();
|
|
7412
|
+
this.actorDefinitions.clear();
|
|
7413
|
+
this.actorTaskDefinitions.clear();
|
|
7414
|
+
this.taskLinks.clear();
|
|
7415
|
+
this.taskSignalObservations.clear();
|
|
7416
|
+
this.taskSignalEmissions.clear();
|
|
7417
|
+
this.taskIntentBindings.clear();
|
|
7418
|
+
this.taskHelperBindings.clear();
|
|
7419
|
+
this.taskGlobalBindings.clear();
|
|
7420
|
+
this.helperHelperBindings.clear();
|
|
7421
|
+
this.helperGlobalBindings.clear();
|
|
7422
|
+
this.routineSignalObservations.clear();
|
|
7423
|
+
}
|
|
7424
|
+
setTaskDefinition(definition) {
|
|
7425
|
+
this.taskDefinitions.set(definition.name, {
|
|
7426
|
+
...definition,
|
|
7427
|
+
kind: definition.kind ?? "task",
|
|
7428
|
+
options: definition.options ? { ...definition.options } : void 0
|
|
7429
|
+
});
|
|
7430
|
+
}
|
|
7431
|
+
setHelperDefinition(definition) {
|
|
7432
|
+
this.helperDefinitions.set(definition.name, {
|
|
7433
|
+
...definition,
|
|
7434
|
+
kind: definition.kind ?? "helper"
|
|
7435
|
+
});
|
|
7436
|
+
}
|
|
7437
|
+
setGlobalDefinition(definition) {
|
|
7438
|
+
this.globalDefinitions.set(definition.name, {
|
|
7439
|
+
...definition,
|
|
7440
|
+
kind: definition.kind ?? "global",
|
|
7441
|
+
value: definition.value
|
|
7442
|
+
});
|
|
7443
|
+
}
|
|
7444
|
+
setRoutineDefinition(definition) {
|
|
7445
|
+
this.routineDefinitions.set(definition.name, {
|
|
7446
|
+
...definition,
|
|
7447
|
+
startTaskNames: [...definition.startTaskNames],
|
|
7448
|
+
isMeta: definition.isMeta === true
|
|
7449
|
+
});
|
|
7450
|
+
}
|
|
7451
|
+
setIntentDefinition(definition) {
|
|
7452
|
+
this.intentDefinitions.set(definition.name, {
|
|
7453
|
+
...definition,
|
|
7454
|
+
input: definition.input ? { ...definition.input } : void 0,
|
|
7455
|
+
output: definition.output ? { ...definition.output } : void 0
|
|
7456
|
+
});
|
|
7457
|
+
}
|
|
7458
|
+
setActorDefinition(definition) {
|
|
7459
|
+
this.actorDefinitions.set(definition.name, {
|
|
7460
|
+
...definition,
|
|
7461
|
+
state: definition.state ? {
|
|
7462
|
+
...definition.state,
|
|
7463
|
+
durable: definition.state.durable ? { ...definition.state.durable } : void 0,
|
|
7464
|
+
runtime: definition.state.runtime ? { ...definition.state.runtime } : void 0
|
|
7465
|
+
} : void 0,
|
|
7466
|
+
tasks: definition.tasks ? definition.tasks.map((task) => ({ ...task })) : void 0
|
|
7467
|
+
});
|
|
7468
|
+
}
|
|
7469
|
+
setActorTaskDefinition(definition) {
|
|
7470
|
+
this.actorTaskDefinitions.set(definition.taskName, {
|
|
7471
|
+
...definition,
|
|
7472
|
+
mode: definition.mode ?? "read",
|
|
7473
|
+
options: definition.options ? { ...definition.options } : void 0
|
|
7474
|
+
});
|
|
7475
|
+
}
|
|
7476
|
+
setTaskLink(definition) {
|
|
7477
|
+
this.taskLinks.set(
|
|
7478
|
+
createLinkKey(
|
|
7479
|
+
definition.predecessorTaskName,
|
|
7480
|
+
definition.successorTaskName
|
|
7481
|
+
),
|
|
7482
|
+
{ ...definition }
|
|
7483
|
+
);
|
|
7484
|
+
}
|
|
7485
|
+
setTaskSignalObservation(definition) {
|
|
7486
|
+
const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
|
|
7487
|
+
this.taskSignalObservations.set(
|
|
7488
|
+
createTaskSignalKey(definition.taskName, signalName),
|
|
7489
|
+
{
|
|
7490
|
+
taskName: definition.taskName,
|
|
7491
|
+
signal: typeof definition.signal === "string" ? definition.signal : {
|
|
7492
|
+
name: definition.signal.name,
|
|
7493
|
+
deliveryMode: definition.signal.deliveryMode,
|
|
7494
|
+
broadcastFilter: definition.signal.broadcastFilter ?? null
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
);
|
|
7498
|
+
}
|
|
7499
|
+
setTaskSignalEmission(definition) {
|
|
7500
|
+
const signalName = typeof definition.signal === "string" ? definition.signal : definition.signal.name;
|
|
7501
|
+
this.taskSignalEmissions.set(
|
|
7502
|
+
`${definition.taskName}=>${definition.mode ?? "after"}=>${signalName}`,
|
|
7503
|
+
{
|
|
7504
|
+
taskName: definition.taskName,
|
|
7505
|
+
mode: definition.mode ?? "after",
|
|
7506
|
+
signal: typeof definition.signal === "string" ? definition.signal : {
|
|
7507
|
+
name: definition.signal.name,
|
|
7508
|
+
deliveryMode: definition.signal.deliveryMode,
|
|
7509
|
+
broadcastFilter: definition.signal.broadcastFilter ?? null
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
);
|
|
7513
|
+
}
|
|
7514
|
+
setTaskIntentBinding(definition) {
|
|
7515
|
+
this.taskIntentBindings.set(
|
|
7516
|
+
createTaskIntentKey(definition.taskName, definition.intentName),
|
|
7517
|
+
{ ...definition }
|
|
7518
|
+
);
|
|
7519
|
+
}
|
|
7520
|
+
setTaskHelperBinding(definition) {
|
|
7521
|
+
this.taskHelperBindings.set(
|
|
7522
|
+
`${definition.taskName}=>${definition.alias}`,
|
|
7523
|
+
{ ...definition }
|
|
7524
|
+
);
|
|
7525
|
+
}
|
|
7526
|
+
setTaskGlobalBinding(definition) {
|
|
7527
|
+
this.taskGlobalBindings.set(
|
|
7528
|
+
`${definition.taskName}=>${definition.alias}`,
|
|
7529
|
+
{ ...definition }
|
|
7530
|
+
);
|
|
7531
|
+
}
|
|
7532
|
+
setHelperHelperBinding(definition) {
|
|
7533
|
+
this.helperHelperBindings.set(
|
|
7534
|
+
`${definition.helperName}=>${definition.alias}`,
|
|
7535
|
+
{ ...definition }
|
|
7536
|
+
);
|
|
7537
|
+
}
|
|
7538
|
+
setHelperGlobalBinding(definition) {
|
|
7539
|
+
this.helperGlobalBindings.set(
|
|
7540
|
+
`${definition.helperName}=>${definition.alias}`,
|
|
7541
|
+
{ ...definition }
|
|
7542
|
+
);
|
|
7543
|
+
}
|
|
7544
|
+
setRoutineSignalObservation(definition) {
|
|
7545
|
+
this.routineSignalObservations.set(
|
|
7546
|
+
createRoutineSignalKey(definition.routineName, definition.signal),
|
|
7547
|
+
{ ...definition }
|
|
7548
|
+
);
|
|
7549
|
+
}
|
|
7550
|
+
isRuntimeOwnedTask(taskName) {
|
|
7551
|
+
return this.taskDefinitions.has(taskName) || this.actorTaskDefinitions.has(taskName);
|
|
7552
|
+
}
|
|
7553
|
+
isRuntimeOwnedHelper(helperName) {
|
|
7554
|
+
return this.helperDefinitions.has(helperName);
|
|
7555
|
+
}
|
|
7556
|
+
isRuntimeOwnedGlobal(globalName) {
|
|
7557
|
+
return this.globalDefinitions.has(globalName);
|
|
7558
|
+
}
|
|
7559
|
+
isRuntimeOwnedRoutine(routineName) {
|
|
7560
|
+
return this.routineDefinitions.has(routineName);
|
|
7561
|
+
}
|
|
7562
|
+
isRuntimeOwnedActor(actorName) {
|
|
7563
|
+
return this.actorDefinitions.has(actorName);
|
|
7564
|
+
}
|
|
7565
|
+
};
|
|
7566
|
+
var runtimeDefinitionRegistry = new RuntimeDefinitionRegistry();
|
|
7567
|
+
|
|
7568
|
+
// src/runtime/sandbox.ts
|
|
7569
|
+
var import_node_vm = __toESM(require("vm"));
|
|
7570
|
+
var import_typescript = __toESM(require("typescript"));
|
|
7571
|
+
var FORBIDDEN_SOURCE_PATTERNS = [
|
|
7572
|
+
{
|
|
7573
|
+
pattern: /\bimport\b/,
|
|
7574
|
+
message: "Runtime handler source must not contain import statements"
|
|
7575
|
+
},
|
|
7576
|
+
{
|
|
7577
|
+
pattern: /\bexport\b/,
|
|
7578
|
+
message: "Runtime handler source must not contain export statements"
|
|
7579
|
+
},
|
|
7580
|
+
{
|
|
7581
|
+
pattern: /\brequire\s*\(/,
|
|
7582
|
+
message: "Runtime handler source must not call require()"
|
|
7583
|
+
},
|
|
7584
|
+
{
|
|
7585
|
+
pattern: /\bprocess\b/,
|
|
7586
|
+
message: "Runtime handler source must not access process"
|
|
7587
|
+
},
|
|
7588
|
+
{
|
|
7589
|
+
pattern: /\bFunction\s*\(/,
|
|
7590
|
+
message: "Runtime handler source must not create dynamic functions"
|
|
7591
|
+
},
|
|
7592
|
+
{
|
|
7593
|
+
pattern: /\beval\s*\(/,
|
|
7594
|
+
message: "Runtime handler source must not call eval()"
|
|
7595
|
+
}
|
|
7596
|
+
];
|
|
7597
|
+
function transpileIfNeeded(source, language, filename) {
|
|
7598
|
+
if (language === "js") {
|
|
7599
|
+
return source;
|
|
7600
|
+
}
|
|
7601
|
+
const result = import_typescript.default.transpileModule(source, {
|
|
7602
|
+
compilerOptions: {
|
|
7603
|
+
target: import_typescript.default.ScriptTarget.ES2020,
|
|
7604
|
+
module: import_typescript.default.ModuleKind.ESNext
|
|
7605
|
+
},
|
|
7606
|
+
fileName: filename,
|
|
7607
|
+
reportDiagnostics: true
|
|
7608
|
+
});
|
|
7609
|
+
const diagnostics = result.diagnostics ?? [];
|
|
7610
|
+
const blockingDiagnostics = diagnostics.filter(
|
|
7611
|
+
(diagnostic) => diagnostic.category === import_typescript.default.DiagnosticCategory.Error
|
|
7612
|
+
);
|
|
7613
|
+
if (blockingDiagnostics.length > 0) {
|
|
7614
|
+
const message = blockingDiagnostics.map((diagnostic) => import_typescript.default.flattenDiagnosticMessageText(diagnostic.messageText, "\n")).join("; ");
|
|
7615
|
+
throw new Error(`TypeScript transpile failed: ${message}`);
|
|
7616
|
+
}
|
|
7617
|
+
return result.outputText;
|
|
7618
|
+
}
|
|
7619
|
+
function createSandbox() {
|
|
7620
|
+
const sandbox = /* @__PURE__ */ Object.create(null);
|
|
7621
|
+
sandbox.global = void 0;
|
|
7622
|
+
sandbox.globalThis = sandbox;
|
|
7623
|
+
sandbox.process = void 0;
|
|
7624
|
+
sandbox.require = void 0;
|
|
7625
|
+
sandbox.module = void 0;
|
|
7626
|
+
sandbox.exports = void 0;
|
|
7627
|
+
sandbox.Buffer = void 0;
|
|
7628
|
+
sandbox.fetch = void 0;
|
|
7629
|
+
sandbox.WebSocket = void 0;
|
|
7630
|
+
sandbox.XMLHttpRequest = void 0;
|
|
7631
|
+
sandbox.setTimeout = void 0;
|
|
7632
|
+
sandbox.setInterval = void 0;
|
|
7633
|
+
sandbox.clearTimeout = void 0;
|
|
7634
|
+
sandbox.clearInterval = void 0;
|
|
7635
|
+
sandbox.queueMicrotask = void 0;
|
|
7636
|
+
return import_node_vm.default.createContext(sandbox);
|
|
7637
|
+
}
|
|
7638
|
+
function compileFunctionFromSource(source, language, filename, label) {
|
|
7639
|
+
const normalizedSource = String(source ?? "").trim();
|
|
7640
|
+
if (!normalizedSource) {
|
|
7641
|
+
throw new Error(`${label} source must be a non-empty string`);
|
|
7642
|
+
}
|
|
7643
|
+
for (const rule of FORBIDDEN_SOURCE_PATTERNS) {
|
|
7644
|
+
if (rule.pattern.test(normalizedSource)) {
|
|
7645
|
+
throw new Error(rule.message);
|
|
7646
|
+
}
|
|
7647
|
+
}
|
|
7648
|
+
const wrappedSource = `const __runtime_handler = ${normalizedSource};
|
|
7649
|
+
__runtime_handler;`;
|
|
7650
|
+
const transpiledSource = transpileIfNeeded(
|
|
7651
|
+
wrappedSource,
|
|
7652
|
+
language,
|
|
7653
|
+
filename
|
|
7654
|
+
).trim();
|
|
7655
|
+
const sandbox = createSandbox();
|
|
7656
|
+
const script = new import_node_vm.default.Script(transpiledSource, {
|
|
7657
|
+
filename
|
|
7658
|
+
});
|
|
7659
|
+
const compiled = script.runInContext(sandbox, {
|
|
7660
|
+
timeout: 1e3,
|
|
7661
|
+
displayErrors: true,
|
|
7662
|
+
contextCodeGeneration: {
|
|
7663
|
+
strings: false,
|
|
7664
|
+
wasm: false
|
|
7665
|
+
}
|
|
7666
|
+
});
|
|
7667
|
+
if (typeof compiled !== "function") {
|
|
7668
|
+
throw new Error(`${label} source must evaluate to a function`);
|
|
7669
|
+
}
|
|
7670
|
+
return compiled;
|
|
7671
|
+
}
|
|
7672
|
+
function compileRuntimeTaskFunction(definition) {
|
|
7673
|
+
return compileFunctionFromSource(
|
|
7674
|
+
definition.handlerSource,
|
|
7675
|
+
definition.language,
|
|
7676
|
+
`${definition.name}.runtime-task.${definition.language}`,
|
|
7677
|
+
`Task "${definition.name}"`
|
|
7678
|
+
);
|
|
7679
|
+
}
|
|
7680
|
+
function compileRuntimeHelperFunction(definition) {
|
|
7681
|
+
return compileFunctionFromSource(
|
|
7682
|
+
definition.handlerSource,
|
|
7683
|
+
definition.language,
|
|
7684
|
+
`${definition.name}.runtime-helper.${definition.language}`,
|
|
7685
|
+
`Helper "${definition.name}"`
|
|
7686
|
+
);
|
|
7687
|
+
}
|
|
7688
|
+
function compileRuntimeActorTaskHandler(definition) {
|
|
7689
|
+
return compileFunctionFromSource(
|
|
7690
|
+
definition.handlerSource,
|
|
7691
|
+
definition.language,
|
|
7692
|
+
`${definition.actorName}.${definition.taskName}.runtime-actor-task.${definition.language}`,
|
|
7693
|
+
`Actor task "${definition.taskName}"`
|
|
7694
|
+
);
|
|
7695
|
+
}
|
|
7696
|
+
|
|
7697
|
+
// src/runtime/sanitize.ts
|
|
7698
|
+
function isPlainObject2(value) {
|
|
7699
|
+
return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
|
|
7700
|
+
}
|
|
7701
|
+
function sanitizeForJson(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
7702
|
+
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
7703
|
+
return value ?? null;
|
|
7704
|
+
}
|
|
7705
|
+
if (typeof value === "bigint") {
|
|
7706
|
+
return value.toString();
|
|
7707
|
+
}
|
|
7708
|
+
if (typeof value === "function") {
|
|
7709
|
+
return `[Function ${value.name || "anonymous"}]`;
|
|
7710
|
+
}
|
|
7711
|
+
if (typeof value === "symbol") {
|
|
7712
|
+
return value.toString();
|
|
7713
|
+
}
|
|
7714
|
+
if (value instanceof Date) {
|
|
7715
|
+
return value.toISOString();
|
|
7716
|
+
}
|
|
7717
|
+
if (value instanceof Set) {
|
|
7718
|
+
return Array.from(value).map((entry) => sanitizeForJson(entry, seen));
|
|
7719
|
+
}
|
|
7720
|
+
if (value instanceof Map) {
|
|
7721
|
+
return Array.from(value.entries()).map(([key, entry]) => [
|
|
7722
|
+
sanitizeForJson(key, seen),
|
|
7723
|
+
sanitizeForJson(entry, seen)
|
|
7724
|
+
]);
|
|
7725
|
+
}
|
|
7726
|
+
if (Array.isArray(value)) {
|
|
7727
|
+
return value.map((entry) => sanitizeForJson(entry, seen));
|
|
7728
|
+
}
|
|
7729
|
+
if (typeof value === "object") {
|
|
7730
|
+
if (seen.has(value)) {
|
|
7731
|
+
return "[Circular]";
|
|
7732
|
+
}
|
|
7733
|
+
seen.add(value);
|
|
7734
|
+
if (!isPlainObject2(value)) {
|
|
7735
|
+
const clone = {};
|
|
7736
|
+
for (const key of Object.keys(value)) {
|
|
7737
|
+
clone[key] = sanitizeForJson(
|
|
7738
|
+
value[key],
|
|
7739
|
+
seen
|
|
7740
|
+
);
|
|
7741
|
+
}
|
|
7742
|
+
clone.__type = value.constructor?.name ?? "Object";
|
|
7743
|
+
return clone;
|
|
7744
|
+
}
|
|
7745
|
+
const result = {};
|
|
7746
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
7747
|
+
result[key] = sanitizeForJson(entry, seen);
|
|
7748
|
+
}
|
|
7749
|
+
return result;
|
|
7750
|
+
}
|
|
7751
|
+
return String(value);
|
|
7752
|
+
}
|
|
7753
|
+
|
|
7018
7754
|
// src/Cadenza.ts
|
|
7019
7755
|
var Cadenza = class {
|
|
7020
7756
|
/**
|
|
@@ -7097,6 +7833,73 @@ var Cadenza = class {
|
|
|
7097
7833
|
throw new Error("Task or Routine name must be a non-empty string.");
|
|
7098
7834
|
}
|
|
7099
7835
|
}
|
|
7836
|
+
static assertGraphMutationAllowed(operationName) {
|
|
7837
|
+
if (this.helperExecutionDepth > 0) {
|
|
7838
|
+
throw new Error(
|
|
7839
|
+
`${operationName} is not allowed during helper execution`
|
|
7840
|
+
);
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
static executeHelper(helper, context, emit, inquire, progressCallback) {
|
|
7844
|
+
const helperContext = context && typeof context === "object" ? context : {};
|
|
7845
|
+
const tools = this.resolveToolsForOwner(
|
|
7846
|
+
helper,
|
|
7847
|
+
helperContext,
|
|
7848
|
+
emit,
|
|
7849
|
+
inquire,
|
|
7850
|
+
progressCallback
|
|
7851
|
+
);
|
|
7852
|
+
this.helperExecutionDepth += 1;
|
|
7853
|
+
try {
|
|
7854
|
+
return helper.helperFunction(
|
|
7855
|
+
helperContext,
|
|
7856
|
+
emit,
|
|
7857
|
+
inquire,
|
|
7858
|
+
tools,
|
|
7859
|
+
progressCallback
|
|
7860
|
+
);
|
|
7861
|
+
} finally {
|
|
7862
|
+
this.helperExecutionDepth = Math.max(0, this.helperExecutionDepth - 1);
|
|
7863
|
+
}
|
|
7864
|
+
}
|
|
7865
|
+
static resolveToolsForOwner(owner, context, emit, inquire, progressCallback) {
|
|
7866
|
+
const helpers = {};
|
|
7867
|
+
const globals = {};
|
|
7868
|
+
for (const [alias, helperName] of owner.helperAliases.entries()) {
|
|
7869
|
+
const helper = this.getHelper(helperName);
|
|
7870
|
+
if (!helper) {
|
|
7871
|
+
continue;
|
|
7872
|
+
}
|
|
7873
|
+
if (helper.isMeta !== owner.isMeta) {
|
|
7874
|
+
throw new Error(
|
|
7875
|
+
`Tool alias "${alias}" resolves across layer boundaries`
|
|
7876
|
+
);
|
|
7877
|
+
}
|
|
7878
|
+
helpers[alias] = (helperContext = context) => this.executeHelper(
|
|
7879
|
+
helper,
|
|
7880
|
+
helperContext,
|
|
7881
|
+
emit,
|
|
7882
|
+
inquire,
|
|
7883
|
+
progressCallback
|
|
7884
|
+
);
|
|
7885
|
+
}
|
|
7886
|
+
for (const [alias, globalName] of owner.globalAliases.entries()) {
|
|
7887
|
+
const globalDefinition = this.getGlobal(globalName);
|
|
7888
|
+
if (!globalDefinition) {
|
|
7889
|
+
continue;
|
|
7890
|
+
}
|
|
7891
|
+
if (globalDefinition.isMeta !== owner.isMeta) {
|
|
7892
|
+
throw new Error(
|
|
7893
|
+
`Global alias "${alias}" resolves across layer boundaries`
|
|
7894
|
+
);
|
|
7895
|
+
}
|
|
7896
|
+
globals[alias] = globalDefinition.value;
|
|
7897
|
+
}
|
|
7898
|
+
return {
|
|
7899
|
+
helpers,
|
|
7900
|
+
globals
|
|
7901
|
+
};
|
|
7902
|
+
}
|
|
7100
7903
|
static resolveTaskOptionsForActorTask(func, options = {}) {
|
|
7101
7904
|
const metadata = getActorTaskRuntimeMetadata(func);
|
|
7102
7905
|
if (!metadata?.forceMeta) {
|
|
@@ -7113,9 +7916,25 @@ var Cadenza = class {
|
|
|
7113
7916
|
static registerActor(actor) {
|
|
7114
7917
|
this.actorCache.set(actor.spec.name, actor);
|
|
7115
7918
|
}
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7919
|
+
static getHelper(name) {
|
|
7920
|
+
return this.helperCache.get(name);
|
|
7921
|
+
}
|
|
7922
|
+
static getAllHelpers() {
|
|
7923
|
+
return Array.from(this.helperCache.values()).filter(
|
|
7924
|
+
(helper) => !helper.destroyed
|
|
7925
|
+
);
|
|
7926
|
+
}
|
|
7927
|
+
static getGlobal(name) {
|
|
7928
|
+
return this.globalCache.get(name);
|
|
7929
|
+
}
|
|
7930
|
+
static getAllGlobals() {
|
|
7931
|
+
return Array.from(this.globalCache.values()).filter(
|
|
7932
|
+
(globalDefinition) => !globalDefinition.destroyed
|
|
7933
|
+
);
|
|
7934
|
+
}
|
|
7935
|
+
/**
|
|
7936
|
+
* Executes the specified task or GraphRoutine with the given context using an internal runner.
|
|
7937
|
+
*
|
|
7119
7938
|
* @param {Task | GraphRoutine} task - The task or GraphRoutine to be executed.
|
|
7120
7939
|
* @param {AnyObject} context - The context in which the task or GraphRoutine should be executed.
|
|
7121
7940
|
* @return {void}
|
|
@@ -7175,6 +7994,9 @@ var Cadenza = class {
|
|
|
7175
7994
|
static get(taskName) {
|
|
7176
7995
|
return this.registry?.tasks.get(taskName) ?? this.taskCache.get(taskName);
|
|
7177
7996
|
}
|
|
7997
|
+
static forgetTask(taskName) {
|
|
7998
|
+
this.taskCache.delete(taskName);
|
|
7999
|
+
}
|
|
7178
8000
|
static getActor(actorName) {
|
|
7179
8001
|
return this.actorCache.get(actorName);
|
|
7180
8002
|
}
|
|
@@ -7182,9 +8004,10 @@ var Cadenza = class {
|
|
|
7182
8004
|
return Array.from(this.actorCache.values());
|
|
7183
8005
|
}
|
|
7184
8006
|
static getRoutine(routineName) {
|
|
7185
|
-
return this.registry?.routines.get(routineName);
|
|
8007
|
+
return this.registry?.routines.get(routineName) ?? this.routineCache.get(routineName);
|
|
7186
8008
|
}
|
|
7187
8009
|
static defineIntent(intent) {
|
|
8010
|
+
this.assertGraphMutationAllowed("Cadenza.defineIntent");
|
|
7188
8011
|
this.inquiryBroker?.addIntent(intent);
|
|
7189
8012
|
return intent;
|
|
7190
8013
|
}
|
|
@@ -7338,6 +8161,7 @@ var Cadenza = class {
|
|
|
7338
8161
|
* participate in the graph like any other task.
|
|
7339
8162
|
*/
|
|
7340
8163
|
static createActor(spec, options = {}) {
|
|
8164
|
+
this.assertGraphMutationAllowed("Cadenza.createActor");
|
|
7341
8165
|
this.bootstrap();
|
|
7342
8166
|
const actor = new Actor(spec, options);
|
|
7343
8167
|
this.registerActor(actor);
|
|
@@ -7375,7 +8199,8 @@ var Cadenza = class {
|
|
|
7375
8199
|
};
|
|
7376
8200
|
const actorOptions = {
|
|
7377
8201
|
isMeta: options.isMeta,
|
|
7378
|
-
definitionSource: definition
|
|
8202
|
+
definitionSource: definition,
|
|
8203
|
+
hydrateDurableState: options.hydrateDurableState
|
|
7379
8204
|
};
|
|
7380
8205
|
return this.createActor(spec, actorOptions);
|
|
7381
8206
|
}
|
|
@@ -7452,6 +8277,7 @@ var Cadenza = class {
|
|
|
7452
8277
|
* ```
|
|
7453
8278
|
*/
|
|
7454
8279
|
static createTask(name, func, description, options = {}) {
|
|
8280
|
+
this.assertGraphMutationAllowed("Cadenza.createTask");
|
|
7455
8281
|
this.bootstrap();
|
|
7456
8282
|
this.validateName(name);
|
|
7457
8283
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7501,6 +8327,164 @@ var Cadenza = class {
|
|
|
7501
8327
|
this.taskCache.set(name, createdTask);
|
|
7502
8328
|
return createdTask;
|
|
7503
8329
|
}
|
|
8330
|
+
static createTaskFromDefinition(definition) {
|
|
8331
|
+
this.bootstrap();
|
|
8332
|
+
this.validateName(definition.name);
|
|
8333
|
+
const existing = this.get(definition.name);
|
|
8334
|
+
if (existing) {
|
|
8335
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedTask(definition.name)) {
|
|
8336
|
+
throw new Error(
|
|
8337
|
+
`Task "${definition.name}" already exists and is not runtime-owned`
|
|
8338
|
+
);
|
|
8339
|
+
}
|
|
8340
|
+
existing.destroy();
|
|
8341
|
+
}
|
|
8342
|
+
const taskFunction = compileRuntimeTaskFunction(definition);
|
|
8343
|
+
const createdTask = definition.kind === "metaTask" ? this.createMetaTask(
|
|
8344
|
+
definition.name,
|
|
8345
|
+
taskFunction,
|
|
8346
|
+
definition.description ?? "",
|
|
8347
|
+
definition.options ?? {}
|
|
8348
|
+
) : this.createTask(
|
|
8349
|
+
definition.name,
|
|
8350
|
+
taskFunction,
|
|
8351
|
+
definition.description ?? "",
|
|
8352
|
+
definition.options ?? {}
|
|
8353
|
+
);
|
|
8354
|
+
runtimeDefinitionRegistry.setTaskDefinition(definition);
|
|
8355
|
+
return createdTask;
|
|
8356
|
+
}
|
|
8357
|
+
static createHelper(name, func, description = "") {
|
|
8358
|
+
this.bootstrap();
|
|
8359
|
+
this.validateName(name);
|
|
8360
|
+
this.assertGraphMutationAllowed("Cadenza.createHelper");
|
|
8361
|
+
if (this.helperCache.has(name)) {
|
|
8362
|
+
throw new Error(`Helper "${name}" already exists`);
|
|
8363
|
+
}
|
|
8364
|
+
const helper = new HelperDefinition(name, func, description, false);
|
|
8365
|
+
this.helperCache.set(name, helper);
|
|
8366
|
+
this.emit("meta.helper.created", {
|
|
8367
|
+
data: {
|
|
8368
|
+
name,
|
|
8369
|
+
version: helper.version,
|
|
8370
|
+
description,
|
|
8371
|
+
functionString: func.toString(),
|
|
8372
|
+
isMeta: false
|
|
8373
|
+
}
|
|
8374
|
+
});
|
|
8375
|
+
return helper;
|
|
8376
|
+
}
|
|
8377
|
+
static createMetaHelper(name, func, description = "") {
|
|
8378
|
+
this.bootstrap();
|
|
8379
|
+
this.validateName(name);
|
|
8380
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaHelper");
|
|
8381
|
+
if (this.helperCache.has(name)) {
|
|
8382
|
+
throw new Error(`Helper "${name}" already exists`);
|
|
8383
|
+
}
|
|
8384
|
+
const helper = new HelperDefinition(name, func, description, true);
|
|
8385
|
+
this.helperCache.set(name, helper);
|
|
8386
|
+
this.emit("meta.helper.created", {
|
|
8387
|
+
data: {
|
|
8388
|
+
name,
|
|
8389
|
+
version: helper.version,
|
|
8390
|
+
description,
|
|
8391
|
+
functionString: func.toString(),
|
|
8392
|
+
isMeta: true
|
|
8393
|
+
}
|
|
8394
|
+
});
|
|
8395
|
+
return helper;
|
|
8396
|
+
}
|
|
8397
|
+
static createHelperFromDefinition(definition) {
|
|
8398
|
+
this.bootstrap();
|
|
8399
|
+
this.validateName(definition.name);
|
|
8400
|
+
const existing = this.getHelper(definition.name);
|
|
8401
|
+
if (existing) {
|
|
8402
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedHelper(definition.name)) {
|
|
8403
|
+
throw new Error(
|
|
8404
|
+
`Helper "${definition.name}" already exists and is not runtime-owned`
|
|
8405
|
+
);
|
|
8406
|
+
}
|
|
8407
|
+
existing.destroy();
|
|
8408
|
+
this.helperCache.delete(definition.name);
|
|
8409
|
+
}
|
|
8410
|
+
const helperFunction = compileRuntimeHelperFunction(definition);
|
|
8411
|
+
const helper = definition.kind === "metaHelper" ? this.createMetaHelper(
|
|
8412
|
+
definition.name,
|
|
8413
|
+
helperFunction,
|
|
8414
|
+
definition.description ?? ""
|
|
8415
|
+
) : this.createHelper(
|
|
8416
|
+
definition.name,
|
|
8417
|
+
helperFunction,
|
|
8418
|
+
definition.description ?? ""
|
|
8419
|
+
);
|
|
8420
|
+
runtimeDefinitionRegistry.setHelperDefinition(definition);
|
|
8421
|
+
return helper;
|
|
8422
|
+
}
|
|
8423
|
+
static createGlobal(name, value, description = "") {
|
|
8424
|
+
this.bootstrap();
|
|
8425
|
+
this.validateName(name);
|
|
8426
|
+
this.assertGraphMutationAllowed("Cadenza.createGlobal");
|
|
8427
|
+
if (this.globalCache.has(name)) {
|
|
8428
|
+
throw new Error(`Global "${name}" already exists`);
|
|
8429
|
+
}
|
|
8430
|
+
const globalDefinition = new GlobalDefinition(name, value, description, false);
|
|
8431
|
+
this.globalCache.set(name, globalDefinition);
|
|
8432
|
+
this.emit("meta.global.created", {
|
|
8433
|
+
data: {
|
|
8434
|
+
name,
|
|
8435
|
+
version: globalDefinition.version,
|
|
8436
|
+
description,
|
|
8437
|
+
isMeta: false,
|
|
8438
|
+
value: globalDefinition.value
|
|
8439
|
+
}
|
|
8440
|
+
});
|
|
8441
|
+
return globalDefinition;
|
|
8442
|
+
}
|
|
8443
|
+
static createMetaGlobal(name, value, description = "") {
|
|
8444
|
+
this.bootstrap();
|
|
8445
|
+
this.validateName(name);
|
|
8446
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaGlobal");
|
|
8447
|
+
if (this.globalCache.has(name)) {
|
|
8448
|
+
throw new Error(`Global "${name}" already exists`);
|
|
8449
|
+
}
|
|
8450
|
+
const globalDefinition = new GlobalDefinition(name, value, description, true);
|
|
8451
|
+
this.globalCache.set(name, globalDefinition);
|
|
8452
|
+
this.emit("meta.global.created", {
|
|
8453
|
+
data: {
|
|
8454
|
+
name,
|
|
8455
|
+
version: globalDefinition.version,
|
|
8456
|
+
description,
|
|
8457
|
+
isMeta: true,
|
|
8458
|
+
value: globalDefinition.value
|
|
8459
|
+
}
|
|
8460
|
+
});
|
|
8461
|
+
return globalDefinition;
|
|
8462
|
+
}
|
|
8463
|
+
static createGlobalFromDefinition(definition) {
|
|
8464
|
+
this.bootstrap();
|
|
8465
|
+
this.validateName(definition.name);
|
|
8466
|
+
const existing = this.getGlobal(definition.name);
|
|
8467
|
+
if (existing) {
|
|
8468
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedGlobal(definition.name)) {
|
|
8469
|
+
throw new Error(
|
|
8470
|
+
`Global "${definition.name}" already exists and is not runtime-owned`
|
|
8471
|
+
);
|
|
8472
|
+
}
|
|
8473
|
+
existing.destroy();
|
|
8474
|
+
this.globalCache.delete(definition.name);
|
|
8475
|
+
}
|
|
8476
|
+
const globalDefinition = definition.kind === "metaGlobal" ? this.createMetaGlobal(
|
|
8477
|
+
definition.name,
|
|
8478
|
+
definition.value,
|
|
8479
|
+
definition.description ?? ""
|
|
8480
|
+
) : this.createGlobal(
|
|
8481
|
+
definition.name,
|
|
8482
|
+
definition.value,
|
|
8483
|
+
definition.description ?? ""
|
|
8484
|
+
);
|
|
8485
|
+
runtimeDefinitionRegistry.setGlobalDefinition(definition);
|
|
8486
|
+
return globalDefinition;
|
|
8487
|
+
}
|
|
7504
8488
|
/**
|
|
7505
8489
|
* Creates a meta task with the specified name, functionality, description, and options.
|
|
7506
8490
|
* This is used for creating tasks that lives on the meta layer.
|
|
@@ -7566,6 +8550,7 @@ var Cadenza = class {
|
|
|
7566
8550
|
*
|
|
7567
8551
|
*/
|
|
7568
8552
|
static createUniqueTask(name, func, description, options = {}) {
|
|
8553
|
+
this.assertGraphMutationAllowed("Cadenza.createUniqueTask");
|
|
7569
8554
|
options.isUnique = true;
|
|
7570
8555
|
return this.createTask(name, func, description, options);
|
|
7571
8556
|
}
|
|
@@ -7614,6 +8599,7 @@ var Cadenza = class {
|
|
|
7614
8599
|
* ```
|
|
7615
8600
|
*/
|
|
7616
8601
|
static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
|
|
8602
|
+
this.assertGraphMutationAllowed("Cadenza.createThrottledTask");
|
|
7617
8603
|
options.concurrency = 1;
|
|
7618
8604
|
options.getTagCallback = throttledIdGetter;
|
|
7619
8605
|
return this.createTask(name, func, description, options);
|
|
@@ -7673,6 +8659,7 @@ var Cadenza = class {
|
|
|
7673
8659
|
* ```
|
|
7674
8660
|
*/
|
|
7675
8661
|
static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
|
|
8662
|
+
this.assertGraphMutationAllowed("Cadenza.createDebounceTask");
|
|
7676
8663
|
this.bootstrap();
|
|
7677
8664
|
this.validateName(name);
|
|
7678
8665
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7801,6 +8788,7 @@ var Cadenza = class {
|
|
|
7801
8788
|
* ```
|
|
7802
8789
|
*/
|
|
7803
8790
|
static createEphemeralTask(name, func, description, options = {}) {
|
|
8791
|
+
this.assertGraphMutationAllowed("Cadenza.createEphemeralTask");
|
|
7804
8792
|
this.bootstrap();
|
|
7805
8793
|
this.validateName(name);
|
|
7806
8794
|
const actorResolvedOptions = this.resolveTaskOptionsForActorTask(
|
|
@@ -7897,12 +8885,46 @@ var Cadenza = class {
|
|
|
7897
8885
|
* ```
|
|
7898
8886
|
*/
|
|
7899
8887
|
static createRoutine(name, tasks, description = "") {
|
|
8888
|
+
this.assertGraphMutationAllowed("Cadenza.createRoutine");
|
|
7900
8889
|
this.bootstrap();
|
|
7901
8890
|
this.validateName(name);
|
|
7902
8891
|
if (tasks.length === 0) {
|
|
7903
8892
|
throw new Error(`Routine '${name}' created with no starting tasks.`);
|
|
7904
8893
|
}
|
|
7905
|
-
|
|
8894
|
+
const createdRoutine = new GraphRoutine(name, tasks, description);
|
|
8895
|
+
this.routineCache.set(name, createdRoutine);
|
|
8896
|
+
return createdRoutine;
|
|
8897
|
+
}
|
|
8898
|
+
static createRoutineFromDefinition(definition) {
|
|
8899
|
+
const existing = this.getRoutine(definition.name);
|
|
8900
|
+
if (existing) {
|
|
8901
|
+
if (!runtimeDefinitionRegistry.isRuntimeOwnedRoutine(definition.name)) {
|
|
8902
|
+
throw new Error(
|
|
8903
|
+
`Routine "${definition.name}" already exists and is not runtime-owned`
|
|
8904
|
+
);
|
|
8905
|
+
}
|
|
8906
|
+
existing.destroy();
|
|
8907
|
+
}
|
|
8908
|
+
const startTasks = definition.startTaskNames.map((taskName) => {
|
|
8909
|
+
const task = this.get(taskName);
|
|
8910
|
+
if (!task) {
|
|
8911
|
+
throw new Error(
|
|
8912
|
+
`Routine "${definition.name}" references missing task "${taskName}"`
|
|
8913
|
+
);
|
|
8914
|
+
}
|
|
8915
|
+
return task;
|
|
8916
|
+
});
|
|
8917
|
+
const routine = definition.isMeta === true ? this.createMetaRoutine(
|
|
8918
|
+
definition.name,
|
|
8919
|
+
startTasks,
|
|
8920
|
+
definition.description ?? ""
|
|
8921
|
+
) : this.createRoutine(
|
|
8922
|
+
definition.name,
|
|
8923
|
+
startTasks,
|
|
8924
|
+
definition.description ?? ""
|
|
8925
|
+
);
|
|
8926
|
+
runtimeDefinitionRegistry.setRoutineDefinition(definition);
|
|
8927
|
+
return routine;
|
|
7906
8928
|
}
|
|
7907
8929
|
/**
|
|
7908
8930
|
* Creates a meta routine with a given name, tasks, and optional description.
|
|
@@ -7917,34 +8939,1418 @@ var Cadenza = class {
|
|
|
7917
8939
|
* @throws {Error} If no starting tasks are provided.
|
|
7918
8940
|
*/
|
|
7919
8941
|
static createMetaRoutine(name, tasks, description = "") {
|
|
8942
|
+
this.assertGraphMutationAllowed("Cadenza.createMetaRoutine");
|
|
7920
8943
|
this.bootstrap();
|
|
7921
8944
|
this.validateName(name);
|
|
7922
8945
|
if (tasks.length === 0) {
|
|
7923
8946
|
throw new Error(`Routine '${name}' created with no starting tasks.`);
|
|
7924
8947
|
}
|
|
7925
|
-
|
|
8948
|
+
const createdRoutine = new GraphRoutine(name, tasks, description, true);
|
|
8949
|
+
this.routineCache.set(name, createdRoutine);
|
|
8950
|
+
return createdRoutine;
|
|
8951
|
+
}
|
|
8952
|
+
static snapshotRuntime() {
|
|
8953
|
+
const taskMap = /* @__PURE__ */ new Map();
|
|
8954
|
+
for (const task of this.taskCache.values()) {
|
|
8955
|
+
taskMap.set(task.name, task);
|
|
8956
|
+
}
|
|
8957
|
+
for (const task of this.registry?.tasks.values() ?? []) {
|
|
8958
|
+
taskMap.set(task.name, task);
|
|
8959
|
+
}
|
|
8960
|
+
const tasks = Array.from(taskMap.values()).map((task) => {
|
|
8961
|
+
const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
|
|
8962
|
+
task.name
|
|
8963
|
+
);
|
|
8964
|
+
const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
|
|
8965
|
+
return {
|
|
8966
|
+
name: task.name,
|
|
8967
|
+
version: task.version,
|
|
8968
|
+
description: task.description,
|
|
8969
|
+
kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
|
|
8970
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name) === true,
|
|
8971
|
+
language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
|
|
8972
|
+
handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
|
|
8973
|
+
concurrency: task.concurrency,
|
|
8974
|
+
timeout: task.timeout,
|
|
8975
|
+
retryCount: task.retryCount,
|
|
8976
|
+
retryDelay: task.retryDelay,
|
|
8977
|
+
retryDelayMax: task.retryDelayMax,
|
|
8978
|
+
retryDelayFactor: task.retryDelayFactor,
|
|
8979
|
+
validateInputContext: task.validateInputContext,
|
|
8980
|
+
validateOutputContext: task.validateOutputContext,
|
|
8981
|
+
inputContextSchema: sanitizeForJson(task.inputContextSchema),
|
|
8982
|
+
outputContextSchema: sanitizeForJson(task.outputContextSchema),
|
|
8983
|
+
nextTaskNames: Array.from(task.nextTasks).map((nextTask) => nextTask.name),
|
|
8984
|
+
predecessorTaskNames: Array.from(task.predecessorTasks).map(
|
|
8985
|
+
(predecessorTask) => predecessorTask.name
|
|
8986
|
+
),
|
|
8987
|
+
signals: {
|
|
8988
|
+
emits: Array.from(task.emitsSignals),
|
|
8989
|
+
emitsAfter: Array.from(task.signalsToEmitAfter),
|
|
8990
|
+
emitsOnFail: Array.from(task.signalsToEmitOnFail),
|
|
8991
|
+
observed: Array.from(task.observedSignals)
|
|
8992
|
+
},
|
|
8993
|
+
intents: {
|
|
8994
|
+
handles: Array.from(task.handlesIntents),
|
|
8995
|
+
inquires: Array.from(task.inquiresIntents)
|
|
8996
|
+
},
|
|
8997
|
+
tools: {
|
|
8998
|
+
helpers: Object.fromEntries(task.helperAliases),
|
|
8999
|
+
globals: Object.fromEntries(task.globalAliases)
|
|
9000
|
+
},
|
|
9001
|
+
actorName: runtimeActorTaskDefinition?.actorName ?? null,
|
|
9002
|
+
actorMode: runtimeActorTaskDefinition?.mode ?? null
|
|
9003
|
+
};
|
|
9004
|
+
});
|
|
9005
|
+
const helpers = this.getAllHelpers().map((helper) => {
|
|
9006
|
+
const runtimeHelperDefinition = runtimeDefinitionRegistry.helperDefinitions.get(helper.name);
|
|
9007
|
+
return {
|
|
9008
|
+
name: helper.name,
|
|
9009
|
+
version: helper.version,
|
|
9010
|
+
description: helper.description,
|
|
9011
|
+
kind: helper.isMeta ? "metaHelper" : "helper",
|
|
9012
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedHelper(helper.name),
|
|
9013
|
+
language: runtimeHelperDefinition?.language ?? null,
|
|
9014
|
+
handlerSource: runtimeHelperDefinition?.handlerSource ?? null,
|
|
9015
|
+
tools: {
|
|
9016
|
+
helpers: Object.fromEntries(helper.helperAliases),
|
|
9017
|
+
globals: Object.fromEntries(helper.globalAliases)
|
|
9018
|
+
}
|
|
9019
|
+
};
|
|
9020
|
+
});
|
|
9021
|
+
const globals = this.getAllGlobals().map((globalDefinition) => ({
|
|
9022
|
+
name: globalDefinition.name,
|
|
9023
|
+
version: globalDefinition.version,
|
|
9024
|
+
description: globalDefinition.description,
|
|
9025
|
+
kind: globalDefinition.isMeta ? "metaGlobal" : "global",
|
|
9026
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedGlobal(
|
|
9027
|
+
globalDefinition.name
|
|
9028
|
+
),
|
|
9029
|
+
value: sanitizeForJson(globalDefinition.value)
|
|
9030
|
+
}));
|
|
9031
|
+
const routineMap = /* @__PURE__ */ new Map();
|
|
9032
|
+
for (const routine of this.routineCache.values()) {
|
|
9033
|
+
routineMap.set(routine.name, routine);
|
|
9034
|
+
}
|
|
9035
|
+
for (const routine of this.registry?.routines.values() ?? []) {
|
|
9036
|
+
routineMap.set(routine.name, routine);
|
|
9037
|
+
}
|
|
9038
|
+
const routines = Array.from(routineMap.values()).map(
|
|
9039
|
+
(routine) => ({
|
|
9040
|
+
name: routine.name,
|
|
9041
|
+
version: routine.version,
|
|
9042
|
+
description: routine.description,
|
|
9043
|
+
isMeta: routine.isMeta,
|
|
9044
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(routine.name) === true,
|
|
9045
|
+
startTaskNames: Array.from(routine.tasks).map((task) => task.name),
|
|
9046
|
+
observedSignals: Array.from(routine.observedSignals)
|
|
9047
|
+
})
|
|
9048
|
+
);
|
|
9049
|
+
const intents = Array.from(this.inquiryBroker?.intents.values() ?? []).map(
|
|
9050
|
+
(intent) => {
|
|
9051
|
+
const sanitizedIntent = sanitizeForJson(intent);
|
|
9052
|
+
return {
|
|
9053
|
+
...sanitizedIntent,
|
|
9054
|
+
runtimeOwned: runtimeDefinitionRegistry.intentDefinitions.has(
|
|
9055
|
+
intent.name
|
|
9056
|
+
)
|
|
9057
|
+
};
|
|
9058
|
+
}
|
|
9059
|
+
);
|
|
9060
|
+
const signals = Array.from(
|
|
9061
|
+
this.signalBroker?.emittedSignalsRegistry.values() ?? []
|
|
9062
|
+
).map((signalName) => ({
|
|
9063
|
+
name: signalName,
|
|
9064
|
+
metadata: sanitizeForJson(
|
|
9065
|
+
this.signalBroker?.signalMetadataRegistry.get(signalName) ?? null
|
|
9066
|
+
) ?? null
|
|
9067
|
+
}));
|
|
9068
|
+
const actors = this.getAllActors().map((actor) => {
|
|
9069
|
+
const definition = actor.toDefinition();
|
|
9070
|
+
const actorKeys = actor.listActorKeys().map((actorKey) => ({
|
|
9071
|
+
actorKey,
|
|
9072
|
+
durableState: sanitizeForJson(actor.getDurableState(actorKey)),
|
|
9073
|
+
runtimeState: sanitizeForJson(actor.getRuntimeState(actorKey)),
|
|
9074
|
+
durableVersion: actor.getDurableVersion(actorKey),
|
|
9075
|
+
runtimeVersion: actor.getRuntimeVersion(actorKey)
|
|
9076
|
+
}));
|
|
9077
|
+
return {
|
|
9078
|
+
name: actor.spec.name,
|
|
9079
|
+
description: actor.spec.description ?? "",
|
|
9080
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedActor(
|
|
9081
|
+
actor.spec.name
|
|
9082
|
+
),
|
|
9083
|
+
definition: sanitizeForJson(definition),
|
|
9084
|
+
actorKeys
|
|
9085
|
+
};
|
|
9086
|
+
});
|
|
9087
|
+
const actorTasks = Array.from(
|
|
9088
|
+
runtimeDefinitionRegistry.actorTaskDefinitions.values()
|
|
9089
|
+
).map((definition) => ({
|
|
9090
|
+
actorName: definition.actorName,
|
|
9091
|
+
taskName: definition.taskName,
|
|
9092
|
+
description: definition.description ?? "",
|
|
9093
|
+
mode: definition.mode ?? "read",
|
|
9094
|
+
language: definition.language,
|
|
9095
|
+
handlerSource: definition.handlerSource,
|
|
9096
|
+
runtimeOwned: true
|
|
9097
|
+
}));
|
|
9098
|
+
const links = Array.from(runtimeDefinitionRegistry.taskLinks.values()).map(
|
|
9099
|
+
(link) => ({ ...link })
|
|
9100
|
+
);
|
|
9101
|
+
return {
|
|
9102
|
+
runtimeMode: "core",
|
|
9103
|
+
bootstrapped: this.isBootstrapped,
|
|
9104
|
+
mode: this.mode,
|
|
9105
|
+
tasks,
|
|
9106
|
+
helpers,
|
|
9107
|
+
globals,
|
|
9108
|
+
routines,
|
|
9109
|
+
intents,
|
|
9110
|
+
signals,
|
|
9111
|
+
actors,
|
|
9112
|
+
actorTasks,
|
|
9113
|
+
links
|
|
9114
|
+
};
|
|
7926
9115
|
}
|
|
7927
9116
|
static reset() {
|
|
7928
9117
|
this.signalBroker?.reset();
|
|
7929
9118
|
this.inquiryBroker?.reset();
|
|
7930
9119
|
this.registry?.reset();
|
|
7931
9120
|
this.taskCache.clear();
|
|
9121
|
+
this.routineCache.clear();
|
|
7932
9122
|
this.actorCache.clear();
|
|
9123
|
+
this.helperCache.clear();
|
|
9124
|
+
this.globalCache.clear();
|
|
7933
9125
|
this.runtimeInquiryDelegate = void 0;
|
|
7934
9126
|
this.runtimeValidationPolicy = {};
|
|
7935
9127
|
this.runtimeValidationScopes.clear();
|
|
7936
9128
|
this.emittedMissingSchemaWarnings.clear();
|
|
9129
|
+
this.helperExecutionDepth = 0;
|
|
9130
|
+
runtimeDefinitionRegistry.reset();
|
|
7937
9131
|
this.isBootstrapped = false;
|
|
7938
9132
|
}
|
|
7939
9133
|
};
|
|
7940
9134
|
Cadenza.taskCache = /* @__PURE__ */ new Map();
|
|
9135
|
+
Cadenza.routineCache = /* @__PURE__ */ new Map();
|
|
7941
9136
|
Cadenza.actorCache = /* @__PURE__ */ new Map();
|
|
9137
|
+
Cadenza.helperCache = /* @__PURE__ */ new Map();
|
|
9138
|
+
Cadenza.globalCache = /* @__PURE__ */ new Map();
|
|
7942
9139
|
Cadenza.runtimeValidationPolicy = {};
|
|
7943
9140
|
Cadenza.runtimeValidationScopes = /* @__PURE__ */ new Map();
|
|
7944
9141
|
Cadenza.emittedMissingSchemaWarnings = /* @__PURE__ */ new Set();
|
|
9142
|
+
Cadenza.helperExecutionDepth = 0;
|
|
7945
9143
|
Cadenza.isBootstrapped = false;
|
|
7946
9144
|
Cadenza.mode = "production";
|
|
7947
9145
|
|
|
9146
|
+
// src/runtime/RuntimeSubscriptionManager.ts
|
|
9147
|
+
var import_uuid8 = require("uuid");
|
|
9148
|
+
function isObject3(value) {
|
|
9149
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9150
|
+
}
|
|
9151
|
+
function asStringOrNull(value) {
|
|
9152
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
9153
|
+
}
|
|
9154
|
+
function asNumberOrNull(value) {
|
|
9155
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
9156
|
+
}
|
|
9157
|
+
function normalizeEventContext(context) {
|
|
9158
|
+
const sanitized = sanitizeForJson(context);
|
|
9159
|
+
return isObject3(sanitized) ? sanitized : { value: sanitized };
|
|
9160
|
+
}
|
|
9161
|
+
function matchesSignalPattern(fullSignal, signalName, patterns) {
|
|
9162
|
+
return patterns.some((pattern) => {
|
|
9163
|
+
if (pattern === "*") {
|
|
9164
|
+
return true;
|
|
9165
|
+
}
|
|
9166
|
+
if (pattern === fullSignal || pattern === signalName) {
|
|
9167
|
+
return true;
|
|
9168
|
+
}
|
|
9169
|
+
if (!pattern.endsWith(".*")) {
|
|
9170
|
+
return false;
|
|
9171
|
+
}
|
|
9172
|
+
const prefix = pattern.slice(0, -2);
|
|
9173
|
+
return signalName === prefix || signalName.startsWith(`${prefix}.`);
|
|
9174
|
+
});
|
|
9175
|
+
}
|
|
9176
|
+
var RuntimeSubscriptionManagerError = class extends Error {
|
|
9177
|
+
constructor(code, message) {
|
|
9178
|
+
super(message);
|
|
9179
|
+
this.code = code;
|
|
9180
|
+
this.name = "RuntimeSubscriptionManagerError";
|
|
9181
|
+
}
|
|
9182
|
+
};
|
|
9183
|
+
var RuntimeSubscriptionManager = class {
|
|
9184
|
+
constructor() {
|
|
9185
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
9186
|
+
this.removeBrokerListener = null;
|
|
9187
|
+
this.nextSequence = 0;
|
|
9188
|
+
this.attach();
|
|
9189
|
+
}
|
|
9190
|
+
dispose() {
|
|
9191
|
+
this.reset();
|
|
9192
|
+
this.removeBrokerListener?.();
|
|
9193
|
+
this.removeBrokerListener = null;
|
|
9194
|
+
}
|
|
9195
|
+
subscribe(signalPatterns, maxQueueSize) {
|
|
9196
|
+
this.attach();
|
|
9197
|
+
const descriptor = {
|
|
9198
|
+
subscriptionId: (0, import_uuid8.v4)(),
|
|
9199
|
+
signalPatterns: [...signalPatterns],
|
|
9200
|
+
maxQueueSize,
|
|
9201
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9202
|
+
pendingEvents: 0
|
|
9203
|
+
};
|
|
9204
|
+
this.subscriptions.set(descriptor.subscriptionId, {
|
|
9205
|
+
descriptor,
|
|
9206
|
+
events: [],
|
|
9207
|
+
nextWaiter: null
|
|
9208
|
+
});
|
|
9209
|
+
return { ...descriptor };
|
|
9210
|
+
}
|
|
9211
|
+
unsubscribe(subscriptionId) {
|
|
9212
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9213
|
+
this.clearWaiter(
|
|
9214
|
+
subscription,
|
|
9215
|
+
new RuntimeSubscriptionManagerError(
|
|
9216
|
+
"not_found",
|
|
9217
|
+
`Subscription "${subscriptionId}" was closed`
|
|
9218
|
+
)
|
|
9219
|
+
);
|
|
9220
|
+
this.subscriptions.delete(subscriptionId);
|
|
9221
|
+
return { ...subscription.descriptor };
|
|
9222
|
+
}
|
|
9223
|
+
async nextEvent(subscriptionId, timeoutMs) {
|
|
9224
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9225
|
+
if (subscription.events.length > 0) {
|
|
9226
|
+
const event = subscription.events.shift() ?? null;
|
|
9227
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9228
|
+
return {
|
|
9229
|
+
subscriptionId,
|
|
9230
|
+
event,
|
|
9231
|
+
timedOut: false,
|
|
9232
|
+
pendingEvents: subscription.events.length
|
|
9233
|
+
};
|
|
9234
|
+
}
|
|
9235
|
+
if (timeoutMs <= 0) {
|
|
9236
|
+
return {
|
|
9237
|
+
subscriptionId,
|
|
9238
|
+
event: null,
|
|
9239
|
+
timedOut: true,
|
|
9240
|
+
pendingEvents: 0
|
|
9241
|
+
};
|
|
9242
|
+
}
|
|
9243
|
+
if (subscription.nextWaiter) {
|
|
9244
|
+
throw new RuntimeSubscriptionManagerError(
|
|
9245
|
+
"conflict",
|
|
9246
|
+
`Subscription "${subscriptionId}" already has a pending nextEvent request`
|
|
9247
|
+
);
|
|
9248
|
+
}
|
|
9249
|
+
return new Promise((resolve, reject) => {
|
|
9250
|
+
const timer = setTimeout(() => {
|
|
9251
|
+
subscription.nextWaiter = null;
|
|
9252
|
+
resolve({
|
|
9253
|
+
subscriptionId,
|
|
9254
|
+
event: null,
|
|
9255
|
+
timedOut: true,
|
|
9256
|
+
pendingEvents: subscription.events.length
|
|
9257
|
+
});
|
|
9258
|
+
}, timeoutMs);
|
|
9259
|
+
subscription.nextWaiter = {
|
|
9260
|
+
resolve: (result) => {
|
|
9261
|
+
clearTimeout(timer);
|
|
9262
|
+
subscription.nextWaiter = null;
|
|
9263
|
+
resolve(result);
|
|
9264
|
+
},
|
|
9265
|
+
reject: (error) => {
|
|
9266
|
+
clearTimeout(timer);
|
|
9267
|
+
subscription.nextWaiter = null;
|
|
9268
|
+
reject(error);
|
|
9269
|
+
},
|
|
9270
|
+
timer
|
|
9271
|
+
};
|
|
9272
|
+
});
|
|
9273
|
+
}
|
|
9274
|
+
pollEvents(subscriptionId, limit) {
|
|
9275
|
+
const subscription = this.requireSubscription(subscriptionId);
|
|
9276
|
+
const events = subscription.events.splice(0, limit);
|
|
9277
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9278
|
+
return {
|
|
9279
|
+
subscriptionId,
|
|
9280
|
+
events,
|
|
9281
|
+
pendingEvents: subscription.events.length
|
|
9282
|
+
};
|
|
9283
|
+
}
|
|
9284
|
+
reset() {
|
|
9285
|
+
for (const subscription of this.subscriptions.values()) {
|
|
9286
|
+
this.clearWaiter(
|
|
9287
|
+
subscription,
|
|
9288
|
+
new RuntimeSubscriptionManagerError(
|
|
9289
|
+
"not_found",
|
|
9290
|
+
`Subscription "${subscription.descriptor.subscriptionId}" was reset`
|
|
9291
|
+
)
|
|
9292
|
+
);
|
|
9293
|
+
subscription.events.length = 0;
|
|
9294
|
+
subscription.descriptor.pendingEvents = 0;
|
|
9295
|
+
}
|
|
9296
|
+
this.subscriptions.clear();
|
|
9297
|
+
}
|
|
9298
|
+
attach() {
|
|
9299
|
+
if (this.removeBrokerListener) {
|
|
9300
|
+
return;
|
|
9301
|
+
}
|
|
9302
|
+
Cadenza.bootstrap();
|
|
9303
|
+
this.removeBrokerListener = Cadenza.signalBroker.addPassiveSignalListener(
|
|
9304
|
+
(signal, context, metadata) => this.captureSignal(signal, context, metadata)
|
|
9305
|
+
);
|
|
9306
|
+
}
|
|
9307
|
+
captureSignal(signal, context, metadata) {
|
|
9308
|
+
if (this.subscriptions.size === 0) {
|
|
9309
|
+
return;
|
|
9310
|
+
}
|
|
9311
|
+
const normalizedContext = normalizeEventContext(context);
|
|
9312
|
+
const emission = isObject3(normalizedContext.__signalEmission) ? normalizedContext.__signalEmission : {};
|
|
9313
|
+
const metadataObject = isObject3(normalizedContext.__metadata) ? normalizedContext.__metadata : {};
|
|
9314
|
+
const fullSignal = signal;
|
|
9315
|
+
const [baseSignalName, ...signalTagParts] = signal.split(":");
|
|
9316
|
+
const signalName = baseSignalName ?? signal;
|
|
9317
|
+
const signalTag = signalTagParts.length > 0 ? signalTagParts.join(":") : null;
|
|
9318
|
+
const eventTemplate = {
|
|
9319
|
+
type: "signal",
|
|
9320
|
+
signal: fullSignal,
|
|
9321
|
+
signalName,
|
|
9322
|
+
signalTag,
|
|
9323
|
+
emittedAt: asStringOrNull(emission.emittedAt),
|
|
9324
|
+
isMeta: emission.isMeta === true || signalName.startsWith("meta."),
|
|
9325
|
+
isSubMeta: normalizedContext.__isSubMeta === true || signalName.startsWith("sub_meta."),
|
|
9326
|
+
metadata: sanitizeForJson(metadata) ?? null,
|
|
9327
|
+
source: {
|
|
9328
|
+
taskName: asStringOrNull(emission.taskName),
|
|
9329
|
+
taskVersion: asNumberOrNull(emission.taskVersion),
|
|
9330
|
+
taskExecutionId: asStringOrNull(emission.taskExecutionId),
|
|
9331
|
+
routineName: asStringOrNull(normalizedContext.__routineName) ?? asStringOrNull(emission.routineName),
|
|
9332
|
+
routineVersion: asNumberOrNull(normalizedContext.__routineVersion) ?? asNumberOrNull(emission.routineVersion),
|
|
9333
|
+
routineExecutionId: asStringOrNull(normalizedContext.__routineExecId) ?? asStringOrNull(emission.routineExecutionId),
|
|
9334
|
+
executionTraceId: asStringOrNull(emission.executionTraceId) ?? asStringOrNull(normalizedContext.__executionTraceId) ?? asStringOrNull(metadataObject.__executionTraceId),
|
|
9335
|
+
consumed: emission.consumed === true,
|
|
9336
|
+
consumedBy: asStringOrNull(emission.consumedBy)
|
|
9337
|
+
},
|
|
9338
|
+
context: normalizedContext
|
|
9339
|
+
};
|
|
9340
|
+
for (const subscription of this.subscriptions.values()) {
|
|
9341
|
+
if (!matchesSignalPattern(
|
|
9342
|
+
fullSignal,
|
|
9343
|
+
signalName,
|
|
9344
|
+
subscription.descriptor.signalPatterns
|
|
9345
|
+
)) {
|
|
9346
|
+
continue;
|
|
9347
|
+
}
|
|
9348
|
+
const event = {
|
|
9349
|
+
id: (0, import_uuid8.v4)(),
|
|
9350
|
+
subscriptionId: subscription.descriptor.subscriptionId,
|
|
9351
|
+
sequence: ++this.nextSequence,
|
|
9352
|
+
...eventTemplate
|
|
9353
|
+
};
|
|
9354
|
+
if (subscription.nextWaiter) {
|
|
9355
|
+
subscription.nextWaiter.resolve({
|
|
9356
|
+
subscriptionId: subscription.descriptor.subscriptionId,
|
|
9357
|
+
event,
|
|
9358
|
+
timedOut: false,
|
|
9359
|
+
pendingEvents: subscription.events.length
|
|
9360
|
+
});
|
|
9361
|
+
continue;
|
|
9362
|
+
}
|
|
9363
|
+
subscription.events.push(event);
|
|
9364
|
+
if (subscription.events.length > subscription.descriptor.maxQueueSize) {
|
|
9365
|
+
subscription.events.shift();
|
|
9366
|
+
}
|
|
9367
|
+
subscription.descriptor.pendingEvents = subscription.events.length;
|
|
9368
|
+
}
|
|
9369
|
+
}
|
|
9370
|
+
clearWaiter(subscription, error) {
|
|
9371
|
+
if (!subscription.nextWaiter) {
|
|
9372
|
+
return;
|
|
9373
|
+
}
|
|
9374
|
+
if (subscription.nextWaiter.timer) {
|
|
9375
|
+
clearTimeout(subscription.nextWaiter.timer);
|
|
9376
|
+
}
|
|
9377
|
+
subscription.nextWaiter.reject(error);
|
|
9378
|
+
subscription.nextWaiter = null;
|
|
9379
|
+
}
|
|
9380
|
+
requireSubscription(subscriptionId) {
|
|
9381
|
+
const subscription = this.subscriptions.get(subscriptionId);
|
|
9382
|
+
if (!subscription) {
|
|
9383
|
+
throw new RuntimeSubscriptionManagerError(
|
|
9384
|
+
"not_found",
|
|
9385
|
+
`No subscription named "${subscriptionId}" exists`
|
|
9386
|
+
);
|
|
9387
|
+
}
|
|
9388
|
+
return subscription;
|
|
9389
|
+
}
|
|
9390
|
+
};
|
|
9391
|
+
|
|
9392
|
+
// src/runtime/RuntimeHost.ts
|
|
9393
|
+
var SUPPORTED_OPERATIONS = [
|
|
9394
|
+
"runtime.bootstrap",
|
|
9395
|
+
"runtime.info",
|
|
9396
|
+
"runtime.detach",
|
|
9397
|
+
"runtime.shutdown",
|
|
9398
|
+
"runtime.reset",
|
|
9399
|
+
"runtime.snapshot",
|
|
9400
|
+
"runtime.subscribe",
|
|
9401
|
+
"runtime.unsubscribe",
|
|
9402
|
+
"runtime.nextEvent",
|
|
9403
|
+
"runtime.pollEvents",
|
|
9404
|
+
"task.upsert",
|
|
9405
|
+
"helper.upsert",
|
|
9406
|
+
"global.upsert",
|
|
9407
|
+
"task.link",
|
|
9408
|
+
"task.observeSignal",
|
|
9409
|
+
"task.emitSignal",
|
|
9410
|
+
"task.respondToIntent",
|
|
9411
|
+
"task.useHelper",
|
|
9412
|
+
"task.useGlobal",
|
|
9413
|
+
"helper.useHelper",
|
|
9414
|
+
"helper.useGlobal",
|
|
9415
|
+
"routine.upsert",
|
|
9416
|
+
"routine.observeSignal",
|
|
9417
|
+
"intent.upsert",
|
|
9418
|
+
"actor.upsert",
|
|
9419
|
+
"actorTask.upsert",
|
|
9420
|
+
"run",
|
|
9421
|
+
"emit",
|
|
9422
|
+
"inquire"
|
|
9423
|
+
];
|
|
9424
|
+
var RuntimeProtocolException = class extends Error {
|
|
9425
|
+
constructor(code, message, details) {
|
|
9426
|
+
super(message);
|
|
9427
|
+
this.code = code;
|
|
9428
|
+
this.details = details;
|
|
9429
|
+
this.name = "RuntimeProtocolException";
|
|
9430
|
+
}
|
|
9431
|
+
};
|
|
9432
|
+
function isObject4(value) {
|
|
9433
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9434
|
+
}
|
|
9435
|
+
function assertObject(value, message) {
|
|
9436
|
+
if (!isObject4(value)) {
|
|
9437
|
+
throw new RuntimeProtocolException("invalid_payload", message);
|
|
9438
|
+
}
|
|
9439
|
+
}
|
|
9440
|
+
function assertString(value, fieldName) {
|
|
9441
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
9442
|
+
throw new RuntimeProtocolException(
|
|
9443
|
+
"invalid_payload",
|
|
9444
|
+
`${fieldName} must be a non-empty string`
|
|
9445
|
+
);
|
|
9446
|
+
}
|
|
9447
|
+
return value;
|
|
9448
|
+
}
|
|
9449
|
+
function assertStringArray(value, fieldName) {
|
|
9450
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
9451
|
+
throw new RuntimeProtocolException(
|
|
9452
|
+
"invalid_payload",
|
|
9453
|
+
`${fieldName} must be an array of strings`
|
|
9454
|
+
);
|
|
9455
|
+
}
|
|
9456
|
+
return value;
|
|
9457
|
+
}
|
|
9458
|
+
function normalizeSignalDefinition2(signal) {
|
|
9459
|
+
if (typeof signal === "string") {
|
|
9460
|
+
return signal;
|
|
9461
|
+
}
|
|
9462
|
+
if (isObject4(signal) && typeof signal.name === "string" && signal.name.trim().length > 0) {
|
|
9463
|
+
return {
|
|
9464
|
+
name: signal.name,
|
|
9465
|
+
deliveryMode: signal.deliveryMode === "single" || signal.deliveryMode === "broadcast" ? signal.deliveryMode : void 0,
|
|
9466
|
+
broadcastFilter: signal.broadcastFilter && isObject4(signal.broadcastFilter) ? signal.broadcastFilter : null
|
|
9467
|
+
};
|
|
9468
|
+
}
|
|
9469
|
+
throw new RuntimeProtocolException(
|
|
9470
|
+
"invalid_payload",
|
|
9471
|
+
"signal must be a signal string or structured signal definition"
|
|
9472
|
+
);
|
|
9473
|
+
}
|
|
9474
|
+
var RuntimeHost = class {
|
|
9475
|
+
constructor(options = {}) {
|
|
9476
|
+
this.pendingControlAction = null;
|
|
9477
|
+
this.subscriptionManager = new RuntimeSubscriptionManager();
|
|
9478
|
+
this.runtimeSharing = options.runtimeSharing ?? "isolated";
|
|
9479
|
+
this.runtimeName = options.runtimeName ?? null;
|
|
9480
|
+
this.sessionId = options.sessionId ?? null;
|
|
9481
|
+
this.sessionRole = options.sessionRole ?? null;
|
|
9482
|
+
this.activeSessionCountProvider = options.activeSessionCountProvider ?? (() => 1);
|
|
9483
|
+
this.daemonProcessId = options.daemonProcessId ?? null;
|
|
9484
|
+
this.onResetRuntime = options.onResetRuntime ?? null;
|
|
9485
|
+
}
|
|
9486
|
+
dispose() {
|
|
9487
|
+
this.subscriptionManager.dispose();
|
|
9488
|
+
}
|
|
9489
|
+
resetSubscriptions() {
|
|
9490
|
+
this.subscriptionManager.reset();
|
|
9491
|
+
}
|
|
9492
|
+
consumeControlAction() {
|
|
9493
|
+
const action = this.pendingControlAction;
|
|
9494
|
+
this.pendingControlAction = null;
|
|
9495
|
+
return action;
|
|
9496
|
+
}
|
|
9497
|
+
handshake() {
|
|
9498
|
+
return {
|
|
9499
|
+
ready: true,
|
|
9500
|
+
protocol: "cadenza-runtime-jsonl",
|
|
9501
|
+
protocolVersion: "1",
|
|
9502
|
+
runtimeMode: "core",
|
|
9503
|
+
runtimeSharing: this.runtimeSharing,
|
|
9504
|
+
runtimeName: this.runtimeName,
|
|
9505
|
+
sessionId: this.sessionId,
|
|
9506
|
+
sessionRole: this.sessionRole,
|
|
9507
|
+
supportedOperations: [...SUPPORTED_OPERATIONS]
|
|
9508
|
+
};
|
|
9509
|
+
}
|
|
9510
|
+
async handle(request) {
|
|
9511
|
+
try {
|
|
9512
|
+
if (!request || typeof request !== "object") {
|
|
9513
|
+
throw new RuntimeProtocolException(
|
|
9514
|
+
"invalid_request",
|
|
9515
|
+
"Request must be an object"
|
|
9516
|
+
);
|
|
9517
|
+
}
|
|
9518
|
+
if (typeof request.operation !== "string" || !SUPPORTED_OPERATIONS.includes(
|
|
9519
|
+
request.operation
|
|
9520
|
+
)) {
|
|
9521
|
+
throw new RuntimeProtocolException(
|
|
9522
|
+
"unsupported_operation",
|
|
9523
|
+
`Unsupported operation: ${String(request.operation ?? "")}`
|
|
9524
|
+
);
|
|
9525
|
+
}
|
|
9526
|
+
const operation = request.operation;
|
|
9527
|
+
this.assertOperationAllowed(operation);
|
|
9528
|
+
const result = await this.dispatch(operation, request.payload);
|
|
9529
|
+
return {
|
|
9530
|
+
id: request.id,
|
|
9531
|
+
operation,
|
|
9532
|
+
ok: true,
|
|
9533
|
+
result: sanitizeForJson(result)
|
|
9534
|
+
};
|
|
9535
|
+
} catch (error) {
|
|
9536
|
+
const normalizedError = this.normalizeError(error);
|
|
9537
|
+
return {
|
|
9538
|
+
id: request?.id,
|
|
9539
|
+
operation: typeof request?.operation === "string" ? request.operation : "runtime.snapshot",
|
|
9540
|
+
ok: false,
|
|
9541
|
+
error: normalizedError
|
|
9542
|
+
};
|
|
9543
|
+
}
|
|
9544
|
+
}
|
|
9545
|
+
normalizeError(error) {
|
|
9546
|
+
if (error instanceof RuntimeSubscriptionManagerError) {
|
|
9547
|
+
return {
|
|
9548
|
+
code: error.code,
|
|
9549
|
+
message: error.message
|
|
9550
|
+
};
|
|
9551
|
+
}
|
|
9552
|
+
if (error instanceof RuntimeProtocolException) {
|
|
9553
|
+
return {
|
|
9554
|
+
code: error.code,
|
|
9555
|
+
message: error.message,
|
|
9556
|
+
details: error.details ? sanitizeForJson(error.details) : void 0
|
|
9557
|
+
};
|
|
9558
|
+
}
|
|
9559
|
+
if (error instanceof Error) {
|
|
9560
|
+
return {
|
|
9561
|
+
code: "runtime_error",
|
|
9562
|
+
message: error.message
|
|
9563
|
+
};
|
|
9564
|
+
}
|
|
9565
|
+
return {
|
|
9566
|
+
code: "runtime_error",
|
|
9567
|
+
message: String(error)
|
|
9568
|
+
};
|
|
9569
|
+
}
|
|
9570
|
+
async dispatch(operation, payload) {
|
|
9571
|
+
switch (operation) {
|
|
9572
|
+
case "runtime.bootstrap":
|
|
9573
|
+
return this.bootstrapRuntime(payload);
|
|
9574
|
+
case "runtime.info":
|
|
9575
|
+
return this.runtimeInfo();
|
|
9576
|
+
case "runtime.detach":
|
|
9577
|
+
return this.detachRuntime();
|
|
9578
|
+
case "runtime.shutdown":
|
|
9579
|
+
return this.shutdownRuntime();
|
|
9580
|
+
case "runtime.reset":
|
|
9581
|
+
return this.resetRuntime();
|
|
9582
|
+
case "runtime.snapshot":
|
|
9583
|
+
return Cadenza.snapshotRuntime();
|
|
9584
|
+
case "runtime.subscribe":
|
|
9585
|
+
return this.subscribe(payload);
|
|
9586
|
+
case "runtime.unsubscribe":
|
|
9587
|
+
return this.unsubscribe(payload);
|
|
9588
|
+
case "runtime.nextEvent":
|
|
9589
|
+
return this.nextEvent(payload);
|
|
9590
|
+
case "runtime.pollEvents":
|
|
9591
|
+
return this.pollEvents(payload);
|
|
9592
|
+
case "task.upsert":
|
|
9593
|
+
return this.upsertTask(payload);
|
|
9594
|
+
case "helper.upsert":
|
|
9595
|
+
return this.upsertHelper(payload);
|
|
9596
|
+
case "global.upsert":
|
|
9597
|
+
return this.upsertGlobal(payload);
|
|
9598
|
+
case "task.link":
|
|
9599
|
+
return this.linkTasks(payload);
|
|
9600
|
+
case "task.observeSignal":
|
|
9601
|
+
return this.observeTaskSignal(payload);
|
|
9602
|
+
case "task.emitSignal":
|
|
9603
|
+
return this.emitTaskSignal(payload);
|
|
9604
|
+
case "task.respondToIntent":
|
|
9605
|
+
return this.bindTaskIntent(payload);
|
|
9606
|
+
case "task.useHelper":
|
|
9607
|
+
return this.bindTaskHelper(payload);
|
|
9608
|
+
case "task.useGlobal":
|
|
9609
|
+
return this.bindTaskGlobal(payload);
|
|
9610
|
+
case "helper.useHelper":
|
|
9611
|
+
return this.bindHelperHelper(payload);
|
|
9612
|
+
case "helper.useGlobal":
|
|
9613
|
+
return this.bindHelperGlobal(payload);
|
|
9614
|
+
case "routine.upsert":
|
|
9615
|
+
return this.upsertRoutine(payload);
|
|
9616
|
+
case "routine.observeSignal":
|
|
9617
|
+
return this.observeRoutineSignal(payload);
|
|
9618
|
+
case "intent.upsert":
|
|
9619
|
+
return this.upsertIntent(payload);
|
|
9620
|
+
case "actor.upsert":
|
|
9621
|
+
return this.upsertActor(payload);
|
|
9622
|
+
case "actorTask.upsert":
|
|
9623
|
+
return this.upsertActorTask(payload);
|
|
9624
|
+
case "run":
|
|
9625
|
+
return this.runTarget(payload);
|
|
9626
|
+
case "emit":
|
|
9627
|
+
return this.emitSignal(payload);
|
|
9628
|
+
case "inquire":
|
|
9629
|
+
return this.inquireIntent(payload);
|
|
9630
|
+
}
|
|
9631
|
+
}
|
|
9632
|
+
assertOperationAllowed(operation) {
|
|
9633
|
+
if (!this.sessionRole) {
|
|
9634
|
+
return;
|
|
9635
|
+
}
|
|
9636
|
+
if (this.sessionRole === "owner") {
|
|
9637
|
+
return;
|
|
9638
|
+
}
|
|
9639
|
+
if (this.sessionRole === "writer") {
|
|
9640
|
+
if (operation === "runtime.reset" || operation === "runtime.shutdown") {
|
|
9641
|
+
throw new RuntimeProtocolException(
|
|
9642
|
+
"forbidden",
|
|
9643
|
+
`Session role "${this.sessionRole}" cannot perform ${operation}`
|
|
9644
|
+
);
|
|
9645
|
+
}
|
|
9646
|
+
return;
|
|
9647
|
+
}
|
|
9648
|
+
const observerOperations = /* @__PURE__ */ new Set([
|
|
9649
|
+
"runtime.info",
|
|
9650
|
+
"runtime.detach",
|
|
9651
|
+
"runtime.snapshot",
|
|
9652
|
+
"runtime.subscribe",
|
|
9653
|
+
"runtime.unsubscribe",
|
|
9654
|
+
"runtime.nextEvent",
|
|
9655
|
+
"runtime.pollEvents",
|
|
9656
|
+
"inquire"
|
|
9657
|
+
]);
|
|
9658
|
+
if (!observerOperations.has(operation)) {
|
|
9659
|
+
throw new RuntimeProtocolException(
|
|
9660
|
+
"forbidden",
|
|
9661
|
+
`Session role "${this.sessionRole}" cannot perform ${operation}`
|
|
9662
|
+
);
|
|
9663
|
+
}
|
|
9664
|
+
}
|
|
9665
|
+
bootstrapRuntime(payload) {
|
|
9666
|
+
const mode = isObject4(payload) && typeof payload.mode === "string" ? payload.mode : void 0;
|
|
9667
|
+
if (mode) {
|
|
9668
|
+
Cadenza.setMode(mode);
|
|
9669
|
+
} else {
|
|
9670
|
+
Cadenza.bootstrap();
|
|
9671
|
+
}
|
|
9672
|
+
return {
|
|
9673
|
+
bootstrapped: true,
|
|
9674
|
+
mode: Cadenza.mode
|
|
9675
|
+
};
|
|
9676
|
+
}
|
|
9677
|
+
runtimeInfo() {
|
|
9678
|
+
return {
|
|
9679
|
+
runtimeMode: "core",
|
|
9680
|
+
runtimeSharing: this.runtimeSharing,
|
|
9681
|
+
runtimeName: this.runtimeName,
|
|
9682
|
+
sessionId: this.sessionId,
|
|
9683
|
+
sessionRole: this.sessionRole,
|
|
9684
|
+
activeSessionCount: this.activeSessionCountProvider(),
|
|
9685
|
+
daemonProcessId: this.daemonProcessId,
|
|
9686
|
+
bootstrapped: Cadenza.isBootstrapped,
|
|
9687
|
+
mode: Cadenza.mode
|
|
9688
|
+
};
|
|
9689
|
+
}
|
|
9690
|
+
detachRuntime() {
|
|
9691
|
+
this.pendingControlAction = "detach";
|
|
9692
|
+
return {
|
|
9693
|
+
detached: true,
|
|
9694
|
+
runtimeName: this.runtimeName,
|
|
9695
|
+
sessionId: this.sessionId
|
|
9696
|
+
};
|
|
9697
|
+
}
|
|
9698
|
+
shutdownRuntime() {
|
|
9699
|
+
this.pendingControlAction = "shutdown";
|
|
9700
|
+
return {
|
|
9701
|
+
shutdown: true,
|
|
9702
|
+
runtimeName: this.runtimeName
|
|
9703
|
+
};
|
|
9704
|
+
}
|
|
9705
|
+
resetRuntime() {
|
|
9706
|
+
if (this.onResetRuntime) {
|
|
9707
|
+
this.onResetRuntime();
|
|
9708
|
+
} else {
|
|
9709
|
+
Cadenza.reset();
|
|
9710
|
+
this.subscriptionManager.reset();
|
|
9711
|
+
}
|
|
9712
|
+
return {
|
|
9713
|
+
reset: true,
|
|
9714
|
+
bootstrapped: false
|
|
9715
|
+
};
|
|
9716
|
+
}
|
|
9717
|
+
subscribe(payload) {
|
|
9718
|
+
assertObject(payload, "runtime.subscribe payload must be an object");
|
|
9719
|
+
const signalPatterns = this.parseSignalPatterns(payload.signalPatterns);
|
|
9720
|
+
const maxQueueSize = this.parsePositiveInteger(
|
|
9721
|
+
payload.maxQueueSize,
|
|
9722
|
+
"maxQueueSize",
|
|
9723
|
+
100
|
|
9724
|
+
);
|
|
9725
|
+
return {
|
|
9726
|
+
subscription: this.subscriptionManager.subscribe(signalPatterns, maxQueueSize)
|
|
9727
|
+
};
|
|
9728
|
+
}
|
|
9729
|
+
unsubscribe(payload) {
|
|
9730
|
+
assertObject(payload, "runtime.unsubscribe payload must be an object");
|
|
9731
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9732
|
+
return {
|
|
9733
|
+
unsubscribed: true,
|
|
9734
|
+
subscription: this.subscriptionManager.unsubscribe(subscriptionId)
|
|
9735
|
+
};
|
|
9736
|
+
}
|
|
9737
|
+
async nextEvent(payload) {
|
|
9738
|
+
assertObject(payload, "runtime.nextEvent payload must be an object");
|
|
9739
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9740
|
+
const timeoutMs = this.parseNonNegativeInteger(
|
|
9741
|
+
payload.timeoutMs,
|
|
9742
|
+
"timeoutMs",
|
|
9743
|
+
0
|
|
9744
|
+
);
|
|
9745
|
+
return this.subscriptionManager.nextEvent(subscriptionId, timeoutMs);
|
|
9746
|
+
}
|
|
9747
|
+
pollEvents(payload) {
|
|
9748
|
+
assertObject(payload, "runtime.pollEvents payload must be an object");
|
|
9749
|
+
const subscriptionId = assertString(payload.subscriptionId, "subscriptionId");
|
|
9750
|
+
const limit = this.parsePositiveInteger(payload.limit, "limit", 50);
|
|
9751
|
+
return this.subscriptionManager.pollEvents(subscriptionId, limit);
|
|
9752
|
+
}
|
|
9753
|
+
upsertTask(payload) {
|
|
9754
|
+
assertObject(payload, "task.upsert payload must be an object");
|
|
9755
|
+
const definition = payload;
|
|
9756
|
+
definition.name = assertString(definition.name, "name");
|
|
9757
|
+
definition.handlerSource = assertString(
|
|
9758
|
+
definition.handlerSource,
|
|
9759
|
+
"handlerSource"
|
|
9760
|
+
);
|
|
9761
|
+
definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
|
|
9762
|
+
throw new RuntimeProtocolException(
|
|
9763
|
+
"invalid_payload",
|
|
9764
|
+
"language must be 'js' or 'ts'"
|
|
9765
|
+
);
|
|
9766
|
+
})();
|
|
9767
|
+
definition.kind = definition.kind === "metaTask" ? "metaTask" : "task";
|
|
9768
|
+
runtimeDefinitionRegistry.setTaskDefinition(definition);
|
|
9769
|
+
const task = Cadenza.createTaskFromDefinition(definition);
|
|
9770
|
+
this.applyTaskDecorations(definition.name);
|
|
9771
|
+
this.applyAllTaskLinks();
|
|
9772
|
+
this.rematerializeRoutinesStartingWith(definition.name);
|
|
9773
|
+
return {
|
|
9774
|
+
task: this.snapshotTask(task)
|
|
9775
|
+
};
|
|
9776
|
+
}
|
|
9777
|
+
upsertHelper(payload) {
|
|
9778
|
+
assertObject(payload, "helper.upsert payload must be an object");
|
|
9779
|
+
const definition = payload;
|
|
9780
|
+
definition.name = assertString(definition.name, "name");
|
|
9781
|
+
definition.handlerSource = assertString(
|
|
9782
|
+
definition.handlerSource,
|
|
9783
|
+
"handlerSource"
|
|
9784
|
+
);
|
|
9785
|
+
definition.language = definition.language === "js" || definition.language === "ts" ? definition.language : (() => {
|
|
9786
|
+
throw new RuntimeProtocolException(
|
|
9787
|
+
"invalid_payload",
|
|
9788
|
+
"language must be 'js' or 'ts'"
|
|
9789
|
+
);
|
|
9790
|
+
})();
|
|
9791
|
+
definition.kind = definition.kind === "metaHelper" ? "metaHelper" : "helper";
|
|
9792
|
+
runtimeDefinitionRegistry.setHelperDefinition(definition);
|
|
9793
|
+
compileRuntimeHelperFunction(definition);
|
|
9794
|
+
Cadenza.createHelperFromDefinition(definition);
|
|
9795
|
+
this.applyHelperDecorations(definition.name);
|
|
9796
|
+
return {
|
|
9797
|
+
helper: this.snapshotHelper(definition.name)
|
|
9798
|
+
};
|
|
9799
|
+
}
|
|
9800
|
+
upsertGlobal(payload) {
|
|
9801
|
+
assertObject(payload, "global.upsert payload must be an object");
|
|
9802
|
+
const definition = {
|
|
9803
|
+
name: assertString(payload.name, "name"),
|
|
9804
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9805
|
+
kind: payload.kind === "metaGlobal" ? "metaGlobal" : "global",
|
|
9806
|
+
value: payload.value
|
|
9807
|
+
};
|
|
9808
|
+
runtimeDefinitionRegistry.setGlobalDefinition(definition);
|
|
9809
|
+
Cadenza.createGlobalFromDefinition(definition);
|
|
9810
|
+
return {
|
|
9811
|
+
global: this.snapshotGlobal(definition.name)
|
|
9812
|
+
};
|
|
9813
|
+
}
|
|
9814
|
+
linkTasks(payload) {
|
|
9815
|
+
assertObject(payload, "task.link payload must be an object");
|
|
9816
|
+
const definition = {
|
|
9817
|
+
predecessorTaskName: assertString(
|
|
9818
|
+
payload.predecessorTaskName,
|
|
9819
|
+
"predecessorTaskName"
|
|
9820
|
+
),
|
|
9821
|
+
successorTaskName: assertString(
|
|
9822
|
+
payload.successorTaskName,
|
|
9823
|
+
"successorTaskName"
|
|
9824
|
+
)
|
|
9825
|
+
};
|
|
9826
|
+
runtimeDefinitionRegistry.setTaskLink(definition);
|
|
9827
|
+
this.applyAllTaskLinks();
|
|
9828
|
+
return {
|
|
9829
|
+
linked: true,
|
|
9830
|
+
...definition
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
observeTaskSignal(payload) {
|
|
9834
|
+
assertObject(payload, "task.observeSignal payload must be an object");
|
|
9835
|
+
const definition = {
|
|
9836
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9837
|
+
signal: normalizeSignalDefinition2(payload.signal)
|
|
9838
|
+
};
|
|
9839
|
+
runtimeDefinitionRegistry.setTaskSignalObservation(definition);
|
|
9840
|
+
this.requireTask(definition.taskName).doOn(definition.signal);
|
|
9841
|
+
return {
|
|
9842
|
+
observed: true,
|
|
9843
|
+
taskName: definition.taskName,
|
|
9844
|
+
signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
|
|
9845
|
+
};
|
|
9846
|
+
}
|
|
9847
|
+
emitTaskSignal(payload) {
|
|
9848
|
+
assertObject(payload, "task.emitSignal payload must be an object");
|
|
9849
|
+
const mode = payload.mode === "attach" || payload.mode === "onFail" ? payload.mode : "after";
|
|
9850
|
+
const definition = {
|
|
9851
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9852
|
+
signal: normalizeSignalDefinition2(payload.signal),
|
|
9853
|
+
mode
|
|
9854
|
+
};
|
|
9855
|
+
runtimeDefinitionRegistry.setTaskSignalEmission(definition);
|
|
9856
|
+
const task = this.requireTask(definition.taskName);
|
|
9857
|
+
if (definition.mode === "attach") {
|
|
9858
|
+
task.attachSignal(definition.signal);
|
|
9859
|
+
} else if (definition.mode === "onFail") {
|
|
9860
|
+
task.emitsOnFail(definition.signal);
|
|
9861
|
+
} else {
|
|
9862
|
+
task.emits(definition.signal);
|
|
9863
|
+
}
|
|
9864
|
+
return {
|
|
9865
|
+
attached: true,
|
|
9866
|
+
taskName: definition.taskName,
|
|
9867
|
+
mode: definition.mode,
|
|
9868
|
+
signal: typeof definition.signal === "string" ? definition.signal : definition.signal.name
|
|
9869
|
+
};
|
|
9870
|
+
}
|
|
9871
|
+
bindTaskIntent(payload) {
|
|
9872
|
+
assertObject(payload, "task.respondToIntent payload must be an object");
|
|
9873
|
+
const taskName = assertString(payload.taskName, "taskName");
|
|
9874
|
+
const intentName = assertString(payload.intentName, "intentName");
|
|
9875
|
+
runtimeDefinitionRegistry.setTaskIntentBinding({
|
|
9876
|
+
taskName,
|
|
9877
|
+
intentName
|
|
9878
|
+
});
|
|
9879
|
+
this.requireTask(taskName).respondsTo(intentName);
|
|
9880
|
+
return {
|
|
9881
|
+
bound: true,
|
|
9882
|
+
taskName,
|
|
9883
|
+
intentName
|
|
9884
|
+
};
|
|
9885
|
+
}
|
|
9886
|
+
bindTaskHelper(payload) {
|
|
9887
|
+
assertObject(payload, "task.useHelper payload must be an object");
|
|
9888
|
+
const definition = {
|
|
9889
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9890
|
+
alias: assertString(payload.alias, "alias"),
|
|
9891
|
+
helperName: assertString(payload.helperName, "helperName")
|
|
9892
|
+
};
|
|
9893
|
+
runtimeDefinitionRegistry.setTaskHelperBinding(definition);
|
|
9894
|
+
this.requireTask(definition.taskName).usesHelpers({
|
|
9895
|
+
[definition.alias]: Cadenza.getHelper(definition.helperName)
|
|
9896
|
+
});
|
|
9897
|
+
return {
|
|
9898
|
+
bound: true,
|
|
9899
|
+
...definition
|
|
9900
|
+
};
|
|
9901
|
+
}
|
|
9902
|
+
bindTaskGlobal(payload) {
|
|
9903
|
+
assertObject(payload, "task.useGlobal payload must be an object");
|
|
9904
|
+
const definition = {
|
|
9905
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
9906
|
+
alias: assertString(payload.alias, "alias"),
|
|
9907
|
+
globalName: assertString(payload.globalName, "globalName")
|
|
9908
|
+
};
|
|
9909
|
+
runtimeDefinitionRegistry.setTaskGlobalBinding(definition);
|
|
9910
|
+
this.requireTask(definition.taskName).usesGlobals({
|
|
9911
|
+
[definition.alias]: Cadenza.getGlobal(definition.globalName)
|
|
9912
|
+
});
|
|
9913
|
+
return {
|
|
9914
|
+
bound: true,
|
|
9915
|
+
...definition
|
|
9916
|
+
};
|
|
9917
|
+
}
|
|
9918
|
+
bindHelperHelper(payload) {
|
|
9919
|
+
assertObject(payload, "helper.useHelper payload must be an object");
|
|
9920
|
+
const definition = {
|
|
9921
|
+
helperName: assertString(payload.helperName, "helperName"),
|
|
9922
|
+
alias: assertString(payload.alias, "alias"),
|
|
9923
|
+
dependencyHelperName: assertString(
|
|
9924
|
+
payload.dependencyHelperName,
|
|
9925
|
+
"dependencyHelperName"
|
|
9926
|
+
)
|
|
9927
|
+
};
|
|
9928
|
+
runtimeDefinitionRegistry.setHelperHelperBinding(definition);
|
|
9929
|
+
const helper = Cadenza.getHelper(definition.helperName);
|
|
9930
|
+
if (!helper) {
|
|
9931
|
+
throw new RuntimeProtocolException(
|
|
9932
|
+
"not_found",
|
|
9933
|
+
`No helper named "${definition.helperName}" exists`
|
|
9934
|
+
);
|
|
9935
|
+
}
|
|
9936
|
+
helper.usesHelpers({
|
|
9937
|
+
[definition.alias]: Cadenza.getHelper(definition.dependencyHelperName)
|
|
9938
|
+
});
|
|
9939
|
+
return {
|
|
9940
|
+
bound: true,
|
|
9941
|
+
...definition
|
|
9942
|
+
};
|
|
9943
|
+
}
|
|
9944
|
+
bindHelperGlobal(payload) {
|
|
9945
|
+
assertObject(payload, "helper.useGlobal payload must be an object");
|
|
9946
|
+
const definition = {
|
|
9947
|
+
helperName: assertString(payload.helperName, "helperName"),
|
|
9948
|
+
alias: assertString(payload.alias, "alias"),
|
|
9949
|
+
globalName: assertString(payload.globalName, "globalName")
|
|
9950
|
+
};
|
|
9951
|
+
runtimeDefinitionRegistry.setHelperGlobalBinding(definition);
|
|
9952
|
+
const helper = Cadenza.getHelper(definition.helperName);
|
|
9953
|
+
if (!helper) {
|
|
9954
|
+
throw new RuntimeProtocolException(
|
|
9955
|
+
"not_found",
|
|
9956
|
+
`No helper named "${definition.helperName}" exists`
|
|
9957
|
+
);
|
|
9958
|
+
}
|
|
9959
|
+
helper.usesGlobals({
|
|
9960
|
+
[definition.alias]: Cadenza.getGlobal(definition.globalName)
|
|
9961
|
+
});
|
|
9962
|
+
return {
|
|
9963
|
+
bound: true,
|
|
9964
|
+
...definition
|
|
9965
|
+
};
|
|
9966
|
+
}
|
|
9967
|
+
upsertRoutine(payload) {
|
|
9968
|
+
assertObject(payload, "routine.upsert payload must be an object");
|
|
9969
|
+
const definition = {
|
|
9970
|
+
name: assertString(payload.name, "name"),
|
|
9971
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
9972
|
+
startTaskNames: assertStringArray(payload.startTaskNames, "startTaskNames"),
|
|
9973
|
+
isMeta: payload.isMeta === true
|
|
9974
|
+
};
|
|
9975
|
+
if (definition.startTaskNames.length === 0) {
|
|
9976
|
+
throw new RuntimeProtocolException(
|
|
9977
|
+
"invalid_payload",
|
|
9978
|
+
"startTaskNames must contain at least one task name"
|
|
9979
|
+
);
|
|
9980
|
+
}
|
|
9981
|
+
runtimeDefinitionRegistry.setRoutineDefinition(definition);
|
|
9982
|
+
const routine = Cadenza.createRoutineFromDefinition(definition);
|
|
9983
|
+
this.applyRoutineDecorations(definition.name);
|
|
9984
|
+
return {
|
|
9985
|
+
routine: this.snapshotRoutine(routine)
|
|
9986
|
+
};
|
|
9987
|
+
}
|
|
9988
|
+
observeRoutineSignal(payload) {
|
|
9989
|
+
assertObject(payload, "routine.observeSignal payload must be an object");
|
|
9990
|
+
const routineName = assertString(payload.routineName, "routineName");
|
|
9991
|
+
const signal = assertString(payload.signal, "signal");
|
|
9992
|
+
runtimeDefinitionRegistry.setRoutineSignalObservation({
|
|
9993
|
+
routineName,
|
|
9994
|
+
signal
|
|
9995
|
+
});
|
|
9996
|
+
this.requireRoutine(routineName).doOn(signal);
|
|
9997
|
+
return {
|
|
9998
|
+
observed: true,
|
|
9999
|
+
routineName,
|
|
10000
|
+
signal
|
|
10001
|
+
};
|
|
10002
|
+
}
|
|
10003
|
+
upsertIntent(payload) {
|
|
10004
|
+
assertObject(payload, "intent.upsert payload must be an object");
|
|
10005
|
+
const intent = {
|
|
10006
|
+
name: assertString(payload.name, "name"),
|
|
10007
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
10008
|
+
input: isObject4(payload.input) ? payload.input : { type: "object" },
|
|
10009
|
+
output: isObject4(payload.output) ? payload.output : { type: "object" }
|
|
10010
|
+
};
|
|
10011
|
+
runtimeDefinitionRegistry.setIntentDefinition(intent);
|
|
10012
|
+
Cadenza.defineIntent(intent);
|
|
10013
|
+
return {
|
|
10014
|
+
intent: sanitizeForJson(intent)
|
|
10015
|
+
};
|
|
10016
|
+
}
|
|
10017
|
+
upsertActor(payload) {
|
|
10018
|
+
assertObject(payload, "actor.upsert payload must be an object");
|
|
10019
|
+
const definition = payload;
|
|
10020
|
+
definition.name = assertString(definition.name, "name");
|
|
10021
|
+
definition.description = assertString(definition.description, "description");
|
|
10022
|
+
definition.defaultKey = assertString(definition.defaultKey, "defaultKey");
|
|
10023
|
+
runtimeDefinitionRegistry.setActorDefinition(definition);
|
|
10024
|
+
const actor = Cadenza.createActorFromDefinition(definition);
|
|
10025
|
+
this.rematerializeActorTasksFor(definition.name);
|
|
10026
|
+
return {
|
|
10027
|
+
actor: sanitizeForJson({
|
|
10028
|
+
name: actor.spec.name,
|
|
10029
|
+
description: actor.spec.description ?? "",
|
|
10030
|
+
defaultKey: actor.spec.defaultKey
|
|
10031
|
+
})
|
|
10032
|
+
};
|
|
10033
|
+
}
|
|
10034
|
+
upsertActorTask(payload) {
|
|
10035
|
+
assertObject(payload, "actorTask.upsert payload must be an object");
|
|
10036
|
+
const definition = {
|
|
10037
|
+
actorName: assertString(payload.actorName, "actorName"),
|
|
10038
|
+
taskName: assertString(payload.taskName, "taskName"),
|
|
10039
|
+
description: typeof payload.description === "string" ? payload.description : "",
|
|
10040
|
+
mode: payload.mode === "write" || payload.mode === "meta" ? payload.mode : "read",
|
|
10041
|
+
handlerSource: assertString(payload.handlerSource, "handlerSource"),
|
|
10042
|
+
language: payload.language === "js" || payload.language === "ts" ? payload.language : (() => {
|
|
10043
|
+
throw new RuntimeProtocolException(
|
|
10044
|
+
"invalid_payload",
|
|
10045
|
+
"language must be 'js' or 'ts'"
|
|
10046
|
+
);
|
|
10047
|
+
})(),
|
|
10048
|
+
options: isObject4(payload.options) ? { ...payload.options } : void 0
|
|
10049
|
+
};
|
|
10050
|
+
runtimeDefinitionRegistry.setActorTaskDefinition(definition);
|
|
10051
|
+
const task = this.materializeActorTask(definition.taskName);
|
|
10052
|
+
this.applyTaskDecorations(definition.taskName);
|
|
10053
|
+
this.applyAllTaskLinks();
|
|
10054
|
+
this.rematerializeRoutinesStartingWith(definition.taskName);
|
|
10055
|
+
return {
|
|
10056
|
+
actorTask: this.snapshotTask(task)
|
|
10057
|
+
};
|
|
10058
|
+
}
|
|
10059
|
+
async runTarget(payload) {
|
|
10060
|
+
assertObject(payload, "run payload must be an object");
|
|
10061
|
+
const targetName = assertString(payload.targetName, "targetName");
|
|
10062
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10063
|
+
let target = Cadenza.getRoutine(targetName);
|
|
10064
|
+
if (!target) {
|
|
10065
|
+
const routineDefinition = runtimeDefinitionRegistry.routineDefinitions.get(targetName);
|
|
10066
|
+
if (routineDefinition) {
|
|
10067
|
+
target = Cadenza.createRoutineFromDefinition(routineDefinition);
|
|
10068
|
+
this.applyRoutineDecorations(targetName);
|
|
10069
|
+
}
|
|
10070
|
+
}
|
|
10071
|
+
target = target ?? Cadenza.get(targetName);
|
|
10072
|
+
if (!target) {
|
|
10073
|
+
throw new RuntimeProtocolException(
|
|
10074
|
+
"not_found",
|
|
10075
|
+
`No task or routine named "${targetName}" exists`
|
|
10076
|
+
);
|
|
10077
|
+
}
|
|
10078
|
+
const runner = "isMeta" in target && target.isMeta ? Cadenza.metaRunner : Cadenza.runner;
|
|
10079
|
+
const runResult = runner.run(target, context);
|
|
10080
|
+
const completedRun = await Promise.resolve(runResult);
|
|
10081
|
+
return {
|
|
10082
|
+
targetName,
|
|
10083
|
+
run: completedRun.export()
|
|
10084
|
+
};
|
|
10085
|
+
}
|
|
10086
|
+
emitSignal(payload) {
|
|
10087
|
+
assertObject(payload, "emit payload must be an object");
|
|
10088
|
+
const signal = assertString(payload.signal, "signal");
|
|
10089
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10090
|
+
const options = isObject4(payload.options) ? payload.options : {};
|
|
10091
|
+
Cadenza.emit(signal, context, options);
|
|
10092
|
+
return {
|
|
10093
|
+
emitted: true,
|
|
10094
|
+
signal
|
|
10095
|
+
};
|
|
10096
|
+
}
|
|
10097
|
+
async inquireIntent(payload) {
|
|
10098
|
+
assertObject(payload, "inquire payload must be an object");
|
|
10099
|
+
const inquiry = assertString(payload.intent, "intent");
|
|
10100
|
+
const context = isObject4(payload.context) ? payload.context : {};
|
|
10101
|
+
const options = isObject4(payload.options) ? payload.options : {};
|
|
10102
|
+
const response = await Cadenza.inquire(inquiry, context, options);
|
|
10103
|
+
return {
|
|
10104
|
+
inquiry,
|
|
10105
|
+
response
|
|
10106
|
+
};
|
|
10107
|
+
}
|
|
10108
|
+
requireTask(taskName) {
|
|
10109
|
+
const task = Cadenza.get(taskName);
|
|
10110
|
+
if (!task) {
|
|
10111
|
+
throw new RuntimeProtocolException(
|
|
10112
|
+
"not_found",
|
|
10113
|
+
`No task named "${taskName}" exists`
|
|
10114
|
+
);
|
|
10115
|
+
}
|
|
10116
|
+
return task;
|
|
10117
|
+
}
|
|
10118
|
+
requireRoutine(routineName) {
|
|
10119
|
+
const routine = Cadenza.getRoutine(routineName);
|
|
10120
|
+
if (!routine) {
|
|
10121
|
+
throw new RuntimeProtocolException(
|
|
10122
|
+
"not_found",
|
|
10123
|
+
`No routine named "${routineName}" exists`
|
|
10124
|
+
);
|
|
10125
|
+
}
|
|
10126
|
+
return routine;
|
|
10127
|
+
}
|
|
10128
|
+
applyTaskDecorations(taskName) {
|
|
10129
|
+
const task = this.requireTask(taskName);
|
|
10130
|
+
for (const observation of runtimeDefinitionRegistry.taskSignalObservations.values()) {
|
|
10131
|
+
if (observation.taskName !== taskName) {
|
|
10132
|
+
continue;
|
|
10133
|
+
}
|
|
10134
|
+
task.doOn(observation.signal);
|
|
10135
|
+
}
|
|
10136
|
+
for (const emission of runtimeDefinitionRegistry.taskSignalEmissions.values()) {
|
|
10137
|
+
if (emission.taskName !== taskName) {
|
|
10138
|
+
continue;
|
|
10139
|
+
}
|
|
10140
|
+
if (emission.mode === "attach") {
|
|
10141
|
+
task.attachSignal(emission.signal);
|
|
10142
|
+
} else if (emission.mode === "onFail") {
|
|
10143
|
+
task.emitsOnFail(emission.signal);
|
|
10144
|
+
} else {
|
|
10145
|
+
task.emits(emission.signal);
|
|
10146
|
+
}
|
|
10147
|
+
}
|
|
10148
|
+
for (const binding of runtimeDefinitionRegistry.taskIntentBindings.values()) {
|
|
10149
|
+
if (binding.taskName !== taskName) {
|
|
10150
|
+
continue;
|
|
10151
|
+
}
|
|
10152
|
+
task.respondsTo(binding.intentName);
|
|
10153
|
+
}
|
|
10154
|
+
for (const binding of runtimeDefinitionRegistry.taskHelperBindings.values()) {
|
|
10155
|
+
if (binding.taskName !== taskName) {
|
|
10156
|
+
continue;
|
|
10157
|
+
}
|
|
10158
|
+
task.usesHelpers({
|
|
10159
|
+
[binding.alias]: Cadenza.getHelper(binding.helperName)
|
|
10160
|
+
});
|
|
10161
|
+
}
|
|
10162
|
+
for (const binding of runtimeDefinitionRegistry.taskGlobalBindings.values()) {
|
|
10163
|
+
if (binding.taskName !== taskName) {
|
|
10164
|
+
continue;
|
|
10165
|
+
}
|
|
10166
|
+
task.usesGlobals({
|
|
10167
|
+
[binding.alias]: Cadenza.getGlobal(binding.globalName)
|
|
10168
|
+
});
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10171
|
+
applyHelperDecorations(helperName) {
|
|
10172
|
+
const helper = Cadenza.getHelper(helperName);
|
|
10173
|
+
if (!helper) {
|
|
10174
|
+
throw new RuntimeProtocolException(
|
|
10175
|
+
"not_found",
|
|
10176
|
+
`No helper named "${helperName}" exists`
|
|
10177
|
+
);
|
|
10178
|
+
}
|
|
10179
|
+
for (const binding of runtimeDefinitionRegistry.helperHelperBindings.values()) {
|
|
10180
|
+
if (binding.helperName !== helperName) {
|
|
10181
|
+
continue;
|
|
10182
|
+
}
|
|
10183
|
+
helper.usesHelpers({
|
|
10184
|
+
[binding.alias]: Cadenza.getHelper(binding.dependencyHelperName)
|
|
10185
|
+
});
|
|
10186
|
+
}
|
|
10187
|
+
for (const binding of runtimeDefinitionRegistry.helperGlobalBindings.values()) {
|
|
10188
|
+
if (binding.helperName !== helperName) {
|
|
10189
|
+
continue;
|
|
10190
|
+
}
|
|
10191
|
+
helper.usesGlobals({
|
|
10192
|
+
[binding.alias]: Cadenza.getGlobal(binding.globalName)
|
|
10193
|
+
});
|
|
10194
|
+
}
|
|
10195
|
+
}
|
|
10196
|
+
applyAllTaskLinks() {
|
|
10197
|
+
for (const link of runtimeDefinitionRegistry.taskLinks.values()) {
|
|
10198
|
+
const predecessor = Cadenza.get(link.predecessorTaskName);
|
|
10199
|
+
const successor = Cadenza.get(link.successorTaskName);
|
|
10200
|
+
if (!predecessor || !successor) {
|
|
10201
|
+
continue;
|
|
10202
|
+
}
|
|
10203
|
+
predecessor.then(successor);
|
|
10204
|
+
}
|
|
10205
|
+
}
|
|
10206
|
+
applyRoutineDecorations(routineName) {
|
|
10207
|
+
const routine = this.requireRoutine(routineName);
|
|
10208
|
+
for (const observation of runtimeDefinitionRegistry.routineSignalObservations.values()) {
|
|
10209
|
+
if (observation.routineName !== routineName) {
|
|
10210
|
+
continue;
|
|
10211
|
+
}
|
|
10212
|
+
routine.doOn(observation.signal);
|
|
10213
|
+
}
|
|
10214
|
+
}
|
|
10215
|
+
rematerializeRoutinesStartingWith(taskName) {
|
|
10216
|
+
for (const definition of runtimeDefinitionRegistry.routineDefinitions.values()) {
|
|
10217
|
+
if (!definition.startTaskNames.includes(taskName)) {
|
|
10218
|
+
continue;
|
|
10219
|
+
}
|
|
10220
|
+
const recreated = Cadenza.createRoutineFromDefinition(definition);
|
|
10221
|
+
this.applyRoutineDecorations(recreated.name);
|
|
10222
|
+
}
|
|
10223
|
+
}
|
|
10224
|
+
rematerializeActorTasksFor(actorName) {
|
|
10225
|
+
for (const definition of runtimeDefinitionRegistry.actorTaskDefinitions.values()) {
|
|
10226
|
+
if (definition.actorName !== actorName) {
|
|
10227
|
+
continue;
|
|
10228
|
+
}
|
|
10229
|
+
this.materializeActorTask(definition.taskName);
|
|
10230
|
+
this.applyTaskDecorations(definition.taskName);
|
|
10231
|
+
this.applyAllTaskLinks();
|
|
10232
|
+
this.rematerializeRoutinesStartingWith(definition.taskName);
|
|
10233
|
+
}
|
|
10234
|
+
}
|
|
10235
|
+
materializeActorTask(taskName) {
|
|
10236
|
+
const definition = runtimeDefinitionRegistry.actorTaskDefinitions.get(taskName);
|
|
10237
|
+
if (!definition) {
|
|
10238
|
+
throw new RuntimeProtocolException(
|
|
10239
|
+
"not_found",
|
|
10240
|
+
`No actor task definition named "${taskName}" exists`
|
|
10241
|
+
);
|
|
10242
|
+
}
|
|
10243
|
+
const actor = Cadenza.getActor(definition.actorName);
|
|
10244
|
+
if (!actor) {
|
|
10245
|
+
throw new RuntimeProtocolException(
|
|
10246
|
+
"not_found",
|
|
10247
|
+
`No actor named "${definition.actorName}" exists`
|
|
10248
|
+
);
|
|
10249
|
+
}
|
|
10250
|
+
const existingTask = Cadenza.get(definition.taskName);
|
|
10251
|
+
if (existingTask && !runtimeDefinitionRegistry.isRuntimeOwnedTask(existingTask.name)) {
|
|
10252
|
+
throw new RuntimeProtocolException(
|
|
10253
|
+
"conflict",
|
|
10254
|
+
`Task "${definition.taskName}" already exists and is not runtime-owned`
|
|
10255
|
+
);
|
|
10256
|
+
}
|
|
10257
|
+
existingTask?.destroy();
|
|
10258
|
+
const handler = compileRuntimeActorTaskHandler(definition);
|
|
10259
|
+
return Cadenza.createTask(
|
|
10260
|
+
definition.taskName,
|
|
10261
|
+
actor.task(handler, { mode: definition.mode }),
|
|
10262
|
+
definition.description ?? "",
|
|
10263
|
+
definition.options ?? {}
|
|
10264
|
+
);
|
|
10265
|
+
}
|
|
10266
|
+
snapshotTask(task) {
|
|
10267
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10268
|
+
const existing = snapshot.tasks.find((entry) => entry.name === task.name);
|
|
10269
|
+
if (existing) {
|
|
10270
|
+
return existing;
|
|
10271
|
+
}
|
|
10272
|
+
const runtimeTaskDefinition = runtimeDefinitionRegistry.taskDefinitions.get(
|
|
10273
|
+
task.name
|
|
10274
|
+
);
|
|
10275
|
+
const runtimeActorTaskDefinition = runtimeDefinitionRegistry.actorTaskDefinitions.get(task.name);
|
|
10276
|
+
return {
|
|
10277
|
+
name: task.name,
|
|
10278
|
+
version: task.version,
|
|
10279
|
+
description: task.description,
|
|
10280
|
+
kind: runtimeActorTaskDefinition ? "actorTask" : task.isMeta ? "metaTask" : "task",
|
|
10281
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedTask(task.name),
|
|
10282
|
+
language: runtimeTaskDefinition?.language ?? runtimeActorTaskDefinition?.language ?? null,
|
|
10283
|
+
handlerSource: runtimeTaskDefinition?.handlerSource ?? runtimeActorTaskDefinition?.handlerSource ?? null,
|
|
10284
|
+
tools: {
|
|
10285
|
+
helpers: Object.fromEntries(task.helperAliases),
|
|
10286
|
+
globals: Object.fromEntries(task.globalAliases)
|
|
10287
|
+
}
|
|
10288
|
+
};
|
|
10289
|
+
}
|
|
10290
|
+
snapshotHelper(helperName) {
|
|
10291
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10292
|
+
return snapshot.helpers.find((entry) => entry.name === helperName) ?? {
|
|
10293
|
+
name: helperName
|
|
10294
|
+
};
|
|
10295
|
+
}
|
|
10296
|
+
snapshotGlobal(globalName) {
|
|
10297
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10298
|
+
return snapshot.globals.find((entry) => entry.name === globalName) ?? {
|
|
10299
|
+
name: globalName
|
|
10300
|
+
};
|
|
10301
|
+
}
|
|
10302
|
+
snapshotRoutine(routine) {
|
|
10303
|
+
const snapshot = Cadenza.snapshotRuntime();
|
|
10304
|
+
return snapshot.routines.find((entry) => entry.name === routine.name) ?? {
|
|
10305
|
+
name: routine.name,
|
|
10306
|
+
version: routine.version,
|
|
10307
|
+
description: routine.description,
|
|
10308
|
+
isMeta: routine.isMeta,
|
|
10309
|
+
runtimeOwned: runtimeDefinitionRegistry.isRuntimeOwnedRoutine(
|
|
10310
|
+
routine.name
|
|
10311
|
+
),
|
|
10312
|
+
startTaskNames: Array.from(routine.tasks).map((task) => task.name),
|
|
10313
|
+
observedSignals: Array.from(routine.observedSignals)
|
|
10314
|
+
};
|
|
10315
|
+
}
|
|
10316
|
+
parseSignalPatterns(value) {
|
|
10317
|
+
if (value === void 0) {
|
|
10318
|
+
return ["*"];
|
|
10319
|
+
}
|
|
10320
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
|
|
10321
|
+
throw new RuntimeProtocolException(
|
|
10322
|
+
"invalid_payload",
|
|
10323
|
+
"signalPatterns must be an array of non-empty strings"
|
|
10324
|
+
);
|
|
10325
|
+
}
|
|
10326
|
+
return Array.from(new Set(value.map((entry) => entry.trim())));
|
|
10327
|
+
}
|
|
10328
|
+
parsePositiveInteger(value, fieldName, fallback) {
|
|
10329
|
+
if (value === void 0) {
|
|
10330
|
+
return fallback;
|
|
10331
|
+
}
|
|
10332
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
10333
|
+
throw new RuntimeProtocolException(
|
|
10334
|
+
"invalid_payload",
|
|
10335
|
+
`${fieldName} must be a positive integer`
|
|
10336
|
+
);
|
|
10337
|
+
}
|
|
10338
|
+
return value;
|
|
10339
|
+
}
|
|
10340
|
+
parseNonNegativeInteger(value, fieldName, fallback) {
|
|
10341
|
+
if (value === void 0) {
|
|
10342
|
+
return fallback;
|
|
10343
|
+
}
|
|
10344
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
10345
|
+
throw new RuntimeProtocolException(
|
|
10346
|
+
"invalid_payload",
|
|
10347
|
+
`${fieldName} must be a non-negative integer`
|
|
10348
|
+
);
|
|
10349
|
+
}
|
|
10350
|
+
return value;
|
|
10351
|
+
}
|
|
10352
|
+
};
|
|
10353
|
+
|
|
7948
10354
|
// src/index.ts
|
|
7949
10355
|
var index_default = Cadenza;
|
|
7950
10356
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -7952,13 +10358,16 @@ var index_default = Cadenza;
|
|
|
7952
10358
|
Actor,
|
|
7953
10359
|
DebounceTask,
|
|
7954
10360
|
EphemeralTask,
|
|
10361
|
+
GlobalDefinition,
|
|
7955
10362
|
GraphContext,
|
|
7956
10363
|
GraphRegistry,
|
|
7957
10364
|
GraphRoutine,
|
|
7958
10365
|
GraphRun,
|
|
7959
10366
|
GraphRunner,
|
|
10367
|
+
HelperDefinition,
|
|
7960
10368
|
InquiryBroker,
|
|
7961
10369
|
META_ACTOR_SESSION_STATE_PERSIST_INTENT,
|
|
10370
|
+
RuntimeHost,
|
|
7962
10371
|
SignalBroker,
|
|
7963
10372
|
SignalEmitter,
|
|
7964
10373
|
Task,
|