@workglow/task-graph 0.2.14 → 0.2.15
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/__tests__/public-exports.test.d.ts +7 -0
- package/dist/__tests__/public-exports.test.d.ts.map +1 -0
- package/dist/browser.js +879 -374
- package/dist/browser.js.map +22 -13
- package/dist/bun.js +879 -374
- package/dist/bun.js.map +22 -13
- package/dist/common.d.ts +4 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/node.js +879 -374
- package/dist/node.js.map +22 -13
- package/dist/task/EntitlementEnforcer.d.ts.map +1 -1
- package/dist/task/IteratorTask.d.ts +1 -1
- package/dist/task/IteratorTask.d.ts.map +1 -1
- package/dist/task/ReduceTask.d.ts +1 -0
- package/dist/task/ReduceTask.d.ts.map +1 -1
- package/dist/task/Task.d.ts +4 -1
- package/dist/task/Task.d.ts.map +1 -1
- package/dist/task/TaskJSON.d.ts +2 -0
- package/dist/task/TaskJSON.d.ts.map +1 -1
- package/dist/task/WhileTask.d.ts.map +1 -1
- package/dist/task/__tests__/DataflowJson.transforms.test.d.ts +7 -0
- package/dist/task/__tests__/DataflowJson.transforms.test.d.ts.map +1 -0
- package/dist/task-graph/ConditionalBuilder.d.ts.map +1 -1
- package/dist/task-graph/Dataflow.d.ts +41 -1
- package/dist/task-graph/Dataflow.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/dist/task-graph/TransformRegistry.d.ts +14 -0
- package/dist/task-graph/TransformRegistry.d.ts.map +1 -0
- package/dist/task-graph/TransformTypes.d.ts +51 -0
- package/dist/task-graph/TransformTypes.d.ts.map +1 -0
- package/dist/task-graph/Workflow.d.ts +13 -2
- package/dist/task-graph/Workflow.d.ts.map +1 -1
- package/dist/task-graph/__tests__/Dataflow.streaming.test.d.ts +7 -0
- package/dist/task-graph/__tests__/Dataflow.streaming.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/Dataflow.transforms.test.d.ts +7 -0
- package/dist/task-graph/__tests__/Dataflow.transforms.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/TaskGraphRunner.transforms.test.d.ts +7 -0
- package/dist/task-graph/__tests__/TaskGraphRunner.transforms.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/TransformRegistry.test.d.ts +6 -0
- package/dist/task-graph/__tests__/TransformRegistry.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/coalesce.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/coalesce.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/date-conversions.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/date-conversions.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/index-access.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/index-access.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/pick.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/pick.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/scalar-conversions.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/scalar-conversions.test.d.ts.map +1 -0
- package/dist/task-graph/__tests__/transforms/string-casts.test.d.ts +6 -0
- package/dist/task-graph/__tests__/transforms/string-casts.test.d.ts.map +1 -0
- package/dist/task-graph/autoConnect.d.ts +39 -0
- package/dist/task-graph/autoConnect.d.ts.map +1 -0
- package/dist/task-graph/transforms/coalesce.d.ts +11 -0
- package/dist/task-graph/transforms/coalesce.d.ts.map +1 -0
- package/dist/task-graph/transforms/date-conversions.d.ts +12 -0
- package/dist/task-graph/transforms/date-conversions.d.ts.map +1 -0
- package/dist/task-graph/transforms/index-access.d.ts +11 -0
- package/dist/task-graph/transforms/index-access.d.ts.map +1 -0
- package/dist/task-graph/transforms/index.d.ts +18 -0
- package/dist/task-graph/transforms/index.d.ts.map +1 -0
- package/dist/task-graph/transforms/pick.d.ts +11 -0
- package/dist/task-graph/transforms/pick.d.ts.map +1 -0
- package/dist/task-graph/transforms/scalar-conversions.d.ts +10 -0
- package/dist/task-graph/transforms/scalar-conversions.d.ts.map +1 -0
- package/dist/task-graph/transforms/string-casts.d.ts +18 -0
- package/dist/task-graph/transforms/string-casts.d.ts.map +1 -0
- package/package.json +7 -7
package/dist/node.js
CHANGED
|
@@ -2,6 +2,98 @@
|
|
|
2
2
|
import { areSemanticallyCompatible } from "@workglow/util/schema";
|
|
3
3
|
import { EventEmitter } from "@workglow/util";
|
|
4
4
|
|
|
5
|
+
// src/task/TaskError.ts
|
|
6
|
+
import { BaseError } from "@workglow/util";
|
|
7
|
+
|
|
8
|
+
class TaskError extends BaseError {
|
|
9
|
+
static type = "TaskError";
|
|
10
|
+
taskType;
|
|
11
|
+
taskId;
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class TaskConfigurationError extends TaskError {
|
|
18
|
+
static type = "TaskConfigurationError";
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class WorkflowError extends TaskError {
|
|
25
|
+
static type = "WorkflowError";
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class TaskAbortedError extends TaskError {
|
|
32
|
+
static type = "TaskAbortedError";
|
|
33
|
+
constructor(message = "Task aborted") {
|
|
34
|
+
super(message);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class TaskTimeoutError extends TaskAbortedError {
|
|
39
|
+
static type = "TaskTimeoutError";
|
|
40
|
+
constructor(timeoutMs) {
|
|
41
|
+
super(timeoutMs ? `Task timed out after ${timeoutMs}ms` : "Task timed out");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class TaskGraphTimeoutError extends TaskTimeoutError {
|
|
46
|
+
static type = "TaskGraphTimeoutError";
|
|
47
|
+
constructor(timeoutMs) {
|
|
48
|
+
super(timeoutMs);
|
|
49
|
+
this.message = timeoutMs ? `Graph execution timed out after ${timeoutMs}ms` : "Graph execution timed out";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class TaskFailedError extends TaskError {
|
|
54
|
+
static type = "TaskFailedError";
|
|
55
|
+
constructor(message = "Task failed") {
|
|
56
|
+
super(message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class JobTaskFailedError extends TaskFailedError {
|
|
61
|
+
static type = "JobTaskFailedError";
|
|
62
|
+
jobError;
|
|
63
|
+
constructor(err) {
|
|
64
|
+
super(String(err));
|
|
65
|
+
this.jobError = err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class TaskJSONError extends TaskError {
|
|
70
|
+
static type = "TaskJSONError";
|
|
71
|
+
constructor(message = "Error converting JSON to a Task") {
|
|
72
|
+
super(message);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
class TaskInvalidInputError extends TaskError {
|
|
77
|
+
static type = "TaskInvalidInputError";
|
|
78
|
+
constructor(message = "Invalid input data") {
|
|
79
|
+
super(message);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
class TaskEntitlementError extends TaskError {
|
|
84
|
+
static type = "TaskEntitlementError";
|
|
85
|
+
constructor(message = "Required entitlements denied") {
|
|
86
|
+
super(message);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
class TaskSerializationError extends TaskError {
|
|
91
|
+
static type = "TaskSerializationError";
|
|
92
|
+
constructor(taskType) {
|
|
93
|
+
super(`Task "${taskType}" cannot be serialized: config contains non-serializable values. ` + `Use a declarative config alternative or remove function-valued config properties.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
5
97
|
// src/task/TaskTypes.ts
|
|
6
98
|
var TaskStatus = {
|
|
7
99
|
PENDING: "PENDING",
|
|
@@ -48,6 +140,21 @@ var TaskConfigSchema = {
|
|
|
48
140
|
additionalProperties: false
|
|
49
141
|
};
|
|
50
142
|
|
|
143
|
+
// src/task-graph/TransformRegistry.ts
|
|
144
|
+
import { createServiceToken, globalServiceRegistry } from "@workglow/util";
|
|
145
|
+
var transformDefs = new Map;
|
|
146
|
+
var TransformRegistry = {
|
|
147
|
+
all: transformDefs,
|
|
148
|
+
registerTransform(def) {
|
|
149
|
+
transformDefs.set(def.id, def);
|
|
150
|
+
},
|
|
151
|
+
unregisterTransform(id) {
|
|
152
|
+
transformDefs.delete(id);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
var TRANSFORM_DEFS = createServiceToken("transform.defs");
|
|
156
|
+
globalServiceRegistry.registerIfAbsent(TRANSFORM_DEFS, () => TransformRegistry.all, true);
|
|
157
|
+
|
|
51
158
|
// src/task-graph/Dataflow.ts
|
|
52
159
|
var DATAFLOW_ALL_PORTS = "*";
|
|
53
160
|
var DATAFLOW_ERROR_PORT = "[error]";
|
|
@@ -177,18 +284,62 @@ class Dataflow {
|
|
|
177
284
|
return result;
|
|
178
285
|
}
|
|
179
286
|
toJSON() {
|
|
180
|
-
|
|
287
|
+
const base = {
|
|
181
288
|
sourceTaskId: this.sourceTaskId,
|
|
182
289
|
sourceTaskPortId: this.sourceTaskPortId,
|
|
183
290
|
targetTaskId: this.targetTaskId,
|
|
184
291
|
targetTaskPortId: this.targetTaskPortId
|
|
185
292
|
};
|
|
293
|
+
if (this._transforms.length > 0) {
|
|
294
|
+
base.transforms = this._transforms.map((s) => ({ id: s.id, params: s.params }));
|
|
295
|
+
}
|
|
296
|
+
return base;
|
|
186
297
|
}
|
|
187
298
|
_compatibilityCache;
|
|
299
|
+
_transforms = [];
|
|
300
|
+
getTransforms() {
|
|
301
|
+
return this._transforms;
|
|
302
|
+
}
|
|
303
|
+
setTransforms(steps) {
|
|
304
|
+
this._transforms = steps.map((s) => ({ id: s.id, params: s.params }));
|
|
305
|
+
this.invalidateCompatibilityCache();
|
|
306
|
+
}
|
|
307
|
+
addTransform(step) {
|
|
308
|
+
this._transforms.push({ id: step.id, params: step.params });
|
|
309
|
+
this.invalidateCompatibilityCache();
|
|
310
|
+
}
|
|
311
|
+
removeTransform(index) {
|
|
312
|
+
this._transforms.splice(index, 1);
|
|
313
|
+
this.invalidateCompatibilityCache();
|
|
314
|
+
}
|
|
315
|
+
async applyTransforms(registry) {
|
|
316
|
+
if (this._transforms.length === 0)
|
|
317
|
+
return;
|
|
318
|
+
const defs = registry.get(TRANSFORM_DEFS);
|
|
319
|
+
let cur = this.value;
|
|
320
|
+
try {
|
|
321
|
+
for (const step of this._transforms) {
|
|
322
|
+
const def = defs.get(step.id);
|
|
323
|
+
if (!def) {
|
|
324
|
+
throw new Error(`Unknown transform: ${step.id}`);
|
|
325
|
+
}
|
|
326
|
+
cur = await def.apply(cur, step.params ?? {});
|
|
327
|
+
}
|
|
328
|
+
this.value = cur;
|
|
329
|
+
} catch (e) {
|
|
330
|
+
const error = e instanceof TaskError ? e : new TaskError(e instanceof Error ? e.message : String(e));
|
|
331
|
+
if (!(e instanceof TaskError) && e instanceof Error && e.stack) {
|
|
332
|
+
error.stack = e.stack;
|
|
333
|
+
}
|
|
334
|
+
this.error = error;
|
|
335
|
+
this.setStatus(TaskStatus.FAILED);
|
|
336
|
+
throw e;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
188
339
|
invalidateCompatibilityCache() {
|
|
189
340
|
this._compatibilityCache = undefined;
|
|
190
341
|
}
|
|
191
|
-
semanticallyCompatible(graph, dataflow) {
|
|
342
|
+
semanticallyCompatible(graph, dataflow, registry) {
|
|
192
343
|
const sourceTask = graph.getTask(dataflow.sourceTaskId);
|
|
193
344
|
const targetTask = graph.getTask(dataflow.targetTaskId);
|
|
194
345
|
const shouldCache = !(sourceTask.constructor.hasDynamicSchemas ?? true) && !(targetTask.constructor.hasDynamicSchemas ?? true);
|
|
@@ -217,7 +368,26 @@ class Dataflow {
|
|
|
217
368
|
if (sourceSchemaProperty === undefined && sourceSchema.additionalProperties === true) {
|
|
218
369
|
sourceSchemaProperty = true;
|
|
219
370
|
}
|
|
220
|
-
|
|
371
|
+
let effectiveSourceSchema = sourceSchemaProperty;
|
|
372
|
+
if (this._transforms.length > 0) {
|
|
373
|
+
const defs = registry ? registry.get(TRANSFORM_DEFS) : TransformRegistry.all;
|
|
374
|
+
try {
|
|
375
|
+
let cur = effectiveSourceSchema === true ? {} : effectiveSourceSchema;
|
|
376
|
+
for (const step of this._transforms) {
|
|
377
|
+
const def = defs.get(step.id);
|
|
378
|
+
if (!def) {
|
|
379
|
+
return "incompatible";
|
|
380
|
+
}
|
|
381
|
+
cur = def.inferOutputSchema(cur, step.params ?? {});
|
|
382
|
+
}
|
|
383
|
+
effectiveSourceSchema = cur;
|
|
384
|
+
} catch {
|
|
385
|
+
if (shouldCache)
|
|
386
|
+
this._compatibilityCache = "incompatible";
|
|
387
|
+
return "incompatible";
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const result = areSemanticallyCompatible(effectiveSourceSchema, targetSchemaProperty);
|
|
221
391
|
if (shouldCache) {
|
|
222
392
|
this._compatibilityCache = result;
|
|
223
393
|
}
|
|
@@ -958,15 +1128,15 @@ import {
|
|
|
958
1128
|
collectPropertyValues,
|
|
959
1129
|
getLogger as getLogger3,
|
|
960
1130
|
getTelemetryProvider as getTelemetryProvider2,
|
|
961
|
-
globalServiceRegistry as
|
|
1131
|
+
globalServiceRegistry as globalServiceRegistry3,
|
|
962
1132
|
ServiceRegistry as ServiceRegistry2,
|
|
963
1133
|
SpanStatusCode as SpanStatusCode2,
|
|
964
1134
|
uuid4 as uuid43
|
|
965
1135
|
} from "@workglow/util";
|
|
966
1136
|
|
|
967
1137
|
// src/storage/TaskOutputRepository.ts
|
|
968
|
-
import { createServiceToken, EventEmitter as EventEmitter2 } from "@workglow/util";
|
|
969
|
-
var TASK_OUTPUT_REPOSITORY =
|
|
1138
|
+
import { createServiceToken as createServiceToken2, EventEmitter as EventEmitter2 } from "@workglow/util";
|
|
1139
|
+
var TASK_OUTPUT_REPOSITORY = createServiceToken2("taskgraph.taskOutputRepository");
|
|
970
1140
|
|
|
971
1141
|
class TaskOutputRepository {
|
|
972
1142
|
outputCompression;
|
|
@@ -1068,103 +1238,11 @@ function getNestedValue(obj, path) {
|
|
|
1068
1238
|
import { deepEqual, EventEmitter as EventEmitter3, uuid4 as uuid42 } from "@workglow/util";
|
|
1069
1239
|
import { compileSchema } from "@workglow/util/schema";
|
|
1070
1240
|
|
|
1071
|
-
// src/task/TaskError.ts
|
|
1072
|
-
import { BaseError } from "@workglow/util";
|
|
1073
|
-
|
|
1074
|
-
class TaskError extends BaseError {
|
|
1075
|
-
static type = "TaskError";
|
|
1076
|
-
taskType;
|
|
1077
|
-
taskId;
|
|
1078
|
-
constructor(message) {
|
|
1079
|
-
super(message);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
class TaskConfigurationError extends TaskError {
|
|
1084
|
-
static type = "TaskConfigurationError";
|
|
1085
|
-
constructor(message) {
|
|
1086
|
-
super(message);
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
class WorkflowError extends TaskError {
|
|
1091
|
-
static type = "WorkflowError";
|
|
1092
|
-
constructor(message) {
|
|
1093
|
-
super(message);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
class TaskAbortedError extends TaskError {
|
|
1098
|
-
static type = "TaskAbortedError";
|
|
1099
|
-
constructor(message = "Task aborted") {
|
|
1100
|
-
super(message);
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
class TaskTimeoutError extends TaskAbortedError {
|
|
1105
|
-
static type = "TaskTimeoutError";
|
|
1106
|
-
constructor(timeoutMs) {
|
|
1107
|
-
super(timeoutMs ? `Task timed out after ${timeoutMs}ms` : "Task timed out");
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
class TaskGraphTimeoutError extends TaskTimeoutError {
|
|
1112
|
-
static type = "TaskGraphTimeoutError";
|
|
1113
|
-
constructor(timeoutMs) {
|
|
1114
|
-
super(timeoutMs);
|
|
1115
|
-
this.message = timeoutMs ? `Graph execution timed out after ${timeoutMs}ms` : "Graph execution timed out";
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
class TaskFailedError extends TaskError {
|
|
1120
|
-
static type = "TaskFailedError";
|
|
1121
|
-
constructor(message = "Task failed") {
|
|
1122
|
-
super(message);
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
class JobTaskFailedError extends TaskFailedError {
|
|
1127
|
-
static type = "JobTaskFailedError";
|
|
1128
|
-
jobError;
|
|
1129
|
-
constructor(err) {
|
|
1130
|
-
super(String(err));
|
|
1131
|
-
this.jobError = err;
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
class TaskJSONError extends TaskError {
|
|
1136
|
-
static type = "TaskJSONError";
|
|
1137
|
-
constructor(message = "Error converting JSON to a Task") {
|
|
1138
|
-
super(message);
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
class TaskInvalidInputError extends TaskError {
|
|
1143
|
-
static type = "TaskInvalidInputError";
|
|
1144
|
-
constructor(message = "Invalid input data") {
|
|
1145
|
-
super(message);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
class TaskEntitlementError extends TaskError {
|
|
1150
|
-
static type = "TaskEntitlementError";
|
|
1151
|
-
constructor(message = "Required entitlements denied") {
|
|
1152
|
-
super(message);
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
class TaskSerializationError extends TaskError {
|
|
1157
|
-
static type = "TaskSerializationError";
|
|
1158
|
-
constructor(taskType) {
|
|
1159
|
-
super(`Task "${taskType}" cannot be serialized: config contains non-serializable values. ` + `Use a declarative config alternative or remove function-valued config properties.`);
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
1241
|
// src/task/TaskRunner.ts
|
|
1164
1242
|
import {
|
|
1165
1243
|
getLogger,
|
|
1166
1244
|
getTelemetryProvider,
|
|
1167
|
-
globalServiceRegistry,
|
|
1245
|
+
globalServiceRegistry as globalServiceRegistry2,
|
|
1168
1246
|
SpanStatusCode
|
|
1169
1247
|
} from "@workglow/util";
|
|
1170
1248
|
|
|
@@ -1280,7 +1358,7 @@ class TaskRunner {
|
|
|
1280
1358
|
task;
|
|
1281
1359
|
abortController;
|
|
1282
1360
|
outputCache;
|
|
1283
|
-
registry =
|
|
1361
|
+
registry = globalServiceRegistry2;
|
|
1284
1362
|
resourceScope;
|
|
1285
1363
|
inputStreams;
|
|
1286
1364
|
timeoutTimer;
|
|
@@ -1551,7 +1629,7 @@ class TaskRunner {
|
|
|
1551
1629
|
});
|
|
1552
1630
|
const cache = config.outputCache ?? this.task.runConfig?.outputCache;
|
|
1553
1631
|
if (cache === true) {
|
|
1554
|
-
let instance =
|
|
1632
|
+
let instance = globalServiceRegistry2.get(TASK_OUTPUT_REPOSITORY);
|
|
1555
1633
|
this.outputCache = instance;
|
|
1556
1634
|
} else if (cache === false) {
|
|
1557
1635
|
this.outputCache = undefined;
|
|
@@ -2438,7 +2516,7 @@ class ConditionalTask extends Task {
|
|
|
2438
2516
|
}
|
|
2439
2517
|
|
|
2440
2518
|
// src/task/EntitlementEnforcer.ts
|
|
2441
|
-
import { createServiceToken as
|
|
2519
|
+
import { createServiceToken as createServiceToken4 } from "@workglow/util";
|
|
2442
2520
|
|
|
2443
2521
|
// src/task/EntitlementPolicy.ts
|
|
2444
2522
|
var EMPTY_POLICY = Object.freeze({
|
|
@@ -2482,7 +2560,7 @@ function can(policy, id, resources) {
|
|
|
2482
2560
|
}
|
|
2483
2561
|
|
|
2484
2562
|
// src/task/EntitlementResolver.ts
|
|
2485
|
-
import { createServiceToken as
|
|
2563
|
+
import { createServiceToken as createServiceToken3 } from "@workglow/util";
|
|
2486
2564
|
var PERMISSIVE_RESOLVER = {
|
|
2487
2565
|
lookup: () => "grant",
|
|
2488
2566
|
prompt: async () => "grant",
|
|
@@ -2493,7 +2571,7 @@ var DENY_ALL_RESOLVER = {
|
|
|
2493
2571
|
prompt: async () => "deny",
|
|
2494
2572
|
save: () => {}
|
|
2495
2573
|
};
|
|
2496
|
-
var ENTITLEMENT_RESOLVER =
|
|
2574
|
+
var ENTITLEMENT_RESOLVER = createServiceToken3("workglow.entitlementResolver");
|
|
2497
2575
|
|
|
2498
2576
|
// src/task/EntitlementEnforcer.ts
|
|
2499
2577
|
function formatEntitlementDenial(denial) {
|
|
@@ -2517,7 +2595,11 @@ function createPolicyEnforcer(policy, resolver = PERMISSIVE_RESOLVER) {
|
|
|
2517
2595
|
for (const result of results) {
|
|
2518
2596
|
if (result.verdict === "denied") {
|
|
2519
2597
|
if (result.matchedRule) {
|
|
2520
|
-
denied.push({
|
|
2598
|
+
denied.push({
|
|
2599
|
+
entitlement: result.entitlement,
|
|
2600
|
+
reason: "policy-deny",
|
|
2601
|
+
matchedRule: result.matchedRule
|
|
2602
|
+
});
|
|
2521
2603
|
} else {
|
|
2522
2604
|
denied.push({ entitlement: result.entitlement, reason: "default-deny" });
|
|
2523
2605
|
}
|
|
@@ -2536,7 +2618,11 @@ function createPolicyEnforcer(policy, resolver = PERMISSIVE_RESOLVER) {
|
|
|
2536
2618
|
if (!result.matchedRule) {
|
|
2537
2619
|
throw new Error(`Invariant violation: ask verdict for "${result.entitlement.id}" is missing matchedRule`);
|
|
2538
2620
|
}
|
|
2539
|
-
denied.push({
|
|
2621
|
+
denied.push({
|
|
2622
|
+
entitlement: result.entitlement,
|
|
2623
|
+
reason: "user-deny",
|
|
2624
|
+
matchedRule: result.matchedRule
|
|
2625
|
+
});
|
|
2540
2626
|
}
|
|
2541
2627
|
}
|
|
2542
2628
|
}
|
|
@@ -2558,7 +2644,7 @@ function createScopedEnforcer(grants) {
|
|
|
2558
2644
|
function createGrantListEnforcer(grants) {
|
|
2559
2645
|
return createScopedEnforcer(grants.map((id) => ({ id })));
|
|
2560
2646
|
}
|
|
2561
|
-
var ENTITLEMENT_ENFORCER =
|
|
2647
|
+
var ENTITLEMENT_ENFORCER = createServiceToken4("workglow.entitlementEnforcer");
|
|
2562
2648
|
|
|
2563
2649
|
// src/task-graph/TaskGraphScheduler.ts
|
|
2564
2650
|
class TopologicalScheduler {
|
|
@@ -2722,7 +2808,7 @@ class TaskGraphRunner {
|
|
|
2722
2808
|
graph;
|
|
2723
2809
|
outputCache;
|
|
2724
2810
|
accumulateLeafOutputs = true;
|
|
2725
|
-
registry =
|
|
2811
|
+
registry = globalServiceRegistry3;
|
|
2726
2812
|
resourceScope;
|
|
2727
2813
|
abortController;
|
|
2728
2814
|
inProgressTasks = new Map;
|
|
@@ -2804,6 +2890,21 @@ class TaskGraphRunner {
|
|
|
2804
2890
|
}
|
|
2805
2891
|
async runGraphReactive(input = {}, config) {
|
|
2806
2892
|
await this.handleStartReactive(config);
|
|
2893
|
+
const telemetry = getTelemetryProvider2();
|
|
2894
|
+
const telemetryEnabled = telemetry.isEnabled;
|
|
2895
|
+
const reactiveRunId = telemetryEnabled ? uuid43() : "";
|
|
2896
|
+
let reactiveSpan;
|
|
2897
|
+
if (telemetryEnabled) {
|
|
2898
|
+
reactiveSpan = telemetry.startSpan("workglow.graph.runReactive", {
|
|
2899
|
+
attributes: {
|
|
2900
|
+
"workglow.graph.reactive.run_id": reactiveRunId,
|
|
2901
|
+
"workglow.graph.task_count": this.graph.getTasks().length,
|
|
2902
|
+
"workglow.graph.dataflow_count": this.graph.getDataflows().length
|
|
2903
|
+
}
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
const t0 = telemetryEnabled ? performance.now() : 0;
|
|
2907
|
+
const taskTimings = [];
|
|
2807
2908
|
const results = [];
|
|
2808
2909
|
try {
|
|
2809
2910
|
for await (const task of this.reactiveScheduler.tasks()) {
|
|
@@ -2813,20 +2914,68 @@ class TaskGraphRunner {
|
|
|
2813
2914
|
this.copyInputFromEdgesToNode(task);
|
|
2814
2915
|
}
|
|
2815
2916
|
const taskInput = isRootTask ? input : {};
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2917
|
+
if (telemetryEnabled) {
|
|
2918
|
+
const taskType = String(task.constructor.runtype || task.constructor.type || "?");
|
|
2919
|
+
const tReactive = performance.now();
|
|
2920
|
+
const taskResult = await task.runReactive(taskInput);
|
|
2921
|
+
const runReactiveMs = performance.now() - tReactive;
|
|
2922
|
+
const tPush = performance.now();
|
|
2923
|
+
await this.pushOutputFromNodeToEdges(task, taskResult);
|
|
2924
|
+
const pushOutputMs = performance.now() - tPush;
|
|
2925
|
+
taskTimings.push({ id: task.id, type: taskType, runReactiveMs, pushOutputMs });
|
|
2926
|
+
if (this.graph.getTargetDataflows(task.id).length === 0) {
|
|
2927
|
+
results.push({
|
|
2928
|
+
id: task.id,
|
|
2929
|
+
type: task.constructor.runtype || task.constructor.type,
|
|
2930
|
+
data: taskResult
|
|
2931
|
+
});
|
|
2932
|
+
}
|
|
2933
|
+
} else {
|
|
2934
|
+
const taskResult = await task.runReactive(taskInput);
|
|
2935
|
+
await this.pushOutputFromNodeToEdges(task, taskResult);
|
|
2936
|
+
if (this.graph.getTargetDataflows(task.id).length === 0) {
|
|
2937
|
+
results.push({
|
|
2938
|
+
id: task.id,
|
|
2939
|
+
type: task.constructor.runtype || task.constructor.type,
|
|
2940
|
+
data: taskResult
|
|
2941
|
+
});
|
|
2942
|
+
}
|
|
2824
2943
|
}
|
|
2825
2944
|
}
|
|
2826
2945
|
await this.handleCompleteReactive();
|
|
2946
|
+
if (reactiveSpan) {
|
|
2947
|
+
const totalMs = performance.now() - t0;
|
|
2948
|
+
reactiveSpan.setAttributes({
|
|
2949
|
+
"workglow.graph.reactive.duration_ms": Math.round(totalMs * 1000) / 1000,
|
|
2950
|
+
"workglow.graph.reactive.tasks_executed": taskTimings.length
|
|
2951
|
+
});
|
|
2952
|
+
reactiveSpan.setStatus(SpanStatusCode2.OK);
|
|
2953
|
+
reactiveSpan.end();
|
|
2954
|
+
getLogger3().debug("task graph runReactive timings", {
|
|
2955
|
+
reactiveRunId,
|
|
2956
|
+
totalMs: Math.round(totalMs * 1000) / 1000,
|
|
2957
|
+
taskTimings
|
|
2958
|
+
});
|
|
2959
|
+
}
|
|
2827
2960
|
return this.filterLeafResults(results);
|
|
2828
2961
|
} catch (error) {
|
|
2829
2962
|
await this.handleErrorReactive();
|
|
2963
|
+
if (reactiveSpan) {
|
|
2964
|
+
const totalMs = performance.now() - t0;
|
|
2965
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2966
|
+
reactiveSpan.setAttributes({
|
|
2967
|
+
"workglow.graph.reactive.duration_ms": Math.round(totalMs * 1000) / 1000,
|
|
2968
|
+
"workglow.graph.reactive.tasks_executed": taskTimings.length
|
|
2969
|
+
});
|
|
2970
|
+
reactiveSpan.setStatus(SpanStatusCode2.ERROR, message);
|
|
2971
|
+
reactiveSpan.end();
|
|
2972
|
+
getLogger3().debug("task graph runReactive failed", {
|
|
2973
|
+
reactiveRunId,
|
|
2974
|
+
totalMs: Math.round(totalMs * 1000) / 1000,
|
|
2975
|
+
taskTimings,
|
|
2976
|
+
error
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2830
2979
|
throw error;
|
|
2831
2980
|
}
|
|
2832
2981
|
}
|
|
@@ -2894,13 +3043,17 @@ class TaskGraphRunner {
|
|
|
2894
3043
|
async pushOutputFromNodeToEdges(node, results) {
|
|
2895
3044
|
const dataflows = this.graph.getTargetDataflows(node.id);
|
|
2896
3045
|
for (const dataflow of dataflows) {
|
|
2897
|
-
|
|
3046
|
+
if (dataflow.stream !== undefined)
|
|
3047
|
+
continue;
|
|
3048
|
+
const compatibility = dataflow.semanticallyCompatible(this.graph, dataflow, this.registry);
|
|
2898
3049
|
if (compatibility === "static") {
|
|
2899
3050
|
dataflow.setPortData(results);
|
|
3051
|
+
await dataflow.applyTransforms(this.registry);
|
|
2900
3052
|
} else if (compatibility === "runtime") {
|
|
2901
3053
|
const task = this.graph.getTask(dataflow.targetTaskId);
|
|
2902
3054
|
const narrowed = await task.narrowInput({ ...results }, this.registry);
|
|
2903
3055
|
dataflow.setPortData(narrowed);
|
|
3056
|
+
await dataflow.applyTransforms(this.registry);
|
|
2904
3057
|
} else {
|
|
2905
3058
|
const resultsKeys = Object.keys(results);
|
|
2906
3059
|
if (resultsKeys.length > 0) {
|
|
@@ -2926,6 +3079,8 @@ class TaskGraphRunner {
|
|
|
2926
3079
|
}
|
|
2927
3080
|
const activeBranches = node.getActiveBranches();
|
|
2928
3081
|
for (const dataflow of dataflows) {
|
|
3082
|
+
if (dataflow.status === TaskStatus.FAILED)
|
|
3083
|
+
continue;
|
|
2929
3084
|
const branchId = portToBranch.get(dataflow.sourceTaskPortId);
|
|
2930
3085
|
if (branchId !== undefined) {
|
|
2931
3086
|
if (activeBranches.has(branchId)) {
|
|
@@ -2941,6 +3096,8 @@ class TaskGraphRunner {
|
|
|
2941
3096
|
return;
|
|
2942
3097
|
}
|
|
2943
3098
|
dataflows.forEach((dataflow) => {
|
|
3099
|
+
if (dataflow.status === TaskStatus.FAILED)
|
|
3100
|
+
return;
|
|
2944
3101
|
dataflow.setStatus(effectiveStatus);
|
|
2945
3102
|
});
|
|
2946
3103
|
}
|
|
@@ -3065,10 +3222,13 @@ class TaskGraphRunner {
|
|
|
3065
3222
|
}
|
|
3066
3223
|
async awaitStreamInputs(task) {
|
|
3067
3224
|
const dataflows = this.graph.getSourceDataflows(task.id);
|
|
3068
|
-
const
|
|
3069
|
-
if (
|
|
3070
|
-
|
|
3071
|
-
|
|
3225
|
+
const streamingDataflows = dataflows.filter((df) => df.stream !== undefined);
|
|
3226
|
+
if (streamingDataflows.length === 0)
|
|
3227
|
+
return;
|
|
3228
|
+
await Promise.all(streamingDataflows.map(async (df) => {
|
|
3229
|
+
await df.awaitStreamValue();
|
|
3230
|
+
await df.applyTransforms(this.registry);
|
|
3231
|
+
}));
|
|
3072
3232
|
}
|
|
3073
3233
|
async runStreamingTask(task, input) {
|
|
3074
3234
|
const streamMode = getOutputStreamMode(task.outputSchema());
|
|
@@ -3203,7 +3363,7 @@ class TaskGraphRunner {
|
|
|
3203
3363
|
if (config?.registry !== undefined) {
|
|
3204
3364
|
this.registry = config.registry;
|
|
3205
3365
|
} else if (this.registry === undefined) {
|
|
3206
|
-
this.registry = new ServiceRegistry2(
|
|
3366
|
+
this.registry = new ServiceRegistry2(globalServiceRegistry3.container.createChildContainer());
|
|
3207
3367
|
}
|
|
3208
3368
|
if (config?.resourceScope !== undefined) {
|
|
3209
3369
|
this.resourceScope = config.resourceScope;
|
|
@@ -4169,6 +4329,246 @@ function serialGraph(tasks, inputHandle, outputHandle) {
|
|
|
4169
4329
|
// src/task-graph/Workflow.ts
|
|
4170
4330
|
import { EventEmitter as EventEmitter5, getLogger as getLogger5, uuid4 as uuid46 } from "@workglow/util";
|
|
4171
4331
|
|
|
4332
|
+
// src/task-graph/autoConnect.ts
|
|
4333
|
+
function autoConnect(graph, sourceTask, targetTask, options) {
|
|
4334
|
+
const matches = new Map;
|
|
4335
|
+
const sourceSchema = sourceTask.outputSchema();
|
|
4336
|
+
const targetSchema = targetTask.inputSchema();
|
|
4337
|
+
const providedInputKeys = options?.providedInputKeys ?? new Set;
|
|
4338
|
+
const connectedInputKeys = options?.connectedInputKeys ?? new Set;
|
|
4339
|
+
const earlierTasks = options?.earlierTasks ?? [];
|
|
4340
|
+
const dryRun = options?.dryRun ?? false;
|
|
4341
|
+
const addDataflow = (df) => {
|
|
4342
|
+
if (!dryRun)
|
|
4343
|
+
graph.addDataflow(df);
|
|
4344
|
+
};
|
|
4345
|
+
const getSpecificTypeIdentifiers = (schema) => {
|
|
4346
|
+
const formats = new Set;
|
|
4347
|
+
const ids = new Set;
|
|
4348
|
+
if (typeof schema === "boolean") {
|
|
4349
|
+
return { formats, ids };
|
|
4350
|
+
}
|
|
4351
|
+
const extractFromSchema = (s) => {
|
|
4352
|
+
if (!s || typeof s !== "object" || Array.isArray(s))
|
|
4353
|
+
return;
|
|
4354
|
+
if (s.format)
|
|
4355
|
+
formats.add(s.format);
|
|
4356
|
+
if (s.$id)
|
|
4357
|
+
ids.add(s.$id);
|
|
4358
|
+
};
|
|
4359
|
+
extractFromSchema(schema);
|
|
4360
|
+
const checkUnion = (schemas) => {
|
|
4361
|
+
if (!schemas)
|
|
4362
|
+
return;
|
|
4363
|
+
for (const s of schemas) {
|
|
4364
|
+
if (typeof s === "boolean")
|
|
4365
|
+
continue;
|
|
4366
|
+
extractFromSchema(s);
|
|
4367
|
+
if (s.items && typeof s.items === "object" && !Array.isArray(s.items)) {
|
|
4368
|
+
extractFromSchema(s.items);
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
};
|
|
4372
|
+
checkUnion(schema.oneOf);
|
|
4373
|
+
checkUnion(schema.anyOf);
|
|
4374
|
+
if (schema.items && typeof schema.items === "object" && !Array.isArray(schema.items)) {
|
|
4375
|
+
extractFromSchema(schema.items);
|
|
4376
|
+
}
|
|
4377
|
+
return { formats, ids };
|
|
4378
|
+
};
|
|
4379
|
+
const isTypeCompatible = (fromPortOutputSchema, toPortInputSchema, requireSpecificType = false) => {
|
|
4380
|
+
if (typeof fromPortOutputSchema === "boolean" || typeof toPortInputSchema === "boolean") {
|
|
4381
|
+
return fromPortOutputSchema === true && toPortInputSchema === true;
|
|
4382
|
+
}
|
|
4383
|
+
const outputIds = getSpecificTypeIdentifiers(fromPortOutputSchema);
|
|
4384
|
+
const inputIds = getSpecificTypeIdentifiers(toPortInputSchema);
|
|
4385
|
+
for (const format of outputIds.formats) {
|
|
4386
|
+
if (inputIds.formats.has(format)) {
|
|
4387
|
+
return true;
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
for (const id of outputIds.ids) {
|
|
4391
|
+
if (inputIds.ids.has(id)) {
|
|
4392
|
+
return true;
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
if (requireSpecificType) {
|
|
4396
|
+
return false;
|
|
4397
|
+
}
|
|
4398
|
+
const idTypeBlank = fromPortOutputSchema.$id === undefined && toPortInputSchema.$id === undefined;
|
|
4399
|
+
if (!idTypeBlank)
|
|
4400
|
+
return false;
|
|
4401
|
+
if (fromPortOutputSchema.type === toPortInputSchema.type)
|
|
4402
|
+
return true;
|
|
4403
|
+
const matchesOneOf = toPortInputSchema.oneOf?.some((schema) => {
|
|
4404
|
+
if (typeof schema === "boolean")
|
|
4405
|
+
return schema;
|
|
4406
|
+
return schema.type === fromPortOutputSchema.type;
|
|
4407
|
+
}) ?? false;
|
|
4408
|
+
const matchesAnyOf = toPortInputSchema.anyOf?.some((schema) => {
|
|
4409
|
+
if (typeof schema === "boolean")
|
|
4410
|
+
return schema;
|
|
4411
|
+
return schema.type === fromPortOutputSchema.type;
|
|
4412
|
+
}) ?? false;
|
|
4413
|
+
return matchesOneOf || matchesAnyOf;
|
|
4414
|
+
};
|
|
4415
|
+
const makeMatch = (fromSchema, toSchema, fromTaskId, toTaskId, comparator) => {
|
|
4416
|
+
if (typeof fromSchema === "object") {
|
|
4417
|
+
if (toSchema === true || typeof toSchema === "object" && toSchema.additionalProperties === true) {
|
|
4418
|
+
const outputKeys = Object.keys(fromSchema.properties || {});
|
|
4419
|
+
if (outputKeys.length > 0) {
|
|
4420
|
+
for (const fromOutputPortId of outputKeys) {
|
|
4421
|
+
if (matches.has(fromOutputPortId))
|
|
4422
|
+
continue;
|
|
4423
|
+
matches.set(fromOutputPortId, fromOutputPortId);
|
|
4424
|
+
addDataflow(new Dataflow(fromTaskId, fromOutputPortId, toTaskId, fromOutputPortId));
|
|
4425
|
+
}
|
|
4426
|
+
} else if (fromSchema.additionalProperties === true) {
|
|
4427
|
+
const sourceGraphTask = graph.getTask(fromTaskId);
|
|
4428
|
+
if (sourceGraphTask && sourceGraphTask.constructor.passthroughInputsToOutputs === true) {
|
|
4429
|
+
const incomingDfs = graph.getSourceDataflows(fromTaskId);
|
|
4430
|
+
for (const df of incomingDfs) {
|
|
4431
|
+
const portId = df.targetTaskPortId;
|
|
4432
|
+
if (portId === DATAFLOW_ALL_PORTS)
|
|
4433
|
+
continue;
|
|
4434
|
+
if (matches.has(portId))
|
|
4435
|
+
continue;
|
|
4436
|
+
if (connectedInputKeys.has(portId))
|
|
4437
|
+
continue;
|
|
4438
|
+
matches.set(portId, portId);
|
|
4439
|
+
addDataflow(new Dataflow(fromTaskId, portId, toTaskId, portId));
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
return;
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
if (typeof fromSchema === "object" && fromSchema.additionalProperties === true && typeof toSchema === "object" && (sourceTask.type === "InputTask" || sourceTask.type === "OutputTask")) {
|
|
4447
|
+
for (const toInputPortId of Object.keys(toSchema.properties || {})) {
|
|
4448
|
+
if (matches.has(toInputPortId))
|
|
4449
|
+
continue;
|
|
4450
|
+
if (connectedInputKeys.has(toInputPortId))
|
|
4451
|
+
continue;
|
|
4452
|
+
matches.set(toInputPortId, toInputPortId);
|
|
4453
|
+
addDataflow(new Dataflow(fromTaskId, toInputPortId, toTaskId, toInputPortId));
|
|
4454
|
+
}
|
|
4455
|
+
return;
|
|
4456
|
+
}
|
|
4457
|
+
if (typeof fromSchema === "boolean" || typeof toSchema === "boolean") {
|
|
4458
|
+
return;
|
|
4459
|
+
}
|
|
4460
|
+
for (const [toInputPortId, toPortInputSchema] of Object.entries(toSchema.properties || {})) {
|
|
4461
|
+
if (matches.has(toInputPortId))
|
|
4462
|
+
continue;
|
|
4463
|
+
if (connectedInputKeys.has(toInputPortId))
|
|
4464
|
+
continue;
|
|
4465
|
+
const candidates = [];
|
|
4466
|
+
for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(fromSchema.properties || {})) {
|
|
4467
|
+
if (comparator([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema])) {
|
|
4468
|
+
candidates.push(fromOutputPortId);
|
|
4469
|
+
}
|
|
4470
|
+
}
|
|
4471
|
+
if (candidates.length === 0)
|
|
4472
|
+
continue;
|
|
4473
|
+
let winner = candidates[0];
|
|
4474
|
+
if (candidates.length > 1) {
|
|
4475
|
+
const targetStreamMode = getPortStreamMode(toSchema, toInputPortId);
|
|
4476
|
+
const streamMatch = candidates.find((portId) => getPortStreamMode(fromSchema, portId) === targetStreamMode);
|
|
4477
|
+
if (streamMatch)
|
|
4478
|
+
winner = streamMatch;
|
|
4479
|
+
}
|
|
4480
|
+
matches.set(toInputPortId, winner);
|
|
4481
|
+
addDataflow(new Dataflow(fromTaskId, winner, toTaskId, toInputPortId));
|
|
4482
|
+
}
|
|
4483
|
+
};
|
|
4484
|
+
makeMatch(sourceSchema, targetSchema, sourceTask.id, targetTask.id, ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {
|
|
4485
|
+
const outputPortIdMatch = fromOutputPortId === toInputPortId;
|
|
4486
|
+
const outputPortIdOutputInput = fromOutputPortId === "output" && toInputPortId === "input";
|
|
4487
|
+
const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;
|
|
4488
|
+
return portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false);
|
|
4489
|
+
});
|
|
4490
|
+
makeMatch(sourceSchema, targetSchema, sourceTask.id, targetTask.id, ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {
|
|
4491
|
+
return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);
|
|
4492
|
+
});
|
|
4493
|
+
const requiredInputs = new Set(typeof targetSchema === "object" ? targetSchema.required || [] : []);
|
|
4494
|
+
const requiredInputsNeedingConnection = [...requiredInputs].filter((r) => !providedInputKeys.has(r) && !connectedInputKeys.has(r));
|
|
4495
|
+
let unmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));
|
|
4496
|
+
if (unmatchedRequired.length > 0 && earlierTasks.length > 0) {
|
|
4497
|
+
for (let i = 0;i < earlierTasks.length && unmatchedRequired.length > 0; i++) {
|
|
4498
|
+
const earlierTask = earlierTasks[i];
|
|
4499
|
+
const earlierOutputSchema = earlierTask.outputSchema();
|
|
4500
|
+
if (earlierTask.type === "InputTask") {
|
|
4501
|
+
const inputConfig = earlierTask.config;
|
|
4502
|
+
const inputSchema = inputConfig?.inputSchema ?? inputConfig?.outputSchema;
|
|
4503
|
+
const isManualSchema = inputSchema && typeof inputSchema === "object" && inputSchema["x-ui-manual"] === true;
|
|
4504
|
+
const inputProperties = isManualSchema && inputSchema && typeof inputSchema === "object" && "properties" in inputSchema && inputSchema.properties && typeof inputSchema.properties === "object" ? new Set(Object.keys(inputSchema.properties)) : undefined;
|
|
4505
|
+
for (const requiredInputId of [...unmatchedRequired]) {
|
|
4506
|
+
if (matches.has(requiredInputId))
|
|
4507
|
+
continue;
|
|
4508
|
+
if (inputProperties && !inputProperties.has(requiredInputId))
|
|
4509
|
+
continue;
|
|
4510
|
+
matches.set(requiredInputId, requiredInputId);
|
|
4511
|
+
addDataflow(new Dataflow(earlierTask.id, requiredInputId, targetTask.id, requiredInputId));
|
|
4512
|
+
}
|
|
4513
|
+
unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));
|
|
4514
|
+
continue;
|
|
4515
|
+
}
|
|
4516
|
+
const makeMatchFromEarlier = (comparator) => {
|
|
4517
|
+
if (typeof earlierOutputSchema === "boolean" || typeof targetSchema === "boolean") {
|
|
4518
|
+
return;
|
|
4519
|
+
}
|
|
4520
|
+
for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(earlierOutputSchema.properties || {})) {
|
|
4521
|
+
for (const requiredInputId of unmatchedRequired) {
|
|
4522
|
+
const toPortInputSchema = targetSchema.properties?.[requiredInputId];
|
|
4523
|
+
if (!matches.has(requiredInputId) && toPortInputSchema && comparator([fromOutputPortId, fromPortOutputSchema], [requiredInputId, toPortInputSchema])) {
|
|
4524
|
+
matches.set(requiredInputId, fromOutputPortId);
|
|
4525
|
+
addDataflow(new Dataflow(earlierTask.id, fromOutputPortId, targetTask.id, requiredInputId));
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
};
|
|
4530
|
+
makeMatchFromEarlier(([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {
|
|
4531
|
+
const outputPortIdMatch = fromOutputPortId === toInputPortId;
|
|
4532
|
+
const outputPortIdOutputInput = fromOutputPortId === "output" && toInputPortId === "input";
|
|
4533
|
+
const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;
|
|
4534
|
+
return portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false);
|
|
4535
|
+
});
|
|
4536
|
+
makeMatchFromEarlier(([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {
|
|
4537
|
+
return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);
|
|
4538
|
+
});
|
|
4539
|
+
unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));
|
|
4540
|
+
}
|
|
4541
|
+
}
|
|
4542
|
+
const stillUnmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));
|
|
4543
|
+
if (stillUnmatchedRequired.length > 0) {
|
|
4544
|
+
return {
|
|
4545
|
+
matches,
|
|
4546
|
+
error: `Could not find matches for required inputs [${stillUnmatchedRequired.join(", ")}] of ${targetTask.type}. ` + `Attempted to match from ${sourceTask.type} and earlier tasks.`,
|
|
4547
|
+
unmatchedRequired: stillUnmatchedRequired
|
|
4548
|
+
};
|
|
4549
|
+
}
|
|
4550
|
+
if (matches.size === 0 && requiredInputsNeedingConnection.length === 0) {
|
|
4551
|
+
const existingTargetConnections = graph.getSourceDataflows(targetTask.id);
|
|
4552
|
+
if (existingTargetConnections.length > 0) {
|
|
4553
|
+
return { matches, unmatchedRequired: [] };
|
|
4554
|
+
}
|
|
4555
|
+
const hasRequiredInputs = requiredInputs.size > 0;
|
|
4556
|
+
const allRequiredInputsProvided = hasRequiredInputs && [...requiredInputs].every((r) => providedInputKeys.has(r));
|
|
4557
|
+
const hasInputsWithDefaults = typeof targetSchema === "object" && targetSchema.properties && Object.values(targetSchema.properties).some((prop) => prop && typeof prop === "object" && ("default" in prop));
|
|
4558
|
+
if (!allRequiredInputsProvided && !hasInputsWithDefaults) {
|
|
4559
|
+
return {
|
|
4560
|
+
matches,
|
|
4561
|
+
error: `Could not find a match between the outputs of ${sourceTask.type} and the inputs of ${targetTask.type}. ` + `You may need to connect the outputs to the inputs via connect() manually.`,
|
|
4562
|
+
unmatchedRequired: []
|
|
4563
|
+
};
|
|
4564
|
+
}
|
|
4565
|
+
}
|
|
4566
|
+
return {
|
|
4567
|
+
matches,
|
|
4568
|
+
unmatchedRequired: []
|
|
4569
|
+
};
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4172
4572
|
// src/task-graph/ConditionalBuilder.ts
|
|
4173
4573
|
import { uuid4 as uuid45 } from "@workglow/util";
|
|
4174
4574
|
class ConditionalBuilder {
|
|
@@ -4532,8 +4932,10 @@ class Workflow {
|
|
|
4532
4932
|
static parallel(args, mergeFn) {
|
|
4533
4933
|
return parallel(args, mergeFn ?? PROPERTY_ARRAY, new Workflow);
|
|
4534
4934
|
}
|
|
4535
|
-
rename(source, target,
|
|
4935
|
+
rename(source, target, indexOrOptions = -1) {
|
|
4536
4936
|
this._error = "";
|
|
4937
|
+
const index = typeof indexOrOptions === "number" ? indexOrOptions : indexOrOptions.index ?? -1;
|
|
4938
|
+
const transforms = typeof indexOrOptions === "number" ? undefined : indexOrOptions.transforms;
|
|
4537
4939
|
const nodes = this._graph.getTasks();
|
|
4538
4940
|
if (-index > nodes.length) {
|
|
4539
4941
|
const errorMsg = `Back index greater than number of tasks`;
|
|
@@ -4556,7 +4958,10 @@ class Workflow {
|
|
|
4556
4958
|
getLogger5().error(this._error);
|
|
4557
4959
|
throw new WorkflowError(errorMsg);
|
|
4558
4960
|
}
|
|
4559
|
-
|
|
4961
|
+
const df = new Dataflow(lastNode.id, source, undefined, target);
|
|
4962
|
+
if (transforms && transforms.length > 0)
|
|
4963
|
+
df.setTransforms(transforms);
|
|
4964
|
+
this._dataFlows.push(df);
|
|
4560
4965
|
return this;
|
|
4561
4966
|
}
|
|
4562
4967
|
onError(handler) {
|
|
@@ -4659,7 +5064,11 @@ class Workflow {
|
|
|
4659
5064
|
addLoopTask(taskClass, config = {}) {
|
|
4660
5065
|
this._error = "";
|
|
4661
5066
|
const parent = getLastTask(this);
|
|
4662
|
-
const
|
|
5067
|
+
const schema = taskClass.configSchema?.();
|
|
5068
|
+
const required = typeof schema === "object" && schema !== null ? schema.required : undefined;
|
|
5069
|
+
const needsMaxIterations = Array.isArray(required) && required.includes("maxIterations");
|
|
5070
|
+
const resolvedConfig = needsMaxIterations && config.maxIterations === undefined ? { ...config, maxIterations: "unbounded" } : config;
|
|
5071
|
+
const task = this.addTaskToGraph(taskClass, { id: uuid46(), ...resolvedConfig });
|
|
4663
5072
|
if (this._dataFlows.length > 0) {
|
|
4664
5073
|
this._dataFlows.forEach((dataflow) => {
|
|
4665
5074
|
const taskSchema = task.inputSchema();
|
|
@@ -4802,237 +5211,7 @@ class Workflow {
|
|
|
4802
5211
|
}
|
|
4803
5212
|
static AutoConnectOptions = Symbol("AutoConnectOptions");
|
|
4804
5213
|
static autoConnect(graph, sourceTask, targetTask, options) {
|
|
4805
|
-
|
|
4806
|
-
const sourceSchema = sourceTask.outputSchema();
|
|
4807
|
-
const targetSchema = targetTask.inputSchema();
|
|
4808
|
-
const providedInputKeys = options?.providedInputKeys ?? new Set;
|
|
4809
|
-
const connectedInputKeys = options?.connectedInputKeys ?? new Set;
|
|
4810
|
-
const earlierTasks = options?.earlierTasks ?? [];
|
|
4811
|
-
const getSpecificTypeIdentifiers = (schema) => {
|
|
4812
|
-
const formats = new Set;
|
|
4813
|
-
const ids = new Set;
|
|
4814
|
-
if (typeof schema === "boolean") {
|
|
4815
|
-
return { formats, ids };
|
|
4816
|
-
}
|
|
4817
|
-
const extractFromSchema = (s) => {
|
|
4818
|
-
if (!s || typeof s !== "object" || Array.isArray(s))
|
|
4819
|
-
return;
|
|
4820
|
-
if (s.format)
|
|
4821
|
-
formats.add(s.format);
|
|
4822
|
-
if (s.$id)
|
|
4823
|
-
ids.add(s.$id);
|
|
4824
|
-
};
|
|
4825
|
-
extractFromSchema(schema);
|
|
4826
|
-
const checkUnion = (schemas) => {
|
|
4827
|
-
if (!schemas)
|
|
4828
|
-
return;
|
|
4829
|
-
for (const s of schemas) {
|
|
4830
|
-
if (typeof s === "boolean")
|
|
4831
|
-
continue;
|
|
4832
|
-
extractFromSchema(s);
|
|
4833
|
-
if (s.items && typeof s.items === "object" && !Array.isArray(s.items)) {
|
|
4834
|
-
extractFromSchema(s.items);
|
|
4835
|
-
}
|
|
4836
|
-
}
|
|
4837
|
-
};
|
|
4838
|
-
checkUnion(schema.oneOf);
|
|
4839
|
-
checkUnion(schema.anyOf);
|
|
4840
|
-
if (schema.items && typeof schema.items === "object" && !Array.isArray(schema.items)) {
|
|
4841
|
-
extractFromSchema(schema.items);
|
|
4842
|
-
}
|
|
4843
|
-
return { formats, ids };
|
|
4844
|
-
};
|
|
4845
|
-
const isTypeCompatible = (fromPortOutputSchema, toPortInputSchema, requireSpecificType = false) => {
|
|
4846
|
-
if (typeof fromPortOutputSchema === "boolean" || typeof toPortInputSchema === "boolean") {
|
|
4847
|
-
return fromPortOutputSchema === true && toPortInputSchema === true;
|
|
4848
|
-
}
|
|
4849
|
-
const outputIds = getSpecificTypeIdentifiers(fromPortOutputSchema);
|
|
4850
|
-
const inputIds = getSpecificTypeIdentifiers(toPortInputSchema);
|
|
4851
|
-
for (const format of outputIds.formats) {
|
|
4852
|
-
if (inputIds.formats.has(format)) {
|
|
4853
|
-
return true;
|
|
4854
|
-
}
|
|
4855
|
-
}
|
|
4856
|
-
for (const id of outputIds.ids) {
|
|
4857
|
-
if (inputIds.ids.has(id)) {
|
|
4858
|
-
return true;
|
|
4859
|
-
}
|
|
4860
|
-
}
|
|
4861
|
-
if (requireSpecificType) {
|
|
4862
|
-
return false;
|
|
4863
|
-
}
|
|
4864
|
-
const idTypeBlank = fromPortOutputSchema.$id === undefined && toPortInputSchema.$id === undefined;
|
|
4865
|
-
if (!idTypeBlank)
|
|
4866
|
-
return false;
|
|
4867
|
-
if (fromPortOutputSchema.type === toPortInputSchema.type)
|
|
4868
|
-
return true;
|
|
4869
|
-
const matchesOneOf = toPortInputSchema.oneOf?.some((schema) => {
|
|
4870
|
-
if (typeof schema === "boolean")
|
|
4871
|
-
return schema;
|
|
4872
|
-
return schema.type === fromPortOutputSchema.type;
|
|
4873
|
-
}) ?? false;
|
|
4874
|
-
const matchesAnyOf = toPortInputSchema.anyOf?.some((schema) => {
|
|
4875
|
-
if (typeof schema === "boolean")
|
|
4876
|
-
return schema;
|
|
4877
|
-
return schema.type === fromPortOutputSchema.type;
|
|
4878
|
-
}) ?? false;
|
|
4879
|
-
return matchesOneOf || matchesAnyOf;
|
|
4880
|
-
};
|
|
4881
|
-
const makeMatch = (fromSchema, toSchema, fromTaskId, toTaskId, comparator) => {
|
|
4882
|
-
if (typeof fromSchema === "object") {
|
|
4883
|
-
if (toSchema === true || typeof toSchema === "object" && toSchema.additionalProperties === true) {
|
|
4884
|
-
const outputKeys = Object.keys(fromSchema.properties || {});
|
|
4885
|
-
if (outputKeys.length > 0) {
|
|
4886
|
-
for (const fromOutputPortId of outputKeys) {
|
|
4887
|
-
if (matches.has(fromOutputPortId))
|
|
4888
|
-
continue;
|
|
4889
|
-
matches.set(fromOutputPortId, fromOutputPortId);
|
|
4890
|
-
graph.addDataflow(new Dataflow(fromTaskId, fromOutputPortId, toTaskId, fromOutputPortId));
|
|
4891
|
-
}
|
|
4892
|
-
} else if (fromSchema.additionalProperties === true) {
|
|
4893
|
-
const sourceGraphTask = graph.getTask(fromTaskId);
|
|
4894
|
-
if (sourceGraphTask && sourceGraphTask.constructor.passthroughInputsToOutputs === true) {
|
|
4895
|
-
const incomingDfs = graph.getSourceDataflows(fromTaskId);
|
|
4896
|
-
for (const df of incomingDfs) {
|
|
4897
|
-
const portId = df.targetTaskPortId;
|
|
4898
|
-
if (portId === DATAFLOW_ALL_PORTS)
|
|
4899
|
-
continue;
|
|
4900
|
-
if (matches.has(portId))
|
|
4901
|
-
continue;
|
|
4902
|
-
if (connectedInputKeys.has(portId))
|
|
4903
|
-
continue;
|
|
4904
|
-
matches.set(portId, portId);
|
|
4905
|
-
graph.addDataflow(new Dataflow(fromTaskId, portId, toTaskId, portId));
|
|
4906
|
-
}
|
|
4907
|
-
}
|
|
4908
|
-
}
|
|
4909
|
-
return;
|
|
4910
|
-
}
|
|
4911
|
-
}
|
|
4912
|
-
if (typeof fromSchema === "object" && fromSchema.additionalProperties === true && typeof toSchema === "object" && (sourceTask.type === "InputTask" || sourceTask.type === "OutputTask")) {
|
|
4913
|
-
for (const toInputPortId of Object.keys(toSchema.properties || {})) {
|
|
4914
|
-
if (matches.has(toInputPortId))
|
|
4915
|
-
continue;
|
|
4916
|
-
if (connectedInputKeys.has(toInputPortId))
|
|
4917
|
-
continue;
|
|
4918
|
-
matches.set(toInputPortId, toInputPortId);
|
|
4919
|
-
graph.addDataflow(new Dataflow(fromTaskId, toInputPortId, toTaskId, toInputPortId));
|
|
4920
|
-
}
|
|
4921
|
-
return;
|
|
4922
|
-
}
|
|
4923
|
-
if (typeof fromSchema === "boolean" || typeof toSchema === "boolean") {
|
|
4924
|
-
return;
|
|
4925
|
-
}
|
|
4926
|
-
for (const [toInputPortId, toPortInputSchema] of Object.entries(toSchema.properties || {})) {
|
|
4927
|
-
if (matches.has(toInputPortId))
|
|
4928
|
-
continue;
|
|
4929
|
-
if (connectedInputKeys.has(toInputPortId))
|
|
4930
|
-
continue;
|
|
4931
|
-
const candidates = [];
|
|
4932
|
-
for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(fromSchema.properties || {})) {
|
|
4933
|
-
if (comparator([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema])) {
|
|
4934
|
-
candidates.push(fromOutputPortId);
|
|
4935
|
-
}
|
|
4936
|
-
}
|
|
4937
|
-
if (candidates.length === 0)
|
|
4938
|
-
continue;
|
|
4939
|
-
let winner = candidates[0];
|
|
4940
|
-
if (candidates.length > 1) {
|
|
4941
|
-
const targetStreamMode = getPortStreamMode(toSchema, toInputPortId);
|
|
4942
|
-
const streamMatch = candidates.find((portId) => getPortStreamMode(fromSchema, portId) === targetStreamMode);
|
|
4943
|
-
if (streamMatch)
|
|
4944
|
-
winner = streamMatch;
|
|
4945
|
-
}
|
|
4946
|
-
matches.set(toInputPortId, winner);
|
|
4947
|
-
graph.addDataflow(new Dataflow(fromTaskId, winner, toTaskId, toInputPortId));
|
|
4948
|
-
}
|
|
4949
|
-
};
|
|
4950
|
-
makeMatch(sourceSchema, targetSchema, sourceTask.id, targetTask.id, ([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {
|
|
4951
|
-
const outputPortIdMatch = fromOutputPortId === toInputPortId;
|
|
4952
|
-
const outputPortIdOutputInput = fromOutputPortId === "output" && toInputPortId === "input";
|
|
4953
|
-
const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;
|
|
4954
|
-
return portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false);
|
|
4955
|
-
});
|
|
4956
|
-
makeMatch(sourceSchema, targetSchema, sourceTask.id, targetTask.id, ([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {
|
|
4957
|
-
return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);
|
|
4958
|
-
});
|
|
4959
|
-
const requiredInputs = new Set(typeof targetSchema === "object" ? targetSchema.required || [] : []);
|
|
4960
|
-
const requiredInputsNeedingConnection = [...requiredInputs].filter((r) => !providedInputKeys.has(r) && !connectedInputKeys.has(r));
|
|
4961
|
-
let unmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));
|
|
4962
|
-
if (unmatchedRequired.length > 0 && earlierTasks.length > 0) {
|
|
4963
|
-
for (let i = 0;i < earlierTasks.length && unmatchedRequired.length > 0; i++) {
|
|
4964
|
-
const earlierTask = earlierTasks[i];
|
|
4965
|
-
const earlierOutputSchema = earlierTask.outputSchema();
|
|
4966
|
-
if (earlierTask.type === "InputTask") {
|
|
4967
|
-
const inputConfig = earlierTask.config;
|
|
4968
|
-
const inputSchema = inputConfig?.inputSchema ?? inputConfig?.outputSchema;
|
|
4969
|
-
const isManualSchema = inputSchema && typeof inputSchema === "object" && inputSchema["x-ui-manual"] === true;
|
|
4970
|
-
const inputProperties = isManualSchema && inputSchema && typeof inputSchema === "object" && "properties" in inputSchema && inputSchema.properties && typeof inputSchema.properties === "object" ? new Set(Object.keys(inputSchema.properties)) : undefined;
|
|
4971
|
-
for (const requiredInputId of [...unmatchedRequired]) {
|
|
4972
|
-
if (matches.has(requiredInputId))
|
|
4973
|
-
continue;
|
|
4974
|
-
if (inputProperties && !inputProperties.has(requiredInputId))
|
|
4975
|
-
continue;
|
|
4976
|
-
matches.set(requiredInputId, requiredInputId);
|
|
4977
|
-
graph.addDataflow(new Dataflow(earlierTask.id, requiredInputId, targetTask.id, requiredInputId));
|
|
4978
|
-
}
|
|
4979
|
-
unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));
|
|
4980
|
-
continue;
|
|
4981
|
-
}
|
|
4982
|
-
const makeMatchFromEarlier = (comparator) => {
|
|
4983
|
-
if (typeof earlierOutputSchema === "boolean" || typeof targetSchema === "boolean") {
|
|
4984
|
-
return;
|
|
4985
|
-
}
|
|
4986
|
-
for (const [fromOutputPortId, fromPortOutputSchema] of Object.entries(earlierOutputSchema.properties || {})) {
|
|
4987
|
-
for (const requiredInputId of unmatchedRequired) {
|
|
4988
|
-
const toPortInputSchema = targetSchema.properties?.[requiredInputId];
|
|
4989
|
-
if (!matches.has(requiredInputId) && toPortInputSchema && comparator([fromOutputPortId, fromPortOutputSchema], [requiredInputId, toPortInputSchema])) {
|
|
4990
|
-
matches.set(requiredInputId, fromOutputPortId);
|
|
4991
|
-
graph.addDataflow(new Dataflow(earlierTask.id, fromOutputPortId, targetTask.id, requiredInputId));
|
|
4992
|
-
}
|
|
4993
|
-
}
|
|
4994
|
-
}
|
|
4995
|
-
};
|
|
4996
|
-
makeMatchFromEarlier(([fromOutputPortId, fromPortOutputSchema], [toInputPortId, toPortInputSchema]) => {
|
|
4997
|
-
const outputPortIdMatch = fromOutputPortId === toInputPortId;
|
|
4998
|
-
const outputPortIdOutputInput = fromOutputPortId === "output" && toInputPortId === "input";
|
|
4999
|
-
const portIdsCompatible = outputPortIdMatch || outputPortIdOutputInput;
|
|
5000
|
-
return portIdsCompatible && isTypeCompatible(fromPortOutputSchema, toPortInputSchema, false);
|
|
5001
|
-
});
|
|
5002
|
-
makeMatchFromEarlier(([_fromOutputPortId, fromPortOutputSchema], [_toInputPortId, toPortInputSchema]) => {
|
|
5003
|
-
return isTypeCompatible(fromPortOutputSchema, toPortInputSchema, true);
|
|
5004
|
-
});
|
|
5005
|
-
unmatchedRequired = unmatchedRequired.filter((r) => !matches.has(r));
|
|
5006
|
-
}
|
|
5007
|
-
}
|
|
5008
|
-
const stillUnmatchedRequired = requiredInputsNeedingConnection.filter((r) => !matches.has(r));
|
|
5009
|
-
if (stillUnmatchedRequired.length > 0) {
|
|
5010
|
-
return {
|
|
5011
|
-
matches,
|
|
5012
|
-
error: `Could not find matches for required inputs [${stillUnmatchedRequired.join(", ")}] of ${targetTask.type}. ` + `Attempted to match from ${sourceTask.type} and earlier tasks.`,
|
|
5013
|
-
unmatchedRequired: stillUnmatchedRequired
|
|
5014
|
-
};
|
|
5015
|
-
}
|
|
5016
|
-
if (matches.size === 0 && requiredInputsNeedingConnection.length === 0) {
|
|
5017
|
-
const existingTargetConnections = graph.getSourceDataflows(targetTask.id);
|
|
5018
|
-
if (existingTargetConnections.length > 0) {
|
|
5019
|
-
return { matches, unmatchedRequired: [] };
|
|
5020
|
-
}
|
|
5021
|
-
const hasRequiredInputs = requiredInputs.size > 0;
|
|
5022
|
-
const allRequiredInputsProvided = hasRequiredInputs && [...requiredInputs].every((r) => providedInputKeys.has(r));
|
|
5023
|
-
const hasInputsWithDefaults = typeof targetSchema === "object" && targetSchema.properties && Object.values(targetSchema.properties).some((prop) => prop && typeof prop === "object" && ("default" in prop));
|
|
5024
|
-
if (!allRequiredInputsProvided && !hasInputsWithDefaults) {
|
|
5025
|
-
return {
|
|
5026
|
-
matches,
|
|
5027
|
-
error: `Could not find a match between the outputs of ${sourceTask.type} and the inputs of ${targetTask.type}. ` + `You may need to connect the outputs to the inputs via connect() manually.`,
|
|
5028
|
-
unmatchedRequired: []
|
|
5029
|
-
};
|
|
5030
|
-
}
|
|
5031
|
-
}
|
|
5032
|
-
return {
|
|
5033
|
-
matches,
|
|
5034
|
-
unmatchedRequired: []
|
|
5035
|
-
};
|
|
5214
|
+
return autoConnect(graph, sourceTask, targetTask, options);
|
|
5036
5215
|
}
|
|
5037
5216
|
finalizeTemplate() {
|
|
5038
5217
|
if (!this._iteratorTask || this.graph.getTasks().length === 0) {
|
|
@@ -5396,6 +5575,304 @@ ${baseIndent}}`;
|
|
|
5396
5575
|
function resetMethodNameCache() {
|
|
5397
5576
|
methodNameCache = undefined;
|
|
5398
5577
|
}
|
|
5578
|
+
// src/task-graph/transforms/pick.ts
|
|
5579
|
+
import { areSemanticallyCompatible as areSemanticallyCompatible2 } from "@workglow/util/schema";
|
|
5580
|
+
function walk(value, path) {
|
|
5581
|
+
if (value == null)
|
|
5582
|
+
return;
|
|
5583
|
+
const parts = path.split(".");
|
|
5584
|
+
let cur = value;
|
|
5585
|
+
for (const p of parts) {
|
|
5586
|
+
if (cur == null)
|
|
5587
|
+
return;
|
|
5588
|
+
cur = cur[p];
|
|
5589
|
+
}
|
|
5590
|
+
return cur;
|
|
5591
|
+
}
|
|
5592
|
+
function walkSchema(schema, path) {
|
|
5593
|
+
const parts = path.split(".");
|
|
5594
|
+
let cur = schema;
|
|
5595
|
+
for (const p of parts) {
|
|
5596
|
+
if (!cur || typeof cur !== "object")
|
|
5597
|
+
return {};
|
|
5598
|
+
if (cur.type !== "object" || !cur.properties || !cur.properties[p]) {
|
|
5599
|
+
return {};
|
|
5600
|
+
}
|
|
5601
|
+
cur = cur.properties[p];
|
|
5602
|
+
}
|
|
5603
|
+
return cur;
|
|
5604
|
+
}
|
|
5605
|
+
var pickTransform = {
|
|
5606
|
+
id: "pick",
|
|
5607
|
+
title: "Pick field",
|
|
5608
|
+
category: "Structural",
|
|
5609
|
+
paramsSchema: {
|
|
5610
|
+
type: "object",
|
|
5611
|
+
properties: {
|
|
5612
|
+
path: { type: "string", description: "Dotted property path" }
|
|
5613
|
+
},
|
|
5614
|
+
required: ["path"]
|
|
5615
|
+
},
|
|
5616
|
+
inferOutputSchema(inputSchema, params) {
|
|
5617
|
+
return walkSchema(inputSchema, params.path);
|
|
5618
|
+
},
|
|
5619
|
+
apply(value, params) {
|
|
5620
|
+
return walk(value, params.path);
|
|
5621
|
+
},
|
|
5622
|
+
suggestFromSchemas(source, target) {
|
|
5623
|
+
if (source.type !== "object" || !source.properties) {
|
|
5624
|
+
return;
|
|
5625
|
+
}
|
|
5626
|
+
const props = source.properties;
|
|
5627
|
+
for (const [name, propSchema] of Object.entries(props)) {
|
|
5628
|
+
const compat = areSemanticallyCompatible2(propSchema, target);
|
|
5629
|
+
if (compat === "static")
|
|
5630
|
+
return { score: 1, params: { path: name } };
|
|
5631
|
+
if (compat === "runtime")
|
|
5632
|
+
return { score: 0.6, params: { path: name } };
|
|
5633
|
+
}
|
|
5634
|
+
return;
|
|
5635
|
+
}
|
|
5636
|
+
};
|
|
5637
|
+
|
|
5638
|
+
// src/task-graph/transforms/index-access.ts
|
|
5639
|
+
import { areSemanticallyCompatible as areSemanticallyCompatible3 } from "@workglow/util/schema";
|
|
5640
|
+
function doIndex(value, idx) {
|
|
5641
|
+
if (!Array.isArray(value))
|
|
5642
|
+
return;
|
|
5643
|
+
const i = idx < 0 ? value.length + idx : idx;
|
|
5644
|
+
return value[i];
|
|
5645
|
+
}
|
|
5646
|
+
var indexTransform = {
|
|
5647
|
+
id: "index",
|
|
5648
|
+
title: "Array index",
|
|
5649
|
+
category: "Structural",
|
|
5650
|
+
paramsSchema: {
|
|
5651
|
+
type: "object",
|
|
5652
|
+
properties: {
|
|
5653
|
+
index: { type: "integer", description: "Array index (negative counts from end)" }
|
|
5654
|
+
},
|
|
5655
|
+
required: ["index"]
|
|
5656
|
+
},
|
|
5657
|
+
inferOutputSchema(inputSchema) {
|
|
5658
|
+
const s = inputSchema;
|
|
5659
|
+
if (s?.type === "array" && s.items)
|
|
5660
|
+
return s.items;
|
|
5661
|
+
return {};
|
|
5662
|
+
},
|
|
5663
|
+
apply(value, params) {
|
|
5664
|
+
return doIndex(value, params.index);
|
|
5665
|
+
},
|
|
5666
|
+
suggestFromSchemas(source, target) {
|
|
5667
|
+
const s = source;
|
|
5668
|
+
if (s?.type !== "array" || !s.items)
|
|
5669
|
+
return;
|
|
5670
|
+
const compat = areSemanticallyCompatible3(s.items, target);
|
|
5671
|
+
if (compat === "static")
|
|
5672
|
+
return { score: 0.9, params: { index: 0 } };
|
|
5673
|
+
if (compat === "runtime")
|
|
5674
|
+
return { score: 0.5, params: { index: 0 } };
|
|
5675
|
+
return;
|
|
5676
|
+
}
|
|
5677
|
+
};
|
|
5678
|
+
|
|
5679
|
+
// src/task-graph/transforms/coalesce.ts
|
|
5680
|
+
function stripNullable(schema) {
|
|
5681
|
+
const s = schema;
|
|
5682
|
+
if (!s || typeof s !== "object")
|
|
5683
|
+
return schema;
|
|
5684
|
+
if (Array.isArray(s.type)) {
|
|
5685
|
+
const nonNull = s.type.filter((t) => t !== "null");
|
|
5686
|
+
if (nonNull.length === 1)
|
|
5687
|
+
return { ...s, type: nonNull[0] };
|
|
5688
|
+
return { ...s, type: nonNull };
|
|
5689
|
+
}
|
|
5690
|
+
return schema;
|
|
5691
|
+
}
|
|
5692
|
+
var coalesceTransform = {
|
|
5693
|
+
id: "coalesce",
|
|
5694
|
+
title: "Coalesce null",
|
|
5695
|
+
category: "Conversion",
|
|
5696
|
+
paramsSchema: {
|
|
5697
|
+
type: "object",
|
|
5698
|
+
properties: { defaultValue: {} },
|
|
5699
|
+
required: ["defaultValue"]
|
|
5700
|
+
},
|
|
5701
|
+
inferOutputSchema: (input) => stripNullable(input),
|
|
5702
|
+
apply: (v, { defaultValue }) => v == null ? defaultValue : v
|
|
5703
|
+
};
|
|
5704
|
+
|
|
5705
|
+
// src/task-graph/transforms/string-casts.ts
|
|
5706
|
+
var stringSchema = { type: "string" };
|
|
5707
|
+
var uppercaseTransform = {
|
|
5708
|
+
id: "uppercase",
|
|
5709
|
+
title: "Uppercase",
|
|
5710
|
+
category: "String",
|
|
5711
|
+
paramsSchema: undefined,
|
|
5712
|
+
inferOutputSchema: () => stringSchema,
|
|
5713
|
+
apply: (v) => String(v ?? "").toUpperCase()
|
|
5714
|
+
};
|
|
5715
|
+
var lowercaseTransform = {
|
|
5716
|
+
id: "lowercase",
|
|
5717
|
+
title: "Lowercase",
|
|
5718
|
+
category: "String",
|
|
5719
|
+
paramsSchema: undefined,
|
|
5720
|
+
inferOutputSchema: () => stringSchema,
|
|
5721
|
+
apply: (v) => String(v ?? "").toLowerCase()
|
|
5722
|
+
};
|
|
5723
|
+
var truncateTransform = {
|
|
5724
|
+
id: "truncate",
|
|
5725
|
+
title: "Truncate",
|
|
5726
|
+
category: "String",
|
|
5727
|
+
paramsSchema: {
|
|
5728
|
+
type: "object",
|
|
5729
|
+
properties: { max: { type: "integer", minimum: 0 } },
|
|
5730
|
+
required: ["max"]
|
|
5731
|
+
},
|
|
5732
|
+
inferOutputSchema: () => stringSchema,
|
|
5733
|
+
apply: (v, { max }) => String(v ?? "").slice(0, max)
|
|
5734
|
+
};
|
|
5735
|
+
var substringTransform = {
|
|
5736
|
+
id: "substring",
|
|
5737
|
+
title: "Substring",
|
|
5738
|
+
category: "String",
|
|
5739
|
+
paramsSchema: {
|
|
5740
|
+
type: "object",
|
|
5741
|
+
properties: {
|
|
5742
|
+
start: { type: "integer" },
|
|
5743
|
+
end: { type: "integer" }
|
|
5744
|
+
},
|
|
5745
|
+
required: ["start"]
|
|
5746
|
+
},
|
|
5747
|
+
inferOutputSchema: () => stringSchema,
|
|
5748
|
+
apply: (v, { start, end }) => String(v ?? "").slice(start, end)
|
|
5749
|
+
};
|
|
5750
|
+
|
|
5751
|
+
// src/task-graph/transforms/date-conversions.ts
|
|
5752
|
+
var isoSchema = { type: "string", format: "date-time" };
|
|
5753
|
+
var numberSchema = { type: "number" };
|
|
5754
|
+
function hasDateTimeFormat(schema) {
|
|
5755
|
+
const s = schema;
|
|
5756
|
+
return s?.type === "string" && s.format === "date-time";
|
|
5757
|
+
}
|
|
5758
|
+
var unixToIsoDateTransform = {
|
|
5759
|
+
id: "unixToIsoDate",
|
|
5760
|
+
title: "Unix timestamp → ISO date",
|
|
5761
|
+
category: "Date",
|
|
5762
|
+
paramsSchema: {
|
|
5763
|
+
type: "object",
|
|
5764
|
+
properties: {
|
|
5765
|
+
unit: { type: "string", enum: ["s", "ms"] }
|
|
5766
|
+
},
|
|
5767
|
+
required: ["unit"]
|
|
5768
|
+
},
|
|
5769
|
+
inferOutputSchema: () => isoSchema,
|
|
5770
|
+
apply: (v, { unit }) => {
|
|
5771
|
+
const n = Number(v);
|
|
5772
|
+
return new Date(unit === "s" ? n * 1000 : n).toISOString();
|
|
5773
|
+
},
|
|
5774
|
+
suggestFromSchemas(source, target) {
|
|
5775
|
+
const s = source;
|
|
5776
|
+
if (s?.type !== "number" && s?.type !== "integer")
|
|
5777
|
+
return;
|
|
5778
|
+
if (!hasDateTimeFormat(target))
|
|
5779
|
+
return;
|
|
5780
|
+
return { score: 0.85, params: { unit: "s" } };
|
|
5781
|
+
}
|
|
5782
|
+
};
|
|
5783
|
+
var isoDateToUnixTransform = {
|
|
5784
|
+
id: "isoDateToUnix",
|
|
5785
|
+
title: "ISO date → Unix ms",
|
|
5786
|
+
category: "Date",
|
|
5787
|
+
paramsSchema: undefined,
|
|
5788
|
+
inferOutputSchema: () => numberSchema,
|
|
5789
|
+
apply: (v) => new Date(String(v)).getTime(),
|
|
5790
|
+
suggestFromSchemas(source, target) {
|
|
5791
|
+
if (!hasDateTimeFormat(source))
|
|
5792
|
+
return;
|
|
5793
|
+
const t = target;
|
|
5794
|
+
if (t?.type !== "number" && t?.type !== "integer")
|
|
5795
|
+
return;
|
|
5796
|
+
return { score: 0.9, params: {} };
|
|
5797
|
+
}
|
|
5798
|
+
};
|
|
5799
|
+
|
|
5800
|
+
// src/task-graph/transforms/scalar-conversions.ts
|
|
5801
|
+
var stringSchema2 = { type: "string" };
|
|
5802
|
+
var booleanSchema = { type: "boolean" };
|
|
5803
|
+
var numberToStringTransform = {
|
|
5804
|
+
id: "numberToString",
|
|
5805
|
+
title: "Number → String",
|
|
5806
|
+
category: "Conversion",
|
|
5807
|
+
paramsSchema: undefined,
|
|
5808
|
+
inferOutputSchema: () => stringSchema2,
|
|
5809
|
+
apply: (v) => String(v),
|
|
5810
|
+
suggestFromSchemas(source, target) {
|
|
5811
|
+
const s = source;
|
|
5812
|
+
const t = target;
|
|
5813
|
+
if ((s?.type === "number" || s?.type === "integer") && t?.type === "string") {
|
|
5814
|
+
return { score: 0.8, params: {} };
|
|
5815
|
+
}
|
|
5816
|
+
return;
|
|
5817
|
+
}
|
|
5818
|
+
};
|
|
5819
|
+
var toBooleanTransform = {
|
|
5820
|
+
id: "toBoolean",
|
|
5821
|
+
title: "To Boolean",
|
|
5822
|
+
category: "Conversion",
|
|
5823
|
+
paramsSchema: undefined,
|
|
5824
|
+
inferOutputSchema: () => booleanSchema,
|
|
5825
|
+
apply: (v) => {
|
|
5826
|
+
if (typeof v === "boolean")
|
|
5827
|
+
return v;
|
|
5828
|
+
if (typeof v === "number")
|
|
5829
|
+
return v !== 0;
|
|
5830
|
+
if (typeof v === "string")
|
|
5831
|
+
return v.toLowerCase() === "true" || v === "1";
|
|
5832
|
+
return Boolean(v);
|
|
5833
|
+
}
|
|
5834
|
+
};
|
|
5835
|
+
var stringifyTransform = {
|
|
5836
|
+
id: "stringify",
|
|
5837
|
+
title: "JSON.stringify",
|
|
5838
|
+
category: "Conversion",
|
|
5839
|
+
paramsSchema: undefined,
|
|
5840
|
+
inferOutputSchema: () => stringSchema2,
|
|
5841
|
+
apply: (v) => JSON.stringify(v),
|
|
5842
|
+
suggestFromSchemas(source, target) {
|
|
5843
|
+
const t = target;
|
|
5844
|
+
return t?.type === "string" ? { score: 0.4, params: {} } : undefined;
|
|
5845
|
+
}
|
|
5846
|
+
};
|
|
5847
|
+
var parseJsonTransform = {
|
|
5848
|
+
id: "parseJson",
|
|
5849
|
+
title: "Parse JSON",
|
|
5850
|
+
category: "Conversion",
|
|
5851
|
+
paramsSchema: undefined,
|
|
5852
|
+
inferOutputSchema: () => ({}),
|
|
5853
|
+
apply: (v) => JSON.parse(String(v))
|
|
5854
|
+
};
|
|
5855
|
+
|
|
5856
|
+
// src/task-graph/transforms/index.ts
|
|
5857
|
+
function registerBuiltInTransforms() {
|
|
5858
|
+
const all = [
|
|
5859
|
+
pickTransform,
|
|
5860
|
+
indexTransform,
|
|
5861
|
+
coalesceTransform,
|
|
5862
|
+
uppercaseTransform,
|
|
5863
|
+
lowercaseTransform,
|
|
5864
|
+
truncateTransform,
|
|
5865
|
+
substringTransform,
|
|
5866
|
+
unixToIsoDateTransform,
|
|
5867
|
+
isoDateToUnixTransform,
|
|
5868
|
+
numberToStringTransform,
|
|
5869
|
+
toBooleanTransform,
|
|
5870
|
+
stringifyTransform,
|
|
5871
|
+
parseJsonTransform
|
|
5872
|
+
];
|
|
5873
|
+
for (const t of all)
|
|
5874
|
+
TransformRegistry.registerTransform(t);
|
|
5875
|
+
}
|
|
5399
5876
|
// src/task/EntitlementProfiles.ts
|
|
5400
5877
|
var BROWSER_GRANTS = [
|
|
5401
5878
|
{ id: Entitlements.NETWORK_HTTP },
|
|
@@ -5918,7 +6395,10 @@ var iteratorTaskConfigSchema = {
|
|
|
5918
6395
|
concurrencyLimit: { type: "integer", minimum: 1 },
|
|
5919
6396
|
batchSize: { type: "integer", minimum: 1 },
|
|
5920
6397
|
maxIterations: {
|
|
5921
|
-
oneOf: [
|
|
6398
|
+
oneOf: [
|
|
6399
|
+
{ type: "integer", minimum: 1 },
|
|
6400
|
+
{ type: "string", const: "unbounded" }
|
|
6401
|
+
]
|
|
5922
6402
|
},
|
|
5923
6403
|
iterationInputConfig: { type: "object", additionalProperties: true }
|
|
5924
6404
|
},
|
|
@@ -6433,7 +6913,10 @@ var whileTaskConfigSchema = {
|
|
|
6433
6913
|
...graphAsTaskConfigSchema["properties"],
|
|
6434
6914
|
condition: {},
|
|
6435
6915
|
maxIterations: {
|
|
6436
|
-
oneOf: [
|
|
6916
|
+
oneOf: [
|
|
6917
|
+
{ type: "integer", minimum: 1 },
|
|
6918
|
+
{ type: "string", const: "unbounded" }
|
|
6919
|
+
]
|
|
6437
6920
|
},
|
|
6438
6921
|
chainIterations: { type: "boolean" },
|
|
6439
6922
|
conditionField: { type: "string" },
|
|
@@ -7008,8 +7491,8 @@ import {
|
|
|
7008
7491
|
JobQueueServer
|
|
7009
7492
|
} from "@workglow/job-queue";
|
|
7010
7493
|
import { InMemoryQueueStorage } from "@workglow/storage";
|
|
7011
|
-
import { createServiceToken as
|
|
7012
|
-
var JOB_QUEUE_FACTORY =
|
|
7494
|
+
import { createServiceToken as createServiceToken5, globalServiceRegistry as globalServiceRegistry4 } from "@workglow/util";
|
|
7495
|
+
var JOB_QUEUE_FACTORY = createServiceToken5("taskgraph.jobQueueFactory");
|
|
7013
7496
|
var defaultJobQueueFactory = async ({
|
|
7014
7497
|
queueName,
|
|
7015
7498
|
jobClass,
|
|
@@ -7036,7 +7519,7 @@ var defaultJobQueueFactory = async ({
|
|
|
7036
7519
|
return { server, client, storage };
|
|
7037
7520
|
};
|
|
7038
7521
|
function registerJobQueueFactory(factory) {
|
|
7039
|
-
|
|
7522
|
+
globalServiceRegistry4.registerInstance(JOB_QUEUE_FACTORY, factory);
|
|
7040
7523
|
}
|
|
7041
7524
|
function createJobQueueFactoryWithOptions(defaultOptions = {}) {
|
|
7042
7525
|
return async ({
|
|
@@ -7070,12 +7553,12 @@ function createJobQueueFactoryWithOptions(defaultOptions = {}) {
|
|
|
7070
7553
|
};
|
|
7071
7554
|
}
|
|
7072
7555
|
function getJobQueueFactory() {
|
|
7073
|
-
if (!
|
|
7556
|
+
if (!globalServiceRegistry4.has(JOB_QUEUE_FACTORY)) {
|
|
7074
7557
|
registerJobQueueFactory(defaultJobQueueFactory);
|
|
7075
7558
|
}
|
|
7076
|
-
return
|
|
7559
|
+
return globalServiceRegistry4.get(JOB_QUEUE_FACTORY);
|
|
7077
7560
|
}
|
|
7078
|
-
if (!
|
|
7561
|
+
if (!globalServiceRegistry4.has(JOB_QUEUE_FACTORY)) {
|
|
7079
7562
|
registerJobQueueFactory(defaultJobQueueFactory);
|
|
7080
7563
|
}
|
|
7081
7564
|
// src/task/MapTask.ts
|
|
@@ -7182,6 +7665,7 @@ var reduceTaskConfigSchema = {
|
|
|
7182
7665
|
...iteratorTaskConfigSchema["properties"],
|
|
7183
7666
|
initialValue: {}
|
|
7184
7667
|
},
|
|
7668
|
+
required: iteratorTaskConfigSchema.required,
|
|
7185
7669
|
additionalProperties: false
|
|
7186
7670
|
};
|
|
7187
7671
|
|
|
@@ -7271,9 +7755,9 @@ queueMicrotask(() => {
|
|
|
7271
7755
|
});
|
|
7272
7756
|
// src/task/TaskRegistry.ts
|
|
7273
7757
|
import {
|
|
7274
|
-
createServiceToken as
|
|
7758
|
+
createServiceToken as createServiceToken6,
|
|
7275
7759
|
getLogger as getLogger6,
|
|
7276
|
-
globalServiceRegistry as
|
|
7760
|
+
globalServiceRegistry as globalServiceRegistry5,
|
|
7277
7761
|
registerInputCompactor,
|
|
7278
7762
|
registerInputResolver
|
|
7279
7763
|
} from "@workglow/util";
|
|
@@ -7311,13 +7795,13 @@ var TaskRegistry = {
|
|
|
7311
7795
|
registerTask,
|
|
7312
7796
|
unregisterTask
|
|
7313
7797
|
};
|
|
7314
|
-
var TASK_CONSTRUCTORS =
|
|
7315
|
-
|
|
7798
|
+
var TASK_CONSTRUCTORS = createServiceToken6("task.constructors");
|
|
7799
|
+
globalServiceRegistry5.registerIfAbsent(TASK_CONSTRUCTORS, () => TaskRegistry.all, true);
|
|
7316
7800
|
function getGlobalTaskConstructors() {
|
|
7317
|
-
return
|
|
7801
|
+
return globalServiceRegistry5.get(TASK_CONSTRUCTORS);
|
|
7318
7802
|
}
|
|
7319
7803
|
function setGlobalTaskConstructors(map) {
|
|
7320
|
-
|
|
7804
|
+
globalServiceRegistry5.registerInstance(TASK_CONSTRUCTORS, map);
|
|
7321
7805
|
}
|
|
7322
7806
|
function getTaskConstructors(registry) {
|
|
7323
7807
|
if (!registry)
|
|
@@ -7414,7 +7898,11 @@ var createGraphFromGraphJSON = (graphJsonObj, registry, options) => {
|
|
|
7414
7898
|
subGraph.addTask(createTaskFromGraphJSON(subitem, registry, options));
|
|
7415
7899
|
}
|
|
7416
7900
|
for (const subitem of graphJsonObj.dataflows) {
|
|
7417
|
-
|
|
7901
|
+
const dataflow = new Dataflow(subitem.sourceTaskId, subitem.sourceTaskPortId, subitem.targetTaskId, subitem.targetTaskPortId);
|
|
7902
|
+
if (subitem.transforms && subitem.transforms.length > 0) {
|
|
7903
|
+
dataflow.setTransforms(subitem.transforms);
|
|
7904
|
+
}
|
|
7905
|
+
subGraph.addDataflow(dataflow);
|
|
7418
7906
|
}
|
|
7419
7907
|
return subGraph;
|
|
7420
7908
|
};
|
|
@@ -7472,8 +7960,8 @@ var registerBaseTasks = () => {
|
|
|
7472
7960
|
return tasks;
|
|
7473
7961
|
};
|
|
7474
7962
|
// src/storage/TaskGraphRepository.ts
|
|
7475
|
-
import { createServiceToken as
|
|
7476
|
-
var TASK_GRAPH_REPOSITORY =
|
|
7963
|
+
import { createServiceToken as createServiceToken7, EventEmitter as EventEmitter7 } from "@workglow/util";
|
|
7964
|
+
var TASK_GRAPH_REPOSITORY = createServiceToken7("taskgraph.taskGraphRepository");
|
|
7477
7965
|
|
|
7478
7966
|
class TaskGraphRepository {
|
|
7479
7967
|
type = "TaskGraphRepository";
|
|
@@ -7633,7 +8121,13 @@ class TaskOutputTabularRepository extends TaskOutputRepository {
|
|
|
7633
8121
|
export {
|
|
7634
8122
|
wrapSchemaInArray,
|
|
7635
8123
|
whileTaskConfigSchema,
|
|
8124
|
+
uppercaseTransform,
|
|
8125
|
+
unixToIsoDateTransform,
|
|
8126
|
+
truncateTransform,
|
|
8127
|
+
toBooleanTransform,
|
|
7636
8128
|
taskPrototypeHasOwnExecute,
|
|
8129
|
+
substringTransform,
|
|
8130
|
+
stringifyTransform,
|
|
7637
8131
|
setTaskQueueRegistry,
|
|
7638
8132
|
setGlobalTaskConstructors,
|
|
7639
8133
|
serialGraph,
|
|
@@ -7647,20 +8141,27 @@ export {
|
|
|
7647
8141
|
resetMethodNameCache,
|
|
7648
8142
|
removeIterationProperties,
|
|
7649
8143
|
registerJobQueueFactory,
|
|
8144
|
+
registerBuiltInTransforms,
|
|
7650
8145
|
registerBaseTasks,
|
|
7651
8146
|
reduceTaskConfigSchema,
|
|
7652
8147
|
pipe,
|
|
8148
|
+
pickTransform,
|
|
8149
|
+
parseJsonTransform,
|
|
7653
8150
|
parallel,
|
|
8151
|
+
numberToStringTransform,
|
|
7654
8152
|
mergeResources,
|
|
7655
8153
|
mergeEntitlements,
|
|
7656
8154
|
mergeEntitlementPair,
|
|
7657
8155
|
mergeChainedOutputToInput,
|
|
7658
8156
|
mapTaskConfigSchema,
|
|
8157
|
+
lowercaseTransform,
|
|
7659
8158
|
iteratorTaskConfigSchema,
|
|
8159
|
+
isoDateToUnixTransform,
|
|
7660
8160
|
isTaskStreamable,
|
|
7661
8161
|
isStrictArraySchema,
|
|
7662
8162
|
isIterationProperty,
|
|
7663
8163
|
isFlexibleSchema,
|
|
8164
|
+
indexTransform,
|
|
7664
8165
|
hasVectorOutput,
|
|
7665
8166
|
hasVectorLikeInput,
|
|
7666
8167
|
hasStructuredOutput,
|
|
@@ -7715,9 +8216,11 @@ export {
|
|
|
7715
8216
|
computeGraphInputSchema,
|
|
7716
8217
|
computeGraphEntitlements,
|
|
7717
8218
|
compactSchemaInputs,
|
|
8219
|
+
coalesceTransform,
|
|
7718
8220
|
can,
|
|
7719
8221
|
calculateNodeDepths,
|
|
7720
8222
|
buildIterationInputSchema,
|
|
8223
|
+
autoConnect,
|
|
7721
8224
|
addIterationContextToSchema,
|
|
7722
8225
|
addBoundaryNodesToGraphJson,
|
|
7723
8226
|
addBoundaryNodesToDependencyJson,
|
|
@@ -7726,6 +8229,7 @@ export {
|
|
|
7726
8229
|
WhileTaskRunner,
|
|
7727
8230
|
WhileTask,
|
|
7728
8231
|
WHILE_CONTEXT_SCHEMA,
|
|
8232
|
+
TransformRegistry,
|
|
7729
8233
|
TaskTimeoutError,
|
|
7730
8234
|
TaskStatus,
|
|
7731
8235
|
TaskSerializationError,
|
|
@@ -7751,6 +8255,7 @@ export {
|
|
|
7751
8255
|
TaskConfigSchema,
|
|
7752
8256
|
TaskAbortedError,
|
|
7753
8257
|
Task,
|
|
8258
|
+
TRANSFORM_DEFS,
|
|
7754
8259
|
TASK_OUTPUT_REPOSITORY,
|
|
7755
8260
|
TASK_GRAPH_REPOSITORY,
|
|
7756
8261
|
TASK_CONSTRUCTORS,
|
|
@@ -7792,4 +8297,4 @@ export {
|
|
|
7792
8297
|
BROWSER_GRANTS
|
|
7793
8298
|
};
|
|
7794
8299
|
|
|
7795
|
-
//# debugId=
|
|
8300
|
+
//# debugId=4F9B198906F7AB6964756E2164756E21
|