@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.mjs
CHANGED
|
@@ -247,6 +247,72 @@ var DatabaseTask = class extends DeputyTask {
|
|
|
247
247
|
var isNode = typeof process !== "undefined" && process.versions?.node != null;
|
|
248
248
|
var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
249
249
|
|
|
250
|
+
// src/utils/inquiry.ts
|
|
251
|
+
var META_INTENT_PREFIX = "meta-";
|
|
252
|
+
var META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT = "meta-runtime-transport-diagnostics";
|
|
253
|
+
function isPlainObject(value) {
|
|
254
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
255
|
+
}
|
|
256
|
+
function deepMergeDeterministic(left, right) {
|
|
257
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
258
|
+
return [...left, ...right];
|
|
259
|
+
}
|
|
260
|
+
if (isPlainObject(left) && isPlainObject(right)) {
|
|
261
|
+
const merged = { ...left };
|
|
262
|
+
const keys = Array.from(/* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])).sort();
|
|
263
|
+
for (const key of keys) {
|
|
264
|
+
if (!(key in left)) {
|
|
265
|
+
merged[key] = right[key];
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (!(key in right)) {
|
|
269
|
+
merged[key] = left[key];
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
merged[key] = deepMergeDeterministic(left[key], right[key]);
|
|
273
|
+
}
|
|
274
|
+
return merged;
|
|
275
|
+
}
|
|
276
|
+
return right;
|
|
277
|
+
}
|
|
278
|
+
function mergeInquiryContexts(contexts) {
|
|
279
|
+
return contexts.reduce((acc, next) => deepMergeDeterministic(acc, next), {});
|
|
280
|
+
}
|
|
281
|
+
function isMetaIntentName(intentName) {
|
|
282
|
+
return intentName.startsWith(META_INTENT_PREFIX);
|
|
283
|
+
}
|
|
284
|
+
function shouldExecuteInquiryResponder(inquiry, responderIsMeta) {
|
|
285
|
+
if (!isMetaIntentName(inquiry)) {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
return responderIsMeta;
|
|
289
|
+
}
|
|
290
|
+
function compareResponderDescriptors(left, right) {
|
|
291
|
+
if (left.serviceName !== right.serviceName) {
|
|
292
|
+
return left.serviceName.localeCompare(right.serviceName);
|
|
293
|
+
}
|
|
294
|
+
if (left.taskName !== right.taskName) {
|
|
295
|
+
return left.taskName.localeCompare(right.taskName);
|
|
296
|
+
}
|
|
297
|
+
if (left.taskVersion !== right.taskVersion) {
|
|
298
|
+
return left.taskVersion - right.taskVersion;
|
|
299
|
+
}
|
|
300
|
+
return left.localTaskName.localeCompare(right.localTaskName);
|
|
301
|
+
}
|
|
302
|
+
function summarizeResponderStatuses(statuses) {
|
|
303
|
+
let responded = 0;
|
|
304
|
+
let failed = 0;
|
|
305
|
+
let timedOut = 0;
|
|
306
|
+
let pending = 0;
|
|
307
|
+
for (const status of statuses) {
|
|
308
|
+
if (status.status === "fulfilled") responded++;
|
|
309
|
+
if (status.status === "failed") failed++;
|
|
310
|
+
if (status.status === "timed_out") timedOut++;
|
|
311
|
+
}
|
|
312
|
+
pending = Math.max(0, statuses.length - responded - failed - timedOut);
|
|
313
|
+
return { responded, failed, timedOut, pending };
|
|
314
|
+
}
|
|
315
|
+
|
|
250
316
|
// src/registry/ServiceRegistry.ts
|
|
251
317
|
var ServiceRegistry = class _ServiceRegistry {
|
|
252
318
|
/**
|
|
@@ -262,11 +328,47 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
262
328
|
this.instances = /* @__PURE__ */ new Map();
|
|
263
329
|
this.deputies = /* @__PURE__ */ new Map();
|
|
264
330
|
this.remoteSignals = /* @__PURE__ */ new Map();
|
|
331
|
+
this.remoteIntents = /* @__PURE__ */ new Map();
|
|
332
|
+
this.remoteIntentDeputiesByKey = /* @__PURE__ */ new Map();
|
|
333
|
+
this.remoteIntentDeputiesByTask = /* @__PURE__ */ new Map();
|
|
265
334
|
this.serviceName = null;
|
|
266
335
|
this.serviceInstanceId = null;
|
|
267
336
|
this.numberOfRunningGraphs = 0;
|
|
268
337
|
this.useSocket = false;
|
|
269
338
|
this.retryCount = 3;
|
|
339
|
+
CadenzaService.defineIntent({
|
|
340
|
+
name: META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT,
|
|
341
|
+
description: "Gather transport diagnostics across all services and communication clients.",
|
|
342
|
+
input: {
|
|
343
|
+
type: "object",
|
|
344
|
+
properties: {
|
|
345
|
+
detailLevel: {
|
|
346
|
+
type: "string",
|
|
347
|
+
constraints: {
|
|
348
|
+
oneOf: ["summary", "full"]
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
includeErrorHistory: {
|
|
352
|
+
type: "boolean"
|
|
353
|
+
},
|
|
354
|
+
errorHistoryLimit: {
|
|
355
|
+
type: "number",
|
|
356
|
+
constraints: {
|
|
357
|
+
min: 1,
|
|
358
|
+
max: 200
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
output: {
|
|
364
|
+
type: "object",
|
|
365
|
+
properties: {
|
|
366
|
+
transportDiagnostics: {
|
|
367
|
+
type: "object"
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
270
372
|
this.handleInstanceUpdateTask = CadenzaService.createMetaTask(
|
|
271
373
|
"Handle Instance Update",
|
|
272
374
|
(ctx, emit) => {
|
|
@@ -306,7 +408,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
306
408
|
if (this.serviceName === serviceName) {
|
|
307
409
|
return false;
|
|
308
410
|
}
|
|
309
|
-
if (!isFrontend && this.deputies.has(serviceName) || this.remoteSignals.has(serviceName)) {
|
|
411
|
+
if (!isFrontend && (this.deputies.has(serviceName) || this.remoteIntents.has(serviceName)) || this.remoteSignals.has(serviceName)) {
|
|
310
412
|
const clientCreated = instances?.some(
|
|
311
413
|
(i) => i.address === address && i.port === port && i.clientCreated && i.isActive
|
|
312
414
|
);
|
|
@@ -356,7 +458,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
356
458
|
for (const serviceInstance of ctx.serviceInstances) {
|
|
357
459
|
yield { serviceInstance };
|
|
358
460
|
}
|
|
359
|
-
}).doOn(
|
|
461
|
+
}).doOn(
|
|
462
|
+
"meta.service_registry.registered_global_signals",
|
|
463
|
+
"meta.service_registry.registered_global_intents"
|
|
464
|
+
).then(this.handleInstanceUpdateTask);
|
|
360
465
|
this.handleGlobalSignalRegistrationTask = CadenzaService.createMetaTask(
|
|
361
466
|
"Handle global Signal Registration",
|
|
362
467
|
(ctx) => {
|
|
@@ -397,6 +502,32 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
397
502
|
},
|
|
398
503
|
"Handles registration of remote signals"
|
|
399
504
|
).emits("meta.service_registry.registered_global_signals").doOn("global.meta.cadenza_db.gathered_sync_data");
|
|
505
|
+
this.handleGlobalIntentRegistrationTask = CadenzaService.createMetaTask(
|
|
506
|
+
"Handle global intent registration",
|
|
507
|
+
(ctx) => {
|
|
508
|
+
const intentToTaskMaps = this.normalizeIntentMaps(ctx);
|
|
509
|
+
const sorted = intentToTaskMaps.sort((a, b) => {
|
|
510
|
+
if (a.deleted && !b.deleted) return -1;
|
|
511
|
+
if (!a.deleted && b.deleted) return 1;
|
|
512
|
+
return 0;
|
|
513
|
+
});
|
|
514
|
+
for (const map of sorted) {
|
|
515
|
+
if (map.deleted) {
|
|
516
|
+
this.unregisterRemoteIntentDeputy(map);
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
CadenzaService.inquiryBroker.addIntent({
|
|
520
|
+
name: map.intentName
|
|
521
|
+
});
|
|
522
|
+
this.registerRemoteIntentDeputy(map);
|
|
523
|
+
}
|
|
524
|
+
return true;
|
|
525
|
+
},
|
|
526
|
+
"Handles registration of remote inquiry intent responders"
|
|
527
|
+
).emits("meta.service_registry.registered_global_intents").doOn(
|
|
528
|
+
"global.meta.cadenza_db.gathered_sync_data",
|
|
529
|
+
"global.meta.graph_metadata.task_intent_associated"
|
|
530
|
+
);
|
|
400
531
|
this.handleServiceNotRespondingTask = CadenzaService.createMetaTask(
|
|
401
532
|
"Handle service not responding",
|
|
402
533
|
(ctx, emit) => {
|
|
@@ -510,7 +641,10 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
510
641
|
});
|
|
511
642
|
return joinedContext;
|
|
512
643
|
}
|
|
513
|
-
).emits("meta.service_registry.initial_sync_complete").then(
|
|
644
|
+
).emits("meta.service_registry.initial_sync_complete").then(
|
|
645
|
+
this.handleGlobalSignalRegistrationTask,
|
|
646
|
+
this.handleGlobalIntentRegistrationTask
|
|
647
|
+
);
|
|
514
648
|
this.fullSyncTask = CadenzaService.createMetaRoutine("Full sync", [
|
|
515
649
|
CadenzaService.createCadenzaDBQueryTask("signal_to_task_map", {
|
|
516
650
|
filter: {
|
|
@@ -518,6 +652,15 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
518
652
|
},
|
|
519
653
|
fields: ["signal_name", "service_name", "deleted"]
|
|
520
654
|
}).then(mergeSyncDataTask),
|
|
655
|
+
CadenzaService.createCadenzaDBQueryTask("intent_to_task_map", {
|
|
656
|
+
fields: [
|
|
657
|
+
"intent_name",
|
|
658
|
+
"task_name",
|
|
659
|
+
"task_version",
|
|
660
|
+
"service_name",
|
|
661
|
+
"deleted"
|
|
662
|
+
]
|
|
663
|
+
}).then(mergeSyncDataTask),
|
|
521
664
|
CadenzaService.createCadenzaDBQueryTask("service_instance", {
|
|
522
665
|
filter: {
|
|
523
666
|
deleted: false,
|
|
@@ -708,6 +851,25 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
708
851
|
__active: self?.isActive ?? false
|
|
709
852
|
};
|
|
710
853
|
}).doOn("meta.socket.status_check_requested");
|
|
854
|
+
this.collectTransportDiagnosticsTask = CadenzaService.createMetaTask(
|
|
855
|
+
"Collect transport diagnostics",
|
|
856
|
+
async (ctx) => {
|
|
857
|
+
const inquiryResult = await CadenzaService.inquire(
|
|
858
|
+
META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT,
|
|
859
|
+
{
|
|
860
|
+
detailLevel: ctx.detailLevel,
|
|
861
|
+
includeErrorHistory: ctx.includeErrorHistory,
|
|
862
|
+
errorHistoryLimit: ctx.errorHistoryLimit
|
|
863
|
+
},
|
|
864
|
+
ctx.inquiryOptions ?? ctx.__inquiryOptions ?? {}
|
|
865
|
+
);
|
|
866
|
+
return {
|
|
867
|
+
...ctx,
|
|
868
|
+
...inquiryResult
|
|
869
|
+
};
|
|
870
|
+
},
|
|
871
|
+
"Collects distributed transport diagnostics using inquiry responders."
|
|
872
|
+
).doOn("meta.service_registry.transport_diagnostics_requested").emits("meta.service_registry.transport_diagnostics_collected").emitsOnFail("meta.service_registry.transport_diagnostics_failed");
|
|
711
873
|
this.insertServiceTask = CadenzaService.createCadenzaDBInsertTask(
|
|
712
874
|
"service",
|
|
713
875
|
{
|
|
@@ -916,8 +1078,125 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
916
1078
|
if (!this._instance) this._instance = new _ServiceRegistry();
|
|
917
1079
|
return this._instance;
|
|
918
1080
|
}
|
|
1081
|
+
buildRemoteIntentDeputyKey(map) {
|
|
1082
|
+
return `${map.intentName}|${map.serviceName}|${map.taskName}|${map.taskVersion ?? 1}`;
|
|
1083
|
+
}
|
|
1084
|
+
normalizeIntentMaps(ctx) {
|
|
1085
|
+
if (Array.isArray(ctx.intentToTaskMaps)) {
|
|
1086
|
+
return ctx.intentToTaskMaps.map((m) => ({
|
|
1087
|
+
intentName: m.intentName ?? m.intent_name,
|
|
1088
|
+
serviceName: m.serviceName ?? m.service_name,
|
|
1089
|
+
taskName: m.taskName ?? m.task_name,
|
|
1090
|
+
taskVersion: m.taskVersion ?? m.task_version ?? 1,
|
|
1091
|
+
deleted: !!m.deleted
|
|
1092
|
+
})).filter((m) => m.intentName && m.serviceName && m.taskName);
|
|
1093
|
+
}
|
|
1094
|
+
const single = ctx.intentToTaskMap ?? ctx.data ?? (ctx.intentName ? ctx : void 0);
|
|
1095
|
+
if (!single) return [];
|
|
1096
|
+
const normalized = {
|
|
1097
|
+
intentName: single.intentName ?? single.intent_name,
|
|
1098
|
+
serviceName: single.serviceName ?? single.service_name,
|
|
1099
|
+
taskName: single.taskName ?? single.task_name,
|
|
1100
|
+
taskVersion: single.taskVersion ?? single.task_version ?? 1,
|
|
1101
|
+
deleted: !!single.deleted
|
|
1102
|
+
};
|
|
1103
|
+
if (!normalized.intentName || !normalized.serviceName || !normalized.taskName)
|
|
1104
|
+
return [];
|
|
1105
|
+
return [normalized];
|
|
1106
|
+
}
|
|
1107
|
+
registerRemoteIntentDeputy(map) {
|
|
1108
|
+
if (!this.serviceName || map.serviceName === this.serviceName) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
const key = this.buildRemoteIntentDeputyKey(map);
|
|
1112
|
+
if (this.remoteIntentDeputiesByKey.has(key)) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const deputyTaskName = `Inquire ${map.intentName} via ${map.serviceName} (${map.taskName} v${map.taskVersion})`;
|
|
1116
|
+
const deputyTask = isMetaIntentName(map.intentName) ? CadenzaService.createMetaDeputyTask(map.taskName, map.serviceName, {
|
|
1117
|
+
register: false,
|
|
1118
|
+
isHidden: true,
|
|
1119
|
+
retryCount: 1,
|
|
1120
|
+
retryDelay: 50,
|
|
1121
|
+
retryDelayFactor: 1.2
|
|
1122
|
+
}) : CadenzaService.createDeputyTask(map.taskName, map.serviceName, {
|
|
1123
|
+
register: false,
|
|
1124
|
+
isHidden: true,
|
|
1125
|
+
retryCount: 1,
|
|
1126
|
+
retryDelay: 50,
|
|
1127
|
+
retryDelayFactor: 1.2
|
|
1128
|
+
});
|
|
1129
|
+
deputyTask.respondsTo(map.intentName);
|
|
1130
|
+
if (!this.remoteIntents.has(map.serviceName)) {
|
|
1131
|
+
this.remoteIntents.set(map.serviceName, /* @__PURE__ */ new Set());
|
|
1132
|
+
}
|
|
1133
|
+
this.remoteIntents.get(map.serviceName).add(map.intentName);
|
|
1134
|
+
const descriptor = {
|
|
1135
|
+
key,
|
|
1136
|
+
intentName: map.intentName,
|
|
1137
|
+
serviceName: map.serviceName,
|
|
1138
|
+
remoteTaskName: map.taskName,
|
|
1139
|
+
remoteTaskVersion: map.taskVersion,
|
|
1140
|
+
localTaskName: deputyTask.name || deputyTaskName,
|
|
1141
|
+
localTask: deputyTask
|
|
1142
|
+
};
|
|
1143
|
+
this.remoteIntentDeputiesByKey.set(key, descriptor);
|
|
1144
|
+
this.remoteIntentDeputiesByTask.set(deputyTask, descriptor);
|
|
1145
|
+
}
|
|
1146
|
+
unregisterRemoteIntentDeputy(map) {
|
|
1147
|
+
const key = this.buildRemoteIntentDeputyKey(map);
|
|
1148
|
+
const descriptor = this.remoteIntentDeputiesByKey.get(key);
|
|
1149
|
+
if (!descriptor) {
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
const task = descriptor.localTask;
|
|
1153
|
+
if (task) {
|
|
1154
|
+
CadenzaService.inquiryBroker.unsubscribe(descriptor.intentName, task);
|
|
1155
|
+
task.destroy();
|
|
1156
|
+
}
|
|
1157
|
+
this.remoteIntentDeputiesByTask.delete(descriptor.localTask);
|
|
1158
|
+
this.remoteIntentDeputiesByKey.delete(key);
|
|
1159
|
+
this.remoteIntents.get(descriptor.serviceName)?.delete(descriptor.intentName);
|
|
1160
|
+
if (!this.remoteIntents.get(descriptor.serviceName)?.size) {
|
|
1161
|
+
this.remoteIntents.delete(descriptor.serviceName);
|
|
1162
|
+
}
|
|
1163
|
+
const deputies = this.deputies.get(descriptor.serviceName);
|
|
1164
|
+
if (deputies) {
|
|
1165
|
+
this.deputies.set(
|
|
1166
|
+
descriptor.serviceName,
|
|
1167
|
+
deputies.filter((d) => d.localTaskName !== descriptor.localTaskName)
|
|
1168
|
+
);
|
|
1169
|
+
if (this.deputies.get(descriptor.serviceName)?.length === 0) {
|
|
1170
|
+
this.deputies.delete(descriptor.serviceName);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
getInquiryResponderDescriptor(task) {
|
|
1175
|
+
const remote = this.remoteIntentDeputiesByTask.get(task);
|
|
1176
|
+
if (remote) {
|
|
1177
|
+
return {
|
|
1178
|
+
isRemote: true,
|
|
1179
|
+
serviceName: remote.serviceName,
|
|
1180
|
+
taskName: remote.remoteTaskName,
|
|
1181
|
+
taskVersion: remote.remoteTaskVersion,
|
|
1182
|
+
localTaskName: remote.localTaskName
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
return {
|
|
1186
|
+
isRemote: false,
|
|
1187
|
+
serviceName: this.serviceName ?? "UnknownService",
|
|
1188
|
+
taskName: task.name,
|
|
1189
|
+
taskVersion: task.version,
|
|
1190
|
+
localTaskName: task.name
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
919
1193
|
reset() {
|
|
920
1194
|
this.instances.clear();
|
|
1195
|
+
this.deputies.clear();
|
|
1196
|
+
this.remoteSignals.clear();
|
|
1197
|
+
this.remoteIntents.clear();
|
|
1198
|
+
this.remoteIntentDeputiesByKey.clear();
|
|
1199
|
+
this.remoteIntentDeputiesByTask.clear();
|
|
921
1200
|
}
|
|
922
1201
|
};
|
|
923
1202
|
|
|
@@ -1034,6 +1313,8 @@ var RestController = class _RestController {
|
|
|
1034
1313
|
* It initializes and configures the REST server tasks.
|
|
1035
1314
|
*/
|
|
1036
1315
|
constructor() {
|
|
1316
|
+
this.fetchClientDiagnostics = /* @__PURE__ */ new Map();
|
|
1317
|
+
this.diagnosticsErrorHistoryLimit = 100;
|
|
1037
1318
|
/**
|
|
1038
1319
|
* Fetches data from the given URL with a specified timeout. This function performs
|
|
1039
1320
|
* a fetch request with the ability to cancel the request if it exceeds the provided timeout duration.
|
|
@@ -1074,6 +1355,11 @@ var RestController = class _RestController {
|
|
|
1074
1355
|
"meta.rest.delegation_requested",
|
|
1075
1356
|
"meta.socket.delegation_requested"
|
|
1076
1357
|
);
|
|
1358
|
+
CadenzaService.createMetaTask(
|
|
1359
|
+
"Collect fetch transport diagnostics",
|
|
1360
|
+
(ctx) => this.collectFetchTransportDiagnostics(ctx),
|
|
1361
|
+
"Responds to distributed transport diagnostics inquiries with REST/fetch client data."
|
|
1362
|
+
).respondsTo(META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT);
|
|
1077
1363
|
CadenzaService.createMetaRoutine(
|
|
1078
1364
|
"RestServer",
|
|
1079
1365
|
[
|
|
@@ -1404,6 +1690,13 @@ var RestController = class _RestController {
|
|
|
1404
1690
|
const port = protocol === "https" ? 443 : servicePort;
|
|
1405
1691
|
const URL = `${protocol}://${serviceAddress}:${port}`;
|
|
1406
1692
|
const fetchId = `${serviceAddress}_${port}`;
|
|
1693
|
+
const fetchDiagnostics = this.ensureFetchClientDiagnostics(
|
|
1694
|
+
fetchId,
|
|
1695
|
+
serviceName,
|
|
1696
|
+
URL
|
|
1697
|
+
);
|
|
1698
|
+
fetchDiagnostics.destroyed = false;
|
|
1699
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1407
1700
|
if (CadenzaService.get(`Send Handshake to ${URL}`)) {
|
|
1408
1701
|
console.error("Fetch client already exists", URL);
|
|
1409
1702
|
return;
|
|
@@ -1425,6 +1718,10 @@ var RestController = class _RestController {
|
|
|
1425
1718
|
);
|
|
1426
1719
|
if (response.__status !== "success") {
|
|
1427
1720
|
const error = response.__error ?? `Failed to connect to service ${serviceName} ${ctx2.serviceInstanceId}`;
|
|
1721
|
+
fetchDiagnostics.connected = false;
|
|
1722
|
+
fetchDiagnostics.lastHandshakeError = error;
|
|
1723
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1724
|
+
this.recordFetchClientError(fetchId, serviceName, URL, error);
|
|
1428
1725
|
CadenzaService.log(
|
|
1429
1726
|
"Fetch handshake failed.",
|
|
1430
1727
|
{ error, serviceName, URL },
|
|
@@ -1434,6 +1731,11 @@ var RestController = class _RestController {
|
|
|
1434
1731
|
return { ...ctx2, __error: error, errored: true };
|
|
1435
1732
|
}
|
|
1436
1733
|
ctx2.serviceInstanceId = response.__serviceInstanceId;
|
|
1734
|
+
fetchDiagnostics.connected = true;
|
|
1735
|
+
fetchDiagnostics.destroyed = false;
|
|
1736
|
+
fetchDiagnostics.lastHandshakeAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1737
|
+
fetchDiagnostics.lastHandshakeError = null;
|
|
1738
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1437
1739
|
CadenzaService.log("Fetch client connected.", {
|
|
1438
1740
|
response,
|
|
1439
1741
|
serviceName,
|
|
@@ -1449,6 +1751,10 @@ var RestController = class _RestController {
|
|
|
1449
1751
|
});
|
|
1450
1752
|
}
|
|
1451
1753
|
} catch (e) {
|
|
1754
|
+
fetchDiagnostics.connected = false;
|
|
1755
|
+
fetchDiagnostics.lastHandshakeError = this.getErrorMessage(e);
|
|
1756
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1757
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1452
1758
|
CadenzaService.log(
|
|
1453
1759
|
"Error in fetch handshake",
|
|
1454
1760
|
{ error: e, serviceName, URL, ctx: ctx2 },
|
|
@@ -1470,6 +1776,8 @@ var RestController = class _RestController {
|
|
|
1470
1776
|
if (ctx2.__remoteRoutineName === void 0) {
|
|
1471
1777
|
return;
|
|
1472
1778
|
}
|
|
1779
|
+
fetchDiagnostics.delegationRequests++;
|
|
1780
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1473
1781
|
let resultContext;
|
|
1474
1782
|
try {
|
|
1475
1783
|
resultContext = await this.fetchDataWithTimeout(
|
|
@@ -1483,8 +1791,21 @@ var RestController = class _RestController {
|
|
|
1483
1791
|
},
|
|
1484
1792
|
3e4
|
|
1485
1793
|
);
|
|
1794
|
+
if (resultContext?.errored || resultContext?.failed) {
|
|
1795
|
+
fetchDiagnostics.delegationFailures++;
|
|
1796
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1797
|
+
this.recordFetchClientError(
|
|
1798
|
+
fetchId,
|
|
1799
|
+
serviceName,
|
|
1800
|
+
URL,
|
|
1801
|
+
resultContext?.__error ?? resultContext?.error ?? "Delegation failed"
|
|
1802
|
+
);
|
|
1803
|
+
}
|
|
1486
1804
|
} catch (e) {
|
|
1487
1805
|
console.error("Error in delegation", e);
|
|
1806
|
+
fetchDiagnostics.delegationFailures++;
|
|
1807
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1808
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1488
1809
|
resultContext = {
|
|
1489
1810
|
__error: `Error: ${e}`,
|
|
1490
1811
|
errored: true,
|
|
@@ -1510,6 +1831,8 @@ var RestController = class _RestController {
|
|
|
1510
1831
|
if (ctx2.__signalName === void 0) {
|
|
1511
1832
|
return;
|
|
1512
1833
|
}
|
|
1834
|
+
fetchDiagnostics.signalTransmissions++;
|
|
1835
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1513
1836
|
let response;
|
|
1514
1837
|
try {
|
|
1515
1838
|
response = await this.fetchDataWithTimeout(
|
|
@@ -1526,8 +1849,21 @@ var RestController = class _RestController {
|
|
|
1526
1849
|
if (ctx2.__routineExecId) {
|
|
1527
1850
|
emit(`meta.fetch.transmitted:${ctx2.__routineExecId}`, response);
|
|
1528
1851
|
}
|
|
1852
|
+
if (response?.errored || response?.failed) {
|
|
1853
|
+
fetchDiagnostics.signalFailures++;
|
|
1854
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1855
|
+
this.recordFetchClientError(
|
|
1856
|
+
fetchId,
|
|
1857
|
+
serviceName,
|
|
1858
|
+
URL,
|
|
1859
|
+
response?.__error ?? response?.error ?? "Signal transmission failed"
|
|
1860
|
+
);
|
|
1861
|
+
}
|
|
1529
1862
|
} catch (e) {
|
|
1530
1863
|
console.error("Error in transmission", e);
|
|
1864
|
+
fetchDiagnostics.signalFailures++;
|
|
1865
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1866
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1531
1867
|
response = {
|
|
1532
1868
|
__error: `Error: ${e}`,
|
|
1533
1869
|
errored: true,
|
|
@@ -1545,6 +1881,8 @@ var RestController = class _RestController {
|
|
|
1545
1881
|
const statusTask = CadenzaService.createMetaTask(
|
|
1546
1882
|
`Request status from ${URL}`,
|
|
1547
1883
|
async (ctx2) => {
|
|
1884
|
+
fetchDiagnostics.statusChecks++;
|
|
1885
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1548
1886
|
let status;
|
|
1549
1887
|
try {
|
|
1550
1888
|
status = await this.fetchDataWithTimeout(
|
|
@@ -1554,7 +1892,20 @@ var RestController = class _RestController {
|
|
|
1554
1892
|
},
|
|
1555
1893
|
1e3
|
|
1556
1894
|
);
|
|
1895
|
+
if (status?.errored || status?.failed) {
|
|
1896
|
+
fetchDiagnostics.statusFailures++;
|
|
1897
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1898
|
+
this.recordFetchClientError(
|
|
1899
|
+
fetchId,
|
|
1900
|
+
serviceName,
|
|
1901
|
+
URL,
|
|
1902
|
+
status?.__error ?? status?.error ?? "Status check failed"
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1557
1905
|
} catch (e) {
|
|
1906
|
+
fetchDiagnostics.statusFailures++;
|
|
1907
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1908
|
+
this.recordFetchClientError(fetchId, serviceName, URL, e);
|
|
1558
1909
|
status = {
|
|
1559
1910
|
__error: `Error: ${e}`,
|
|
1560
1911
|
errored: true,
|
|
@@ -1566,6 +1917,9 @@ var RestController = class _RestController {
|
|
|
1566
1917
|
"Requests status"
|
|
1567
1918
|
).doOn("meta.fetch.status_check_requested").emits("meta.fetch.status_checked").emitsOnFail("meta.fetch.status_check_failed");
|
|
1568
1919
|
CadenzaService.createEphemeralMetaTask("Destroy fetch client", () => {
|
|
1920
|
+
fetchDiagnostics.connected = false;
|
|
1921
|
+
fetchDiagnostics.destroyed = true;
|
|
1922
|
+
fetchDiagnostics.updatedAt = Date.now();
|
|
1569
1923
|
CadenzaService.log("Destroying fetch client", { URL, serviceName });
|
|
1570
1924
|
handshakeTask.destroy();
|
|
1571
1925
|
delegateTask.destroy();
|
|
@@ -1614,6 +1968,144 @@ var RestController = class _RestController {
|
|
|
1614
1968
|
if (!this._instance) this._instance = new _RestController();
|
|
1615
1969
|
return this._instance;
|
|
1616
1970
|
}
|
|
1971
|
+
resolveTransportDiagnosticsOptions(ctx) {
|
|
1972
|
+
const detailLevel = ctx.detailLevel === "full" ? "full" : "summary";
|
|
1973
|
+
const includeErrorHistory = Boolean(ctx.includeErrorHistory);
|
|
1974
|
+
const requestedLimit = Number(ctx.errorHistoryLimit);
|
|
1975
|
+
const errorHistoryLimit = Number.isFinite(requestedLimit) ? Math.max(1, Math.min(200, Math.trunc(requestedLimit))) : 10;
|
|
1976
|
+
return {
|
|
1977
|
+
detailLevel,
|
|
1978
|
+
includeErrorHistory,
|
|
1979
|
+
errorHistoryLimit
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
ensureFetchClientDiagnostics(fetchId, serviceName, url) {
|
|
1983
|
+
let state = this.fetchClientDiagnostics.get(fetchId);
|
|
1984
|
+
if (!state) {
|
|
1985
|
+
state = {
|
|
1986
|
+
fetchId,
|
|
1987
|
+
serviceName,
|
|
1988
|
+
url,
|
|
1989
|
+
connected: false,
|
|
1990
|
+
destroyed: false,
|
|
1991
|
+
lastHandshakeAt: null,
|
|
1992
|
+
lastHandshakeError: null,
|
|
1993
|
+
lastError: null,
|
|
1994
|
+
lastErrorAt: 0,
|
|
1995
|
+
errorHistory: [],
|
|
1996
|
+
delegationRequests: 0,
|
|
1997
|
+
delegationFailures: 0,
|
|
1998
|
+
signalTransmissions: 0,
|
|
1999
|
+
signalFailures: 0,
|
|
2000
|
+
statusChecks: 0,
|
|
2001
|
+
statusFailures: 0,
|
|
2002
|
+
updatedAt: Date.now()
|
|
2003
|
+
};
|
|
2004
|
+
this.fetchClientDiagnostics.set(fetchId, state);
|
|
2005
|
+
} else {
|
|
2006
|
+
state.serviceName = serviceName;
|
|
2007
|
+
state.url = url;
|
|
2008
|
+
}
|
|
2009
|
+
return state;
|
|
2010
|
+
}
|
|
2011
|
+
getErrorMessage(error) {
|
|
2012
|
+
if (error instanceof Error) {
|
|
2013
|
+
return error.message;
|
|
2014
|
+
}
|
|
2015
|
+
if (typeof error === "string") {
|
|
2016
|
+
return error;
|
|
2017
|
+
}
|
|
2018
|
+
try {
|
|
2019
|
+
return JSON.stringify(error);
|
|
2020
|
+
} catch {
|
|
2021
|
+
return String(error);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
recordFetchClientError(fetchId, serviceName, url, error) {
|
|
2025
|
+
const state = this.ensureFetchClientDiagnostics(fetchId, serviceName, url);
|
|
2026
|
+
const message = this.getErrorMessage(error);
|
|
2027
|
+
const now = Date.now();
|
|
2028
|
+
state.lastError = message;
|
|
2029
|
+
state.lastErrorAt = now;
|
|
2030
|
+
state.updatedAt = now;
|
|
2031
|
+
state.errorHistory.push({ at: new Date(now).toISOString(), message });
|
|
2032
|
+
if (state.errorHistory.length > this.diagnosticsErrorHistoryLimit) {
|
|
2033
|
+
state.errorHistory.splice(
|
|
2034
|
+
0,
|
|
2035
|
+
state.errorHistory.length - this.diagnosticsErrorHistoryLimit
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
collectFetchTransportDiagnostics(ctx) {
|
|
2040
|
+
const { detailLevel, includeErrorHistory, errorHistoryLimit } = this.resolveTransportDiagnosticsOptions(ctx);
|
|
2041
|
+
const serviceName = CadenzaService.serviceRegistry.serviceName ?? "UnknownService";
|
|
2042
|
+
const states = Array.from(this.fetchClientDiagnostics.values()).sort(
|
|
2043
|
+
(a, b) => a.fetchId.localeCompare(b.fetchId)
|
|
2044
|
+
);
|
|
2045
|
+
const summary = {
|
|
2046
|
+
detailLevel,
|
|
2047
|
+
totalClients: states.length,
|
|
2048
|
+
connectedClients: states.filter((state) => state.connected).length,
|
|
2049
|
+
destroyedClients: states.filter((state) => state.destroyed).length,
|
|
2050
|
+
delegationRequests: states.reduce(
|
|
2051
|
+
(acc, state) => acc + state.delegationRequests,
|
|
2052
|
+
0
|
|
2053
|
+
),
|
|
2054
|
+
delegationFailures: states.reduce(
|
|
2055
|
+
(acc, state) => acc + state.delegationFailures,
|
|
2056
|
+
0
|
|
2057
|
+
),
|
|
2058
|
+
signalTransmissions: states.reduce(
|
|
2059
|
+
(acc, state) => acc + state.signalTransmissions,
|
|
2060
|
+
0
|
|
2061
|
+
),
|
|
2062
|
+
signalFailures: states.reduce((acc, state) => acc + state.signalFailures, 0),
|
|
2063
|
+
statusChecks: states.reduce((acc, state) => acc + state.statusChecks, 0),
|
|
2064
|
+
statusFailures: states.reduce((acc, state) => acc + state.statusFailures, 0),
|
|
2065
|
+
latestError: states.slice().sort((a, b) => b.lastErrorAt - a.lastErrorAt).find((state) => state.lastError)?.lastError ?? null
|
|
2066
|
+
};
|
|
2067
|
+
if (detailLevel === "summary") {
|
|
2068
|
+
return {
|
|
2069
|
+
transportDiagnostics: {
|
|
2070
|
+
[serviceName]: {
|
|
2071
|
+
fetchClient: summary
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
}
|
|
2076
|
+
const clients = states.map((state) => {
|
|
2077
|
+
const details = {
|
|
2078
|
+
fetchId: state.fetchId,
|
|
2079
|
+
serviceName: state.serviceName,
|
|
2080
|
+
url: state.url,
|
|
2081
|
+
connected: state.connected,
|
|
2082
|
+
destroyed: state.destroyed,
|
|
2083
|
+
lastHandshakeAt: state.lastHandshakeAt,
|
|
2084
|
+
lastHandshakeError: state.lastHandshakeError,
|
|
2085
|
+
latestError: state.lastError,
|
|
2086
|
+
delegationRequests: state.delegationRequests,
|
|
2087
|
+
delegationFailures: state.delegationFailures,
|
|
2088
|
+
signalTransmissions: state.signalTransmissions,
|
|
2089
|
+
signalFailures: state.signalFailures,
|
|
2090
|
+
statusChecks: state.statusChecks,
|
|
2091
|
+
statusFailures: state.statusFailures
|
|
2092
|
+
};
|
|
2093
|
+
if (includeErrorHistory) {
|
|
2094
|
+
details.errorHistory = state.errorHistory.slice(-errorHistoryLimit);
|
|
2095
|
+
}
|
|
2096
|
+
return details;
|
|
2097
|
+
});
|
|
2098
|
+
return {
|
|
2099
|
+
transportDiagnostics: {
|
|
2100
|
+
[serviceName]: {
|
|
2101
|
+
fetchClient: {
|
|
2102
|
+
...summary,
|
|
2103
|
+
clients
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
1617
2109
|
};
|
|
1618
2110
|
|
|
1619
2111
|
// src/network/SocketController.ts
|
|
@@ -1661,10 +2153,6 @@ var waitForSocketConnection = async (socket, timeoutMs, createError) => {
|
|
|
1661
2153
|
|
|
1662
2154
|
// src/network/SocketController.ts
|
|
1663
2155
|
var SocketController = class _SocketController {
|
|
1664
|
-
static get instance() {
|
|
1665
|
-
if (!this._instance) this._instance = new _SocketController();
|
|
1666
|
-
return this._instance;
|
|
1667
|
-
}
|
|
1668
2156
|
/**
|
|
1669
2157
|
* Constructs the `SocketServer`, setting up a WebSocket server with specific configurations,
|
|
1670
2158
|
* including connection state recovery, rate limiting, CORS handling, and custom event handling.
|
|
@@ -1683,6 +2171,13 @@ var SocketController = class _SocketController {
|
|
|
1683
2171
|
* Initializes the `SocketServer` to be ready for WebSocket communication.
|
|
1684
2172
|
*/
|
|
1685
2173
|
constructor() {
|
|
2174
|
+
this.socketClientDiagnostics = /* @__PURE__ */ new Map();
|
|
2175
|
+
this.diagnosticsErrorHistoryLimit = 100;
|
|
2176
|
+
CadenzaService.createMetaTask(
|
|
2177
|
+
"Collect socket transport diagnostics",
|
|
2178
|
+
(ctx) => this.collectSocketTransportDiagnostics(ctx),
|
|
2179
|
+
"Responds to distributed transport diagnostics inquiries with socket client data."
|
|
2180
|
+
).respondsTo(META_RUNTIME_TRANSPORT_DIAGNOSTICS_INTENT);
|
|
1686
2181
|
CadenzaService.createMetaRoutine(
|
|
1687
2182
|
"SocketServer",
|
|
1688
2183
|
[
|
|
@@ -1910,6 +2405,13 @@ var SocketController = class _SocketController {
|
|
|
1910
2405
|
const port = protocol === "https" ? 443 : servicePort;
|
|
1911
2406
|
const URL = `${socketProtocol}://${serviceAddress}:${port}`;
|
|
1912
2407
|
const fetchId = `${serviceAddress}_${port}`;
|
|
2408
|
+
const socketDiagnostics = this.ensureSocketClientDiagnostics(
|
|
2409
|
+
fetchId,
|
|
2410
|
+
serviceName,
|
|
2411
|
+
URL
|
|
2412
|
+
);
|
|
2413
|
+
socketDiagnostics.destroyed = false;
|
|
2414
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
1913
2415
|
let handshake = false;
|
|
1914
2416
|
let errorCount = 0;
|
|
1915
2417
|
const ERROR_LIMIT = 5;
|
|
@@ -1919,6 +2421,11 @@ var SocketController = class _SocketController {
|
|
|
1919
2421
|
}
|
|
1920
2422
|
const pendingDelegationIds = /* @__PURE__ */ new Set();
|
|
1921
2423
|
const pendingTimers = /* @__PURE__ */ new Set();
|
|
2424
|
+
const syncPendingCounts = () => {
|
|
2425
|
+
socketDiagnostics.pendingDelegations = pendingDelegationIds.size;
|
|
2426
|
+
socketDiagnostics.pendingTimers = pendingTimers.size;
|
|
2427
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2428
|
+
};
|
|
1922
2429
|
let handshakeTask = null;
|
|
1923
2430
|
let emitWhenReady = null;
|
|
1924
2431
|
let transmitTask = null;
|
|
@@ -1968,6 +2475,12 @@ var SocketController = class _SocketController {
|
|
|
1968
2475
|
{ socketId: socket?.id, serviceName, URL, event },
|
|
1969
2476
|
"error"
|
|
1970
2477
|
);
|
|
2478
|
+
this.recordSocketClientError(
|
|
2479
|
+
fetchId,
|
|
2480
|
+
serviceName,
|
|
2481
|
+
URL,
|
|
2482
|
+
waitResult.error
|
|
2483
|
+
);
|
|
1971
2484
|
resolveWithError(waitResult.error);
|
|
1972
2485
|
return;
|
|
1973
2486
|
}
|
|
@@ -1976,6 +2489,7 @@ var SocketController = class _SocketController {
|
|
|
1976
2489
|
timer = setTimeout(() => {
|
|
1977
2490
|
if (timer) {
|
|
1978
2491
|
pendingTimers.delete(timer);
|
|
2492
|
+
syncPendingCounts();
|
|
1979
2493
|
timer = null;
|
|
1980
2494
|
}
|
|
1981
2495
|
CadenzaService.log(
|
|
@@ -1983,9 +2497,16 @@ var SocketController = class _SocketController {
|
|
|
1983
2497
|
{ socketId: socket?.id, serviceName, URL },
|
|
1984
2498
|
"error"
|
|
1985
2499
|
);
|
|
2500
|
+
this.recordSocketClientError(
|
|
2501
|
+
fetchId,
|
|
2502
|
+
serviceName,
|
|
2503
|
+
URL,
|
|
2504
|
+
`Socket event '${event}' timed out`
|
|
2505
|
+
);
|
|
1986
2506
|
resolveWithError(`Socket event '${event}' timed out`);
|
|
1987
2507
|
}, timeoutMs + 10);
|
|
1988
2508
|
pendingTimers.add(timer);
|
|
2509
|
+
syncPendingCounts();
|
|
1989
2510
|
}
|
|
1990
2511
|
const connectedSocket = socket;
|
|
1991
2512
|
if (!connectedSocket) {
|
|
@@ -1998,6 +2519,7 @@ var SocketController = class _SocketController {
|
|
|
1998
2519
|
if (timer) {
|
|
1999
2520
|
clearTimeout(timer);
|
|
2000
2521
|
pendingTimers.delete(timer);
|
|
2522
|
+
syncPendingCounts();
|
|
2001
2523
|
timer = null;
|
|
2002
2524
|
}
|
|
2003
2525
|
if (err) {
|
|
@@ -2011,6 +2533,12 @@ var SocketController = class _SocketController {
|
|
|
2011
2533
|
},
|
|
2012
2534
|
"warning"
|
|
2013
2535
|
);
|
|
2536
|
+
this.recordSocketClientError(
|
|
2537
|
+
fetchId,
|
|
2538
|
+
serviceName,
|
|
2539
|
+
URL,
|
|
2540
|
+
err
|
|
2541
|
+
);
|
|
2014
2542
|
response = {
|
|
2015
2543
|
__error: `Timeout error: ${err}`,
|
|
2016
2544
|
errored: true,
|
|
@@ -2027,6 +2555,10 @@ var SocketController = class _SocketController {
|
|
|
2027
2555
|
};
|
|
2028
2556
|
socket.on("connect", () => {
|
|
2029
2557
|
if (handshake) return;
|
|
2558
|
+
socketDiagnostics.connected = true;
|
|
2559
|
+
socketDiagnostics.destroyed = false;
|
|
2560
|
+
socketDiagnostics.socketId = socket?.id ?? null;
|
|
2561
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2030
2562
|
CadenzaService.emit(`meta.socket_client.connected:${fetchId}`, ctx);
|
|
2031
2563
|
});
|
|
2032
2564
|
socket.on("delegation_progress", (ctx2) => {
|
|
@@ -2045,6 +2577,12 @@ var SocketController = class _SocketController {
|
|
|
2045
2577
|
});
|
|
2046
2578
|
socket.on("connect_error", (err) => {
|
|
2047
2579
|
handshake = false;
|
|
2580
|
+
socketDiagnostics.connected = false;
|
|
2581
|
+
socketDiagnostics.handshake = false;
|
|
2582
|
+
socketDiagnostics.connectErrors++;
|
|
2583
|
+
socketDiagnostics.lastHandshakeError = err.message;
|
|
2584
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2585
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2048
2586
|
CadenzaService.log(
|
|
2049
2587
|
"Socket connect error",
|
|
2050
2588
|
{ error: err.message, serviceName, socketId: socket?.id, URL },
|
|
@@ -2053,9 +2591,16 @@ var SocketController = class _SocketController {
|
|
|
2053
2591
|
CadenzaService.emit(`meta.socket_client.connect_error:${fetchId}`, err);
|
|
2054
2592
|
});
|
|
2055
2593
|
socket.on("reconnect_attempt", (attempt) => {
|
|
2594
|
+
socketDiagnostics.reconnectAttempts = Math.max(
|
|
2595
|
+
socketDiagnostics.reconnectAttempts,
|
|
2596
|
+
attempt
|
|
2597
|
+
);
|
|
2598
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2056
2599
|
CadenzaService.log(`Reconnect attempt: ${attempt}`);
|
|
2057
2600
|
});
|
|
2058
2601
|
socket.on("reconnect", (attempt) => {
|
|
2602
|
+
socketDiagnostics.connected = true;
|
|
2603
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2059
2604
|
CadenzaService.log(`Socket reconnected after ${attempt} tries`, {
|
|
2060
2605
|
socketId: socket?.id,
|
|
2061
2606
|
URL,
|
|
@@ -2064,6 +2609,12 @@ var SocketController = class _SocketController {
|
|
|
2064
2609
|
});
|
|
2065
2610
|
socket.on("reconnect_error", (err) => {
|
|
2066
2611
|
handshake = false;
|
|
2612
|
+
socketDiagnostics.connected = false;
|
|
2613
|
+
socketDiagnostics.handshake = false;
|
|
2614
|
+
socketDiagnostics.reconnectErrors++;
|
|
2615
|
+
socketDiagnostics.lastHandshakeError = err.message;
|
|
2616
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2617
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2067
2618
|
CadenzaService.log(
|
|
2068
2619
|
"Socket reconnect failed.",
|
|
2069
2620
|
{ error: err.message, serviceName, URL, socketId: socket?.id },
|
|
@@ -2072,6 +2623,9 @@ var SocketController = class _SocketController {
|
|
|
2072
2623
|
});
|
|
2073
2624
|
socket.on("error", (err) => {
|
|
2074
2625
|
errorCount++;
|
|
2626
|
+
socketDiagnostics.socketErrors++;
|
|
2627
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2628
|
+
this.recordSocketClientError(fetchId, serviceName, URL, err);
|
|
2075
2629
|
CadenzaService.log(
|
|
2076
2630
|
"Socket error",
|
|
2077
2631
|
{ error: err, socketId: socket?.id, URL, serviceName },
|
|
@@ -2080,6 +2634,11 @@ var SocketController = class _SocketController {
|
|
|
2080
2634
|
CadenzaService.emit("meta.socket_client.error", err);
|
|
2081
2635
|
});
|
|
2082
2636
|
socket.on("disconnect", () => {
|
|
2637
|
+
const disconnectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2638
|
+
socketDiagnostics.connected = false;
|
|
2639
|
+
socketDiagnostics.handshake = false;
|
|
2640
|
+
socketDiagnostics.lastDisconnectAt = disconnectedAt;
|
|
2641
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2083
2642
|
CadenzaService.log(
|
|
2084
2643
|
"Socket disconnected.",
|
|
2085
2644
|
{ URL, serviceName, socketId: socket?.id },
|
|
@@ -2098,6 +2657,8 @@ var SocketController = class _SocketController {
|
|
|
2098
2657
|
async (ctx2, emit) => {
|
|
2099
2658
|
if (handshake) return;
|
|
2100
2659
|
handshake = true;
|
|
2660
|
+
socketDiagnostics.handshake = true;
|
|
2661
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2101
2662
|
await emitWhenReady?.(
|
|
2102
2663
|
"handshake",
|
|
2103
2664
|
{
|
|
@@ -2109,6 +2670,11 @@ var SocketController = class _SocketController {
|
|
|
2109
2670
|
1e4,
|
|
2110
2671
|
(result) => {
|
|
2111
2672
|
if (result.status === "success") {
|
|
2673
|
+
socketDiagnostics.connected = true;
|
|
2674
|
+
socketDiagnostics.handshake = true;
|
|
2675
|
+
socketDiagnostics.lastHandshakeAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2676
|
+
socketDiagnostics.lastHandshakeError = null;
|
|
2677
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2112
2678
|
CadenzaService.log("Socket client connected", {
|
|
2113
2679
|
result,
|
|
2114
2680
|
serviceName,
|
|
@@ -2116,6 +2682,16 @@ var SocketController = class _SocketController {
|
|
|
2116
2682
|
URL
|
|
2117
2683
|
});
|
|
2118
2684
|
} else {
|
|
2685
|
+
socketDiagnostics.connected = false;
|
|
2686
|
+
socketDiagnostics.handshake = false;
|
|
2687
|
+
socketDiagnostics.lastHandshakeError = result?.__error ?? result?.error ?? "Socket handshake failed";
|
|
2688
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2689
|
+
this.recordSocketClientError(
|
|
2690
|
+
fetchId,
|
|
2691
|
+
serviceName,
|
|
2692
|
+
URL,
|
|
2693
|
+
socketDiagnostics.lastHandshakeError
|
|
2694
|
+
);
|
|
2119
2695
|
CadenzaService.log(
|
|
2120
2696
|
"Socket handshake failed",
|
|
2121
2697
|
{ result, serviceName, socketId: socket?.id, URL },
|
|
@@ -2138,6 +2714,7 @@ var SocketController = class _SocketController {
|
|
|
2138
2714
|
delete ctx2.__broadcast;
|
|
2139
2715
|
const requestSentAt = Date.now();
|
|
2140
2716
|
pendingDelegationIds.add(ctx2.__metadata.__deputyExecId);
|
|
2717
|
+
syncPendingCounts();
|
|
2141
2718
|
emitWhenReady?.(
|
|
2142
2719
|
"delegation",
|
|
2143
2720
|
ctx2,
|
|
@@ -2155,6 +2732,15 @@ var SocketController = class _SocketController {
|
|
|
2155
2732
|
}
|
|
2156
2733
|
);
|
|
2157
2734
|
pendingDelegationIds.delete(ctx2.__metadata.__deputyExecId);
|
|
2735
|
+
syncPendingCounts();
|
|
2736
|
+
if (resultContext?.errored || resultContext?.failed) {
|
|
2737
|
+
this.recordSocketClientError(
|
|
2738
|
+
fetchId,
|
|
2739
|
+
serviceName,
|
|
2740
|
+
URL,
|
|
2741
|
+
resultContext?.__error ?? resultContext?.error ?? "Socket delegation failed"
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2158
2744
|
resolve(resultContext);
|
|
2159
2745
|
}
|
|
2160
2746
|
);
|
|
@@ -2190,6 +2776,10 @@ var SocketController = class _SocketController {
|
|
|
2190
2776
|
`Shutdown SocketClient ${URL}`,
|
|
2191
2777
|
(ctx2, emit) => {
|
|
2192
2778
|
handshake = false;
|
|
2779
|
+
socketDiagnostics.connected = false;
|
|
2780
|
+
socketDiagnostics.handshake = false;
|
|
2781
|
+
socketDiagnostics.destroyed = true;
|
|
2782
|
+
socketDiagnostics.updatedAt = Date.now();
|
|
2193
2783
|
CadenzaService.log("Shutting down socket client", { URL, serviceName });
|
|
2194
2784
|
socket?.close();
|
|
2195
2785
|
handshakeTask?.destroy();
|
|
@@ -2219,10 +2809,12 @@ var SocketController = class _SocketController {
|
|
|
2219
2809
|
});
|
|
2220
2810
|
}
|
|
2221
2811
|
pendingDelegationIds.clear();
|
|
2812
|
+
syncPendingCounts();
|
|
2222
2813
|
for (const timer of pendingTimers) {
|
|
2223
2814
|
clearTimeout(timer);
|
|
2224
2815
|
}
|
|
2225
2816
|
pendingTimers.clear();
|
|
2817
|
+
syncPendingCounts();
|
|
2226
2818
|
},
|
|
2227
2819
|
"Shuts down the socket client"
|
|
2228
2820
|
).doOn(
|
|
@@ -2236,6 +2828,157 @@ var SocketController = class _SocketController {
|
|
|
2236
2828
|
"Connects to a specified socket server"
|
|
2237
2829
|
).doOn("meta.fetch.handshake_complete").emitsOnFail("meta.socket_client.connect_failed");
|
|
2238
2830
|
}
|
|
2831
|
+
static get instance() {
|
|
2832
|
+
if (!this._instance) this._instance = new _SocketController();
|
|
2833
|
+
return this._instance;
|
|
2834
|
+
}
|
|
2835
|
+
resolveTransportDiagnosticsOptions(ctx) {
|
|
2836
|
+
const detailLevel = ctx.detailLevel === "full" ? "full" : "summary";
|
|
2837
|
+
const includeErrorHistory = Boolean(ctx.includeErrorHistory);
|
|
2838
|
+
const requestedLimit = Number(ctx.errorHistoryLimit);
|
|
2839
|
+
const errorHistoryLimit = Number.isFinite(requestedLimit) ? Math.max(1, Math.min(200, Math.trunc(requestedLimit))) : 10;
|
|
2840
|
+
return {
|
|
2841
|
+
detailLevel,
|
|
2842
|
+
includeErrorHistory,
|
|
2843
|
+
errorHistoryLimit
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
ensureSocketClientDiagnostics(fetchId, serviceName, url) {
|
|
2847
|
+
let state = this.socketClientDiagnostics.get(fetchId);
|
|
2848
|
+
if (!state) {
|
|
2849
|
+
state = {
|
|
2850
|
+
fetchId,
|
|
2851
|
+
serviceName,
|
|
2852
|
+
url,
|
|
2853
|
+
socketId: null,
|
|
2854
|
+
connected: false,
|
|
2855
|
+
handshake: false,
|
|
2856
|
+
reconnectAttempts: 0,
|
|
2857
|
+
connectErrors: 0,
|
|
2858
|
+
reconnectErrors: 0,
|
|
2859
|
+
socketErrors: 0,
|
|
2860
|
+
pendingDelegations: 0,
|
|
2861
|
+
pendingTimers: 0,
|
|
2862
|
+
destroyed: false,
|
|
2863
|
+
lastHandshakeAt: null,
|
|
2864
|
+
lastHandshakeError: null,
|
|
2865
|
+
lastDisconnectAt: null,
|
|
2866
|
+
lastError: null,
|
|
2867
|
+
lastErrorAt: 0,
|
|
2868
|
+
errorHistory: [],
|
|
2869
|
+
updatedAt: Date.now()
|
|
2870
|
+
};
|
|
2871
|
+
this.socketClientDiagnostics.set(fetchId, state);
|
|
2872
|
+
} else {
|
|
2873
|
+
state.serviceName = serviceName;
|
|
2874
|
+
state.url = url;
|
|
2875
|
+
}
|
|
2876
|
+
return state;
|
|
2877
|
+
}
|
|
2878
|
+
getErrorMessage(error) {
|
|
2879
|
+
if (error instanceof Error) {
|
|
2880
|
+
return error.message;
|
|
2881
|
+
}
|
|
2882
|
+
if (typeof error === "string") {
|
|
2883
|
+
return error;
|
|
2884
|
+
}
|
|
2885
|
+
try {
|
|
2886
|
+
return JSON.stringify(error);
|
|
2887
|
+
} catch {
|
|
2888
|
+
return String(error);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
recordSocketClientError(fetchId, serviceName, url, error) {
|
|
2892
|
+
const state = this.ensureSocketClientDiagnostics(fetchId, serviceName, url);
|
|
2893
|
+
const message = this.getErrorMessage(error);
|
|
2894
|
+
const now = Date.now();
|
|
2895
|
+
state.lastError = message;
|
|
2896
|
+
state.lastErrorAt = now;
|
|
2897
|
+
state.updatedAt = now;
|
|
2898
|
+
state.errorHistory.push({
|
|
2899
|
+
at: new Date(now).toISOString(),
|
|
2900
|
+
message
|
|
2901
|
+
});
|
|
2902
|
+
if (state.errorHistory.length > this.diagnosticsErrorHistoryLimit) {
|
|
2903
|
+
state.errorHistory.splice(
|
|
2904
|
+
0,
|
|
2905
|
+
state.errorHistory.length - this.diagnosticsErrorHistoryLimit
|
|
2906
|
+
);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
collectSocketTransportDiagnostics(ctx) {
|
|
2910
|
+
const { detailLevel, includeErrorHistory, errorHistoryLimit } = this.resolveTransportDiagnosticsOptions(ctx);
|
|
2911
|
+
const serviceName = CadenzaService.serviceRegistry.serviceName ?? "UnknownService";
|
|
2912
|
+
const states = Array.from(this.socketClientDiagnostics.values()).sort(
|
|
2913
|
+
(a, b) => a.fetchId.localeCompare(b.fetchId)
|
|
2914
|
+
);
|
|
2915
|
+
const summary = {
|
|
2916
|
+
detailLevel,
|
|
2917
|
+
totalClients: states.length,
|
|
2918
|
+
connectedClients: states.filter((state) => state.connected).length,
|
|
2919
|
+
activeHandshakes: states.filter((state) => state.handshake).length,
|
|
2920
|
+
pendingDelegations: states.reduce(
|
|
2921
|
+
(acc, state) => acc + state.pendingDelegations,
|
|
2922
|
+
0
|
|
2923
|
+
),
|
|
2924
|
+
pendingTimers: states.reduce((acc, state) => acc + state.pendingTimers, 0),
|
|
2925
|
+
reconnectAttempts: states.reduce(
|
|
2926
|
+
(acc, state) => acc + state.reconnectAttempts,
|
|
2927
|
+
0
|
|
2928
|
+
),
|
|
2929
|
+
connectErrors: states.reduce((acc, state) => acc + state.connectErrors, 0),
|
|
2930
|
+
reconnectErrors: states.reduce(
|
|
2931
|
+
(acc, state) => acc + state.reconnectErrors,
|
|
2932
|
+
0
|
|
2933
|
+
),
|
|
2934
|
+
socketErrors: states.reduce((acc, state) => acc + state.socketErrors, 0),
|
|
2935
|
+
latestError: states.slice().sort((a, b) => b.lastErrorAt - a.lastErrorAt).find((state) => state.lastError)?.lastError ?? null
|
|
2936
|
+
};
|
|
2937
|
+
if (detailLevel === "summary") {
|
|
2938
|
+
return {
|
|
2939
|
+
transportDiagnostics: {
|
|
2940
|
+
[serviceName]: {
|
|
2941
|
+
socketClient: summary
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
const clients = states.map((state) => {
|
|
2947
|
+
const details = {
|
|
2948
|
+
fetchId: state.fetchId,
|
|
2949
|
+
serviceName: state.serviceName,
|
|
2950
|
+
url: state.url,
|
|
2951
|
+
socketId: state.socketId,
|
|
2952
|
+
connected: state.connected,
|
|
2953
|
+
handshake: state.handshake,
|
|
2954
|
+
reconnectAttempts: state.reconnectAttempts,
|
|
2955
|
+
connectErrors: state.connectErrors,
|
|
2956
|
+
reconnectErrors: state.reconnectErrors,
|
|
2957
|
+
socketErrors: state.socketErrors,
|
|
2958
|
+
pendingDelegations: state.pendingDelegations,
|
|
2959
|
+
pendingTimers: state.pendingTimers,
|
|
2960
|
+
destroyed: state.destroyed,
|
|
2961
|
+
lastHandshakeAt: state.lastHandshakeAt,
|
|
2962
|
+
lastHandshakeError: state.lastHandshakeError,
|
|
2963
|
+
lastDisconnectAt: state.lastDisconnectAt,
|
|
2964
|
+
latestError: state.lastError
|
|
2965
|
+
};
|
|
2966
|
+
if (includeErrorHistory) {
|
|
2967
|
+
details.errorHistory = state.errorHistory.slice(-errorHistoryLimit);
|
|
2968
|
+
}
|
|
2969
|
+
return details;
|
|
2970
|
+
});
|
|
2971
|
+
return {
|
|
2972
|
+
transportDiagnostics: {
|
|
2973
|
+
[serviceName]: {
|
|
2974
|
+
socketClient: {
|
|
2975
|
+
...summary,
|
|
2976
|
+
clients
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
}
|
|
2239
2982
|
};
|
|
2240
2983
|
|
|
2241
2984
|
// src/utils/tools.ts
|
|
@@ -2339,25 +3082,8 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2339
3082
|
return {
|
|
2340
3083
|
data: {
|
|
2341
3084
|
...ctx.data,
|
|
2342
|
-
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
2343
|
-
|
|
2344
|
-
subOperation: "insert",
|
|
2345
|
-
table: "context_schema",
|
|
2346
|
-
data: {
|
|
2347
|
-
...ctx.data.inputContextSchemaId
|
|
2348
|
-
},
|
|
2349
|
-
return: "uuid"
|
|
2350
|
-
} : null,
|
|
2351
|
-
outputContextSchemaId: ctx.data.outputContextSchemaId ? {
|
|
2352
|
-
subOperation: "insert",
|
|
2353
|
-
table: "context_schema",
|
|
2354
|
-
data: {
|
|
2355
|
-
...ctx.data.outputContextSchemaId
|
|
2356
|
-
},
|
|
2357
|
-
return: "uuid"
|
|
2358
|
-
} : null
|
|
2359
|
-
},
|
|
2360
|
-
transaction: true
|
|
3085
|
+
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
3086
|
+
}
|
|
2361
3087
|
};
|
|
2362
3088
|
}).doOn("meta.task.created").emits("global.meta.graph_metadata.task_created");
|
|
2363
3089
|
CadenzaService.createMetaTask("Handle task update", (ctx) => {
|
|
@@ -2564,9 +3290,11 @@ var GraphMetadataController = class _GraphMetadataController {
|
|
|
2564
3290
|
{ concurrency: 100, isSubMeta: true }
|
|
2565
3291
|
).doOn("meta.node.mapped", "meta.node.detected_previous_task_execution").emits("global.meta.graph_metadata.relationship_executed");
|
|
2566
3292
|
CadenzaService.createMetaTask("Handle Intent Creation", (ctx) => {
|
|
3293
|
+
const intentName = ctx.data?.name;
|
|
2567
3294
|
return {
|
|
2568
3295
|
data: {
|
|
2569
|
-
...ctx.data
|
|
3296
|
+
...ctx.data,
|
|
3297
|
+
isMeta: intentName ? isMetaIntentName(intentName) : false
|
|
2570
3298
|
}
|
|
2571
3299
|
};
|
|
2572
3300
|
}).doOn("meta.inquiry_broker.added").emits("global.meta.graph_metadata.intent_created");
|
|
@@ -2598,6 +3326,52 @@ var SCHEMA_TYPES = [
|
|
|
2598
3326
|
// src/database/DatabaseController.ts
|
|
2599
3327
|
import { Pool } from "pg";
|
|
2600
3328
|
import { camelCase, snakeCase } from "lodash-es";
|
|
3329
|
+
function resolveTableQueryIntents(serviceName, tableName, table, defaultInputSchema) {
|
|
3330
|
+
const resolvedServiceName = serviceName ?? "unknown-service";
|
|
3331
|
+
const defaultIntentName = `query-${resolvedServiceName}-${tableName}`;
|
|
3332
|
+
const defaultDescription = `Perform a query operation on the ${tableName} table`;
|
|
3333
|
+
const intents = [
|
|
3334
|
+
{
|
|
3335
|
+
name: defaultIntentName,
|
|
3336
|
+
description: defaultDescription,
|
|
3337
|
+
input: defaultInputSchema
|
|
3338
|
+
}
|
|
3339
|
+
];
|
|
3340
|
+
const warnings = [];
|
|
3341
|
+
const names = /* @__PURE__ */ new Set([defaultIntentName]);
|
|
3342
|
+
for (const customIntent of table.customIntents?.query ?? []) {
|
|
3343
|
+
const name = typeof customIntent === "string" ? customIntent.trim() : customIntent.intent?.trim();
|
|
3344
|
+
if (!name) {
|
|
3345
|
+
warnings.push(`Skipped empty custom query intent for table '${tableName}'.`);
|
|
3346
|
+
continue;
|
|
3347
|
+
}
|
|
3348
|
+
if (name.length > 100) {
|
|
3349
|
+
warnings.push(
|
|
3350
|
+
`Skipped custom query intent '${name}' for table '${tableName}': name must be <= 100 characters.`
|
|
3351
|
+
);
|
|
3352
|
+
continue;
|
|
3353
|
+
}
|
|
3354
|
+
if (name.includes(" ") || name.includes(".") || name.includes("\\")) {
|
|
3355
|
+
warnings.push(
|
|
3356
|
+
`Skipped custom query intent '${name}' for table '${tableName}': name cannot contain spaces, dots or backslashes.`
|
|
3357
|
+
);
|
|
3358
|
+
continue;
|
|
3359
|
+
}
|
|
3360
|
+
if (names.has(name)) {
|
|
3361
|
+
warnings.push(
|
|
3362
|
+
`Skipped duplicate custom query intent '${name}' for table '${tableName}'.`
|
|
3363
|
+
);
|
|
3364
|
+
continue;
|
|
3365
|
+
}
|
|
3366
|
+
names.add(name);
|
|
3367
|
+
intents.push({
|
|
3368
|
+
name,
|
|
3369
|
+
description: typeof customIntent === "string" ? `Perform a query operation on the ${tableName} table` : customIntent.description ?? defaultDescription,
|
|
3370
|
+
input: typeof customIntent === "string" ? defaultInputSchema : customIntent.input ?? defaultInputSchema
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3373
|
+
return { intents, warnings };
|
|
3374
|
+
}
|
|
2601
3375
|
var DatabaseController = class _DatabaseController {
|
|
2602
3376
|
/**
|
|
2603
3377
|
* Constructor for initializing the `DatabaseService` class.
|
|
@@ -2739,6 +3513,20 @@ var DatabaseController = class _DatabaseController {
|
|
|
2739
3513
|
}
|
|
2740
3514
|
}
|
|
2741
3515
|
}
|
|
3516
|
+
if (table.customIntents?.query) {
|
|
3517
|
+
if (!Array.isArray(table.customIntents.query)) {
|
|
3518
|
+
throw new Error(
|
|
3519
|
+
`Invalid customIntents.query for ${tableName}: expected array`
|
|
3520
|
+
);
|
|
3521
|
+
}
|
|
3522
|
+
for (const customIntent of table.customIntents.query) {
|
|
3523
|
+
if (typeof customIntent !== "string" && (typeof customIntent !== "object" || !customIntent || typeof customIntent.intent !== "string")) {
|
|
3524
|
+
throw new Error(
|
|
3525
|
+
`Invalid custom query intent on ${tableName}: expected string or object with intent`
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
2742
3530
|
}
|
|
2743
3531
|
}
|
|
2744
3532
|
console.log("SCHEMA VALIDATED");
|
|
@@ -3775,13 +4563,30 @@ var DatabaseController = class _DatabaseController {
|
|
|
3775
4563
|
}) ?? []
|
|
3776
4564
|
);
|
|
3777
4565
|
if (op === "query") {
|
|
3778
|
-
const
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
4566
|
+
const { intents, warnings } = resolveTableQueryIntents(
|
|
4567
|
+
CadenzaService.serviceRegistry?.serviceName,
|
|
4568
|
+
tableName,
|
|
4569
|
+
table,
|
|
4570
|
+
schema
|
|
4571
|
+
);
|
|
4572
|
+
for (const warning of warnings) {
|
|
4573
|
+
CadenzaService.log(
|
|
4574
|
+
"Skipped custom query intent registration.",
|
|
4575
|
+
{
|
|
4576
|
+
tableName,
|
|
4577
|
+
warning
|
|
4578
|
+
},
|
|
4579
|
+
"warning"
|
|
4580
|
+
);
|
|
4581
|
+
}
|
|
4582
|
+
for (const intent of intents) {
|
|
4583
|
+
CadenzaService.defineIntent({
|
|
4584
|
+
name: intent.name,
|
|
4585
|
+
description: intent.description,
|
|
4586
|
+
input: intent.input
|
|
4587
|
+
});
|
|
4588
|
+
}
|
|
4589
|
+
task.respondsTo(...intents.map((intent) => intent.name));
|
|
3785
4590
|
}
|
|
3786
4591
|
}
|
|
3787
4592
|
getInputSchema(op, tableName, table) {
|
|
@@ -3873,18 +4678,18 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3873
4678
|
Object.entries(table.fields).map((field) => {
|
|
3874
4679
|
return [
|
|
3875
4680
|
field[0],
|
|
3876
|
-
|
|
3877
|
-
{
|
|
4681
|
+
{
|
|
4682
|
+
value: {
|
|
3878
4683
|
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3879
4684
|
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3880
4685
|
},
|
|
3881
|
-
{
|
|
4686
|
+
effect: {
|
|
3882
4687
|
type: "string",
|
|
3883
4688
|
constraints: {
|
|
3884
4689
|
oneOf: ["increment", "decrement", "set"]
|
|
3885
4690
|
}
|
|
3886
4691
|
},
|
|
3887
|
-
{
|
|
4692
|
+
subOperation: {
|
|
3888
4693
|
type: "object",
|
|
3889
4694
|
properties: {
|
|
3890
4695
|
subOperation: {
|
|
@@ -3894,17 +4699,17 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3894
4699
|
table: {
|
|
3895
4700
|
type: "string"
|
|
3896
4701
|
},
|
|
3897
|
-
data:
|
|
3898
|
-
{
|
|
4702
|
+
data: {
|
|
4703
|
+
single: {
|
|
3899
4704
|
type: "object"
|
|
3900
4705
|
},
|
|
3901
|
-
{
|
|
4706
|
+
batch: {
|
|
3902
4707
|
type: "array",
|
|
3903
4708
|
items: {
|
|
3904
4709
|
type: "object"
|
|
3905
4710
|
}
|
|
3906
4711
|
}
|
|
3907
|
-
|
|
4712
|
+
},
|
|
3908
4713
|
filter: {
|
|
3909
4714
|
type: "object"
|
|
3910
4715
|
},
|
|
@@ -3920,7 +4725,7 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3920
4725
|
},
|
|
3921
4726
|
required: ["subOperation", "table"]
|
|
3922
4727
|
}
|
|
3923
|
-
|
|
4728
|
+
}
|
|
3924
4729
|
];
|
|
3925
4730
|
})
|
|
3926
4731
|
)
|
|
@@ -3928,13 +4733,13 @@ function getInsertDataSchemaFromTable(table, tableName) {
|
|
|
3928
4733
|
required: Object.entries(table.fields).filter((field) => field[1].required || field[1].primary).map((field) => field[0]),
|
|
3929
4734
|
strict: true
|
|
3930
4735
|
};
|
|
3931
|
-
return
|
|
3932
|
-
dataSchema,
|
|
3933
|
-
{
|
|
4736
|
+
return {
|
|
4737
|
+
single: dataSchema,
|
|
4738
|
+
batch: {
|
|
3934
4739
|
type: "array",
|
|
3935
4740
|
items: dataSchema
|
|
3936
4741
|
}
|
|
3937
|
-
|
|
4742
|
+
};
|
|
3938
4743
|
}
|
|
3939
4744
|
function getQueryFilterSchemaFromTable(table, tableName) {
|
|
3940
4745
|
return {
|
|
@@ -3944,24 +4749,24 @@ function getQueryFilterSchemaFromTable(table, tableName) {
|
|
|
3944
4749
|
Object.entries(table.fields).map((field) => {
|
|
3945
4750
|
return [
|
|
3946
4751
|
field[0],
|
|
3947
|
-
|
|
3948
|
-
{
|
|
4752
|
+
{
|
|
4753
|
+
value: {
|
|
3949
4754
|
type: tableFieldTypeToSchemaType(field[1].type),
|
|
3950
4755
|
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
3951
4756
|
},
|
|
3952
|
-
{
|
|
4757
|
+
in: {
|
|
3953
4758
|
type: "array",
|
|
3954
4759
|
items: {
|
|
3955
4760
|
type: tableFieldTypeToSchemaType(field[1].type)
|
|
3956
4761
|
}
|
|
3957
4762
|
}
|
|
3958
|
-
|
|
4763
|
+
}
|
|
3959
4764
|
];
|
|
3960
4765
|
})
|
|
3961
4766
|
)
|
|
3962
4767
|
},
|
|
3963
4768
|
strict: true,
|
|
3964
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4769
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
3965
4770
|
};
|
|
3966
4771
|
}
|
|
3967
4772
|
function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
@@ -3973,7 +4778,7 @@ function getQueryFieldsSchemaFromTable(table, tableName) {
|
|
|
3973
4778
|
oneOf: Object.keys(table.fields)
|
|
3974
4779
|
}
|
|
3975
4780
|
},
|
|
3976
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4781
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
3977
4782
|
};
|
|
3978
4783
|
}
|
|
3979
4784
|
function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
@@ -4020,7 +4825,7 @@ function getQueryJoinsSchemaFromTable(table, tableName) {
|
|
|
4020
4825
|
)
|
|
4021
4826
|
},
|
|
4022
4827
|
strict: true,
|
|
4023
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4828
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4024
4829
|
};
|
|
4025
4830
|
}
|
|
4026
4831
|
function getQuerySortSchemaFromTable(table, tableName) {
|
|
@@ -4042,7 +4847,7 @@ function getQuerySortSchemaFromTable(table, tableName) {
|
|
|
4042
4847
|
)
|
|
4043
4848
|
},
|
|
4044
4849
|
strict: true,
|
|
4045
|
-
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry
|
|
4850
|
+
description: `Inferred from table '${tableName}' on database service ${CadenzaService.serviceRegistry?.serviceName ?? "unknown-service"}.`
|
|
4046
4851
|
};
|
|
4047
4852
|
}
|
|
4048
4853
|
function getQueryLimitSchemaFromTable() {
|
|
@@ -4104,12 +4909,10 @@ function getQueryOnConflictSchemaFromTable(table, tableName) {
|
|
|
4104
4909
|
Object.entries(table.fields).map((field) => {
|
|
4105
4910
|
return [
|
|
4106
4911
|
field[0],
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
}
|
|
4112
|
-
]
|
|
4912
|
+
{
|
|
4913
|
+
type: tableFieldTypeToSchemaType(field[1].type),
|
|
4914
|
+
description: `Inferred from field '${field[0]}' of type [${field[1].type}] on table ${tableName}.`
|
|
4915
|
+
}
|
|
4113
4916
|
];
|
|
4114
4917
|
})
|
|
4115
4918
|
)
|
|
@@ -4467,6 +5270,75 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4467
5270
|
{ concurrency: 30 }
|
|
4468
5271
|
) : CadenzaService.get("dbInsertSignalToTaskMap"))?.then(registerSignalTask)
|
|
4469
5272
|
);
|
|
5273
|
+
const registerIntentTask = CadenzaService.createMetaTask(
|
|
5274
|
+
"Record intent registration",
|
|
5275
|
+
(ctx) => {
|
|
5276
|
+
if (!ctx.__syncing) {
|
|
5277
|
+
return;
|
|
5278
|
+
}
|
|
5279
|
+
CadenzaService.debounce("meta.sync_controller.synced_resource", {
|
|
5280
|
+
delayMs: 3e3
|
|
5281
|
+
});
|
|
5282
|
+
const task = CadenzaService.get(ctx.__taskName);
|
|
5283
|
+
task.__registeredIntents = task.__registeredIntents ?? /* @__PURE__ */ new Set();
|
|
5284
|
+
task.__registeredIntents.add(ctx.__intent);
|
|
5285
|
+
}
|
|
5286
|
+
);
|
|
5287
|
+
this.registerIntentToTaskMapTask = CadenzaService.createMetaTask(
|
|
5288
|
+
"Split intents of task",
|
|
5289
|
+
function* (ctx) {
|
|
5290
|
+
const task = ctx.task;
|
|
5291
|
+
if (task.hidden || !task.register) return;
|
|
5292
|
+
task.__registeredIntents = task.__registeredIntents ?? /* @__PURE__ */ new Set();
|
|
5293
|
+
task.__invalidMetaIntentWarnings = task.__invalidMetaIntentWarnings ?? /* @__PURE__ */ new Set();
|
|
5294
|
+
for (const intent of task.handlesIntents) {
|
|
5295
|
+
if (task.__registeredIntents.has(intent)) continue;
|
|
5296
|
+
if (isMetaIntentName(intent) && !task.isMeta) {
|
|
5297
|
+
if (!task.__invalidMetaIntentWarnings.has(intent)) {
|
|
5298
|
+
task.__invalidMetaIntentWarnings.add(intent);
|
|
5299
|
+
CadenzaService.log(
|
|
5300
|
+
"Skipping intent-to-task registration: non-meta task cannot handle meta intent.",
|
|
5301
|
+
{
|
|
5302
|
+
intent,
|
|
5303
|
+
taskName: task.name,
|
|
5304
|
+
taskVersion: task.version
|
|
5305
|
+
},
|
|
5306
|
+
"warning"
|
|
5307
|
+
);
|
|
5308
|
+
}
|
|
5309
|
+
continue;
|
|
5310
|
+
}
|
|
5311
|
+
yield {
|
|
5312
|
+
data: {
|
|
5313
|
+
intentName: intent,
|
|
5314
|
+
taskName: task.name,
|
|
5315
|
+
taskVersion: task.version,
|
|
5316
|
+
serviceName: CadenzaService.serviceRegistry.serviceName
|
|
5317
|
+
},
|
|
5318
|
+
__taskName: task.name,
|
|
5319
|
+
__intent: intent
|
|
5320
|
+
};
|
|
5321
|
+
}
|
|
5322
|
+
}
|
|
5323
|
+
).then(
|
|
5324
|
+
(this.isCadenzaDBReady ? CadenzaService.createCadenzaDBInsertTask(
|
|
5325
|
+
"intent_to_task_map",
|
|
5326
|
+
{
|
|
5327
|
+
onConflict: {
|
|
5328
|
+
target: [
|
|
5329
|
+
"intent_name",
|
|
5330
|
+
"task_name",
|
|
5331
|
+
"task_version",
|
|
5332
|
+
"service_name"
|
|
5333
|
+
],
|
|
5334
|
+
action: {
|
|
5335
|
+
do: "nothing"
|
|
5336
|
+
}
|
|
5337
|
+
}
|
|
5338
|
+
},
|
|
5339
|
+
{ concurrency: 30 }
|
|
5340
|
+
) : CadenzaService.get("dbInsertIntentToTaskMap"))?.then(registerIntentTask)
|
|
5341
|
+
);
|
|
4470
5342
|
this.registerTaskMapTask = CadenzaService.createMetaTask(
|
|
4471
5343
|
"Register task map to DB",
|
|
4472
5344
|
function* (ctx) {
|
|
@@ -4589,6 +5461,7 @@ var GraphSyncController = class _GraphSyncController {
|
|
|
4589
5461
|
CadenzaService.registry.doForEachTask.clone().doOn("meta.sync_controller.synced_tasks").then(
|
|
4590
5462
|
this.registerTaskMapTask,
|
|
4591
5463
|
this.registerSignalToTaskMapTask,
|
|
5464
|
+
this.registerIntentToTaskMapTask,
|
|
4592
5465
|
this.registerDeputyRelationshipTask
|
|
4593
5466
|
);
|
|
4594
5467
|
CadenzaService.registry.getAllRoutines.clone().doOn("meta.sync_controller.synced_routines").then(this.splitTasksInRoutines);
|
|
@@ -4730,11 +5603,192 @@ var CadenzaService = class {
|
|
|
4730
5603
|
Cadenza.interval(signal, context, intervalMs, leading, startDateTime);
|
|
4731
5604
|
}
|
|
4732
5605
|
static defineIntent(intent) {
|
|
4733
|
-
this.inquiryBroker?.
|
|
5606
|
+
this.inquiryBroker?.addIntent(intent);
|
|
4734
5607
|
return intent;
|
|
4735
5608
|
}
|
|
4736
|
-
static
|
|
4737
|
-
return this.
|
|
5609
|
+
static getInquiryResponderDescriptor(task) {
|
|
5610
|
+
return this.serviceRegistry.getInquiryResponderDescriptor(task);
|
|
5611
|
+
}
|
|
5612
|
+
static compareInquiryResponders(left, right) {
|
|
5613
|
+
return compareResponderDescriptors(left.descriptor, right.descriptor);
|
|
5614
|
+
}
|
|
5615
|
+
static buildInquirySummary(inquiry, startedAt, statuses, totalResponders) {
|
|
5616
|
+
const counts = summarizeResponderStatuses(statuses);
|
|
5617
|
+
const isMetaInquiry = isMetaIntentName(inquiry);
|
|
5618
|
+
const eligibleResponders = statuses.length;
|
|
5619
|
+
return {
|
|
5620
|
+
inquiry,
|
|
5621
|
+
isMetaInquiry,
|
|
5622
|
+
totalResponders,
|
|
5623
|
+
eligibleResponders,
|
|
5624
|
+
filteredOutResponders: Math.max(0, totalResponders - eligibleResponders),
|
|
5625
|
+
responded: counts.responded,
|
|
5626
|
+
failed: counts.failed,
|
|
5627
|
+
timedOut: counts.timedOut,
|
|
5628
|
+
pending: counts.pending,
|
|
5629
|
+
durationMs: Date.now() - startedAt,
|
|
5630
|
+
responders: statuses
|
|
5631
|
+
};
|
|
5632
|
+
}
|
|
5633
|
+
static async inquire(inquiry, context, options = {}) {
|
|
5634
|
+
this.bootstrap();
|
|
5635
|
+
const observer = this.inquiryBroker?.inquiryObservers.get(inquiry);
|
|
5636
|
+
const allResponders = observer ? Array.from(observer.tasks).map((task) => ({
|
|
5637
|
+
task,
|
|
5638
|
+
descriptor: this.getInquiryResponderDescriptor(task)
|
|
5639
|
+
})) : [];
|
|
5640
|
+
const isMetaInquiry = isMetaIntentName(inquiry);
|
|
5641
|
+
const responders = allResponders.filter(({ task, descriptor }) => {
|
|
5642
|
+
const shouldExecute = shouldExecuteInquiryResponder(inquiry, task.isMeta);
|
|
5643
|
+
if (shouldExecute) {
|
|
5644
|
+
return true;
|
|
5645
|
+
}
|
|
5646
|
+
const warningKey = `${inquiry}|${descriptor.serviceName}|${descriptor.taskName}|${descriptor.taskVersion}|${descriptor.localTaskName}`;
|
|
5647
|
+
if (!this.warnedInvalidMetaIntentResponderKeys.has(warningKey)) {
|
|
5648
|
+
this.warnedInvalidMetaIntentResponderKeys.add(warningKey);
|
|
5649
|
+
this.log(
|
|
5650
|
+
"Skipping non-meta task for meta intent inquiry.",
|
|
5651
|
+
{
|
|
5652
|
+
inquiry,
|
|
5653
|
+
responder: descriptor
|
|
5654
|
+
},
|
|
5655
|
+
"warning",
|
|
5656
|
+
descriptor.serviceName
|
|
5657
|
+
);
|
|
5658
|
+
}
|
|
5659
|
+
return false;
|
|
5660
|
+
});
|
|
5661
|
+
if (responders.length === 0) {
|
|
5662
|
+
return {
|
|
5663
|
+
__inquiryMeta: {
|
|
5664
|
+
inquiry,
|
|
5665
|
+
isMetaInquiry,
|
|
5666
|
+
totalResponders: allResponders.length,
|
|
5667
|
+
eligibleResponders: 0,
|
|
5668
|
+
filteredOutResponders: allResponders.length,
|
|
5669
|
+
responded: 0,
|
|
5670
|
+
failed: 0,
|
|
5671
|
+
timedOut: 0,
|
|
5672
|
+
pending: 0,
|
|
5673
|
+
durationMs: 0,
|
|
5674
|
+
responders: []
|
|
5675
|
+
}
|
|
5676
|
+
};
|
|
5677
|
+
}
|
|
5678
|
+
responders.sort(this.compareInquiryResponders.bind(this));
|
|
5679
|
+
const overallTimeoutMs = options.overallTimeoutMs ?? options.timeout ?? 0;
|
|
5680
|
+
const requireComplete = options.requireComplete ?? false;
|
|
5681
|
+
const perResponderTimeoutMs = options.perResponderTimeoutMs;
|
|
5682
|
+
const startedAt = Date.now();
|
|
5683
|
+
const statuses = [];
|
|
5684
|
+
const statusByTask = /* @__PURE__ */ new Map();
|
|
5685
|
+
for (const responder of responders) {
|
|
5686
|
+
const status = {
|
|
5687
|
+
...responder.descriptor,
|
|
5688
|
+
status: "timed_out",
|
|
5689
|
+
durationMs: 0
|
|
5690
|
+
};
|
|
5691
|
+
statuses.push(status);
|
|
5692
|
+
statusByTask.set(responder.task, status);
|
|
5693
|
+
}
|
|
5694
|
+
const resultsByTask = /* @__PURE__ */ new Map();
|
|
5695
|
+
const resolverTasks = [];
|
|
5696
|
+
const pending = new Set(responders.map((r) => r.task));
|
|
5697
|
+
const startTimeByTask = /* @__PURE__ */ new Map();
|
|
5698
|
+
this.emit("meta.inquiry_broker.inquire", { inquiry, context });
|
|
5699
|
+
return new Promise((resolve, reject) => {
|
|
5700
|
+
let finalized = false;
|
|
5701
|
+
let timeoutId;
|
|
5702
|
+
const finalize = (timedOut) => {
|
|
5703
|
+
if (finalized) return;
|
|
5704
|
+
finalized = true;
|
|
5705
|
+
if (timeoutId) {
|
|
5706
|
+
clearTimeout(timeoutId);
|
|
5707
|
+
timeoutId = void 0;
|
|
5708
|
+
}
|
|
5709
|
+
for (const resolverTask of resolverTasks) {
|
|
5710
|
+
resolverTask.destroy();
|
|
5711
|
+
}
|
|
5712
|
+
if (timedOut && pending.size > 0) {
|
|
5713
|
+
for (const task of pending) {
|
|
5714
|
+
const status = statusByTask.get(task);
|
|
5715
|
+
if (!status) continue;
|
|
5716
|
+
status.status = "timed_out";
|
|
5717
|
+
status.durationMs = Date.now() - (startTimeByTask.get(task) ?? startedAt);
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
const fulfilledContexts = responders.filter((responder) => resultsByTask.has(responder.task)).map((responder) => resultsByTask.get(responder.task));
|
|
5721
|
+
const mergedContext = mergeInquiryContexts(fulfilledContexts);
|
|
5722
|
+
const inquiryMeta = this.buildInquirySummary(
|
|
5723
|
+
inquiry,
|
|
5724
|
+
startedAt,
|
|
5725
|
+
statuses,
|
|
5726
|
+
allResponders.length
|
|
5727
|
+
);
|
|
5728
|
+
const responseContext = {
|
|
5729
|
+
...mergedContext,
|
|
5730
|
+
__inquiryMeta: inquiryMeta
|
|
5731
|
+
};
|
|
5732
|
+
if (requireComplete && (timedOut || inquiryMeta.failed > 0 || inquiryMeta.timedOut > 0 || inquiryMeta.pending > 0)) {
|
|
5733
|
+
reject({
|
|
5734
|
+
...responseContext,
|
|
5735
|
+
__error: `Inquiry '${inquiry}' did not complete successfully`,
|
|
5736
|
+
errored: true
|
|
5737
|
+
});
|
|
5738
|
+
return;
|
|
5739
|
+
}
|
|
5740
|
+
resolve(responseContext);
|
|
5741
|
+
};
|
|
5742
|
+
if (overallTimeoutMs > 0) {
|
|
5743
|
+
timeoutId = setTimeout(() => finalize(true), overallTimeoutMs);
|
|
5744
|
+
}
|
|
5745
|
+
for (const responder of responders) {
|
|
5746
|
+
const { task, descriptor } = responder;
|
|
5747
|
+
const inquiryId = uuid3();
|
|
5748
|
+
startTimeByTask.set(task, Date.now());
|
|
5749
|
+
const resolverTask = this.createEphemeralMetaTask(
|
|
5750
|
+
`Resolve inquiry ${inquiry} for ${descriptor.localTaskName}`,
|
|
5751
|
+
(resultCtx) => {
|
|
5752
|
+
if (finalized) {
|
|
5753
|
+
return;
|
|
5754
|
+
}
|
|
5755
|
+
pending.delete(task);
|
|
5756
|
+
const status = statusByTask.get(task);
|
|
5757
|
+
if (status) {
|
|
5758
|
+
status.durationMs = Date.now() - (startTimeByTask.get(task) ?? startedAt);
|
|
5759
|
+
if (resultCtx?.errored || resultCtx?.failed) {
|
|
5760
|
+
status.status = "failed";
|
|
5761
|
+
status.error = String(
|
|
5762
|
+
resultCtx?.__error ?? resultCtx?.error ?? "Inquiry responder failed"
|
|
5763
|
+
);
|
|
5764
|
+
} else {
|
|
5765
|
+
status.status = "fulfilled";
|
|
5766
|
+
resultsByTask.set(task, resultCtx);
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
if (pending.size === 0) {
|
|
5770
|
+
finalize(false);
|
|
5771
|
+
}
|
|
5772
|
+
},
|
|
5773
|
+
"Resolves distributed inquiry responder result",
|
|
5774
|
+
{ register: false }
|
|
5775
|
+
).doOn(`meta.node.graph_completed:${inquiryId}`);
|
|
5776
|
+
resolverTasks.push(resolverTask);
|
|
5777
|
+
const executionContext = {
|
|
5778
|
+
...context,
|
|
5779
|
+
__routineExecId: inquiryId,
|
|
5780
|
+
__isInquiry: true
|
|
5781
|
+
};
|
|
5782
|
+
if (perResponderTimeoutMs !== void 0) {
|
|
5783
|
+
executionContext.__timeout = perResponderTimeoutMs;
|
|
5784
|
+
}
|
|
5785
|
+
if (task.isMeta) {
|
|
5786
|
+
this.metaRunner?.run(task, executionContext);
|
|
5787
|
+
} else {
|
|
5788
|
+
this.runner?.run(task, executionContext);
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
});
|
|
4738
5792
|
}
|
|
4739
5793
|
/**
|
|
4740
5794
|
* Executes the given task or graph routine within the provided context using the configured runner.
|
|
@@ -5771,6 +6825,7 @@ var CadenzaService = class {
|
|
|
5771
6825
|
};
|
|
5772
6826
|
CadenzaService.isBootstrapped = false;
|
|
5773
6827
|
CadenzaService.serviceCreated = false;
|
|
6828
|
+
CadenzaService.warnedInvalidMetaIntentResponderKeys = /* @__PURE__ */ new Set();
|
|
5774
6829
|
|
|
5775
6830
|
// src/index.ts
|
|
5776
6831
|
import {
|