@workglow/task-graph 0.2.20 → 0.2.21
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/browser.js +221 -98
- package/dist/browser.js.map +17 -19
- package/dist/bun.js +221 -98
- package/dist/bun.js.map +17 -19
- package/dist/common.d.ts +0 -1
- package/dist/common.d.ts.map +1 -1
- package/dist/node.js +221 -98
- package/dist/node.js.map +17 -19
- package/dist/task/FallbackTaskRunner.d.ts.map +1 -1
- package/dist/task/GraphAsTaskRunner.d.ts.map +1 -1
- package/dist/task/ITask.d.ts +18 -9
- package/dist/task/ITask.d.ts.map +1 -1
- package/dist/task/ITaskRunner.d.ts +15 -0
- package/dist/task/ITaskRunner.d.ts.map +1 -1
- package/dist/task/StreamTypes.d.ts +23 -1
- package/dist/task/StreamTypes.d.ts.map +1 -1
- package/dist/task/Task.d.ts +9 -2
- package/dist/task/Task.d.ts.map +1 -1
- package/dist/task/TaskEvents.d.ts +2 -2
- package/dist/task/TaskEvents.d.ts.map +1 -1
- package/dist/task/TaskRunner.d.ts +17 -8
- package/dist/task/TaskRunner.d.ts.map +1 -1
- package/dist/task/WhileTask.d.ts.map +1 -1
- package/dist/task-graph/Dataflow.d.ts +20 -0
- package/dist/task-graph/Dataflow.d.ts.map +1 -1
- package/dist/task-graph/ITaskGraph.d.ts +1 -1
- package/dist/task-graph/ITaskGraph.d.ts.map +1 -1
- package/dist/task-graph/IWorkflow.d.ts +0 -2
- package/dist/task-graph/IWorkflow.d.ts.map +1 -1
- package/dist/task-graph/TaskGraph.d.ts +1 -13
- package/dist/task-graph/TaskGraph.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphEvents.d.ts +1 -1
- package/dist/task-graph/TaskGraphEvents.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts +5 -8
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/dist/task-graph/Workflow.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/refcountable.d.ts +0 -29
- package/dist/refcountable.d.ts.map +0 -1
package/dist/browser.js
CHANGED
|
@@ -180,7 +180,14 @@ class Dataflow {
|
|
|
180
180
|
status = TaskStatus.PENDING;
|
|
181
181
|
error;
|
|
182
182
|
stream = undefined;
|
|
183
|
+
latestSnapshot = undefined;
|
|
184
|
+
getCurrentValue() {
|
|
185
|
+
if (this.value !== undefined)
|
|
186
|
+
return this.value;
|
|
187
|
+
return this.latestSnapshot;
|
|
188
|
+
}
|
|
183
189
|
setStream(stream) {
|
|
190
|
+
this.latestSnapshot = undefined;
|
|
184
191
|
this.stream = stream;
|
|
185
192
|
}
|
|
186
193
|
getStream() {
|
|
@@ -226,6 +233,7 @@ class Dataflow {
|
|
|
226
233
|
}
|
|
227
234
|
}
|
|
228
235
|
reset() {
|
|
236
|
+
this.latestSnapshot = undefined;
|
|
229
237
|
this.status = TaskStatus.PENDING;
|
|
230
238
|
this.error = undefined;
|
|
231
239
|
this.value = undefined;
|
|
@@ -271,6 +279,7 @@ class Dataflow {
|
|
|
271
279
|
} else {
|
|
272
280
|
this.value = entireDataBlock[this.sourceTaskPortId];
|
|
273
281
|
}
|
|
282
|
+
this.latestSnapshot = undefined;
|
|
274
283
|
}
|
|
275
284
|
getPortData() {
|
|
276
285
|
let result;
|
|
@@ -1142,31 +1151,7 @@ import {
|
|
|
1142
1151
|
SpanStatusCode as SpanStatusCode2,
|
|
1143
1152
|
uuid4 as uuid43
|
|
1144
1153
|
} from "@workglow/util";
|
|
1145
|
-
|
|
1146
|
-
// src/refcountable.ts
|
|
1147
|
-
var GLOBAL_KEY = Symbol.for("@workglow/task-graph/refcountable.predicates");
|
|
1148
|
-
var _g = globalThis;
|
|
1149
|
-
if (!Array.isArray(_g[GLOBAL_KEY])) {
|
|
1150
|
-
_g[GLOBAL_KEY] = [];
|
|
1151
|
-
}
|
|
1152
|
-
var predicates = _g[GLOBAL_KEY];
|
|
1153
|
-
function registerRefcountablePredicate(p) {
|
|
1154
|
-
predicates.push(p);
|
|
1155
|
-
}
|
|
1156
|
-
function asRefcountable(v) {
|
|
1157
|
-
if (v === null || v === undefined)
|
|
1158
|
-
return null;
|
|
1159
|
-
if (typeof v !== "object")
|
|
1160
|
-
return null;
|
|
1161
|
-
for (const p of predicates) {
|
|
1162
|
-
if (p(v))
|
|
1163
|
-
return v;
|
|
1164
|
-
}
|
|
1165
|
-
return null;
|
|
1166
|
-
}
|
|
1167
|
-
function _resetRefcountablePredicatesForTests() {
|
|
1168
|
-
predicates.length = 0;
|
|
1169
|
-
}
|
|
1154
|
+
import { previewSource } from "@workglow/util/media";
|
|
1170
1155
|
|
|
1171
1156
|
// src/storage/TaskOutputRepository.ts
|
|
1172
1157
|
import { createServiceToken as createServiceToken2, EventEmitter as EventEmitter2 } from "@workglow/util";
|
|
@@ -1435,7 +1420,6 @@ class TaskRunner {
|
|
|
1435
1420
|
timeoutTimer;
|
|
1436
1421
|
pendingTimeoutError;
|
|
1437
1422
|
shouldAccumulate = true;
|
|
1438
|
-
runWithPreviews = false;
|
|
1439
1423
|
telemetrySpan;
|
|
1440
1424
|
constructor(task) {
|
|
1441
1425
|
this.task = task;
|
|
@@ -1544,6 +1528,100 @@ class TaskRunner {
|
|
|
1544
1528
|
return this.task.runOutputData;
|
|
1545
1529
|
}
|
|
1546
1530
|
}
|
|
1531
|
+
async* runPreviewStream(overrides = {}) {
|
|
1532
|
+
const graph = this.task.parentGraph;
|
|
1533
|
+
const dataflowInfos = [];
|
|
1534
|
+
if (graph) {
|
|
1535
|
+
for (const df of graph.getSourceDataflows(this.task.id)) {
|
|
1536
|
+
const upstream = graph.getTask(df.sourceTaskId);
|
|
1537
|
+
if (upstream) {
|
|
1538
|
+
dataflowInfos.push({
|
|
1539
|
+
upstream,
|
|
1540
|
+
sourcePort: df.sourceTaskPortId,
|
|
1541
|
+
targetPort: df.targetTaskPortId
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
const upstreamTasks = new Set(dataflowInfos.map((d) => d.upstream));
|
|
1547
|
+
const pendingUpstreams = new Set([...upstreamTasks].filter((u) => u.status === TaskStatus.STREAMING || u.status === TaskStatus.PENDING || u.status === TaskStatus.PROCESSING));
|
|
1548
|
+
let dirty = true;
|
|
1549
|
+
let wakeResolve;
|
|
1550
|
+
const wakeNext = () => new Promise((resolve) => {
|
|
1551
|
+
wakeResolve = resolve;
|
|
1552
|
+
});
|
|
1553
|
+
const wake = () => {
|
|
1554
|
+
const r = wakeResolve;
|
|
1555
|
+
wakeResolve = undefined;
|
|
1556
|
+
if (r)
|
|
1557
|
+
r();
|
|
1558
|
+
};
|
|
1559
|
+
const cleanupFns = [];
|
|
1560
|
+
for (const upstream of pendingUpstreams) {
|
|
1561
|
+
const myDataflows = dataflowInfos.filter((d) => d.upstream === upstream);
|
|
1562
|
+
const onChunk = (event) => {
|
|
1563
|
+
if (event.type !== "snapshot")
|
|
1564
|
+
return;
|
|
1565
|
+
const snapshotData = event.data;
|
|
1566
|
+
if (snapshotData) {
|
|
1567
|
+
for (const { sourcePort, targetPort } of myDataflows) {
|
|
1568
|
+
const value = sourcePort === "*" ? snapshotData : snapshotData[sourcePort];
|
|
1569
|
+
if (value !== undefined) {
|
|
1570
|
+
this.task.runInputData[targetPort] = value;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
dirty = true;
|
|
1575
|
+
wake();
|
|
1576
|
+
};
|
|
1577
|
+
const onEnd = () => {
|
|
1578
|
+
pendingUpstreams.delete(upstream);
|
|
1579
|
+
wake();
|
|
1580
|
+
};
|
|
1581
|
+
const onStatus = (status) => {
|
|
1582
|
+
if (status === TaskStatus.COMPLETED || status === TaskStatus.FAILED || status === TaskStatus.DISABLED) {
|
|
1583
|
+
pendingUpstreams.delete(upstream);
|
|
1584
|
+
wake();
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
upstream.on("stream_chunk", onChunk);
|
|
1588
|
+
upstream.on("stream_end", onEnd);
|
|
1589
|
+
upstream.on("status", onStatus);
|
|
1590
|
+
cleanupFns.push(() => {
|
|
1591
|
+
upstream.off("stream_chunk", onChunk);
|
|
1592
|
+
upstream.off("stream_end", onEnd);
|
|
1593
|
+
upstream.off("status", onStatus);
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
for (const upstream of [...pendingUpstreams]) {
|
|
1597
|
+
if (upstream.status === TaskStatus.COMPLETED || upstream.status === TaskStatus.FAILED || upstream.status === TaskStatus.DISABLED) {
|
|
1598
|
+
pendingUpstreams.delete(upstream);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
try {
|
|
1602
|
+
while (true) {
|
|
1603
|
+
if (dirty) {
|
|
1604
|
+
dirty = false;
|
|
1605
|
+
try {
|
|
1606
|
+
const out = await this.runPreview(overrides);
|
|
1607
|
+
yield out;
|
|
1608
|
+
} catch (err) {
|
|
1609
|
+
getLogger().debug("runPreviewStream iteration failed", {
|
|
1610
|
+
taskId: this.task.config?.id,
|
|
1611
|
+
error: err
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
continue;
|
|
1615
|
+
}
|
|
1616
|
+
if (pendingUpstreams.size === 0)
|
|
1617
|
+
return;
|
|
1618
|
+
await wakeNext();
|
|
1619
|
+
}
|
|
1620
|
+
} finally {
|
|
1621
|
+
for (const off of cleanupFns)
|
|
1622
|
+
off();
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1547
1625
|
abort() {
|
|
1548
1626
|
if (this.task.hasChildren()) {
|
|
1549
1627
|
this.task.subGraph.abort();
|
|
@@ -1594,7 +1672,7 @@ class TaskRunner {
|
|
|
1594
1672
|
}
|
|
1595
1673
|
const accumulated = this.shouldAccumulate ? new Map : undefined;
|
|
1596
1674
|
const accumulatedObjects = this.shouldAccumulate ? new Map : undefined;
|
|
1597
|
-
let
|
|
1675
|
+
let streamingStarted = false;
|
|
1598
1676
|
let finalOutput;
|
|
1599
1677
|
this.task.emit("stream_start");
|
|
1600
1678
|
const stream = this.task.executeStream(input, {
|
|
@@ -1606,25 +1684,33 @@ class TaskRunner {
|
|
|
1606
1684
|
inputStreams: this.inputStreams
|
|
1607
1685
|
});
|
|
1608
1686
|
for await (const event of stream) {
|
|
1609
|
-
chunkCount++;
|
|
1610
|
-
if (chunkCount === 1) {
|
|
1611
|
-
this.task.status = TaskStatus.STREAMING;
|
|
1612
|
-
this.task.emit("status", this.task.status);
|
|
1613
|
-
}
|
|
1614
1687
|
if (event.type === "snapshot") {
|
|
1615
1688
|
this.task.runOutputData = event.data;
|
|
1616
1689
|
}
|
|
1617
1690
|
switch (event.type) {
|
|
1691
|
+
case "phase": {
|
|
1692
|
+
this.task.emit("stream_chunk", event);
|
|
1693
|
+
await this.handleProgress(event.progress, event.message);
|
|
1694
|
+
break;
|
|
1695
|
+
}
|
|
1618
1696
|
case "text-delta": {
|
|
1697
|
+
if (!streamingStarted) {
|
|
1698
|
+
streamingStarted = true;
|
|
1699
|
+
this.task.status = TaskStatus.STREAMING;
|
|
1700
|
+
this.task.emit("status", this.task.status);
|
|
1701
|
+
}
|
|
1619
1702
|
if (accumulated) {
|
|
1620
1703
|
accumulated.set(event.port, (accumulated.get(event.port) ?? "") + event.textDelta);
|
|
1621
1704
|
}
|
|
1622
1705
|
this.task.emit("stream_chunk", event);
|
|
1623
|
-
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
1624
|
-
await this.handleProgress(progress);
|
|
1625
1706
|
break;
|
|
1626
1707
|
}
|
|
1627
1708
|
case "object-delta": {
|
|
1709
|
+
if (!streamingStarted) {
|
|
1710
|
+
streamingStarted = true;
|
|
1711
|
+
this.task.status = TaskStatus.STREAMING;
|
|
1712
|
+
this.task.emit("status", this.task.status);
|
|
1713
|
+
}
|
|
1628
1714
|
if (accumulatedObjects) {
|
|
1629
1715
|
const existing = accumulatedObjects.get(event.port);
|
|
1630
1716
|
if (Array.isArray(event.objectDelta)) {
|
|
@@ -1651,14 +1737,15 @@ class TaskRunner {
|
|
|
1651
1737
|
[event.port]: accumulatedObjects?.get(event.port) ?? event.objectDelta
|
|
1652
1738
|
};
|
|
1653
1739
|
this.task.emit("stream_chunk", event);
|
|
1654
|
-
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
1655
|
-
await this.handleProgress(progress);
|
|
1656
1740
|
break;
|
|
1657
1741
|
}
|
|
1658
1742
|
case "snapshot": {
|
|
1743
|
+
if (!streamingStarted) {
|
|
1744
|
+
streamingStarted = true;
|
|
1745
|
+
this.task.status = TaskStatus.STREAMING;
|
|
1746
|
+
this.task.emit("status", this.task.status);
|
|
1747
|
+
}
|
|
1659
1748
|
this.task.emit("stream_chunk", event);
|
|
1660
|
-
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
1661
|
-
await this.handleProgress(progress);
|
|
1662
1749
|
break;
|
|
1663
1750
|
}
|
|
1664
1751
|
case "finish": {
|
|
@@ -1675,9 +1762,32 @@ class TaskRunner {
|
|
|
1675
1762
|
merged[port] = obj;
|
|
1676
1763
|
}
|
|
1677
1764
|
}
|
|
1765
|
+
if (streamMode === "replace" && Object.keys(merged).length === 0) {
|
|
1766
|
+
const lastSnapshot = this.task.runOutputData;
|
|
1767
|
+
if (lastSnapshot && Object.keys(lastSnapshot).length > 0) {
|
|
1768
|
+
finalOutput = lastSnapshot;
|
|
1769
|
+
this.task.emit("stream_chunk", {
|
|
1770
|
+
type: "finish",
|
|
1771
|
+
data: lastSnapshot
|
|
1772
|
+
});
|
|
1773
|
+
break;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1678
1776
|
finalOutput = merged;
|
|
1679
1777
|
this.task.emit("stream_chunk", { type: "finish", data: merged });
|
|
1680
1778
|
} else {
|
|
1779
|
+
const finishData = event.data ?? {};
|
|
1780
|
+
if (streamMode === "replace" && Object.keys(finishData).length === 0) {
|
|
1781
|
+
const lastSnapshot = this.task.runOutputData;
|
|
1782
|
+
if (lastSnapshot && Object.keys(lastSnapshot).length > 0) {
|
|
1783
|
+
finalOutput = lastSnapshot;
|
|
1784
|
+
this.task.emit("stream_chunk", {
|
|
1785
|
+
type: "finish",
|
|
1786
|
+
data: lastSnapshot
|
|
1787
|
+
});
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1681
1791
|
finalOutput = event.data;
|
|
1682
1792
|
this.task.emit("stream_chunk", event);
|
|
1683
1793
|
}
|
|
@@ -1718,7 +1828,6 @@ class TaskRunner {
|
|
|
1718
1828
|
this.outputCache = cache;
|
|
1719
1829
|
}
|
|
1720
1830
|
this.shouldAccumulate = config.shouldAccumulate !== false;
|
|
1721
|
-
this.runWithPreviews = config.runWithPreviews === true;
|
|
1722
1831
|
if (config.updateProgress) {
|
|
1723
1832
|
this.updateProgress = config.updateProgress;
|
|
1724
1833
|
}
|
|
@@ -1773,7 +1882,7 @@ class TaskRunner {
|
|
|
1773
1882
|
return;
|
|
1774
1883
|
this.clearTimeoutTimer();
|
|
1775
1884
|
this.task.status = TaskStatus.ABORTING;
|
|
1776
|
-
this.
|
|
1885
|
+
await this.handleProgress(100);
|
|
1777
1886
|
this.task.error = this.pendingTimeoutError ?? new TaskAbortedError;
|
|
1778
1887
|
this.pendingTimeoutError = undefined;
|
|
1779
1888
|
if (this.telemetrySpan) {
|
|
@@ -1801,9 +1910,9 @@ class TaskRunner {
|
|
|
1801
1910
|
this.clearTimeoutTimer();
|
|
1802
1911
|
this.pendingTimeoutError = undefined;
|
|
1803
1912
|
this.task.completedAt = new Date;
|
|
1804
|
-
this.task.progress = 100;
|
|
1805
1913
|
this.task.status = TaskStatus.COMPLETED;
|
|
1806
1914
|
this.abortController = undefined;
|
|
1915
|
+
await this.handleProgress(100);
|
|
1807
1916
|
if (this.telemetrySpan) {
|
|
1808
1917
|
this.telemetrySpan.setStatus(SpanStatusCode.OK);
|
|
1809
1918
|
this.telemetrySpan.end();
|
|
@@ -1819,7 +1928,7 @@ class TaskRunner {
|
|
|
1819
1928
|
if (this.task.status === TaskStatus.DISABLED)
|
|
1820
1929
|
return;
|
|
1821
1930
|
this.task.status = TaskStatus.DISABLED;
|
|
1822
|
-
this.
|
|
1931
|
+
await this.handleProgress(100);
|
|
1823
1932
|
this.task.completedAt = new Date;
|
|
1824
1933
|
this.abortController = undefined;
|
|
1825
1934
|
this.task.emit("disabled");
|
|
@@ -1839,8 +1948,6 @@ class TaskRunner {
|
|
|
1839
1948
|
this.task.subGraph.abort();
|
|
1840
1949
|
}
|
|
1841
1950
|
this.task.completedAt = new Date;
|
|
1842
|
-
this.task.progress = 100;
|
|
1843
|
-
this.task.status = TaskStatus.FAILED;
|
|
1844
1951
|
if (err instanceof TaskError) {
|
|
1845
1952
|
this.task.error = err;
|
|
1846
1953
|
} else {
|
|
@@ -1850,7 +1957,9 @@ class TaskRunner {
|
|
|
1850
1957
|
this.task.error.taskType ??= this.task.type;
|
|
1851
1958
|
this.task.error.taskId ??= this.task.id;
|
|
1852
1959
|
}
|
|
1960
|
+
this.task.status = TaskStatus.FAILED;
|
|
1853
1961
|
this.abortController = undefined;
|
|
1962
|
+
await this.handleProgress(100);
|
|
1854
1963
|
if (this.telemetrySpan) {
|
|
1855
1964
|
this.telemetrySpan.setStatus(SpanStatusCode.ERROR, this.task.error.message);
|
|
1856
1965
|
this.telemetrySpan.setAttributes({ "workglow.task.error": this.task.error.message });
|
|
@@ -1912,6 +2021,7 @@ class Task {
|
|
|
1912
2021
|
async executePreview(_input, _context) {
|
|
1913
2022
|
return;
|
|
1914
2023
|
}
|
|
2024
|
+
parentGraph;
|
|
1915
2025
|
_runner;
|
|
1916
2026
|
get runner() {
|
|
1917
2027
|
if (!this._runner) {
|
|
@@ -2291,6 +2401,10 @@ class Task {
|
|
|
2291
2401
|
return obj.map((item) => this.stripSymbols(item));
|
|
2292
2402
|
}
|
|
2293
2403
|
if (typeof obj === "object") {
|
|
2404
|
+
const proto = Object.getPrototypeOf(obj);
|
|
2405
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
2406
|
+
return obj;
|
|
2407
|
+
}
|
|
2294
2408
|
const result = {};
|
|
2295
2409
|
for (const key in obj) {
|
|
2296
2410
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
@@ -2881,6 +2995,12 @@ function taskPrototypeHasOwnExecute(task) {
|
|
|
2881
2995
|
}
|
|
2882
2996
|
var PROPERTY_ARRAY = "PROPERTY_ARRAY";
|
|
2883
2997
|
var GRAPH_RESULT_ARRAY = "GRAPH_RESULT_ARRAY";
|
|
2998
|
+
function isImageValueShape(v) {
|
|
2999
|
+
if (v === null || typeof v !== "object")
|
|
3000
|
+
return false;
|
|
3001
|
+
const o = v;
|
|
3002
|
+
return typeof o.width === "number" && typeof o.height === "number" && typeof o.previewScale === "number";
|
|
3003
|
+
}
|
|
2884
3004
|
|
|
2885
3005
|
class TaskGraphRunner {
|
|
2886
3006
|
processScheduler;
|
|
@@ -2890,7 +3010,6 @@ class TaskGraphRunner {
|
|
|
2890
3010
|
graph;
|
|
2891
3011
|
outputCache;
|
|
2892
3012
|
accumulateLeafOutputs = true;
|
|
2893
|
-
runWithPreviews = false;
|
|
2894
3013
|
registry = globalServiceRegistry3;
|
|
2895
3014
|
resourceScope;
|
|
2896
3015
|
abortController;
|
|
@@ -3120,27 +3239,27 @@ class TaskGraphRunner {
|
|
|
3120
3239
|
const dataflows = this.graph.getSourceDataflows(task.id);
|
|
3121
3240
|
dataflows.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
3122
3241
|
for (const dataflow of dataflows) {
|
|
3123
|
-
|
|
3242
|
+
const live = dataflow.getCurrentValue();
|
|
3243
|
+
const port = dataflow.targetTaskPortId;
|
|
3244
|
+
let portData;
|
|
3245
|
+
if (port === DATAFLOW_ALL_PORTS) {
|
|
3246
|
+
portData = live;
|
|
3247
|
+
} else if (port === DATAFLOW_ERROR_PORT) {
|
|
3248
|
+
portData = { [DATAFLOW_ERROR_PORT]: dataflow.error };
|
|
3249
|
+
} else {
|
|
3250
|
+
portData = { [port]: live };
|
|
3251
|
+
}
|
|
3252
|
+
this.addInputData(task, portData);
|
|
3124
3253
|
}
|
|
3125
3254
|
}
|
|
3126
3255
|
async pushOutputFromNodeToEdges(node, results) {
|
|
3127
3256
|
const dataflows = this.graph.getTargetDataflows(node.id);
|
|
3128
|
-
if (Object.keys(results).length > 0) {
|
|
3129
|
-
const
|
|
3130
|
-
for (const dataflow of dataflows) {
|
|
3131
|
-
if (dataflow.stream !== undefined)
|
|
3132
|
-
continue;
|
|
3133
|
-
const port = dataflow.sourceTaskPortId;
|
|
3134
|
-
consumerCounts.set(port, (consumerCounts.get(port) ?? 0) + 1);
|
|
3135
|
-
}
|
|
3136
|
-
for (const [port, count] of consumerCounts) {
|
|
3137
|
-
const extra = this.runWithPreviews ? count : count - 1;
|
|
3138
|
-
if (extra <= 0)
|
|
3139
|
-
continue;
|
|
3257
|
+
if (this.previewRunning && Object.keys(results).length > 0) {
|
|
3258
|
+
for (const port of Object.keys(results)) {
|
|
3140
3259
|
const value = results[port];
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3260
|
+
if (isImageValueShape(value)) {
|
|
3261
|
+
results[port] = await previewSource(value);
|
|
3262
|
+
}
|
|
3144
3263
|
}
|
|
3145
3264
|
}
|
|
3146
3265
|
for (const dataflow of dataflows) {
|
|
@@ -3312,8 +3431,7 @@ class TaskGraphRunner {
|
|
|
3312
3431
|
outputCache: this.outputCache ?? false,
|
|
3313
3432
|
updateProgress: async (task2, progress, message, ...args) => await this.handleProgress(task2, progress, message, ...args),
|
|
3314
3433
|
registry: this.registry,
|
|
3315
|
-
resourceScope: this.resourceScope
|
|
3316
|
-
runWithPreviews: this.runWithPreviews
|
|
3434
|
+
resourceScope: this.resourceScope
|
|
3317
3435
|
});
|
|
3318
3436
|
await this.pushOutputFromNodeToEdges(task, results);
|
|
3319
3437
|
return {
|
|
@@ -3363,8 +3481,7 @@ class TaskGraphRunner {
|
|
|
3363
3481
|
shouldAccumulate,
|
|
3364
3482
|
updateProgress: async (task2, progress, message, ...args) => await this.handleProgress(task2, progress, message, ...args),
|
|
3365
3483
|
registry: this.registry,
|
|
3366
|
-
resourceScope: this.resourceScope
|
|
3367
|
-
runWithPreviews: this.runWithPreviews
|
|
3484
|
+
resourceScope: this.resourceScope
|
|
3368
3485
|
});
|
|
3369
3486
|
await this.pushOutputFromNodeToEdges(task, results);
|
|
3370
3487
|
return {
|
|
@@ -3382,7 +3499,7 @@ class TaskGraphRunner {
|
|
|
3382
3499
|
static isPortDelta(event) {
|
|
3383
3500
|
return event.type === "text-delta" || event.type === "object-delta";
|
|
3384
3501
|
}
|
|
3385
|
-
createStreamFromTaskEvents(task, portId) {
|
|
3502
|
+
createStreamFromTaskEvents(task, portId, edgesForGroup) {
|
|
3386
3503
|
return new ReadableStream({
|
|
3387
3504
|
start: (controller) => {
|
|
3388
3505
|
const onChunk = (event) => {
|
|
@@ -3390,6 +3507,15 @@ class TaskGraphRunner {
|
|
|
3390
3507
|
if (portId !== undefined && TaskGraphRunner.isPortDelta(event) && event.port !== portId) {
|
|
3391
3508
|
return;
|
|
3392
3509
|
}
|
|
3510
|
+
if (event.type === "snapshot") {
|
|
3511
|
+
const data = event.data;
|
|
3512
|
+
if (data) {
|
|
3513
|
+
for (const edge of edgesForGroup) {
|
|
3514
|
+
const portValue = edge.sourceTaskPortId === DATAFLOW_ALL_PORTS ? data : data[edge.sourceTaskPortId];
|
|
3515
|
+
edge.latestSnapshot = portValue;
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3393
3519
|
controller.enqueue(event);
|
|
3394
3520
|
} catch {}
|
|
3395
3521
|
};
|
|
@@ -3421,7 +3547,7 @@ class TaskGraphRunner {
|
|
|
3421
3547
|
}
|
|
3422
3548
|
for (const [portKey, edges] of groups) {
|
|
3423
3549
|
const filterPort = portKey === DATAFLOW_ALL_PORTS ? undefined : portKey;
|
|
3424
|
-
const stream = this.createStreamFromTaskEvents(task, filterPort);
|
|
3550
|
+
const stream = this.createStreamFromTaskEvents(task, filterPort, edges);
|
|
3425
3551
|
if (edges.length === 1) {
|
|
3426
3552
|
edges[0].setStream(stream);
|
|
3427
3553
|
} else {
|
|
@@ -3439,17 +3565,6 @@ class TaskGraphRunner {
|
|
|
3439
3565
|
}
|
|
3440
3566
|
}
|
|
3441
3567
|
resetTask(graph, task, runId) {
|
|
3442
|
-
const previous = task.runOutputData;
|
|
3443
|
-
if (previous) {
|
|
3444
|
-
for (const port of Object.keys(previous)) {
|
|
3445
|
-
const ref = asRefcountable(previous[port]);
|
|
3446
|
-
if (!ref)
|
|
3447
|
-
continue;
|
|
3448
|
-
try {
|
|
3449
|
-
ref.release();
|
|
3450
|
-
} catch {}
|
|
3451
|
-
}
|
|
3452
|
-
}
|
|
3453
3568
|
task.status = TaskStatus.PENDING;
|
|
3454
3569
|
task.resetInputData();
|
|
3455
3570
|
task.runOutputData = {};
|
|
@@ -3483,7 +3598,6 @@ class TaskGraphRunner {
|
|
|
3483
3598
|
this.resourceScope = config.resourceScope;
|
|
3484
3599
|
}
|
|
3485
3600
|
this.accumulateLeafOutputs = config?.accumulateLeafOutputs !== false;
|
|
3486
|
-
this.runWithPreviews = config?.runWithPreviews === true;
|
|
3487
3601
|
if (config?.outputCache !== undefined) {
|
|
3488
3602
|
if (typeof config.outputCache === "boolean") {
|
|
3489
3603
|
if (config.outputCache === true) {
|
|
@@ -3583,7 +3697,6 @@ class TaskGraphRunner {
|
|
|
3583
3697
|
throw new TaskConfigurationError(`Graph has ${taskCount} tasks, exceeding the limit of ${config.maxTasks}`);
|
|
3584
3698
|
}
|
|
3585
3699
|
}
|
|
3586
|
-
this.runWithPreviews = false;
|
|
3587
3700
|
this.previewScheduler.reset();
|
|
3588
3701
|
this.previewRunning = true;
|
|
3589
3702
|
}
|
|
@@ -3659,15 +3772,21 @@ class TaskGraphRunner {
|
|
|
3659
3772
|
async handleProgress(task, progress, message, ...args) {
|
|
3660
3773
|
const contributors = this.graph.getTasks().filter(taskPrototypeHasOwnExecute);
|
|
3661
3774
|
if (contributors.length > 1) {
|
|
3662
|
-
const
|
|
3663
|
-
|
|
3775
|
+
const determinate = contributors.filter((t) => t.progress !== undefined);
|
|
3776
|
+
if (determinate.length === 0) {
|
|
3777
|
+
progress = undefined;
|
|
3778
|
+
} else {
|
|
3779
|
+
const sum = determinate.reduce((acc, t) => acc + t.progress, 0);
|
|
3780
|
+
progress = Math.round(sum / determinate.length);
|
|
3781
|
+
}
|
|
3664
3782
|
} else if (contributors.length === 1) {
|
|
3665
3783
|
const [only] = contributors;
|
|
3666
3784
|
progress = only.progress;
|
|
3667
3785
|
}
|
|
3668
3786
|
this.pushStatusFromNodeToEdges(this.graph, task);
|
|
3669
3787
|
this.graph.emit("graph_progress", progress, message, args);
|
|
3670
|
-
|
|
3788
|
+
const isActive = task.status === TaskStatus.PROCESSING || task.status === TaskStatus.STREAMING;
|
|
3789
|
+
if (isActive && task.runOutputData && Object.keys(task.runOutputData).length > 0) {
|
|
3671
3790
|
await this.pushOutputFromNodeToEdges(task, task.runOutputData);
|
|
3672
3791
|
}
|
|
3673
3792
|
}
|
|
@@ -3683,8 +3802,7 @@ class GraphAsTaskRunner extends TaskRunner {
|
|
|
3683
3802
|
parentSignal: this.abortController?.signal,
|
|
3684
3803
|
outputCache: this.outputCache,
|
|
3685
3804
|
registry: this.registry,
|
|
3686
|
-
resourceScope: this.resourceScope
|
|
3687
|
-
runWithPreviews: this.runWithPreviews
|
|
3805
|
+
resourceScope: this.resourceScope
|
|
3688
3806
|
});
|
|
3689
3807
|
unsubscribe();
|
|
3690
3808
|
return results;
|
|
@@ -4147,8 +4265,7 @@ class TaskGraph {
|
|
|
4147
4265
|
registry: config?.registry,
|
|
4148
4266
|
timeout: config?.timeout,
|
|
4149
4267
|
maxTasks: config?.maxTasks,
|
|
4150
|
-
resourceScope: config?.resourceScope
|
|
4151
|
-
runWithPreviews: config?.runWithPreviews
|
|
4268
|
+
resourceScope: config?.resourceScope
|
|
4152
4269
|
});
|
|
4153
4270
|
}
|
|
4154
4271
|
runPreview(input = {}, config = {}) {
|
|
@@ -4176,10 +4293,16 @@ class TaskGraph {
|
|
|
4176
4293
|
return this._dag.isAcyclic();
|
|
4177
4294
|
}
|
|
4178
4295
|
addTask(task, config) {
|
|
4179
|
-
|
|
4296
|
+
const t = ensureTask(task, config);
|
|
4297
|
+
t.parentGraph = this;
|
|
4298
|
+
return this._dag.addNode(t);
|
|
4180
4299
|
}
|
|
4181
4300
|
addTasks(tasks) {
|
|
4182
|
-
|
|
4301
|
+
const resolved = tasks.map(ensureTask);
|
|
4302
|
+
for (const t of resolved) {
|
|
4303
|
+
t.parentGraph = this;
|
|
4304
|
+
}
|
|
4305
|
+
return this._dag.addNodes(resolved);
|
|
4183
4306
|
}
|
|
4184
4307
|
addDataflow(dataflow) {
|
|
4185
4308
|
return this._dag.addEdge(dataflow.sourceTaskId, dataflow.targetTaskId, dataflow);
|
|
@@ -5001,8 +5124,7 @@ class Workflow {
|
|
|
5001
5124
|
parentSignal: this._abortController.signal,
|
|
5002
5125
|
outputCache: this._outputCache,
|
|
5003
5126
|
registry: config?.registry ?? this._registry,
|
|
5004
|
-
resourceScope: config?.resourceScope
|
|
5005
|
-
runWithPreviews: config?.runWithPreviews
|
|
5127
|
+
resourceScope: config?.resourceScope
|
|
5006
5128
|
});
|
|
5007
5129
|
const results = this.graph.mergeExecuteOutputsToRunOutput(output, PROPERTY_ARRAY);
|
|
5008
5130
|
this.events.emit("complete");
|
|
@@ -6083,6 +6205,8 @@ class FallbackTaskRunner extends GraphAsTaskRunner {
|
|
|
6083
6205
|
const totalAttempts = alternatives.length;
|
|
6084
6206
|
let currentAttemptIndex = 0;
|
|
6085
6207
|
const onSubgraphProgress = (innerProgress, message) => {
|
|
6208
|
+
if (innerProgress === undefined)
|
|
6209
|
+
return;
|
|
6086
6210
|
const blended = Math.round((currentAttemptIndex + innerProgress / 100) / totalAttempts * 100);
|
|
6087
6211
|
this.handleProgress(blended, message ?? `Data alternative ${currentAttemptIndex + 1}/${totalAttempts}`);
|
|
6088
6212
|
};
|
|
@@ -6456,7 +6580,7 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
|
|
|
6456
6580
|
this.task.emit("iteration_start", index, iterationCount);
|
|
6457
6581
|
const onGraphProgress = (p, message) => {
|
|
6458
6582
|
this.task.emit("iteration_progress", index, iterationCount, p, message);
|
|
6459
|
-
if (this.aggregatingParentMapProgress && this.mapPartialIterationCount > 0) {
|
|
6583
|
+
if (p !== undefined && this.aggregatingParentMapProgress && this.mapPartialIterationCount > 0) {
|
|
6460
6584
|
this.mapPartialProgress[index] = Math.max(this.mapPartialProgress[index] ?? 0, p);
|
|
6461
6585
|
this.emitMapParentProgressFromPartials(message);
|
|
6462
6586
|
}
|
|
@@ -7167,6 +7291,8 @@ class WhileTask extends GraphAsTask {
|
|
|
7167
7291
|
let currentOutput = {};
|
|
7168
7292
|
const effectiveMax = arrayAnalysis ? Math.min(this.maxIterations, arrayAnalysis.iterationCount) : this.maxIterations;
|
|
7169
7293
|
const onInnerGraphProgress = (innerProgress, innerMessage) => {
|
|
7294
|
+
if (innerProgress === undefined)
|
|
7295
|
+
return;
|
|
7170
7296
|
const blended = Math.min(Math.round((this._currentIteration + innerProgress / 100) / effectiveMax * 100), 99);
|
|
7171
7297
|
const message = innerMessage ? `Iteration ${this._currentIteration + 1}/${effectiveMax}: ${innerMessage}` : `Iteration ${this._currentIteration + 1}/${effectiveMax}`;
|
|
7172
7298
|
context.updateProgress(blended, message);
|
|
@@ -7242,6 +7368,8 @@ ${err.stack}`;
|
|
|
7242
7368
|
let currentOutput = {};
|
|
7243
7369
|
const effectiveMax = arrayAnalysis ? Math.min(this.maxIterations, arrayAnalysis.iterationCount) : this.maxIterations;
|
|
7244
7370
|
const onInnerGraphProgress = (innerProgress, innerMessage) => {
|
|
7371
|
+
if (innerProgress === undefined)
|
|
7372
|
+
return;
|
|
7245
7373
|
const blended = Math.min(Math.round((this._currentIteration + innerProgress / 100) / effectiveMax * 100), 99);
|
|
7246
7374
|
const message = innerMessage ? `Iteration ${this._currentIteration + 1}/${effectiveMax}: ${innerMessage}` : `Iteration ${this._currentIteration + 1}/${effectiveMax}`;
|
|
7247
7375
|
context.updateProgress(blended, message);
|
|
@@ -8877,8 +9005,6 @@ function installDevToolsFormatters() {
|
|
|
8877
9005
|
window.devtoolsFormatters = window.devtoolsFormatters || [];
|
|
8878
9006
|
window.devtoolsFormatters.push(new WorkflowAPIConsoleFormatter, new CreateWorkflowConsoleFormatter, new WorkflowConsoleFormatter, new TaskConsoleFormatter, new ReactElementConsoleFormatter, new DataflowConsoleFormatter, new DAGConsoleFormatter);
|
|
8879
9007
|
}
|
|
8880
|
-
// src/browser.ts
|
|
8881
|
-
registerRefcountablePredicate((v) => !!v && typeof v === "object" && ("backend" in v) && ("retain" in v) && ("release" in v) && ("materialize" in v));
|
|
8882
9008
|
export {
|
|
8883
9009
|
wrapSchemaInArray,
|
|
8884
9010
|
whileTaskConfigSchema,
|
|
@@ -8901,7 +9027,6 @@ export {
|
|
|
8901
9027
|
resolveIterationBound,
|
|
8902
9028
|
resetMethodNameCache,
|
|
8903
9029
|
removeIterationProperties,
|
|
8904
|
-
registerRefcountablePredicate,
|
|
8905
9030
|
registerPortCodec,
|
|
8906
9031
|
registerJobQueueFactory,
|
|
8907
9032
|
registerBuiltInTransforms,
|
|
@@ -8987,11 +9112,9 @@ export {
|
|
|
8987
9112
|
calculateNodeDepths,
|
|
8988
9113
|
buildIterationInputSchema,
|
|
8989
9114
|
autoConnect,
|
|
8990
|
-
asRefcountable,
|
|
8991
9115
|
addIterationContextToSchema,
|
|
8992
9116
|
addBoundaryNodesToGraphJson,
|
|
8993
9117
|
addBoundaryNodesToDependencyJson,
|
|
8994
|
-
_resetRefcountablePredicatesForTests,
|
|
8995
9118
|
_resetPortCodecsForTests,
|
|
8996
9119
|
WorkflowError,
|
|
8997
9120
|
Workflow,
|
|
@@ -9066,4 +9189,4 @@ export {
|
|
|
9066
9189
|
BROWSER_GRANTS
|
|
9067
9190
|
};
|
|
9068
9191
|
|
|
9069
|
-
//# debugId=
|
|
9192
|
+
//# debugId=D6E121D6994748F964756E2164756E21
|