modelfusion 0.53.0 → 0.53.1
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/model-function/executeStreamCall.cjs +72 -35
- package/model-function/executeStreamCall.js +72 -35
- package/package.json +1 -1
- package/util/AsyncQueue.cjs +26 -11
- package/util/AsyncQueue.d.ts +2 -0
- package/util/AsyncQueue.js +26 -11
- package/util/AsyncQueue.test.cjs +1 -1
- package/util/AsyncQueue.test.js +1 -1
- package/util/delay.cjs +2 -2
- package/util/delay.d.ts +1 -1
- package/util/delay.js +2 -2
- package/util/index.cjs +1 -0
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
@@ -55,53 +55,90 @@ async function executeStreamCall({ model, options, input, functionType, startStr
|
|
55
55
|
const responseQueue = new AsyncQueue_js_1.AsyncQueue();
|
56
56
|
// run async:
|
57
57
|
(async function () {
|
58
|
-
|
59
|
-
|
60
|
-
const
|
58
|
+
try {
|
59
|
+
const loopResult = await (0, runSafe_js_1.runSafe)(async () => {
|
60
|
+
for await (const event of deltaIterable) {
|
61
|
+
if (event?.type === "error") {
|
62
|
+
const error = event.error;
|
63
|
+
const finishMetadata = {
|
64
|
+
eventType: "finished",
|
65
|
+
...startMetadata,
|
66
|
+
finishTimestamp: new Date(),
|
67
|
+
durationInMs: durationMeasurement.durationInMs,
|
68
|
+
};
|
69
|
+
eventSource.notify(error instanceof AbortError_js_1.AbortError
|
70
|
+
? {
|
71
|
+
...finishMetadata,
|
72
|
+
result: { status: "abort" },
|
73
|
+
}
|
74
|
+
: {
|
75
|
+
...finishMetadata,
|
76
|
+
result: { status: "error", error },
|
77
|
+
});
|
78
|
+
throw error;
|
79
|
+
}
|
80
|
+
if (event?.type === "delta") {
|
81
|
+
const value = processDelta(event);
|
82
|
+
if (value !== undefined) {
|
83
|
+
responseQueue.push(value);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
if (processFinished != null) {
|
88
|
+
const value = processFinished();
|
89
|
+
if (value !== undefined) {
|
90
|
+
responseQueue.push(value);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
});
|
94
|
+
// deal with abort or errors that happened during streaming:
|
95
|
+
if (!loopResult.ok) {
|
61
96
|
const finishMetadata = {
|
62
97
|
eventType: "finished",
|
63
98
|
...startMetadata,
|
64
99
|
finishTimestamp: new Date(),
|
65
100
|
durationInMs: durationMeasurement.durationInMs,
|
66
101
|
};
|
67
|
-
|
68
|
-
|
69
|
-
...finishMetadata,
|
70
|
-
result: { status: "abort" },
|
71
|
-
}
|
72
|
-
: {
|
102
|
+
if (loopResult.isAborted) {
|
103
|
+
eventSource.notify({
|
73
104
|
...finishMetadata,
|
74
|
-
|
105
|
+
eventType: "finished",
|
106
|
+
result: {
|
107
|
+
status: "abort",
|
108
|
+
},
|
75
109
|
});
|
76
|
-
|
77
|
-
|
78
|
-
if (event?.type === "delta") {
|
79
|
-
const value = processDelta(event);
|
80
|
-
if (value !== undefined) {
|
81
|
-
responseQueue.push(value);
|
110
|
+
responseQueue.error(new AbortError_js_1.AbortError());
|
111
|
+
return; // error is handled through queue
|
82
112
|
}
|
113
|
+
eventSource.notify({
|
114
|
+
...finishMetadata,
|
115
|
+
eventType: "finished",
|
116
|
+
result: {
|
117
|
+
status: "error",
|
118
|
+
error: loopResult.error,
|
119
|
+
},
|
120
|
+
});
|
121
|
+
responseQueue.error(loopResult.error);
|
122
|
+
return; // error is handled through queue
|
83
123
|
}
|
124
|
+
const finishMetadata = {
|
125
|
+
eventType: "finished",
|
126
|
+
...startMetadata,
|
127
|
+
finishTimestamp: new Date(),
|
128
|
+
durationInMs: durationMeasurement.durationInMs,
|
129
|
+
};
|
130
|
+
eventSource.notify({
|
131
|
+
...finishMetadata,
|
132
|
+
result: {
|
133
|
+
status: "success",
|
134
|
+
...getResult(),
|
135
|
+
},
|
136
|
+
});
|
84
137
|
}
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
responseQueue.push(value);
|
89
|
-
}
|
138
|
+
finally {
|
139
|
+
// always close the queue when done, no matter where a potential error happened:
|
140
|
+
responseQueue.close();
|
90
141
|
}
|
91
|
-
responseQueue.close();
|
92
|
-
const finishMetadata = {
|
93
|
-
eventType: "finished",
|
94
|
-
...startMetadata,
|
95
|
-
finishTimestamp: new Date(),
|
96
|
-
durationInMs: durationMeasurement.durationInMs,
|
97
|
-
};
|
98
|
-
eventSource.notify({
|
99
|
-
...finishMetadata,
|
100
|
-
result: {
|
101
|
-
status: "success",
|
102
|
-
...getResult(),
|
103
|
-
},
|
104
|
-
});
|
105
142
|
})();
|
106
143
|
return responseQueue;
|
107
144
|
});
|
@@ -52,53 +52,90 @@ export async function executeStreamCall({ model, options, input, functionType, s
|
|
52
52
|
const responseQueue = new AsyncQueue();
|
53
53
|
// run async:
|
54
54
|
(async function () {
|
55
|
-
|
56
|
-
|
57
|
-
const
|
55
|
+
try {
|
56
|
+
const loopResult = await runSafe(async () => {
|
57
|
+
for await (const event of deltaIterable) {
|
58
|
+
if (event?.type === "error") {
|
59
|
+
const error = event.error;
|
60
|
+
const finishMetadata = {
|
61
|
+
eventType: "finished",
|
62
|
+
...startMetadata,
|
63
|
+
finishTimestamp: new Date(),
|
64
|
+
durationInMs: durationMeasurement.durationInMs,
|
65
|
+
};
|
66
|
+
eventSource.notify(error instanceof AbortError
|
67
|
+
? {
|
68
|
+
...finishMetadata,
|
69
|
+
result: { status: "abort" },
|
70
|
+
}
|
71
|
+
: {
|
72
|
+
...finishMetadata,
|
73
|
+
result: { status: "error", error },
|
74
|
+
});
|
75
|
+
throw error;
|
76
|
+
}
|
77
|
+
if (event?.type === "delta") {
|
78
|
+
const value = processDelta(event);
|
79
|
+
if (value !== undefined) {
|
80
|
+
responseQueue.push(value);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
if (processFinished != null) {
|
85
|
+
const value = processFinished();
|
86
|
+
if (value !== undefined) {
|
87
|
+
responseQueue.push(value);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
});
|
91
|
+
// deal with abort or errors that happened during streaming:
|
92
|
+
if (!loopResult.ok) {
|
58
93
|
const finishMetadata = {
|
59
94
|
eventType: "finished",
|
60
95
|
...startMetadata,
|
61
96
|
finishTimestamp: new Date(),
|
62
97
|
durationInMs: durationMeasurement.durationInMs,
|
63
98
|
};
|
64
|
-
|
65
|
-
|
66
|
-
...finishMetadata,
|
67
|
-
result: { status: "abort" },
|
68
|
-
}
|
69
|
-
: {
|
99
|
+
if (loopResult.isAborted) {
|
100
|
+
eventSource.notify({
|
70
101
|
...finishMetadata,
|
71
|
-
|
102
|
+
eventType: "finished",
|
103
|
+
result: {
|
104
|
+
status: "abort",
|
105
|
+
},
|
72
106
|
});
|
73
|
-
|
74
|
-
|
75
|
-
if (event?.type === "delta") {
|
76
|
-
const value = processDelta(event);
|
77
|
-
if (value !== undefined) {
|
78
|
-
responseQueue.push(value);
|
107
|
+
responseQueue.error(new AbortError());
|
108
|
+
return; // error is handled through queue
|
79
109
|
}
|
110
|
+
eventSource.notify({
|
111
|
+
...finishMetadata,
|
112
|
+
eventType: "finished",
|
113
|
+
result: {
|
114
|
+
status: "error",
|
115
|
+
error: loopResult.error,
|
116
|
+
},
|
117
|
+
});
|
118
|
+
responseQueue.error(loopResult.error);
|
119
|
+
return; // error is handled through queue
|
80
120
|
}
|
121
|
+
const finishMetadata = {
|
122
|
+
eventType: "finished",
|
123
|
+
...startMetadata,
|
124
|
+
finishTimestamp: new Date(),
|
125
|
+
durationInMs: durationMeasurement.durationInMs,
|
126
|
+
};
|
127
|
+
eventSource.notify({
|
128
|
+
...finishMetadata,
|
129
|
+
result: {
|
130
|
+
status: "success",
|
131
|
+
...getResult(),
|
132
|
+
},
|
133
|
+
});
|
81
134
|
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
responseQueue.push(value);
|
86
|
-
}
|
135
|
+
finally {
|
136
|
+
// always close the queue when done, no matter where a potential error happened:
|
137
|
+
responseQueue.close();
|
87
138
|
}
|
88
|
-
responseQueue.close();
|
89
|
-
const finishMetadata = {
|
90
|
-
eventType: "finished",
|
91
|
-
...startMetadata,
|
92
|
-
finishTimestamp: new Date(),
|
93
|
-
durationInMs: durationMeasurement.durationInMs,
|
94
|
-
};
|
95
|
-
eventSource.notify({
|
96
|
-
...finishMetadata,
|
97
|
-
result: {
|
98
|
-
status: "success",
|
99
|
-
...getResult(),
|
100
|
-
},
|
101
|
-
});
|
102
139
|
})();
|
103
140
|
return responseQueue;
|
104
141
|
});
|
package/package.json
CHANGED
package/util/AsyncQueue.cjs
CHANGED
@@ -22,7 +22,7 @@ class AsyncQueue {
|
|
22
22
|
enumerable: true,
|
23
23
|
configurable: true,
|
24
24
|
writable: true,
|
25
|
-
value:
|
25
|
+
value: Array()
|
26
26
|
});
|
27
27
|
Object.defineProperty(this, "pendingResolvers", {
|
28
28
|
enumerable: true,
|
@@ -37,6 +37,11 @@ class AsyncQueue {
|
|
37
37
|
value: false
|
38
38
|
});
|
39
39
|
}
|
40
|
+
processPendingResolvers() {
|
41
|
+
while (this.pendingResolvers.length > 0) {
|
42
|
+
this.pendingResolvers.shift()?.();
|
43
|
+
}
|
44
|
+
}
|
40
45
|
/**
|
41
46
|
* Pushes an element onto the queue. If the queue is closed, an error is thrown.
|
42
47
|
*
|
@@ -47,12 +52,17 @@ class AsyncQueue {
|
|
47
52
|
*/
|
48
53
|
push(value) {
|
49
54
|
if (this.closed) {
|
50
|
-
throw new Error("Cannot push value to closed queue.
|
55
|
+
throw new Error("Cannot push value to closed queue.");
|
51
56
|
}
|
52
|
-
this.values.push(value);
|
53
|
-
|
54
|
-
|
57
|
+
this.values.push({ type: "value", value });
|
58
|
+
this.processPendingResolvers();
|
59
|
+
}
|
60
|
+
error(error) {
|
61
|
+
if (this.closed) {
|
62
|
+
throw new Error("Cannot push error to closed queue.");
|
55
63
|
}
|
64
|
+
this.values.push({ type: "error", error });
|
65
|
+
this.processPendingResolvers();
|
56
66
|
}
|
57
67
|
/**
|
58
68
|
* Closes the queue, preventing more elements from being pushed onto it.
|
@@ -62,9 +72,7 @@ class AsyncQueue {
|
|
62
72
|
*/
|
63
73
|
close() {
|
64
74
|
this.closed = true;
|
65
|
-
|
66
|
-
this.pendingResolvers.shift()?.();
|
67
|
-
}
|
75
|
+
this.processPendingResolvers();
|
68
76
|
}
|
69
77
|
/**
|
70
78
|
* Creates and returns an async iterator that allows the queue to be consumed.
|
@@ -81,11 +89,18 @@ class AsyncQueue {
|
|
81
89
|
[Symbol.asyncIterator]() {
|
82
90
|
let position = 0;
|
83
91
|
return {
|
84
|
-
next: () => new Promise((resolve) => {
|
92
|
+
next: () => new Promise((resolve, reject) => {
|
85
93
|
const attemptResolve = () => {
|
86
94
|
if (position < this.values.length) {
|
87
|
-
|
88
|
-
|
95
|
+
const entry = this.values[position++];
|
96
|
+
switch (entry.type) {
|
97
|
+
case "value":
|
98
|
+
resolve({ value: entry.value, done: false });
|
99
|
+
break;
|
100
|
+
case "error":
|
101
|
+
reject(entry.error);
|
102
|
+
break;
|
103
|
+
}
|
89
104
|
}
|
90
105
|
else if (this.closed) {
|
91
106
|
// The queue is closed, and there are no more values. Complete the iteration.
|
package/util/AsyncQueue.d.ts
CHANGED
@@ -17,6 +17,7 @@ export declare class AsyncQueue<T> implements AsyncIterable<T> {
|
|
17
17
|
private values;
|
18
18
|
private pendingResolvers;
|
19
19
|
private closed;
|
20
|
+
private processPendingResolvers;
|
20
21
|
/**
|
21
22
|
* Pushes an element onto the queue. If the queue is closed, an error is thrown.
|
22
23
|
*
|
@@ -26,6 +27,7 @@ export declare class AsyncQueue<T> implements AsyncIterable<T> {
|
|
26
27
|
* queue.push(2);
|
27
28
|
*/
|
28
29
|
push(value: T): void;
|
30
|
+
error(error: unknown): void;
|
29
31
|
/**
|
30
32
|
* Closes the queue, preventing more elements from being pushed onto it.
|
31
33
|
*
|
package/util/AsyncQueue.js
CHANGED
@@ -19,7 +19,7 @@ export class AsyncQueue {
|
|
19
19
|
enumerable: true,
|
20
20
|
configurable: true,
|
21
21
|
writable: true,
|
22
|
-
value:
|
22
|
+
value: Array()
|
23
23
|
});
|
24
24
|
Object.defineProperty(this, "pendingResolvers", {
|
25
25
|
enumerable: true,
|
@@ -34,6 +34,11 @@ export class AsyncQueue {
|
|
34
34
|
value: false
|
35
35
|
});
|
36
36
|
}
|
37
|
+
processPendingResolvers() {
|
38
|
+
while (this.pendingResolvers.length > 0) {
|
39
|
+
this.pendingResolvers.shift()?.();
|
40
|
+
}
|
41
|
+
}
|
37
42
|
/**
|
38
43
|
* Pushes an element onto the queue. If the queue is closed, an error is thrown.
|
39
44
|
*
|
@@ -44,12 +49,17 @@ export class AsyncQueue {
|
|
44
49
|
*/
|
45
50
|
push(value) {
|
46
51
|
if (this.closed) {
|
47
|
-
throw new Error("Cannot push value to closed queue.
|
52
|
+
throw new Error("Cannot push value to closed queue.");
|
48
53
|
}
|
49
|
-
this.values.push(value);
|
50
|
-
|
51
|
-
|
54
|
+
this.values.push({ type: "value", value });
|
55
|
+
this.processPendingResolvers();
|
56
|
+
}
|
57
|
+
error(error) {
|
58
|
+
if (this.closed) {
|
59
|
+
throw new Error("Cannot push error to closed queue.");
|
52
60
|
}
|
61
|
+
this.values.push({ type: "error", error });
|
62
|
+
this.processPendingResolvers();
|
53
63
|
}
|
54
64
|
/**
|
55
65
|
* Closes the queue, preventing more elements from being pushed onto it.
|
@@ -59,9 +69,7 @@ export class AsyncQueue {
|
|
59
69
|
*/
|
60
70
|
close() {
|
61
71
|
this.closed = true;
|
62
|
-
|
63
|
-
this.pendingResolvers.shift()?.();
|
64
|
-
}
|
72
|
+
this.processPendingResolvers();
|
65
73
|
}
|
66
74
|
/**
|
67
75
|
* Creates and returns an async iterator that allows the queue to be consumed.
|
@@ -78,11 +86,18 @@ export class AsyncQueue {
|
|
78
86
|
[Symbol.asyncIterator]() {
|
79
87
|
let position = 0;
|
80
88
|
return {
|
81
|
-
next: () => new Promise((resolve) => {
|
89
|
+
next: () => new Promise((resolve, reject) => {
|
82
90
|
const attemptResolve = () => {
|
83
91
|
if (position < this.values.length) {
|
84
|
-
|
85
|
-
|
92
|
+
const entry = this.values[position++];
|
93
|
+
switch (entry.type) {
|
94
|
+
case "value":
|
95
|
+
resolve({ value: entry.value, done: false });
|
96
|
+
break;
|
97
|
+
case "error":
|
98
|
+
reject(entry.error);
|
99
|
+
break;
|
100
|
+
}
|
86
101
|
}
|
87
102
|
else if (this.closed) {
|
88
103
|
// The queue is closed, and there are no more values. Complete the iteration.
|
package/util/AsyncQueue.test.cjs
CHANGED
@@ -134,5 +134,5 @@ const AsyncQueue_js_1 = require("./AsyncQueue.cjs");
|
|
134
134
|
(0, vitest_1.test)("throw error when pushing to a closed queue", async () => {
|
135
135
|
const asyncQueue = new AsyncQueue_js_1.AsyncQueue();
|
136
136
|
asyncQueue.close();
|
137
|
-
(0, vitest_1.expect)(() => asyncQueue.push(1)).toThrowError("Cannot push value to closed queue.
|
137
|
+
(0, vitest_1.expect)(() => asyncQueue.push(1)).toThrowError("Cannot push value to closed queue.");
|
138
138
|
});
|
package/util/AsyncQueue.test.js
CHANGED
@@ -132,5 +132,5 @@ test("each consumer receives all pushed values under varying conditions", async
|
|
132
132
|
test("throw error when pushing to a closed queue", async () => {
|
133
133
|
const asyncQueue = new AsyncQueue();
|
134
134
|
asyncQueue.close();
|
135
|
-
expect(() => asyncQueue.push(1)).toThrowError("Cannot push value to closed queue.
|
135
|
+
expect(() => asyncQueue.push(1)).toThrowError("Cannot push value to closed queue.");
|
136
136
|
});
|
package/util/delay.cjs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.delay = void 0;
|
4
|
-
async function delay(
|
5
|
-
return new Promise((resolve) => setTimeout(resolve,
|
4
|
+
async function delay(delayInMs) {
|
5
|
+
return new Promise((resolve) => setTimeout(resolve, delayInMs));
|
6
6
|
}
|
7
7
|
exports.delay = delay;
|
package/util/delay.d.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export declare function delay(
|
1
|
+
export declare function delay(delayInMs: number): Promise<void>;
|
package/util/delay.js
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
export async function delay(
|
2
|
-
return new Promise((resolve) => setTimeout(resolve,
|
1
|
+
export async function delay(delayInMs) {
|
2
|
+
return new Promise((resolve) => setTimeout(resolve, delayInMs));
|
3
3
|
}
|
package/util/index.cjs
CHANGED
@@ -17,5 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./AsyncQueue.cjs"), exports);
|
18
18
|
__exportStar(require("./JSONParseError.cjs"), exports);
|
19
19
|
__exportStar(require("./cosineSimilarity.cjs"), exports);
|
20
|
+
__exportStar(require("./delay.cjs"), exports);
|
20
21
|
__exportStar(require("./getAudioFileExtension.cjs"), exports);
|
21
22
|
__exportStar(require("./parseJSON.cjs"), exports);
|
package/util/index.d.ts
CHANGED