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