@cadenza.io/service 2.4.0 → 2.5.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/dist/index.d.mts +211 -133
- package/dist/index.d.ts +211 -133
- package/dist/index.js +1119 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1119 -64
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -295,6 +295,72 @@ var DatabaseTask = class extends DeputyTask {
|
|
|
295
295
|
var isNode = typeof process !== "undefined" && process.versions?.node != null;
|
|
296
296
|
var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
297
297
|
|
|
298
|
+
// src/utils/inquiry.ts
|
|
299
|
+
var META_INTENT_PREFIX = "meta-";
|
|
300
|
+
var META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT = "meta-runtime-transport-diagnostics";
|
|
301
|
+
function isPlainObject(value) {
|
|
302
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
303
|
+
}
|
|
304
|
+
function deepMergeDeterministic(left, right) {
|
|
305
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
306
|
+
return [...left, ...right];
|
|
307
|
+
}
|
|
308
|
+
if (isPlainObject(left) && isPlainObject(right)) {
|
|
309
|
+
const merged = { ...left };
|
|
310
|
+
const keys = Array.from(/* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])).sort();
|
|
311
|
+
for (const key of keys) {
|
|
312
|
+
if (!(key in left)) {
|
|
313
|
+
merged[key] = right[key];
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (!(key in right)) {
|
|
317
|
+
merged[key] = left[key];
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
merged[key] = deepMergeDeterministic(left[key], right[key]);
|
|
321
|
+
}
|
|
322
|
+
return merged;
|
|
323
|
+
}
|
|
324
|
+
return right;
|
|
325
|
+
}
|
|
326
|
+
function mergeInquiryContexts(contexts) {
|
|
327
|
+
return contexts.reduce((acc, next) => deepMergeDeterministic(acc, next), {});
|
|
328
|
+
}
|
|
329
|
+
function isMetaIntentName(intentName) {
|
|
330
|
+
return intentName.startsWith(META_INTENT_PREFIX);
|
|
331
|
+
}
|
|
332
|
+
function shouldExecuteInquiryResponder(inquiry, responderIsMeta) {
|
|
333
|
+
if (!isMetaIntentName(inquiry)) {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
return responderIsMeta;
|
|
337
|
+
}
|
|
338
|
+
function compareResponderDescriptors(left, right) {
|
|
339
|
+
if (left.serviceName !== right.serviceName) {
|
|
340
|
+
return left.serviceName.localeCompare(right.serviceName);
|
|
341
|
+
}
|
|
342
|
+
if (left.taskName !== right.taskName) {
|
|
343
|
+
return left.taskName.localeCompare(right.taskName);
|
|
344
|
+
}
|
|
345
|
+
if (left.taskVersion !== right.taskVersion) {
|
|
346
|
+
return left.taskVersion - right.taskVersion;
|
|
347
|
+
}
|
|
348
|
+
return left.localTaskName.localeCompare(right.localTaskName);
|
|
349
|
+
}
|
|
350
|
+
function summarizeResponderStatuses(statuses) {
|
|
351
|
+
let responded = 0;
|
|
352
|
+
let failed = 0;
|
|
353
|
+
let timedOut = 0;
|
|
354
|
+
let pending = 0;
|
|
355
|
+
for (const status of statuses) {
|
|
356
|
+
if (status.status === "fulfilled") responded++;
|
|
357
|
+
if (status.status === "failed") failed++;
|
|
358
|
+
if (status.status === "timed_out") timedOut++;
|
|
359
|
+
}
|
|
360
|
+
pending = Math.max(0, statuses.length - responded - failed - timedOut);
|
|
361
|
+
return { responded, failed, timedOut, pending };
|
|
362
|
+
}
|
|
363
|
+
|
|
298
364
|
// src/registry/ServiceRegistry.ts
|
|
299
365
|
var ServiceRegistry = class _ServiceRegistry {
|
|
300
366
|
/**
|
|
@@ -310,11 +376,47 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
310
376
|
this.instances = /* @__PURE__ */ new Map();
|
|
311
377
|
this.deputies = /* @__PURE__ */ new Map();
|
|
312
378
|
this.remoteSignals = /* @__PURE__ */ new Map();
|
|
379
|
+
this.remoteIntents = /* @__PURE__ */ new Map();
|
|
380
|
+
this.remoteIntentDeputiesByKey = /* @__PURE__ */ new Map();
|
|
381
|
+
this.remoteIntentDeputiesByTask = /* @__PURE__ */ new Map();
|
|
313
382
|
this.serviceName = null;
|
|
314
383
|
this.serviceInstanceId = null;
|
|
315
384
|
this.numberOfRunningGraphs = 0;
|
|
316
385
|
this.useSocket = false;
|
|
317
386
|
this.retryCount = 3;
|
|
387
|
+
CadenzaService.defineIntent({
|
|
388
|
+
name: META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT,
|
|
389
|
+
description: "Gather transport diagnostics across all services and communication clients.",
|
|
390
|
+
input: {
|
|
391
|
+
type: "object",
|
|
392
|
+
properties: {
|
|
393
|
+
detailLevel: {
|
|
394
|
+
type: "string",
|
|
395
|
+
constraints: {
|
|
396
|
+
oneOf: ["summary", "full"]
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
includeErrorHistory: {
|
|
400
|
+
type: "boolean"
|
|
401
|
+
},
|
|
402
|
+
errorHistoryLimit: {
|
|
403
|
+
type: "number",
|
|
404
|
+
constraints: {
|
|
405
|
+
min: 1,
|
|
406
|
+
max: 200
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
output: {
|
|
412
|
+
type: "object",
|
|
413
|
+
properties: {
|
|
414
|
+
transportDiagnostics: {
|
|
415
|
+
type: "object"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
318
420
|
this.handleInstanceUpdateTask = CadenzaService.createMetaTask(
|
|
319
421
|
"Handle Instance Update",
|
|
320
422
|
(ctx, emit) => {
|
|
@@ -354,7 +456,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
354
456
|
if (this.serviceName === serviceName) {
|
|
355
457
|
return false;
|
|
356
458
|
}
|
|
357
|
-
if (!isFrontend && this.deputies.has(serviceName) || this.remoteSignals.has(serviceName)) {
|
|
459
|
+
if (!isFrontend && (this.deputies.has(serviceName) || this.remoteIntents.has(serviceName)) || this.remoteSignals.has(serviceName)) {
|
|
358
460
|
const clientCreated = instances?.some(
|
|
359
461
|
(i) => i.address === address && i.port === port && i.clientCreated && i.isActive
|
|
360
462
|
);
|
|
@@ -404,7 +506,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
404
506
|
for (const serviceInstance of ctx.serviceInstances) {
|
|
405
507
|
yield { serviceInstance };
|
|
406
508
|
}
|
|
407
|
-
}).doOn(
|
|
509
|
+
}).doOn(
|
|
510
|
+
"meta.service_registry.registered_global_signals",
|
|
511
|
+
"meta.service_registry.registered_global_intents"
|
|
512
|
+
).then(this.handleInstanceUpdateTask);
|
|
408
513
|
this.handleGlobalSignalRegistrationTask = CadenzaService.createMetaTask(
|
|
409
514
|
"Handle global Signal Registration",
|
|
410
515
|
(ctx) => {
|
|
@@ -445,6 +550,32 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
445
550
|
},
|
|
446
551
|
"Handles registration of remote signals"
|
|
447
552
|
).emits("meta.service_registry.registered_global_signals").doOn("global.meta.cadenza_db.gathered_sync_data");
|
|
553
|
+
this.handleGlobalIntentRegistrationTask = CadenzaService.createMetaTask(
|
|
554
|
+
"Handle global intent registration",
|
|
555
|
+
(ctx) => {
|
|
556
|
+
const intentToTaskMaps = this.normalizeIntentMaps(ctx);
|
|
557
|
+
const sorted = intentToTaskMaps.sort((a, b) => {
|
|
558
|
+
if (a.deleted && !b.deleted) return -1;
|
|
559
|
+
if (!a.deleted && b.deleted) return 1;
|
|
560
|
+
return 0;
|
|
561
|
+
});
|
|
562
|
+
for (const map of sorted) {
|
|
563
|
+
if (map.deleted) {
|
|
564
|
+
this.unregisterRemoteIntentDeputy(map);
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
CadenzaService.inquiryBroker.addIntent({
|
|
568
|
+
name: map.intentName
|
|
569
|
+
});
|
|
570
|
+
this.registerRemoteIntentDeputy(map);
|
|
571
|
+
}
|
|
572
|
+
return true;
|
|
573
|
+
},
|
|
574
|
+
"Handles registration of remote inquiry intent responders"
|
|
575
|
+
).emits("meta.service_registry.registered_global_intents").doOn(
|
|
576
|
+
"global.meta.cadenza_db.gathered_sync_data",
|
|
577
|
+
"global.meta.graph_metadata.task_intent_associated"
|
|
578
|
+
);
|
|
448
579
|
this.handleServiceNotRespondingTask = CadenzaService.createMetaTask(
|
|
449
580
|
"Handle service not responding",
|
|
450
581
|
(ctx, emit) => {
|
|
@@ -558,7 +689,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
558
689
|
});
|
|
559
690
|
return joinedContext;
|
|
560
691
|
}
|
|
561
|
-
).emits("meta.service_registry.initial_sync_complete").then(
|
|
692
|
+
).emits("meta.service_registry.initial_sync_complete").then(
|
|
693
|
+
this.handleGlobalSignalRegistrationTask,
|
|
694
|
+
this.handleGlobalIntentRegistrationTask
|
|
695
|
+
);
|
|
562
696
|
this.fullSyncTask = CadenzaService.createMetaRoutine("Full sync", [
|
|
563
697
|
CadenzaService.createCadenzaDBQueryTask("signal_to_task_map", {
|
|
564
698
|
filter: {
|
|
@@ -566,6 +700,15 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
566
700
|
},
|
|
567
701
|
fields: ["signal_name", "service_name", "deleted"]
|
|
568
702
|
}).then(mergeSyncDataTask),
|
|
703
|
+
CadenzaService.createCadenzaDBQueryTask("intent_to_task_map", {
|
|
704
|
+
fields: [
|
|
705
|
+
"intent_name",
|
|
706
|
+
"task_name",
|
|
707
|
+
"task_version",
|
|
708
|
+
"service_name",
|
|
709
|
+
"deleted"
|
|
710
|
+
]
|
|
711
|
+
}).then(mergeSyncDataTask),
|
|
569
712
|
CadenzaService.createCadenzaDBQueryTask("service_instance", {
|
|
570
713
|
filter: {
|
|
571
714
|
deleted: false,
|
|
@@ -756,6 +899,25 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
756
899
|
__active: self?.isActive ?? false
|
|
757
900
|
};
|
|
758
901
|
}).doOn("meta.socket.status_check_requested");
|
|
902
|
+
this.collectTransportDiagnosticsTask = CadenzaService.createMetaTask(
|
|
903
|
+
"Collect transport diagnostics",
|
|
904
|
+
async (ctx) => {
|
|
905
|
+
const inquiryResult = await CadenzaService.inquire(
|
|
906
|
+
META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT,
|
|
907
|
+
{
|
|
908
|
+
detailLevel: ctx.detailLevel,
|
|
909
|
+
includeErrorHistory: ctx.includeErrorHistory,
|
|
910
|
+
errorHistoryLimit: ctx.errorHistoryLimit
|
|
911
|
+
},
|
|
912
|
+
ctx.inquiryOptions ?? ctx.__inquiryOptions ?? {}
|
|
913
|
+
);
|
|
914
|
+
return {
|
|
915
|
+
...ctx,
|
|
916
|
+
...inquiryResult
|
|
917
|
+
};
|
|
918
|
+
},
|
|
919
|
+
"Collects distributed transport diagnostics using inquiry responders."
|
|
920
|
+
).doOn("meta.service_registry.transport_diagnostics_requested").emits("meta.service_registry.transport_diagnostics_collected").emitsOnFail("meta.service_registry.transport_diagnostics_failed");
|
|
759
921
|
this.insertServiceTask = CadenzaService.createCadenzaDBInsertTask(
|
|
760
922
|
"service",
|
|
761
923
|
{
|
|
@@ -964,8 +1126,125 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
964
1126
|
if (!this._instance) this._instance = new _ServiceRegistry();
|
|
965
1127
|
return this._instance;
|
|
966
1128
|
}
|
|
1129
|
+
buildRemoteIntentDeputyKey(map) {
|
|
1130
|
+
return `${map.intentName}|${map.serviceName}|${map.taskName}|${map.taskVersion ?? 1}`;
|
|
1131
|
+
}
|
|
1132
|
+
normalizeIntentMaps(ctx) {
|
|
1133
|
+
if (Array.isArray(ctx.intentToTaskMaps)) {
|
|
1134
|
+
return ctx.intentToTaskMaps.map((m) => ({
|
|
1135
|
+
intentName: m.intentName ?? m.intent_name,
|
|
1136
|
+
serviceName: m.serviceName ?? m.service_name,
|
|
1137
|
+
taskName: m.taskName ?? m.task_name,
|
|
1138
|
+
taskVersion: m.taskVersion ?? m.task_version ?? 1,
|
|
1139
|
+
deleted: !!m.deleted
|
|
1140
|
+
})).filter((m) => m.intentName && m.serviceName && m.taskName);
|
|
1141
|
+
}
|
|
1142
|
+
const single = ctx.intentToTaskMap ?? ctx.data ?? (ctx.intentName ? ctx : void 0);
|
|
1143
|
+
if (!single) return [];
|
|
1144
|
+
const normalized = {
|
|
1145
|
+
intentName: single.intentName ?? single.intent_name,
|
|
1146
|
+
serviceName: single.serviceName ?? single.service_name,
|
|
1147
|
+
taskName: single.taskName ?? single.task_name,
|
|
1148
|
+
taskVersion: single.taskVersion ?? single.task_version ?? 1,
|
|
1149
|
+
deleted: !!single.deleted
|
|
1150
|
+
};
|
|
1151
|
+
if (!normalized.intentName || !normalized.serviceName || !normalized.taskName)
|
|
1152
|
+
return [];
|
|
1153
|
+
return [normalized];
|
|
1154
|
+
}
|
|
1155
|
+
registerRemoteIntentDeputy(map) {
|
|
1156
|
+
if (!this.serviceName || map.serviceName === this.serviceName) {
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
const key = this.buildRemoteIntentDeputyKey(map);
|
|
1160
|
+
if (this.remoteIntentDeputiesByKey.has(key)) {
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
const deputyTaskName = `Inquire ${map.intentName} via ${map.serviceName} (${map.taskName} v${map.taskVersion})`;
|
|
1164
|
+
const deputyTask = isMetaIntentName(map.intentName) ? CadenzaService.createMetaDeputyTask(map.taskName, map.serviceName, {
|
|
1165
|
+
register: false,
|
|
1166
|
+
isHidden: true,
|
|
1167
|
+
retryCount: 1,
|
|
1168
|
+
retryDelay: 50,
|
|
1169
|
+
retryDelayFactor: 1.2
|
|
1170
|
+
}) : CadenzaService.createDeputyTask(map.taskName, map.serviceName, {
|
|
1171
|
+
register: false,
|
|
1172
|
+
isHidden: true,
|
|
1173
|
+
retryCount: 1,
|
|
1174
|
+
retryDelay: 50,
|
|
1175
|
+
retryDelayFactor: 1.2
|
|
1176
|
+
});
|
|
1177
|
+
deputyTask.respondsTo(map.intentName);
|
|
1178
|
+
if (!this.remoteIntents.has(map.serviceName)) {
|
|
1179
|
+
this.remoteIntents.set(map.serviceName, /* @__PURE__ */ new Set());
|
|
1180
|
+
}
|
|
1181
|
+
this.remoteIntents.get(map.serviceName).add(map.intentName);
|
|
1182
|
+
const descriptor = {
|
|
1183
|
+
key,
|
|
1184
|
+
intentName: map.intentName,
|
|
1185
|
+
serviceName: map.serviceName,
|
|
1186
|
+
remoteTaskName: map.taskName,
|
|
1187
|
+
remoteTaskVersion: map.taskVersion,
|
|
1188
|
+
localTaskName: deputyTask.name || deputyTaskName,
|
|
1189
|
+
localTask: deputyTask
|
|
1190
|
+
};
|
|
1191
|
+
this.remoteIntentDeputiesByKey.set(key, descriptor);
|
|
1192
|
+
this.remoteIntentDeputiesByTask.set(deputyTask, descriptor);
|
|
1193
|
+
}
|
|
1194
|
+
unregisterRemoteIntentDeputy(map) {
|
|
1195
|
+
const key = this.buildRemoteIntentDeputyKey(map);
|
|
1196
|
+
const descriptor = this.remoteIntentDeputiesByKey.get(key);
|
|
1197
|
+
if (!descriptor) {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const task = descriptor.localTask;
|
|
1201
|
+
if (task) {
|
|
1202
|
+
CadenzaService.inquiryBroker.unsubscribe(descriptor.intentName, task);
|
|
1203
|
+
task.destroy();
|
|
1204
|
+
}
|
|
1205
|
+
this.remoteIntentDeputiesByTask.delete(descriptor.localTask);
|
|
1206
|
+
this.remoteIntentDeputiesByKey.delete(key);
|
|
1207
|
+
this.remoteIntents.get(descriptor.serviceName)?.delete(descriptor.intentName);
|
|
1208
|
+
if (!this.remoteIntents.get(descriptor.serviceName)?.size) {
|
|
1209
|
+
this.remoteIntents.delete(descriptor.serviceName);
|
|
1210
|
+
}
|
|
1211
|
+
const deputies = this.deputies.get(descriptor.serviceName);
|
|
1212
|
+
if (deputies) {
|
|
1213
|
+
this.deputies.set(
|
|
1214
|
+
descriptor.serviceName,
|
|
1215
|
+
deputies.filter((d) => d.localTaskName !== descriptor.localTaskName)
|
|
1216
|
+
);
|
|
1217
|
+
if (this.deputies.get(descriptor.serviceName)?.length === 0) {
|
|
1218
|
+
this.deputies.delete(descriptor.serviceName);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
getInquiryResponderDescriptor(task) {
|
|
1223
|
+
const remote = this.remoteIntentDeputiesByTask.get(task);
|
|
1224
|
+
if (remote) {
|
|
1225
|
+
return {
|
|
1226
|
+
isRemote: true,
|
|
1227
|
+
serviceName: remote.serviceName,
|
|
1228
|
+
taskName: remote.remoteTaskName,
|
|
1229
|
+
taskVersion: remote.remoteTaskVersion,
|
|
1230
|
+
localTaskName: remote.localTaskName
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
return {
|
|
1234
|
+
isRemote: false,
|
|
1235
|
+
serviceName: this.serviceName ?? "UnknownService",
|
|
1236
|
+
taskName: task.name,
|
|
1237
|
+
taskVersion: task.version,
|
|
1238
|
+
localTaskName: task.name
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
967
1241
|
reset() {
|
|
968
1242
|
this.instances.clear();
|
|
1243
|
+
this.deputies.clear();
|
|
1244
|
+
this.remoteSignals.clear();
|
|
1245
|
+
this.remoteIntents.clear();
|
|
1246
|
+
this.remoteIntentDeputiesByKey.clear();
|
|
1247
|
+
this.remoteIntentDeputiesByTask.clear();
|
|
969
1248
|
}
|
|
970
1249
|
};
|
|
971
1250
|
|
|
@@ -1082,6 +1361,8 @@ var RestController = class _RestController {
|
|
|
1082
1361
|
* It initializes and configures the REST server tasks.
|
|
1083
1362
|
*/
|
|
1084
1363
|
constructor() {
|
|
1364
|
+
this.fetchClientDiagnostics = /* @__PURE__ */ new Map();
|
|
1365
|
+
this.diagnosticsErrorHistoryLimit = 100;
|
|
1085
1366
|
/**
|
|
1086
1367
|
* Fetches data from the given URL with a specified timeout. This function performs
|
|
1087
1368
|
* a fetch request with the ability to cancel the request if it exceeds the provided timeout duration.
|
|
@@ -1122,6 +1403,11 @@ var RestController = class _RestController {
|
|
|
1122
1403
|
"meta.rest.delegation_requested",
|
|
1123
1404
|
"meta.socket.delegation_requested"
|
|
1124
1405
|
);
|
|
1406
|
+
CadenzaService.createMetaTask(
|
|
1407
|
+
"Collect fetch transport diagnostics",
|
|
1408
|
+
(ctx) => this.collectFetchTransportDiagnostics(ctx),
|
|
1409
|
+
"Responds to distributed transport diagnostics inquiries with REST/fetch client data."
|
|
1410
|
+
).respondsTo(META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT);
|
|
1125
1411
|
CadenzaService.createMetaRoutine(
|
|
1126
1412
|
"RestServer",
|
|
1127
1413
|
[
|
|
@@ -1452,6 +1738,13 @@ var RestController = class _RestController {
|
|
|
1452
1738
|
const port = protocol === "https" ? 443 : servicePort;
|
|
1453
1739
|
const URL = `${protocol}://${serviceAddress}:${port}`;
|
|
1454
1740
|
const fetchId = `${serviceAddress}_${port}`;
|
|
1741
|
+
const fetchDiagnostics = this.ensureFetchClientDiagnostics(
|
|
1742
|
+
fetchId,
|
|
1743
|
+
serviceName,
|
|
1744
|
+
URL
|
|
1745
|
+
);
|
|
1746
|
+
fetchDiagnostics.destroyed = false;
|
|
1747
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1455
1748
|
if (CadenzaService.get(`Send Handshake to ${URL}`)) {
|
|
1456
1749
|
console.error("Fetch client already exists", URL);
|
|
1457
1750
|
return;
|
|
@@ -1473,6 +1766,10 @@ var RestController = class _RestController {
|
|
|
1473
1766
|
);
|
|
1474
1767
|
if (response.__status !== "success") {
|
|
1475
1768
|
const error = response.__error ?? `Failed to connect to service ${serviceName} ${ctx2.serviceInstanceId}`;
|
|
1769
|
+
fetchDiagnostics.connected = false;
|
|
1770
|
+
fetchDiagnostics.lastHandshakeError = error;
|
|
1771
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1772
|
+
this.recordFetchClientError(fetchId, serviceName, URL, error);
|
|
1476
1773
|
CadenzaService.log(
|
|
1477
1774
|
"Fetch handshake failed.",
|
|
1478
1775
|
{ error, serviceName, URL },
|
|
@@ -1482,6 +1779,11 @@ var RestController = class _RestController {
|
|
|
1482
1779
|
return { ...ctx2, __error: error, errored: true };
|
|
1483
1780
|
}
|
|
1484
1781
|
ctx2.serviceInstanceId = response.__serviceInstanceId;
|
|
1782
|
+
fetchDiagnostics.connected = true;
|
|
1783
|
+
fetchDiagnostics.destroyed = false;
|
|
1784
|
+
fetchDiagnostics.lastHandshakeAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1785
|
+
fetchDiagnostics.lastHandshakeError = null;
|
|
1786
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1485
1787
|
CadenzaService.log("Fetch client connected.", {
|
|
1486
1788
|
response,
|
|
1487
1789
|
serviceName,
|
|
@@ -1497,6 +1799,10 @@ var RestController = class _RestController {
|
|
|
1497
1799
|
});
|
|
1498
1800
|
}
|
|
1499
1801
|
} catch (e) {
|
|
1802
|
+
fetchDiagnostics.connected = false;
|
|
1803
|
+
fetchDiagnostics.lastHandshakeError = this.getErrorMessage(e);
|
|
1804
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1805
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1500
1806
|
CadenzaService.log(
|
|
1501
1807
|
"Error in fetch handshake",
|
|
1502
1808
|
{ error: e, serviceName, URL, ctx: ctx2 },
|
|
@@ -1518,6 +1824,8 @@ var RestController = class _RestController {
|
|
|
1518
1824
|
if (ctx2.__remoteRoutineName === void 0) {
|
|
1519
1825
|
return;
|
|
1520
1826
|
}
|
|
1827
|
+
fetchDiagnostics.delegationRequests++;
|
|
1828
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1521
1829
|
let resultContext;
|
|
1522
1830
|
try {
|
|
1523
1831
|
resultContext = await this.fetchDataWithTimeout(
|
|
@@ -1531,8 +1839,21 @@ var RestController = class _RestController {
|
|
|
1531
1839
|
},
|
|
1532
1840
|
3e4
|
|
1533
1841
|
);
|
|
1842
|
+
if (resultContext?.errored || resultContext?.failed) {
|
|
1843
|
+
fetchDiagnostics.delegationFailures++;
|
|
1844
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1845
|
+
this.recordFetchClientError(
|
|
1846
|
+
fetchId,
|
|
1847
|
+
serviceName,
|
|
1848
|
+
URL,
|
|
1849
|
+
resultContext?.__error ?? resultContext?.error ?? "Delegation failed"
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1534
1852
|
} catch (e) {
|
|
1535
1853
|
console.error("Error in delegation", e);
|
|
1854
|
+
fetchDiagnostics.delegationFailures++;
|
|
1855
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1856
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1536
1857
|
resultContext = {
|
|
1537
1858
|
__error: `Error: ${e}`,
|
|
1538
1859
|
errored: true,
|
|
@@ -1558,6 +1879,8 @@ var RestController = class _RestController {
|
|
|
1558
1879
|
if (ctx2.__signalName === void 0) {
|
|
1559
1880
|
return;
|
|
1560
1881
|
}
|
|
1882
|
+
fetchDiagnostics.signalTransmissions++;
|
|
1883
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1561
1884
|
let response;
|
|
1562
1885
|
try {
|
|
1563
1886
|
response = await this.fetchDataWithTimeout(
|
|
@@ -1574,8 +1897,21 @@ var RestController = class _RestController {
|
|
|
1574
1897
|
if (ctx2.__routineExecId) {
|
|
1575
1898
|
emit(`meta.fetch.transmitted:${ctx2.__routineExecId}`, response);
|
|
1576
1899
|
}
|
|
1900
|
+
if (response?.errored || response?.failed) {
|
|
1901
|
+
fetchDiagnostics.signalFailures++;
|
|
1902
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1903
|
+
this.recordFetchClientError(
|
|
1904
|
+
fetchId,
|
|
1905
|
+
serviceName,
|
|
1906
|
+
URL,
|
|
1907
|
+
response?.__error ?? response?.error ?? "Signal transmission failed"
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1577
1910
|
} catch (e) {
|
|
1578
1911
|
console.error("Error in transmission", e);
|
|
1912
|
+
fetchDiagnostics.signalFailures++;
|
|
1913
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1914
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1579
1915
|
response = {
|
|
1580
1916
|
__error: `Error: ${e}`,
|
|
1581
1917
|
errored: true,
|
|
@@ -1593,6 +1929,8 @@ var RestController = class _RestController {
|
|
|
1593
1929
|
const statusTask = CadenzaService.createMetaTask(
|
|
1594
1930
|
`Request status from ${URL}`,
|
|
1595
1931
|
async (ctx2) => {
|
|
1932
|
+
fetchDiagnostics.statusChecks++;
|
|
1933
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1596
1934
|
let status;
|
|
1597
1935
|
try {
|
|
1598
1936
|
status = await this.fetchDataWithTimeout(
|
|
@@ -1602,7 +1940,20 @@ var RestController = class _RestController {
|
|
|
1602
1940
|
},
|
|
1603
1941
|
1e3
|
|
1604
1942
|
);
|
|
1943
|
+
if (status?.errored || status?.failed) {
|
|
1944
|
+
fetchDiagnostics.statusFailures++;
|
|
1945
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1946
|
+
this.recordFetchClientError(
|
|
1947
|
+
fetchId,
|
|
1948
|
+
serviceName,
|
|
1949
|
+
URL,
|
|
1950
|
+
status?.__error ?? status?.error ?? "Status check failed"
|
|
1951
|
+
);
|
|
1952
|
+
}
|
|
1605
1953
|
} catch (e) {
|
|
1954
|
+
fetchDiagnostics.statusFailures++;
|
|
1955
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1956
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1606
1957
|
status = {
|
|
1607
1958
|
__error: `Error: ${e}`,
|
|
1608
1959
|
errored: true,
|
|
@@ -1614,6 +1965,9 @@ var RestController = class _RestController {
|
|
|
1614
1965
|
"Requests status"
|
|
1615
1966
|
).doOn("meta.fetch.status_check_requested").emits("meta.fetch.status_checked").emitsOnFail("meta.fetch.status_check_failed");
|
|
1616
1967
|
CadenzaService.createEphemeralMetaTask("Destroy fetch client", () => {
|
|
1968
|
+
fetchDiagnostics.connected = false;
|
|
1969
|
+
fetchDiagnostics.destroyed = true;
|
|
1970
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1617
1971
|
CadenzaService.log("Destroying fetch client", { URL, serviceName });
|
|
1618
1972
|
handshakeTask.destroy();
|
|
1619
1973
|
delegateTask.destroy();
|
|
@@ -1662,6 +2016,144 @@ var RestController = class _RestController {
|
|
|
1662
2016
|
if (!this._instance) this._instance = new _RestController();
|
|
1663
2017
|
return this._instance;
|
|
1664
2018
|
}
|
|
2019
|
+
resolveTransportDiagnosticsOptions(ctx) {
|
|
2020
|
+
const detailLevel = ctx.detailLevel === "full" ? "full" : "summary";
|
|
2021
|
+
const includeErrorHistory = Boolean(ctx.includeErrorHistory);
|
|
2022
|
+
const requestedLimit = Number(ctx.errorHistoryLimit);
|
|
2023
|
+
const errorHistoryLimit = Number.isFinite(requestedLimit) ? Math.max(1, Math.min(200, Math.trunc(requestedLimit))) : 10;
|
|
2024
|
+
return {
|
|
2025
|
+
detailLevel,
|
|
2026
|
+
includeErrorHistory,
|
|
2027
|
+
errorHistoryLimit
|
|
2028
|
+
};
|
|
2029
|
+
}
|
|
2030
|
+
ensureFetchClientDiagnostics(fetchId, serviceName, url) {
|
|
2031
|
+
let state = this.fetchClientDiagnostics.get(fetchId);
|
|
2032
|
+
if (!state) {
|
|
2033
|
+
state = {
|
|
2034
|
+
fetchId,
|
|
2035
|
+
serviceName,
|
|
2036
|
+
url,
|
|
2037
|
+
connected: false,
|
|
2038
|
+
destroyed: false,
|
|
2039
|
+
lastHandshakeAt: null,
|
|
2040
|
+
lastHandshakeError: null,
|
|
2041
|
+
lastError: null,
|
|
2042
|
+
lastErrorAt: 0,
|
|
2043
|
+
errorHistory: [],
|
|
2044
|
+
delegationRequests: 0,
|
|
2045
|
+
delegationFailures: 0,
|
|
2046
|
+
signalTransmissions: 0,
|
|
2047
|
+
signalFailures: 0,
|
|
2048
|
+
statusChecks: 0,
|
|
2049
|
+
statusFailures: 0,
|
|
2050
|
+
updatedAt: Date.now()
|
|
2051
|
+
};
|
|
2052
|
+
this.fetchClientDiagnostics.set(fetchId, state);
|
|
2053
|
+
} else {
|
|
2054
|
+
state.serviceName = serviceName;
|
|
2055
|
+
state.url = url;
|
|
2056
|
+
}
|
|
2057
|
+
return state;
|
|
2058
|
+
}
|
|
2059
|
+
getErrorMessage(error) {
|
|
2060
|
+
if (error instanceof Error) {
|
|
2061
|
+
return error.message;
|
|
2062
|
+
}
|
|
2063
|
+
if (typeof error === "string") {
|
|
2064
|
+
return error;
|
|
2065
|
+
}
|
|
2066
|
+
try {
|
|
2067
|
+
return JSON.stringify(error);
|
|
2068
|
+
} catch {
|
|
2069
|
+
return String(error);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
recordFetchClientError(fetchId, serviceName, url, error) {
|
|
2073
|
+
const state = this.ensureFetchClientDiagnostics(fetchId, serviceName, url);
|
|
2074
|
+
const message = this.getErrorMessage(error);
|
|
2075
|
+
const now = Date.now();
|
|
2076
|
+
state.lastError = message;
|
|
2077
|
+
state.lastErrorAt = now;
|
|
2078
|
+
state.updatedAt = now;
|
|
2079
|
+
state.errorHistory.push({ at: new Date(now).toISOString(), message });
|
|
2080
|
+
if (state.errorHistory.length > this.diagnosticsErrorHistoryLimit) {
|
|
2081
|
+
state.errorHistory.splice(
|
|
2082
|
+
0,
|
|
2083
|
+
state.errorHistory.length - this.diagnosticsErrorHistoryLimit
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
collectFetchTransportDiagnostics(ctx) {
|
|
2088
|
+
const { detailLevel, includeErrorHistory, errorHistoryLimit } = this.resolveTransportDiagnosticsOptions(ctx);
|
|
2089
|
+
const serviceName = CadenzaService.serviceRegistry.serviceName ?? "UnknownService";
|
|
2090
|
+
const states = Array.from(this.fetchClientDiagnostics.values()).sort(
|
|
2091
|
+
(a, b) => a.fetchId.localeCompare(b.fetchId)
|
|
2092
|
+
);
|
|
2093
|
+
const summary = {
|
|
2094
|
+
detailLevel,
|
|
2095
|
+
totalClients: states.length,
|
|
2096
|
+
connectedClients: states.filter((state) => state.connected).length,
|
|
2097
|
+
destroyedClients: states.filter((state) => state.destroyed).length,
|
|
2098
|
+
delegationRequests: states.reduce(
|
|
2099
|
+
(acc, state) => acc + state.delegationRequests,
|
|
2100
|
+
0
|
|
2101
|
+
),
|
|
2102
|
+
delegationFailures: states.reduce(
|
|
2103
|
+
(acc, state) => acc + state.delegationFailures,
|
|
2104
|
+
0
|
|
2105
|
+
),
|
|
2106
|
+
signalTransmissions: states.reduce(
|
|
2107
|
+
(acc, state) => acc + state.signalTransmissions,
|
|
2108
|
+
0
|
|
2109
|
+
),
|
|
2110
|
+
signalFailures: states.reduce((acc, state) => acc + state.signalFailures, 0),
|
|
2111
|
+
statusChecks: states.reduce((acc, state) => acc + state.statusChecks, 0),
|
|
2112
|
+
statusFailures: states.reduce((acc, state) => acc + state.statusFailures, 0),
|
|
2113
|
+
latestError: states.slice().sort((a, b) => b.lastErrorAt - a.lastErrorAt).find((state) => state.lastError)?.lastError ?? null
|
|
2114
|
+
};
|
|
2115
|
+
if (detailLevel === "summary") {
|
|
2116
|
+
return {
|
|
2117
|
+
transportDiagnostics: {
|
|
2118
|
+
[serviceName]: {
|
|
2119
|
+
fetchClient: summary
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
const clients = states.map((state) => {
|
|
2125
|
+
const details = {
|
|
2126
|
+
fetchId: state.fetchId,
|
|
2127
|
+
serviceName: state.serviceName,
|
|
2128
|
+
url: state.url,
|
|
2129
|
+
connected: state.connected,
|
|
2130
|
+
destroyed: state.destroyed,
|
|
2131
|
+
lastHandshakeAt: state.lastHandshakeAt,
|
|
2132
|
+
lastHandshakeError: state.lastHandshakeError,
|
|
2133
|
+
latestError: state.lastError,
|
|
2134
|
+
delegationRequests: state.delegationRequests,
|
|
2135
|
+
delegationFailures: state.delegationFailures,
|
|
2136
|
+
signalTransmissions: state.signalTransmissions,
|
|
2137
|
+
signalFailures: state.signalFailures,
|
|
2138
|
+
statusChecks: state.statusChecks,
|
|
2139
|
+
statusFailures: state.statusFailures
|
|
2140
|
+
};
|
|
2141
|
+
if (includeErrorHistory) {
|
|
2142
|
+
details.errorHistory = state.errorHistory.slice(-errorHistoryLimit);
|
|
2143
|
+
}
|
|
2144
|
+
return details;
|
|
2145
|
+
});
|
|
2146
|
+
return {
|
|
2147
|
+
transportDiagnostics: {
|
|
2148
|
+
[serviceName]: {
|
|
2149
|
+
fetchClient: {
|
|
2150
|
+
...summary,
|
|
2151
|
+
clients
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
1665
2157
|
};
|
|
1666
2158
|
|
|
1667
2159
|
// src/network/SocketController.ts
|
|
@@ -1709,10 +2201,6 @@ var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
|
1709
2201
|
|
|
1710
2202
|
// src/network/SocketController.ts
|
|
1711
2203
|
var SocketController = class _SocketController {
|
|
1712
|
-
static get instance() {
|
|
1713
|
-
if (!this._instance) this._instance = new _SocketController();
|
|
1714
|
-
return this._instance;
|
|
1715
|
-
}
|
|
1716
2204
|
/**
|
|
1717
2205
|
* Constructs the `SocketServer`, setting up a WebSocket server with specific configurations,
|
|
1718
2206
|
* including connection state recovery, rate limiting, CORS handling, and custom event handling.
|
|
@@ -1731,6 +2219,13 @@ var SocketController = class _SocketController {
|
|
|
1731
2219
|
* Initializes the `SocketServer` to be ready for WebSocket communication.
|
|
1732
2220
|
*/
|
|
1733
2221
|
constructor() {
|
|
2222
|
+
this.socketClientDiagnostics = /* @__PURE__ */ new Map();
|
|
2223
|
+
this.diagnosticsErrorHistoryLimit = 100;
|
|
2224
|
+
CadenzaService.createMetaTask(
|
|
2225
|
+
"Collect socket transport diagnostics",
|
|
2226
|
+
(ctx) => this.collectSocketTransportDiagnostics(ctx),
|
|
2227
|
+
"Responds to distributed transport diagnostics inquiries with socket client data."
|
|
2228
|
+
).respondsTo(META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT);
|
|
1734
2229
|
CadenzaService.createMetaRoutine(
|
|
1735
2230
|
"SocketServer",
|
|
1736
2231
|
[
|
|
@@ -1958,6 +2453,13 @@ var SocketController = class _SocketController {
|
|
|
1958
2453
|
const port = protocol === "https" ? 443 : servicePort;
|
|
1959
2454
|
const URL = `${socketProtocol}://${serviceAddress}:${port}`;
|
|
1960
2455
|
const fetchId = `${serviceAddress}_${port}`;
|
|
2456
|
+
const socketDiagnostics = this.ensureSocketClientDiagnostics(
|
|
2457
|
+
fetchId,
|
|
2458
|
+
serviceName,
|
|
2459
|
+
URL
|
|
2460
|
+
);
|
|
2461
|
+
socketDiagnostics.destroyed = false;
|
|
2462
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
1961
2463
|
let handshake = false;
|
|
1962
2464
|
let errorCount = 0;
|
|
1963
2465
|
const ERROR_LIMIT = 5;
|
|
@@ -1967,6 +2469,11 @@ var SocketController = class _SocketController {
|
|
|
1967
2469
|
}
|
|
1968
2470
|
const pendingDelegationIds = /* @__PURE__ */ new Set();
|
|
1969
2471
|
const pendingTimers = /* @__PURE__ */ new Set();
|
|
2472
|
+
const syncPendingCounts = () => {
|
|
2473
|
+
socketDiagnostics.pendingDelegations = pendingDelegationIds.size;
|
|
2474
|
+
socketDiagnostics.pendingTimers = pendingTimers.size;
|
|
2475
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2476
|
+
};
|
|
1970
2477
|
let handshakeTask = null;
|
|
1971
2478
|
let emitWhenReady = null;
|
|
1972
2479
|
let transmitTask = null;
|
|
@@ -2016,6 +2523,12 @@ var SocketController = class _SocketController {
|
|
|
2016
2523
|
{ socketId: socket?.id, serviceName, URL, event },
|
|
2017
2524
|
"error"
|
|
2018
2525
|
);
|
|
2526
|
+
this.recordSocketClientError(
|
|
2527
|
+
fetchId,
|
|
2528
|
+
serviceName,
|
|
2529
|
+
URL,
|
|
2530
|
+
waitResult.error
|
|
2531
|
+
);
|
|
2019
2532
|
resolveWithError(waitResult.error);
|
|
2020
2533
|
return;
|
|
2021
2534
|
}
|
|
@@ -2024,6 +2537,7 @@ var SocketController = class _SocketController {
|
|
|
2024
2537
|
timer = setTimeout(() => {
|
|
2025
2538
|
if (timer) {
|
|
2026
2539
|
pendingTimers.delete(timer);
|
|
2540
|
+
syncPendingCounts();
|
|
2027
2541
|
timer = null;
|
|
2028
2542
|
}
|
|
2029
2543
|
CadenzaService.log(
|
|
@@ -2031,9 +2545,16 @@ var SocketController = class _SocketController {
|
|
|
2031
2545
|
{ socketId: socket?.id, serviceName, URL },
|
|
2032
2546
|
"error"
|
|
2033
2547
|
);
|
|
2548
|
+
this.recordSocketClientError(
|
|
2549
|
+
fetchId,
|
|
2550
|
+
serviceName,
|
|
2551
|
+
URL,
|
|
2552
|
+
`Socket event '${event}' timed out`
|
|
2553
|
+
);
|
|
2034
2554
|
resolveWithError(`Socket event '${event}' timed out`);
|
|
2035
2555
|
}, timeoutMs + 10);
|
|
2036
2556
|
pendingTimers.add(timer);
|
|
2557
|
+
syncPendingCounts();
|
|
2037
2558
|
}
|
|
2038
2559
|
const connectedSocket = socket;
|
|
2039
2560
|
if (!connectedSocket) {
|
|
@@ -2046,6 +2567,7 @@ var SocketController = class _SocketController {
|
|
|
2046
2567
|
if (timer) {
|
|
2047
2568
|
clearTimeout(timer);
|
|
2048
2569
|
pendingTimers.delete(timer);
|
|
2570
|
+
syncPendingCounts();
|
|
2049
2571
|
timer = null;
|
|
2050
2572
|
}
|
|
2051
2573
|
if (err) {
|
|
@@ -2059,6 +2581,12 @@ var SocketController = class _SocketController {
|
|
|
2059
2581
|
},
|
|
2060
2582
|
"warning"
|
|
2061
2583
|
);
|
|
2584
|
+
this.recordSocketClientError(
|
|
2585
|
+
fetchId,
|
|
2586
|
+
serviceName,
|
|
2587
|
+
URL,
|
|
2588
|
+
err
|
|
2589
|
+
);
|
|
2062
2590
|
response = {
|
|
2063
2591
|
__error: `Timeout error: ${err}`,
|
|
2064
2592
|
errored: true,
|
|
@@ -2075,6 +2603,10 @@ var SocketController = class _SocketController {
|
|
|
2075
2603
|
};
|
|
2076
2604
|
socket.on("connect", () => {
|
|
2077
2605
|
if (handshake) return;
|
|
2606
|
+
socketDiagnostics.connected = true;
|
|
2607
|
+
socketDiagnostics.destroyed = false;
|
|
2608
|
+
socketDiagnostics.socketId = socket?.id ?? null;
|
|
2609
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2078
2610
|
CadenzaService.emit(`meta.socket_client.connected:${fetchId}`, ctx);
|
|
2079
2611
|
});
|
|
2080
2612
|
socket.on("delegation_progress", (ctx2) => {
|
|
@@ -2093,6 +2625,12 @@ var SocketController = class _SocketController {
|
|
|
2093
2625
|
});
|
|
2094
2626
|
socket.on("connect_error", (err) => {
|
|
2095
2627
|
handshake = false;
|
|
2628
|
+
socketDiagnostics.connected = false;
|
|
2629
|
+
socketDiagnostics.handshake = false;
|
|
2630
|
+
socketDiagnostics.connectErrors++;
|
|
2631
|
+
socketDiagnostics.lastHandshakeError = err.message;
|
|
2632
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2633
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2096
2634
|
CadenzaService.log(
|
|
2097
2635
|
"Socket connect error",
|
|
2098
2636
|
{ error: err.message, serviceName, socketId: socket?.id, URL },
|
|
@@ -2101,9 +2639,16 @@ var SocketController = class _SocketController {
|
|
|
2101
2639
|
CadenzaService.emit(`meta.socket_client.connect_error:${fetchId}`, err);
|
|
2102
2640
|
});
|
|
2103
2641
|
socket.on("reconnect_attempt", (attempt) => {
|
|
2642
|
+
socketDiagnostics.reconnectAttempts = Math.max(
|
|
2643
|
+
socketDiagnostics.reconnectAttempts,
|
|
2644
|
+
attempt
|
|
2645
|
+
);
|
|
2646
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2104
2647
|
CadenzaService.log(`Reconnect attempt: ${attempt}`);
|
|
2105
2648
|
});
|
|
2106
2649
|
socket.on("reconnect", (attempt) => {
|
|
2650
|
+
socketDiagnostics.connected = true;
|
|
2651
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2107
2652
|
CadenzaService.log(`Socket reconnected after ${attempt} tries`, {
|
|
2108
2653
|
socketId: socket?.id,
|
|
2109
2654
|
URL,
|
|
@@ -2112,6 +2657,12 @@ var SocketController = class _SocketController {
|
|
|
2112
2657
|
});
|
|
2113
2658
|
socket.on("reconnect_error", (err) => {
|
|
2114
2659
|
handshake = false;
|
|
2660
|
+
socketDiagnostics.connected = false;
|
|
2661
|
+
socketDiagnostics.handshake = false;
|
|
2662
|
+
socketDiagnostics.reconnectErrors++;
|
|
2663
|
+
socketDiagnostics.lastHandshakeError = err.message;
|
|
2664
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2665
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2115
2666
|
CadenzaService.log(
|
|
2116
2667
|
"Socket reconnect failed.",
|
|
2117
2668
|
{ error: err.message, serviceName, URL, socketId: socket?.id },
|
|
@@ -2120,6 +2671,9 @@ var SocketController = class _SocketController {
|
|
|
2120
2671
|
});
|
|
2121
2672
|
socket.on("error", (err) => {
|
|
2122
2673
|
errorCount++;
|
|
2674
|
+
socketDiagnostics.socketErrors++;
|
|
2675
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2676
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2123
2677
|
CadenzaService.log(
|
|
2124
2678
|
"Socket error",
|
|
2125
2679
|
{ error: err, socketId: socket?.id, URL, serviceName },
|
|
@@ -2128,6 +2682,11 @@ var SocketController = class _SocketController {
|
|
|
2128
2682
|
CadenzaService.emit("meta.socket_client.error", err);
|
|
2129
2683
|
});
|
|
2130
2684
|
socket.on("disconnect", () => {
|
|
2685
|
+
const disconnectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2686
|
+
socketDiagnostics.connected = false;
|
|
2687
|
+
socketDiagnostics.handshake = false;
|
|
2688
|
+
socketDiagnostics.lastDisconnectAt = disconnectedAt;
|
|
2689
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2131
2690
|
CadenzaService.log(
|
|
2132
2691
|
"Socket disconnected.",
|
|
2133
2692
|
{ URL, serviceName, socketId: socket?.id },
|
|
@@ -2146,6 +2705,8 @@ var SocketController = class _SocketController {
|
|
|
2146
2705
|
async (ctx2, emit) => {
|
|
2147
2706
|
if (handshake) return;
|
|
2148
2707
|
handshake = true;
|
|
2708
|
+
socketDiagnostics.handshake = true;
|
|
2709
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2149
2710
|
await emitWhenReady?.(
|
|
2150
2711
|
"handshake",
|
|
2151
2712
|
{
|
|
@@ -2157,6 +2718,11 @@ var SocketController = class _SocketController {
|
|
|
2157
2718
|
1e4,
|
|
2158
2719
|
(result) => {
|
|
2159
2720
|
if (result.status === "success") {
|
|
2721
|
+
socketDiagnostics.connected = true;
|
|
2722
|
+
socketDiagnostics.handshake = true;
|
|
2723
|
+
socketDiagnostics.lastHandshakeAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2724
|
+
socketDiagnostics.lastHandshakeError = null;
|
|
2725
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2160
2726
|
CadenzaService.log("Socket client connected", {
|
|
2161
2727
|
result,
|
|
2162
2728
|
serviceName,
|
|
@@ -2164,6 +2730,16 @@ var SocketController = class _SocketController {
|
|
|
2164
2730
|
URL
|
|
2165
2731
|
});
|
|
2166
2732
|
} else {
|
|
2733
|
+
socketDiagnostics.connected = false;
|
|
2734
|
+
socketDiagnostics.handshake = false;
|
|
2735
|
+
socketDiagnostics.lastHandshakeError = result?.__error ?? result?.error ?? "Socket handshake failed";
|
|
2736
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2737
|
+
this.recordSocketClientError(
|
|
2738
|
+
fetchId,
|
|
2739
|
+
serviceName,
|
|
2740
|
+
URL,
|
|
2741
|
+
socketDiagnostics.lastHandshakeError
|
|
2742
|
+
);
|
|
2167
2743
|
CadenzaService.log(
|
|
2168
2744
|
"Socket handshake failed",
|
|
2169
2745
|
{ result, serviceName, socketId: socket?.id, URL },
|
|
@@ -2186,6 +2762,7 @@ var SocketController = class _SocketController {
|
|
|
2186
2762
|
delete ctx2.__broadcast;
|
|
2187
2763
|
const requestSentAt = Date.now();
|
|
2188
2764
|
pendingDelegationIds.add(ctx2.__metadata.__deputyExecId);
|
|
2765
|
+
syncPendingCounts();
|
|
2189
2766
|
emitWhenReady?.(
|
|
2190
2767
|
"delegation",
|
|
2191
2768
|
ctx2,
|
|
@@ -2203,6 +2780,15 @@ var SocketController = class _SocketController {
|
|
|
2203
2780
|
}
|
|
2204
2781
|
);
|
|
2205
2782
|
pendingDelegationIds.delete(ctx2.__metadata.__deputyExecId);
|
|
2783
|
+
syncPendingCounts();
|
|
2784
|
+
if (resultContext?.errored || resultContext?.failed) {
|
|
2785
|
+
this.recordSocketClientError(
|
|
2786
|
+
fetchId,
|
|
2787
|
+
serviceName,
|
|
2788
|
+
URL,
|
|
2789
|
+
resultContext?.__error ?? resultContext?.error ?? "Socket delegation failed"
|
|
2790
|
+
);
|
|
2791
|
+
}
|
|
2206
2792
|
resolve(resultContext);
|
|
2207
2793
|
}
|
|
2208
2794
|
);
|
|
@@ -2238,6 +2824,10 @@ var SocketController = class _SocketController {
|
|
|
2238
2824
|
`Shutdown SocketClient ${URL}`,
|
|
2239
2825
|
(ctx2, emit) => {
|
|
2240
2826
|
handshake = false;
|
|
2827
|
+
socketDiagnostics.connected = false;
|
|
2828
|
+
socketDiagnostics.handshake = false;
|
|
2829
|
+
socketDiagnostics.destroyed = true;
|
|
2830
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2241
2831
|
CadenzaService.log("Shutting down socket client", { URL, serviceName });
|
|
2242
2832
|
socket?.close();
|
|
2243
2833
|
handshakeTask?.destroy();
|
|
@@ -2267,10 +2857,12 @@ var SocketController = class _SocketController {
|
|
|
2267
2857
|
});
|
|
2268
2858
|
}
|
|
2269
2859
|
pendingDelegationIds.clear();
|
|
2860
|
+
syncPendingCounts();
|
|
2270
2861
|
for (const timer of pendingTimers) {
|
|
2271
2862
|
clearTimeout(timer);
|
|
2272
2863
|
}
|
|
2273
2864
|
pendingTimers.clear();
|
|
2865
|
+
syncPendingCounts();
|
|
2274
2866
|
},
|
|
2275
2867
|
"Shuts down the socket client"
|
|
2276
2868
|
).doOn(
|
|
@@ -2284,6 +2876,157 @@ var SocketController = class _SocketController {
|
|
|
2284
2876
|
"Connects to a specified socket server"
|
|
2285
2877
|
).doOn("meta.fetch.handshake_complete").emitsOnFail("meta.socket_client.connect_failed");
|
|
2286
2878
|
}
|
|
2879
|
+
static get instance() {
|
|
2880
|
+
if (!this._instance) this._instance = new _SocketController();
|
|
2881
|
+
return this._instance;
|
|
2882
|
+
}
|
|
2883
|
+
resolveTransportDiagnosticsOptions(ctx) {
|
|
2884
|
+
const detailLevel = ctx.detailLevel === "full" ? "full" : "summary";
|
|
2885
|
+
const includeErrorHistory = Boolean(ctx.includeErrorHistory);
|
|
2886
|
+
const requestedLimit = Number(ctx.errorHistoryLimit);
|
|
2887
|
+
const errorHistoryLimit = Number.isFinite(requestedLimit) ? Math.max(1, Math.min(200, Math.trunc(requestedLimit))) : 10;
|
|
2888
|
+
return {
|
|
2889
|
+
detailLevel,
|
|
2890
|
+
includeErrorHistory,
|
|
2891
|
+
errorHistoryLimit
|
|
2892
|
+
};
|
|
2893
|
+
}
|
|
2894
|
+
ensureSocketClientDiagnostics(fetchId, serviceName, url) {
|
|
2895
|
+
let state = this.socketClientDiagnostics.get(fetchId);
|
|
2896
|
+
if (!state) {
|
|
2897
|
+
state = {
|
|
2898
|
+
fetchId,
|
|
2899
|
+
serviceName,
|
|
2900
|
+
url,
|
|
2901
|
+
socketId: null,
|
|
2902
|
+
connected: false,
|
|
2903
|
+
handshake: false,
|
|
2904
|
+
reconnectAttempts: 0,
|
|
2905
|
+
connectErrors: 0,
|
|
2906
|
+
reconnectErrors: 0,
|
|
2907
|
+
socketErrors: 0,
|
|
2908
|
+
pendingDelegations: 0,
|
|
2909
|
+
pendingTimers: 0,
|
|
2910
|
+
destroyed: false,
|
|
2911
|
+
lastHandshakeAt: null,
|
|
2912
|
+
lastHandshakeError: null,
|
|
2913
|
+
lastDisconnectAt: null,
|
|
2914
|
+
lastError: null,
|
|
2915
|
+
lastErrorAt: 0,
|
|
2916
|
+
errorHistory: [],
|
|
2917
|
+
updatedAt: Date.now()
|
|
2918
|
+
};
|
|
2919
|
+
this.socketClientDiagnostics.set(fetchId, state);
|
|
2920
|
+
} else {
|
|
2921
|
+
state.serviceName = serviceName;
|
|
2922
|
+
state.url = url;
|
|
2923
|
+
}
|
|
2924
|
+
return state;
|
|
2925
|
+
}
|
|
2926
|
+
getErrorMessage(error) {
|
|
2927
|
+
if (error instanceof Error) {
|
|
2928
|
+
return error.message;
|
|
2929
|
+
}
|
|
2930
|
+
if (typeof error === "string") {
|
|
2931
|
+
return error;
|
|
2932
|
+
}
|
|
2933
|
+
try {
|
|
2934
|
+
return JSON.stringify(error);
|
|
2935
|
+
} catch {
|
|
2936
|
+
return String(error);
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
recordSocketClientError(fetchId, serviceName, url, error) {
|
|
2940
|
+
const state = this.ensureSocketClientDiagnostics(fetchId, serviceName, url);
|
|
2941
|
+
const message = this.getErrorMessage(error);
|
|
2942
|
+
const now = Date.now();
|
|
2943
|
+
state.lastError = message;
|
|
2944
|
+
state.lastErrorAt = now;
|
|
2945
|
+
state.updatedAt = now;
|
|
2946
|
+
state.errorHistory.push({
|
|
2947
|
+
at: new Date(now).toISOString(),
|
|
2948
|
+
message
|
|
2949
|
+
});
|
|
2950
|
+
if (state.errorHistory.length > this.diagnosticsErrorHistoryLimit) {
|
|
2951
|
+
state.errorHistory.splice(
|
|
2952
|
+
0,
|
|
2953
|
+
state.errorHistory.length - this.diagnosticsErrorHistoryLimit
|
|
2954
|
+
);
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
collectSocketTransportDiagnostics(ctx) {
|
|
2958
|
+
const { detailLevel, includeErrorHistory, errorHistoryLimit } = this.resolveTransportDiagnosticsOptions(ctx);
|
|
2959
|
+
const serviceName = CadenzaService.serviceRegistry.serviceName ?? "UnknownService";
|
|
2960
|
+
const states = Array.from(this.socketClientDiagnostics.values()).sort(
|
|
2961
|
+
(a, b) => a.fetchId.localeCompare(b.fetchId)
|
|
2962
|
+
);
|
|
2963
|
+
const summary = {
|
|
2964
|
+
detailLevel,
|
|
2965
|
+
totalClients: states.length,
|
|
2966
|
+
connectedClients: states.filter((state) => state.connected).length,
|
|
2967
|
+
activeHandshakes: states.filter((state) => state.handshake).length,
|
|
2968
|
+
pendingDelegations: states.reduce(
|
|
2969
|
+
(acc, state) => acc + state.pendingDelegations,
|
|
2970
|
+
0
|
|
2971
|
+
),
|
|
2972
|
+
pendingTimers: states.reduce((acc, state) => acc + state.pendingTimers, 0),
|
|
2973
|
+
reconnectAttempts: states.reduce(
|
|
2974
|
+
(acc, state) => acc + state.reconnectAttempts,
|
|
2975
|
+
0
|
|
2976
|
+
),
|
|
2977
|
+
connectErrors: states.reduce((acc, state) => acc + state.connectErrors, 0),
|
|
2978
|
+
reconnectErrors: states.reduce(
|
|
2979
|
+
(acc, state) => acc + state.reconnectErrors,
|
|
2980
|
+
0
|
|
2981
|
+
),
|
|
2982
|
+
socketErrors: states.reduce((acc, state) => acc + state.socketErrors, 0),
|
|
2983
|
+
latestError: states.slice().sort((a, b) => b.lastErrorAt - a.lastErrorAt).find((state) => state.lastError)?.lastError ?? null
|
|
2984
|
+
};
|
|
2985
|
+
if (detailLevel === "summary") {
|
|
2986
|
+
return {
|
|
2987
|
+
transportDiagnostics: {
|
|
2988
|
+
[serviceName]: {
|
|
2989
|
+
socketClient: summary
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2994
|
+
const clients = states.map((state) => {
|
|
2995
|
+
const details = {
|
|
2996
|
+
fetchId: state.fetchId,
|
|
2997
|
+
serviceName: state.serviceName,
|
|
2998
|
+
url: state.url,
|
|
2999
|
+
socketId: state.socketId,
|
|
3000
|
+
connected: state.connected,
|
|
3001
|
+
handshake: state.handshake,
|
|
3002
|
+
reconnectAttempts: state.reconnectAttempts,
|
|
3003
|
+
connectErrors: state.connectErrors,
|
|
3004
|
+
reconnectErrors: state.reconnectErrors,
|
|
3005
|
+
socketErrors: state.socketErrors,
|
|
3006
|
+
pendingDelegations: state.pendingDelegations,
|
|
3007
|
+
pendingTimers: state.pendingTimers,
|
|
3008
|
+
destroyed: state.destroyed,
|
|
3009
|
+
lastHandshakeAt: state.lastHandshakeAt,
|
|
3010
|
+
lastHandshakeError: state.lastHandshakeError,
|
|
3011
|
+
lastDisconnectAt: state.lastDisconnectAt,
|
|
3012
|
+
latestError: state.lastError
|
|
3013
|
+
};
|
|
3014
|
+
if (includeErrorHistory) {
|
|
3015
|
+
details.errorHistory = state.errorHistory.slice(-errorHistoryLimit);
|
|
3016
|
+
}
|
|
3017
|
+
return details;
|
|
3018
|
+
});
|
|
3019
|
+
return {
|
|
3020
|
+
transportDiagnostics: {
|
|
3021
|
+
[serviceName]: {
|
|
3022
|
+
socketClient: {
|
|
3023
|
+
...summary,
|
|
3024
|
+
clients
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
}
|
|
2287
3030
|
};
|
|
2288
3031
|
|
|
2289
3032
|
// src/utils/tools.ts
|
|
@@ -2387,25 +3130,8 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2387
3130
|
return {
|
|
2388
3131
|
data: {
|
|
2389
3132
|
...ctx.data,
|
|
2390
|
-
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
2391
|
-
|
|
2392
|
-
subOperation: "insert",
|
|
2393
|
-
table: "context_schema",
|
|
2394
|
-
data: {
|
|
2395
|
-
...ctx.data.inputContextSchemaId
|
|
2396
|
-
},
|
|
2397
|
-
return: "uuid"
|
|
2398
|
-
} : null,
|
|
2399
|
-
outputContextSchemaId: ctx.data.outputContextSchemaId ? {
|
|
2400
|
-
subOperation: "insert",
|
|
2401
|
-
table: "context_schema",
|
|
2402
|
-
data: {
|
|
2403
|
-
...ctx.data.outputContextSchemaId
|
|
2404
|
-
},
|
|
2405
|
-
return: "uuid"
|
|
2406
|
-
} : null
|
|
2407
|
-
},
|
|
2408
|
-
transaction: true
|
|
3133
|
+
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
3134
|
+
}
|
|
2409
3135
|
};
|
|
2410
3136
|
}).doOn("meta.task.created").emits("global.meta.graph_metadata.task_created");
|
|
2411
3137
|
CadenzaService.createMetaTask("Handle task update", (ctx) => {
|
|
@@ -2612,9 +3338,11 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2612
3338
|
{ concurrency: 100, isSubMeta: true }
|
|
2613
3339
|
).doOn("meta.node.mapped", "meta.node.detected_previous_task_execution").emits("global.meta.graph_metadata.relationship_executed");
|
|
2614
3340
|
CadenzaService.createMetaTask("Handle Intent Creation", (ctx) => {
|
|
3341
|
+
const intentName = ctx.data?.name;
|
|
2615
3342
|
return {
|
|
2616
3343
|
data: {
|
|
2617
|
-
...ctx.data
|
|
3344
|
+
...ctx.data,
|
|
3345
|
+
isMeta: intentName ? isMetaIntentName(intentName) : false
|
|
2618
3346
|
}
|
|
2619
3347
|
};
|
|
2620
3348
|
}).doOn("meta.inquiry_broker.added").emits("global.meta.graph_metadata.intent_created");
|
|
@@ -2646,6 +3374,52 @@ var SCHEMA_TYPES = [
|
|
|
2646
3374
|
// src/database/DatabaseController.ts
|
|
2647
3375
|
var import_pg = require("pg");
|
|
2648
3376
|
var import_lodash_es = require("lodash-es");
|
|
3377
|
+
function resolveTableQueryIntents(serviceName, tableName, table, defaultInputSchema) {
|
|
3378
|
+
const resolvedServiceName = serviceName ?? "unknown-service";
|
|
3379
|
+
const defaultIntentName = `query-${resolvedServiceName}-${tableName}`;
|
|
3380
|
+
const defaultDescription = `Perform a query operation on the ${tableName} table`;
|
|
3381
|
+
const intents = [
|
|
3382
|
+
{
|
|
3383
|
+
name: defaultIntentName,
|
|
3384
|
+
description: defaultDescription,
|
|
3385
|
+
input: defaultInputSchema
|
|
3386
|
+
}
|
|
3387
|
+
];
|
|
3388
|
+
const warnings = [];
|
|
3389
|
+
const names = /* @__PURE__ */ new Set([defaultIntentName]);
|
|
3390
|
+
for (const customIntent of table.customIntents?.query ?? []) {
|
|
3391
|
+
const name = typeof customIntent === "string" ? customIntent.trim() : customIntent.intent?.trim();
|
|
3392
|
+
if (!name) {
|
|
3393
|
+
warnings.push(`Skipped empty custom query intent for table '${tableName}'.`);
|
|
3394
|
+
continue;
|
|
3395
|
+
}
|
|
3396
|
+
if (name.length > 100) {
|
|
3397
|
+
warnings.push(
|
|
3398
|
+
`Skipped custom query intent '${name}' for table '${tableName}': name must be <= 100 characters.`
|
|
3399
|
+
);
|
|
3400
|
+
continue;
|
|
3401
|
+
}
|
|
3402
|
+
if (name.includes(" ") || name.includes(".") || name.includes("\\")) {
|
|
3403
|
+
warnings.push(
|
|
3404
|
+
`Skipped custom query intent '${name}' for table '${tableName}': name cannot contain spaces, dots or backslashes.`
|
|
3405
|
+
);
|
|
3406
|
+
continue;
|
|
3407
|
+
}
|
|
3408
|
+
if (names.has(name)) {
|
|
3409
|
+
warnings.push(
|
|
3410
|
+
`Skipped duplicate custom query intent '${name}' for table '${tableName}'.`
|
|
3411
|
+
);
|
|
3412
|
+
continue;
|
|
3413
|
+
}
|
|
3414
|
+
names.add(name);
|
|
3415
|
+
intents.push({
|
|
3416
|
+
name,
|
|
3417
|
+
description: typeof customIntent === "string" ? `Perform a query operation on the ${tableName} table` : customIntent.description ?? defaultDescription,
|
|
3418
|
+
input: typeof customIntent === "string" ? defaultInputSchema : customIntent.input ?? defaultInputSchema
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3421
|
+
return { intents, warnings };
|
|
3422
|
+
}
|
|
2649
3423
|
var DatabaseController = class _DatabaseController {
|
|
2650
3424
|
/**
|
|
2651
3425
|
* Constructor for initializing the `DatabaseService` class.
|
|
@@ -2787,6 +3561,20 @@ var DatabaseController = class _DatabaseController {
|
|
|
2787
3561
|
}
|
|
2788
3562
|
}
|
|
2789
3563
|
}
|
|
3564
|
+
if (table.customIntents?.query) {
|
|
3565
|
+
if (!Array.isArray(table.customIntents.query)) {
|
|
3566
|
+
throw new Error(
|
|
3567
|
+
`Invalid customIntents.query for ${tableName}: expected array`
|
|
3568
|
+
);
|
|
3569
|
+
}
|
|
3570
|
+
for (const customIntent of table.customIntents.query) {
|
|
3571
|
+
if (typeof customIntent !== "string" && (typeof customIntent !== "object" || !customIntent || typeof customIntent.intent !== "string")) {
|
|
3572
|
+
throw new Error(
|
|
3573
|
+
`Invalid custom query intent on ${tableName}: expected string or object with intent`
|
|
3574
|
+
);
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
2790
3578
|
}
|
|
2791
3579
|
}
|
|
2792
3580
|
console.log("SCHEMA VALIDATED");
|
|
@@ -3823,13 +4611,30 @@ var DatabaseController = class _DatabaseController {
|
|
|
3823
4611
|
}) ?? []
|
|
3824
4612
|
);
|
|
3825
4613
|
if (op === "query") {
|
|
3826
|
-
const
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
4614
|
+
const { intents, warnings } = resolveTableQueryIntents(
|
|
4615
|
+
CadenzaService.serviceRegistry?.serviceName,
|
|
4616
|
+
tableName,
|
|
4617
|
+
table,
|
|
4618
|
+
schema
|
|
4619
|
+
);
|
|
4620
|
+
for (const warning of warnings) {
|
|
4621
|
+
CadenzaService.log(
|
|
4622
|
+
"Skipped custom query intent registration.",
|
|
4623
|
+
{
|
|
4624
|
+
tableName,
|
|
4625
|
+
warning
|
|
4626
|
+
},
|
|
4627
|
+
"warning"
|
|
4628
|
+
);
|
|
4629
|
+
}
|
|
4630
|
+
for (const intent of intents) {
|
|
4631
|
+
CadenzaService.defineIntent({
|
|
4632
|
+
name: intent.name,
|
|
4633
|
+
description: intent.description,
|
|
4634
|
+
input: intent.input
|
|
4635
|
+
});
|
|
4636
|
+
}
|
|
4637
|
+
task.respondsTo(...intents.map((intent) => intent.name));
|
|
3833
4638
|
}
|
|
3834
4639
|
}
|
|
3835
4640
|
getInputSchema(op, tableName, table) {
|
|
@@ -3921,18 +4726,18 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3921
4726
|
Object.entries(table.fields).map((field) => {
|
|
3922
4727
|
return [
|
|
3923
4728
|
field[0],
|
|
3924
|
-
|
|
3925
|
-
{
|
|
4729
|
+
{
|
|
4730
|
+
value: {
|
|
3926
4731
|
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3927
4732
|
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3928
4733
|
},
|
|
3929
|
-
{
|
|
4734
|
+
effect: {
|
|
3930
4735
|
type: "string",
|
|
3931
4736
|
constraints: {
|
|
3932
4737
|
oneOf: ["increment", "decrement", "set"]
|
|
3933
4738
|
}
|
|
3934
4739
|
},
|
|
3935
|
-
{
|
|
4740
|
+
subOperation: {
|
|
3936
4741
|
type: "object",
|
|
3937
4742
|
properties: {
|
|
3938
4743
|
subOperation: {
|
|
@@ -3942,17 +4747,17 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3942
4747
|
table: {
|
|
3943
4748
|
type: "string"
|
|
3944
4749
|
},
|
|
3945
|
-
data:
|
|
3946
|
-
{
|
|
4750
|
+
data: {
|
|
4751
|
+
single: {
|
|
3947
4752
|
type: "object"
|
|
3948
4753
|
},
|
|
3949
|
-
{
|
|
4754
|
+
batch: {
|
|
3950
4755
|
type: "array",
|
|
3951
4756
|
items: {
|
|
3952
4757
|
type: "object"
|
|
3953
4758
|
}
|
|
3954
4759
|
}
|
|
3955
|
-
|
|
4760
|
+
},
|
|
3956
4761
|
filter: {
|
|
3957
4762
|
type: "object"
|
|
3958
4763
|
},
|
|
@@ -3968,7 +4773,7 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3968
4773
|
},
|
|
3969
4774
|
required: ["subOperation", "table"]
|
|
3970
4775
|
}
|
|
3971
|
-
|
|
4776
|
+
}
|
|
3972
4777
|
];
|
|
3973
4778
|
})
|
|
3974
4779
|
)
|
|
@@ -3976,13 +4781,13 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3976
4781
|
required: Object.entries(table.fields).filter((field) => field[1].required || field[1].primary).map((field) => field[0]),
|
|
3977
4782
|
strict: true
|
|
3978
4783
|
};
|
|
3979
|
-
return
|
|
3980
|
-
dataSchema,
|
|
3981
|
-
{
|
|
4784
|
+
return {
|
|
4785
|
+
single: dataSchema,
|
|
4786
|
+
batch: {
|
|
3982
4787
|
type: "array",
|
|
3983
4788
|
items: dataSchema
|
|
3984
4789
|
}
|
|
3985
|
-
|
|
4790
|
+
};
|
|
3986
4791
|
}
|
|
3987
4792
|
function getQueryFilterSchemaFromTable(table, tableName) {
|
|
3988
4793
|
return {
|
|
@@ -3992,24 +4797,24 @@ function getQueryFilterSchemaFromTable(table, tableName) {
|
|
|
3992
4797
|
Object.entries(table.fields).map((field) => {
|
|
3993
4798
|
return [
|
|
3994
4799
|
field[0],
|
|
3995
|
-
|
|
3996
|
-
{
|
|
4800
|
+
{
|
|
4801
|
+
value: {
|
|
3997
4802
|
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3998
4803
|
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3999
4804
|
},
|
|
4000
|
-
{
|
|
4805
|
+
in: {
|
|
4001
4806
|
type: "array",
|
|
4002
4807
|
items: {
|
|
4003
4808
|
type: tableFieldTypeToSchemaType(field[1].type)
|
|
4004
4809
|
}
|
|
4005
4810
|
}
|
|
4006
|
-
|
|
4811
|
+
}
|
|
4007
4812
|
];
|
|
4008
4813
|
})
|
|
4009
4814
|
)
|
|
4010
4815
|
},
|
|
4011
4816
|
strict: true,
|
|
4012
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4817
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4013
4818
|
};
|
|
4014
4819
|
}
|
|
4015
4820
|
function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
@@ -4021,7 +4826,7 @@ function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
|
4021
4826
|
oneOf: Object.keys(table.fields)
|
|
4022
4827
|
}
|
|
4023
4828
|
},
|
|
4024
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4829
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4025
4830
|
};
|
|
4026
4831
|
}
|
|
4027
4832
|
function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
@@ -4068,7 +4873,7 @@ function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
|
4068
4873
|
)
|
|
4069
4874
|
},
|
|
4070
4875
|
strict: true,
|
|
4071
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4876
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4072
4877
|
};
|
|
4073
4878
|
}
|
|
4074
4879
|
function getQuerySortSchemaFromTable(table, tableName) {
|
|
@@ -4090,7 +4895,7 @@ function getQuerySortSchemaFromTable(table, tableName) {
|
|
|
4090
4895
|
)
|
|
4091
4896
|
},
|
|
4092
4897
|
strict: true,
|
|
4093
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4898
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4094
4899
|
};
|
|
4095
4900
|
}
|
|
4096
4901
|
function getQueryLimitSchemaFromTable() {
|
|
@@ -4152,12 +4957,10 @@ function getQueryOnConflictSchemaFromTable(table, tableName) {
|
|
|
4152
4957
|
Object.entries(table.fields).map((field) => {
|
|
4153
4958
|
return [
|
|
4154
4959
|
field[0],
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
}
|
|
4160
|
-
]
|
|
4960
|
+
{
|
|
4961
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
4962
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
4963
|
+
}
|
|
4161
4964
|
];
|
|
4162
4965
|
})
|
|
4163
4966
|
)
|
|
@@ -4515,6 +5318,75 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4515
5318
|
{ concurrency: 30 }
|
|
4516
5319
|
) : CadenzaService.get("dbInsertSignalToTaskMap"))?.then(registerSignalTask)
|
|
4517
5320
|
);
|
|
5321
|
+
const registerIntentTask = CadenzaService.createMetaTask(
|
|
5322
|
+
"Record intent registration",
|
|
5323
|
+
(ctx) => {
|
|
5324
|
+
if (!ctx.__syncing) {
|
|
5325
|
+
return;
|
|
5326
|
+
}
|
|
5327
|
+
CadenzaService.debounce("meta.sync_controller.synced_resource", {
|
|
5328
|
+
delayMs: 3e3
|
|
5329
|
+
});
|
|
5330
|
+
const task = CadenzaService.get(ctx.__taskName);
|
|
5331
|
+
task.__registeredIntents = task.__registeredIntents ?? /* @__PURE__ */ new Set();
|
|
5332
|
+
task.__registeredIntents.add(ctx.__intent);
|
|
5333
|
+
}
|
|
5334
|
+
);
|
|
5335
|
+
this.registerIntentToTaskMapTask = CadenzaService.createMetaTask(
|
|
5336
|
+
"Split intents of task",
|
|
5337
|
+
function* (ctx) {
|
|
5338
|
+
const task = ctx.task;
|
|
5339
|
+
if (task.hidden || !task.register) return;
|
|
5340
|
+
task.__registeredIntents = task.__registeredIntents ?? /* @__PURE__ */ new Set();
|
|
5341
|
+
task.__invalidMetaIntentWarnings = task.__invalidMetaIntentWarnings ?? /* @__PURE__ */ new Set();
|
|
5342
|
+
for (const intent of task.handlesIntents) {
|
|
5343
|
+
if (task.__registeredIntents.has(intent)) continue;
|
|
5344
|
+
if (isMetaIntentName(intent) && !task.isMeta) {
|
|
5345
|
+
if (!task.__invalidMetaIntentWarnings.has(intent)) {
|
|
5346
|
+
task.__invalidMetaIntentWarnings.add(intent);
|
|
5347
|
+
CadenzaService.log(
|
|
5348
|
+
"Skipping intent-to-task registration: non-meta task cannot handle meta intent.",
|
|
5349
|
+
{
|
|
5350
|
+
intent,
|
|
5351
|
+
taskName: task.name,
|
|
5352
|
+
taskVersion: task.version
|
|
5353
|
+
},
|
|
5354
|
+
"warning"
|
|
5355
|
+
);
|
|
5356
|
+
}
|
|
5357
|
+
continue;
|
|
5358
|
+
}
|
|
5359
|
+
yield {
|
|
5360
|
+
data: {
|
|
5361
|
+
intentName: intent,
|
|
5362
|
+
taskName: task.name,
|
|
5363
|
+
taskVersion: task.version,
|
|
5364
|
+
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
5365
|
+
},
|
|
5366
|
+
__taskName: task.name,
|
|
5367
|
+
__intent: intent
|
|
5368
|
+
};
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
).then(
|
|
5372
|
+
(this.isCadenzaDBReady ? CadenzaService.createCadenzaDBInsertTask(
|
|
5373
|
+
"intent_to_task_map",
|
|
5374
|
+
{
|
|
5375
|
+
onConflict: {
|
|
5376
|
+
target: [
|
|
5377
|
+
"intent_name",
|
|
5378
|
+
"task_name",
|
|
5379
|
+
"task_version",
|
|
5380
|
+
"service_name"
|
|
5381
|
+
],
|
|
5382
|
+
action: {
|
|
5383
|
+
do: "nothing"
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
},
|
|
5387
|
+
{ concurrency: 30 }
|
|
5388
|
+
) : CadenzaService.get("dbInsertIntentToTaskMap"))?.then(registerIntentTask)
|
|
5389
|
+
);
|
|
4518
5390
|
this.registerTaskMapTask = CadenzaService.createMetaTask(
|
|
4519
5391
|
"Register task map to DB",
|
|
4520
5392
|
function* (ctx) {
|
|
@@ -4637,6 +5509,7 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4637
5509
|
CadenzaService.registry.doForEachTask.clone().doOn("meta.sync_controller.synced_tasks").then(
|
|
4638
5510
|
this.registerTaskMapTask,
|
|
4639
5511
|
this.registerSignalToTaskMapTask,
|
|
5512
|
+
this.registerIntentToTaskMapTask,
|
|
4640
5513
|
this.registerDeputyRelationshipTask
|
|
4641
5514
|
);
|
|
4642
5515
|
CadenzaService.registry.getAllRoutines.clone().doOn("meta.sync_controller.synced_routines").then(this.splitTasksInRoutines);
|
|
@@ -4778,11 +5651,192 @@ var CadenzaService = class {
|
|
|
4778
5651
|
import_core3.default.interval(signal, context, intervalMs, leading, startDateTime);
|
|
4779
5652
|
}
|
|
4780
5653
|
static defineIntent(intent) {
|
|
4781
|
-
this.inquiryBroker?.
|
|
5654
|
+
this.inquiryBroker?.addIntent(intent);
|
|
4782
5655
|
return intent;
|
|
4783
5656
|
}
|
|
4784
|
-
static
|
|
4785
|
-
return this.
|
|
5657
|
+
static getInquiryResponderDescriptor(task) {
|
|
5658
|
+
return this.serviceRegistry.getInquiryResponderDescriptor(task);
|
|
5659
|
+
}
|
|
5660
|
+
static compareInquiryResponders(left, right) {
|
|
5661
|
+
return compareResponderDescriptors(left.descriptor, right.descriptor);
|
|
5662
|
+
}
|
|
5663
|
+
static buildInquirySummary(inquiry, startedAt, statuses, totalResponders) {
|
|
5664
|
+
const counts = summarizeResponderStatuses(statuses);
|
|
5665
|
+
const isMetaInquiry = isMetaIntentName(inquiry);
|
|
5666
|
+
const eligibleResponders = statuses.length;
|
|
5667
|
+
return {
|
|
5668
|
+
inquiry,
|
|
5669
|
+
isMetaInquiry,
|
|
5670
|
+
totalResponders,
|
|
5671
|
+
eligibleResponders,
|
|
5672
|
+
filteredOutResponders: Math.max(0, totalResponders - eligibleResponders),
|
|
5673
|
+
responded: counts.responded,
|
|
5674
|
+
failed: counts.failed,
|
|
5675
|
+
timedOut: counts.timedOut,
|
|
5676
|
+
pending: counts.pending,
|
|
5677
|
+
durationMs: Date.now() - startedAt,
|
|
5678
|
+
responders: statuses
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5681
|
+
static async inquire(inquiry, context, options = {}) {
|
|
5682
|
+
this.bootstrap();
|
|
5683
|
+
const observer = this.inquiryBroker?.inquiryObservers.get(inquiry);
|
|
5684
|
+
const allResponders = observer ? Array.from(observer.tasks).map((task) => ({
|
|
5685
|
+
task,
|
|
5686
|
+
descriptor: this.getInquiryResponderDescriptor(task)
|
|
5687
|
+
})) : [];
|
|
5688
|
+
const isMetaInquiry = isMetaIntentName(inquiry);
|
|
5689
|
+
const responders = allResponders.filter(({ task, descriptor }) => {
|
|
5690
|
+
const shouldExecute = shouldExecuteInquiryResponder(inquiry, task.isMeta);
|
|
5691
|
+
if (shouldExecute) {
|
|
5692
|
+
return true;
|
|
5693
|
+
}
|
|
5694
|
+
const warningKey = `${inquiry}|${descriptor.serviceName}|${descriptor.taskName}|${descriptor.taskVersion}|${descriptor.localTaskName}`;
|
|
5695
|
+
if (!this.warnedInvalidMetaIntentResponderKeys.has(warningKey)) {
|
|
5696
|
+
this.warnedInvalidMetaIntentResponderKeys.add(warningKey);
|
|
5697
|
+
this.log(
|
|
5698
|
+
"Skipping non-meta task for meta intent inquiry.",
|
|
5699
|
+
{
|
|
5700
|
+
inquiry,
|
|
5701
|
+
responder: descriptor
|
|
5702
|
+
},
|
|
5703
|
+
"warning",
|
|
5704
|
+
descriptor.serviceName
|
|
5705
|
+
);
|
|
5706
|
+
}
|
|
5707
|
+
return false;
|
|
5708
|
+
});
|
|
5709
|
+
if (responders.length === 0) {
|
|
5710
|
+
return {
|
|
5711
|
+
__inquiryMeta: {
|
|
5712
|
+
inquiry,
|
|
5713
|
+
isMetaInquiry,
|
|
5714
|
+
totalResponders: allResponders.length,
|
|
5715
|
+
eligibleResponders: 0,
|
|
5716
|
+
filteredOutResponders: allResponders.length,
|
|
5717
|
+
responded: 0,
|
|
5718
|
+
failed: 0,
|
|
5719
|
+
timedOut: 0,
|
|
5720
|
+
pending: 0,
|
|
5721
|
+
durationMs: 0,
|
|
5722
|
+
responders: []
|
|
5723
|
+
}
|
|
5724
|
+
};
|
|
5725
|
+
}
|
|
5726
|
+
responders.sort(this.compareInquiryResponders.bind(this));
|
|
5727
|
+
const overallTimeoutMs = options.overallTimeoutMs ?? options.timeout ?? 0;
|
|
5728
|
+
const requireComplete = options.requireComplete ?? false;
|
|
5729
|
+
const perResponderTimeoutMs = options.perResponderTimeoutMs;
|
|
5730
|
+
const startedAt = Date.now();
|
|
5731
|
+
const statuses = [];
|
|
5732
|
+
const statusByTask = /* @__PURE__ */ new Map();
|
|
5733
|
+
for (const responder of responders) {
|
|
5734
|
+
const status = {
|
|
5735
|
+
...responder.descriptor,
|
|
5736
|
+
status: "timed_out",
|
|
5737
|
+
durationMs: 0
|
|
5738
|
+
};
|
|
5739
|
+
statuses.push(status);
|
|
5740
|
+
statusByTask.set(responder.task, status);
|
|
5741
|
+
}
|
|
5742
|
+
const resultsByTask = /* @__PURE__ */ new Map();
|
|
5743
|
+
const resolverTasks = [];
|
|
5744
|
+
const pending = new Set(responders.map((r) => r.task));
|
|
5745
|
+
const startTimeByTask = /* @__PURE__ */ new Map();
|
|
5746
|
+
this.emit("meta.inquiry_broker.inquire", { inquiry, context });
|
|
5747
|
+
return new Promise((resolve, reject) => {
|
|
5748
|
+
let finalized = false;
|
|
5749
|
+
let timeoutId;
|
|
5750
|
+
const finalize = (timedOut) => {
|
|
5751
|
+
if (finalized) return;
|
|
5752
|
+
finalized = true;
|
|
5753
|
+
if (timeoutId) {
|
|
5754
|
+
clearTimeout(timeoutId);
|
|
5755
|
+
timeoutId = void 0;
|
|
5756
|
+
}
|
|
5757
|
+
for (const resolverTask of resolverTasks) {
|
|
5758
|
+
resolverTask.destroy();
|
|
5759
|
+
}
|
|
5760
|
+
if (timedOut && pending.size > 0) {
|
|
5761
|
+
for (const task of pending) {
|
|
5762
|
+
const status = statusByTask.get(task);
|
|
5763
|
+
if (!status) continue;
|
|
5764
|
+
status.status = "timed_out";
|
|
5765
|
+
status.durationMs = Date.now() - (startTimeByTask.get(task) ?? startedAt);
|
|
5766
|
+
}
|
|
5767
|
+
}
|
|
5768
|
+
const fulfilledContexts = responders.filter((responder) => resultsByTask.has(responder.task)).map((responder) => resultsByTask.get(responder.task));
|
|
5769
|
+
const mergedContext = mergeInquiryContexts(fulfilledContexts);
|
|
5770
|
+
const inquiryMeta = this.buildInquirySummary(
|
|
5771
|
+
inquiry,
|
|
5772
|
+
startedAt,
|
|
5773
|
+
statuses,
|
|
5774
|
+
allResponders.length
|
|
5775
|
+
);
|
|
5776
|
+
const responseContext = {
|
|
5777
|
+
...mergedContext,
|
|
5778
|
+
__inquiryMeta: inquiryMeta
|
|
5779
|
+
};
|
|
5780
|
+
if (requireComplete && (timedOut || inquiryMeta.failed > 0 || inquiryMeta.timedOut > 0 || inquiryMeta.pending > 0)) {
|
|
5781
|
+
reject({
|
|
5782
|
+
...responseContext,
|
|
5783
|
+
__error: `Inquiry '${inquiry}' did not complete successfully`,
|
|
5784
|
+
errored: true
|
|
5785
|
+
});
|
|
5786
|
+
return;
|
|
5787
|
+
}
|
|
5788
|
+
resolve(responseContext);
|
|
5789
|
+
};
|
|
5790
|
+
if (overallTimeoutMs > 0) {
|
|
5791
|
+
timeoutId = setTimeout(() => finalize(true), overallTimeoutMs);
|
|
5792
|
+
}
|
|
5793
|
+
for (const responder of responders) {
|
|
5794
|
+
const { task, descriptor } = responder;
|
|
5795
|
+
const inquiryId = (0, import_uuid3.v4)();
|
|
5796
|
+
startTimeByTask.set(task, Date.now());
|
|
5797
|
+
const resolverTask = this.createEphemeralMetaTask(
|
|
5798
|
+
`Resolve inquiry ${inquiry} for ${descriptor.localTaskName}`,
|
|
5799
|
+
(resultCtx) => {
|
|
5800
|
+
if (finalized) {
|
|
5801
|
+
return;
|
|
5802
|
+
}
|
|
5803
|
+
pending.delete(task);
|
|
5804
|
+
const status = statusByTask.get(task);
|
|
5805
|
+
if (status) {
|
|
5806
|
+
status.durationMs = Date.now() - (startTimeByTask.get(task) ?? startedAt);
|
|
5807
|
+
if (resultCtx?.errored || resultCtx?.failed) {
|
|
5808
|
+
status.status = "failed";
|
|
5809
|
+
status.error = String(
|
|
5810
|
+
resultCtx?.__error ?? resultCtx?.error ?? "Inquiry responder failed"
|
|
5811
|
+
);
|
|
5812
|
+
} else {
|
|
5813
|
+
status.status = "fulfilled";
|
|
5814
|
+
resultsByTask.set(task, resultCtx);
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
if (pending.size === 0) {
|
|
5818
|
+
finalize(false);
|
|
5819
|
+
}
|
|
5820
|
+
},
|
|
5821
|
+
"Resolves distributed inquiry responder result",
|
|
5822
|
+
{ register: false }
|
|
5823
|
+
).doOn(`meta.node.graph_completed:${inquiryId}`);
|
|
5824
|
+
resolverTasks.push(resolverTask);
|
|
5825
|
+
const executionContext = {
|
|
5826
|
+
...context,
|
|
5827
|
+
__routineExecId: inquiryId,
|
|
5828
|
+
__isInquiry: true
|
|
5829
|
+
};
|
|
5830
|
+
if (perResponderTimeoutMs !== void 0) {
|
|
5831
|
+
executionContext.__timeout = perResponderTimeoutMs;
|
|
5832
|
+
}
|
|
5833
|
+
if (task.isMeta) {
|
|
5834
|
+
this.metaRunner?.run(task, executionContext);
|
|
5835
|
+
} else {
|
|
5836
|
+
this.runner?.run(task, executionContext);
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
});
|
|
4786
5840
|
}
|
|
4787
5841
|
/**
|
|
4788
5842
|
* Executes the given task or graph routine within the provided context using the configured runner.
|
|
@@ -5819,6 +6873,7 @@ var CadenzaService = class {
|
|
|
5819
6873
|
};
|
|
5820
6874
|
CadenzaService.isBootstrapped = false;
|
|
5821
6875
|
CadenzaService.serviceCreated = false;
|
|
6876
|
+
CadenzaService.warnedInvalidMetaIntentResponderKeys = /* @__PURE__ */ new Set();
|
|
5822
6877
|
|
|
5823
6878
|
// src/index.ts
|
|
5824
6879
|
var import_core4 = require("@cadenza.io/core");
|