modelfusion 0.53.2 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/browser/convertAudioChunksToBase64.cjs +8 -0
- package/browser/convertAudioChunksToBase64.d.ts +4 -0
- package/browser/convertAudioChunksToBase64.js +4 -0
- package/browser/convertBlobToBase64.cjs +23 -0
- package/browser/convertBlobToBase64.d.ts +1 -0
- package/browser/convertBlobToBase64.js +19 -0
- package/{ui → browser}/index.cjs +5 -0
- package/browser/index.d.ts +6 -0
- package/browser/index.js +6 -0
- package/browser/invokeFlow.cjs +23 -0
- package/browser/invokeFlow.d.ts +8 -0
- package/browser/invokeFlow.js +19 -0
- package/{event-source → browser}/readEventSource.cjs +8 -3
- package/{event-source → browser}/readEventSource.d.ts +3 -1
- package/{event-source → browser}/readEventSource.js +8 -3
- package/{event-source → browser}/readEventSourceStream.cjs +1 -1
- package/{event-source → browser}/readEventSourceStream.js +1 -1
- package/event-source/createEventSourceStream.cjs +7 -3
- package/event-source/createEventSourceStream.js +7 -3
- package/event-source/index.cjs +0 -2
- package/event-source/index.d.ts +0 -2
- package/event-source/index.js +0 -2
- package/index.cjs +0 -1
- package/index.d.ts +0 -1
- package/index.js +0 -1
- package/package.json +13 -4
- package/server/fastify/AssetStorage.cjs +2 -0
- package/server/fastify/AssetStorage.d.ts +17 -0
- package/server/fastify/AssetStorage.js +1 -0
- package/server/fastify/DefaultFlow.cjs +22 -0
- package/server/fastify/DefaultFlow.d.ts +16 -0
- package/server/fastify/DefaultFlow.js +18 -0
- package/server/fastify/FileSystemAssetStorage.cjs +60 -0
- package/server/fastify/FileSystemAssetStorage.d.ts +19 -0
- package/server/fastify/FileSystemAssetStorage.js +56 -0
- package/server/fastify/FileSystemLogger.cjs +48 -0
- package/server/fastify/FileSystemLogger.d.ts +18 -0
- package/server/fastify/FileSystemLogger.js +44 -0
- package/server/fastify/Flow.cjs +2 -0
- package/server/fastify/Flow.d.ts +9 -0
- package/server/fastify/Flow.js +1 -0
- package/server/fastify/FlowRun.cjs +71 -0
- package/server/fastify/FlowRun.d.ts +28 -0
- package/server/fastify/FlowRun.js +67 -0
- package/server/fastify/FlowSchema.cjs +2 -0
- package/server/fastify/FlowSchema.d.ts +5 -0
- package/server/fastify/FlowSchema.js +1 -0
- package/server/fastify/Logger.cjs +2 -0
- package/server/fastify/Logger.d.ts +13 -0
- package/server/fastify/Logger.js +1 -0
- package/server/fastify/PathProvider.cjs +34 -0
- package/server/fastify/PathProvider.d.ts +12 -0
- package/server/fastify/PathProvider.js +30 -0
- package/server/fastify/index.cjs +24 -0
- package/server/fastify/index.d.ts +8 -0
- package/server/fastify/index.js +8 -0
- package/server/fastify/modelFusionFlowPlugin.cjs +102 -0
- package/server/fastify/modelFusionFlowPlugin.d.ts +12 -0
- package/server/fastify/modelFusionFlowPlugin.js +98 -0
- package/ui/index.d.ts +0 -1
- package/ui/index.js +0 -1
- /package/{ui → browser}/MediaSourceAppender.cjs +0 -0
- /package/{ui → browser}/MediaSourceAppender.d.ts +0 -0
- /package/{ui → browser}/MediaSourceAppender.js +0 -0
- /package/{event-source → browser}/readEventSourceStream.d.ts +0 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
import { promises as fs } from "node:fs";
|
2
|
+
import { join } from "node:path";
|
3
|
+
export class FileSystemLogger {
|
4
|
+
constructor({ path }) {
|
5
|
+
Object.defineProperty(this, "logPath", {
|
6
|
+
enumerable: true,
|
7
|
+
configurable: true,
|
8
|
+
writable: true,
|
9
|
+
value: void 0
|
10
|
+
});
|
11
|
+
this.logPath = path;
|
12
|
+
}
|
13
|
+
async logFunctionEvent({ run, event, }) {
|
14
|
+
const timestamp = event.startTimestamp.getTime();
|
15
|
+
try {
|
16
|
+
const logPath = this.logPath(run);
|
17
|
+
await fs.mkdir(logPath, { recursive: true });
|
18
|
+
await fs.writeFile(join(logPath, `${timestamp}-${event.callId}-${event.functionId ?? event.functionType}-${event.eventType}.json`), JSON.stringify(event));
|
19
|
+
}
|
20
|
+
catch (error) {
|
21
|
+
this.logError({
|
22
|
+
run,
|
23
|
+
message: `Failed to write function event ${event.callId}`,
|
24
|
+
error,
|
25
|
+
});
|
26
|
+
}
|
27
|
+
}
|
28
|
+
async logError(options) {
|
29
|
+
const timestamp = Date.now();
|
30
|
+
try {
|
31
|
+
const logPath = this.logPath(options.run);
|
32
|
+
return fs.writeFile(join(logPath, `${timestamp}-error.json`), JSON.stringify({
|
33
|
+
timestamp: new Date(timestamp).toISOString(),
|
34
|
+
runId: options.run.runId,
|
35
|
+
message: options.message,
|
36
|
+
error: options.error,
|
37
|
+
}));
|
38
|
+
}
|
39
|
+
catch (error) {
|
40
|
+
console.error(`Failed to write error log`);
|
41
|
+
console.error(error);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,71 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.FlowRun = void 0;
|
4
|
+
const DefaultRun_js_1 = require("../../core/DefaultRun.cjs");
|
5
|
+
const AsyncQueue_js_1 = require("../../util/AsyncQueue.cjs");
|
6
|
+
class FlowRun extends DefaultRun_js_1.DefaultRun {
|
7
|
+
constructor({ paths, assetStorage, logger, }) {
|
8
|
+
super();
|
9
|
+
Object.defineProperty(this, "eventQueue", {
|
10
|
+
enumerable: true,
|
11
|
+
configurable: true,
|
12
|
+
writable: true,
|
13
|
+
value: new AsyncQueue_js_1.AsyncQueue()
|
14
|
+
});
|
15
|
+
Object.defineProperty(this, "assetStorage", {
|
16
|
+
enumerable: true,
|
17
|
+
configurable: true,
|
18
|
+
writable: true,
|
19
|
+
value: void 0
|
20
|
+
});
|
21
|
+
Object.defineProperty(this, "logger", {
|
22
|
+
enumerable: true,
|
23
|
+
configurable: true,
|
24
|
+
writable: true,
|
25
|
+
value: void 0
|
26
|
+
});
|
27
|
+
Object.defineProperty(this, "paths", {
|
28
|
+
enumerable: true,
|
29
|
+
configurable: true,
|
30
|
+
writable: true,
|
31
|
+
value: void 0
|
32
|
+
});
|
33
|
+
Object.defineProperty(this, "functionObserver", {
|
34
|
+
enumerable: true,
|
35
|
+
configurable: true,
|
36
|
+
writable: true,
|
37
|
+
value: {
|
38
|
+
onFunctionEvent: async (event) => {
|
39
|
+
this.logger.logFunctionEvent({
|
40
|
+
run: this,
|
41
|
+
event,
|
42
|
+
});
|
43
|
+
},
|
44
|
+
}
|
45
|
+
});
|
46
|
+
this.paths = paths;
|
47
|
+
this.assetStorage = assetStorage;
|
48
|
+
this.logger = logger;
|
49
|
+
}
|
50
|
+
publishEvent(event) {
|
51
|
+
this.eventQueue.push(event);
|
52
|
+
}
|
53
|
+
async storeBinaryAsset(asset) {
|
54
|
+
await this.assetStorage.storeAsset({
|
55
|
+
run: this,
|
56
|
+
asset,
|
57
|
+
});
|
58
|
+
return this.paths.getAssetUrl(this.runId, asset.name);
|
59
|
+
}
|
60
|
+
async storeTextAsset(asset) {
|
61
|
+
return this.storeBinaryAsset({
|
62
|
+
data: Buffer.from(asset.text),
|
63
|
+
contentType: asset.contentType,
|
64
|
+
name: asset.name,
|
65
|
+
});
|
66
|
+
}
|
67
|
+
finish() {
|
68
|
+
this.eventQueue.close();
|
69
|
+
}
|
70
|
+
}
|
71
|
+
exports.FlowRun = FlowRun;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { DefaultRun } from "../../core/DefaultRun.js";
|
2
|
+
import { FunctionEvent } from "../../core/FunctionEvent.js";
|
3
|
+
import { AsyncQueue } from "../../util/AsyncQueue.js";
|
4
|
+
import { Asset, AssetStorage } from "./AssetStorage.js";
|
5
|
+
import { Logger } from "./Logger.js";
|
6
|
+
import { PathProvider } from "./PathProvider.js";
|
7
|
+
export declare class FlowRun<EVENT> extends DefaultRun {
|
8
|
+
readonly eventQueue: AsyncQueue<EVENT>;
|
9
|
+
private readonly assetStorage;
|
10
|
+
private readonly logger;
|
11
|
+
private readonly paths;
|
12
|
+
constructor({ paths, assetStorage, logger, }: {
|
13
|
+
paths: PathProvider;
|
14
|
+
assetStorage: AssetStorage;
|
15
|
+
logger: Logger;
|
16
|
+
});
|
17
|
+
readonly functionObserver: {
|
18
|
+
onFunctionEvent: (event: FunctionEvent) => Promise<void>;
|
19
|
+
};
|
20
|
+
publishEvent(event: EVENT): void;
|
21
|
+
storeBinaryAsset(asset: Asset): Promise<string>;
|
22
|
+
storeTextAsset(asset: {
|
23
|
+
text: string;
|
24
|
+
contentType: string;
|
25
|
+
name: string;
|
26
|
+
}): Promise<string>;
|
27
|
+
finish(): void;
|
28
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { DefaultRun } from "../../core/DefaultRun.js";
|
2
|
+
import { AsyncQueue } from "../../util/AsyncQueue.js";
|
3
|
+
export class FlowRun extends DefaultRun {
|
4
|
+
constructor({ paths, assetStorage, logger, }) {
|
5
|
+
super();
|
6
|
+
Object.defineProperty(this, "eventQueue", {
|
7
|
+
enumerable: true,
|
8
|
+
configurable: true,
|
9
|
+
writable: true,
|
10
|
+
value: new AsyncQueue()
|
11
|
+
});
|
12
|
+
Object.defineProperty(this, "assetStorage", {
|
13
|
+
enumerable: true,
|
14
|
+
configurable: true,
|
15
|
+
writable: true,
|
16
|
+
value: void 0
|
17
|
+
});
|
18
|
+
Object.defineProperty(this, "logger", {
|
19
|
+
enumerable: true,
|
20
|
+
configurable: true,
|
21
|
+
writable: true,
|
22
|
+
value: void 0
|
23
|
+
});
|
24
|
+
Object.defineProperty(this, "paths", {
|
25
|
+
enumerable: true,
|
26
|
+
configurable: true,
|
27
|
+
writable: true,
|
28
|
+
value: void 0
|
29
|
+
});
|
30
|
+
Object.defineProperty(this, "functionObserver", {
|
31
|
+
enumerable: true,
|
32
|
+
configurable: true,
|
33
|
+
writable: true,
|
34
|
+
value: {
|
35
|
+
onFunctionEvent: async (event) => {
|
36
|
+
this.logger.logFunctionEvent({
|
37
|
+
run: this,
|
38
|
+
event,
|
39
|
+
});
|
40
|
+
},
|
41
|
+
}
|
42
|
+
});
|
43
|
+
this.paths = paths;
|
44
|
+
this.assetStorage = assetStorage;
|
45
|
+
this.logger = logger;
|
46
|
+
}
|
47
|
+
publishEvent(event) {
|
48
|
+
this.eventQueue.push(event);
|
49
|
+
}
|
50
|
+
async storeBinaryAsset(asset) {
|
51
|
+
await this.assetStorage.storeAsset({
|
52
|
+
run: this,
|
53
|
+
asset,
|
54
|
+
});
|
55
|
+
return this.paths.getAssetUrl(this.runId, asset.name);
|
56
|
+
}
|
57
|
+
async storeTextAsset(asset) {
|
58
|
+
return this.storeBinaryAsset({
|
59
|
+
data: Buffer.from(asset.text),
|
60
|
+
contentType: asset.contentType,
|
61
|
+
name: asset.name,
|
62
|
+
});
|
63
|
+
}
|
64
|
+
finish() {
|
65
|
+
this.eventQueue.close();
|
66
|
+
}
|
67
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { FunctionEvent } from "../../core/FunctionEvent.js";
|
2
|
+
import { FlowRun } from "./FlowRun.js";
|
3
|
+
export interface Logger {
|
4
|
+
logFunctionEvent(options: {
|
5
|
+
run: FlowRun<unknown>;
|
6
|
+
event: FunctionEvent;
|
7
|
+
}): Promise<void>;
|
8
|
+
logError(options: {
|
9
|
+
run: FlowRun<unknown>;
|
10
|
+
message: string;
|
11
|
+
error: unknown;
|
12
|
+
}): Promise<void>;
|
13
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.PathProvider = void 0;
|
4
|
+
class PathProvider {
|
5
|
+
constructor({ baseUrl, basePath }) {
|
6
|
+
Object.defineProperty(this, "baseUrl", {
|
7
|
+
enumerable: true,
|
8
|
+
configurable: true,
|
9
|
+
writable: true,
|
10
|
+
value: void 0
|
11
|
+
});
|
12
|
+
Object.defineProperty(this, "basePath", {
|
13
|
+
enumerable: true,
|
14
|
+
configurable: true,
|
15
|
+
writable: true,
|
16
|
+
value: void 0
|
17
|
+
});
|
18
|
+
this.baseUrl = baseUrl;
|
19
|
+
this.basePath = basePath;
|
20
|
+
}
|
21
|
+
getAssetUrl(runId, assetName) {
|
22
|
+
return `${this.baseUrl}${this.basePath}/${runId}/assets/${assetName}`;
|
23
|
+
}
|
24
|
+
getAssetPathTemplate() {
|
25
|
+
return `${this.basePath}/:runId/assets/:assetName`;
|
26
|
+
}
|
27
|
+
getEventsUrl(runId) {
|
28
|
+
return `${this.baseUrl}${this.basePath}/${runId}/events`;
|
29
|
+
}
|
30
|
+
getEventsPathTemplate() {
|
31
|
+
return `${this.basePath}/:runId/events`;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
exports.PathProvider = PathProvider;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export declare class PathProvider {
|
2
|
+
readonly baseUrl: string;
|
3
|
+
readonly basePath: string;
|
4
|
+
constructor({ baseUrl, basePath }: {
|
5
|
+
baseUrl: string;
|
6
|
+
basePath: string;
|
7
|
+
});
|
8
|
+
getAssetUrl(runId: string, assetName: string): string;
|
9
|
+
getAssetPathTemplate(): string;
|
10
|
+
getEventsUrl(runId: string): string;
|
11
|
+
getEventsPathTemplate(): string;
|
12
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
export class PathProvider {
|
2
|
+
constructor({ baseUrl, basePath }) {
|
3
|
+
Object.defineProperty(this, "baseUrl", {
|
4
|
+
enumerable: true,
|
5
|
+
configurable: true,
|
6
|
+
writable: true,
|
7
|
+
value: void 0
|
8
|
+
});
|
9
|
+
Object.defineProperty(this, "basePath", {
|
10
|
+
enumerable: true,
|
11
|
+
configurable: true,
|
12
|
+
writable: true,
|
13
|
+
value: void 0
|
14
|
+
});
|
15
|
+
this.baseUrl = baseUrl;
|
16
|
+
this.basePath = basePath;
|
17
|
+
}
|
18
|
+
getAssetUrl(runId, assetName) {
|
19
|
+
return `${this.baseUrl}${this.basePath}/${runId}/assets/${assetName}`;
|
20
|
+
}
|
21
|
+
getAssetPathTemplate() {
|
22
|
+
return `${this.basePath}/:runId/assets/:assetName`;
|
23
|
+
}
|
24
|
+
getEventsUrl(runId) {
|
25
|
+
return `${this.baseUrl}${this.basePath}/${runId}/events`;
|
26
|
+
}
|
27
|
+
getEventsPathTemplate() {
|
28
|
+
return `${this.basePath}/:runId/events`;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./AssetStorage.cjs"), exports);
|
18
|
+
__exportStar(require("./DefaultFlow.cjs"), exports);
|
19
|
+
__exportStar(require("./FileSystemAssetStorage.cjs"), exports);
|
20
|
+
__exportStar(require("./FileSystemLogger.cjs"), exports);
|
21
|
+
__exportStar(require("./Flow.cjs"), exports);
|
22
|
+
__exportStar(require("./FlowRun.cjs"), exports);
|
23
|
+
__exportStar(require("./Logger.cjs"), exports);
|
24
|
+
__exportStar(require("./modelFusionFlowPlugin.cjs"), exports);
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export * from "./AssetStorage.js";
|
2
|
+
export * from "./DefaultFlow.js";
|
3
|
+
export * from "./FileSystemAssetStorage.js";
|
4
|
+
export * from "./FileSystemLogger.js";
|
5
|
+
export * from "./Flow.js";
|
6
|
+
export * from "./FlowRun.js";
|
7
|
+
export * from "./Logger.js";
|
8
|
+
export * from "./modelFusionFlowPlugin.js";
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export * from "./AssetStorage.js";
|
2
|
+
export * from "./DefaultFlow.js";
|
3
|
+
export * from "./FileSystemAssetStorage.js";
|
4
|
+
export * from "./FileSystemLogger.js";
|
5
|
+
export * from "./Flow.js";
|
6
|
+
export * from "./FlowRun.js";
|
7
|
+
export * from "./Logger.js";
|
8
|
+
export * from "./modelFusionFlowPlugin.js";
|
@@ -0,0 +1,102 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.modelFusionFastifyPlugin = void 0;
|
4
|
+
const getRun_js_1 = require("../../core/getRun.cjs");
|
5
|
+
const FlowRun_js_1 = require("./FlowRun.cjs");
|
6
|
+
const PathProvider_js_1 = require("./PathProvider.cjs");
|
7
|
+
const modelFusionFastifyPlugin = async (fastify, { flow, baseUrl, basePath, assetStorage, logger, }) => {
|
8
|
+
const paths = new PathProvider_js_1.PathProvider({
|
9
|
+
baseUrl,
|
10
|
+
basePath,
|
11
|
+
});
|
12
|
+
const runs = {};
|
13
|
+
fastify.post(paths.basePath, async (request) => {
|
14
|
+
const run = new FlowRun_js_1.FlowRun({
|
15
|
+
paths,
|
16
|
+
assetStorage,
|
17
|
+
logger,
|
18
|
+
});
|
19
|
+
runs[run.runId] = run;
|
20
|
+
// body the request body is json, parse and validate it:
|
21
|
+
const input = flow.schema.input.parse(request.body);
|
22
|
+
// start longer-running process (no await):
|
23
|
+
(0, getRun_js_1.withRun)(run, async () => {
|
24
|
+
flow
|
25
|
+
.process({
|
26
|
+
input,
|
27
|
+
run,
|
28
|
+
})
|
29
|
+
.catch((error) => {
|
30
|
+
logger.logError({
|
31
|
+
run,
|
32
|
+
message: "Failed to process flow",
|
33
|
+
error,
|
34
|
+
});
|
35
|
+
})
|
36
|
+
.finally(async () => {
|
37
|
+
run.finish();
|
38
|
+
});
|
39
|
+
});
|
40
|
+
return {
|
41
|
+
id: run.runId,
|
42
|
+
url: paths.getEventsUrl(run.runId),
|
43
|
+
};
|
44
|
+
});
|
45
|
+
fastify.get(paths.getAssetPathTemplate(), async (request, reply) => {
|
46
|
+
const runId = request.params.runId; // eslint-disable-line @typescript-eslint/no-explicit-any
|
47
|
+
const assetName = request.params.assetName; // eslint-disable-line @typescript-eslint/no-explicit-any
|
48
|
+
const asset = await assetStorage.readAsset({
|
49
|
+
run: runs[runId],
|
50
|
+
assetName,
|
51
|
+
});
|
52
|
+
if (asset == null) {
|
53
|
+
logger.logError({
|
54
|
+
run: runs[runId],
|
55
|
+
message: `Asset ${assetName} not found`,
|
56
|
+
error: new Error(`Asset ${assetName} not found`),
|
57
|
+
});
|
58
|
+
reply.status(404);
|
59
|
+
return { error: `Asset ${assetName} not found` };
|
60
|
+
}
|
61
|
+
const headers = {
|
62
|
+
"Access-Control-Allow-Origin": "*",
|
63
|
+
"Content-Length": asset.data.length,
|
64
|
+
"Content-Type": asset.contentType,
|
65
|
+
"Cache-Control": "no-cache",
|
66
|
+
};
|
67
|
+
reply.raw.writeHead(200, headers);
|
68
|
+
reply.raw.write(asset.data);
|
69
|
+
reply.raw.end();
|
70
|
+
return;
|
71
|
+
});
|
72
|
+
fastify.get(paths.getEventsPathTemplate(), async (request, reply) => {
|
73
|
+
const runId = request.params.runId; // eslint-disable-line @typescript-eslint/no-explicit-any
|
74
|
+
const eventQueue = runs[runId]?.eventQueue;
|
75
|
+
if (!eventQueue) {
|
76
|
+
return {
|
77
|
+
error: `No event queue found for run ID ${runId}`,
|
78
|
+
};
|
79
|
+
}
|
80
|
+
const headers = {
|
81
|
+
"Access-Control-Allow-Origin": "*",
|
82
|
+
"Content-Type": "text/event-stream",
|
83
|
+
Connection: "keep-alive",
|
84
|
+
"Cache-Control": "no-cache",
|
85
|
+
"Content-Encoding": "none",
|
86
|
+
};
|
87
|
+
reply.raw.writeHead(200, headers);
|
88
|
+
const textEncoder = new TextEncoder();
|
89
|
+
for await (const event of eventQueue) {
|
90
|
+
if (reply.raw.destroyed) {
|
91
|
+
break; // client disconnected
|
92
|
+
}
|
93
|
+
reply.raw.write(textEncoder.encode(`data: ${JSON.stringify(event)}\n\n`));
|
94
|
+
}
|
95
|
+
if (!reply.raw.destroyed) {
|
96
|
+
reply.raw.write(textEncoder.encode(`data: [DONE]\n\n`));
|
97
|
+
}
|
98
|
+
reply.raw.end();
|
99
|
+
return;
|
100
|
+
});
|
101
|
+
};
|
102
|
+
exports.modelFusionFastifyPlugin = modelFusionFastifyPlugin;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import type { FastifyPluginAsync } from "fastify";
|
2
|
+
import type { AssetStorage } from "./AssetStorage.js";
|
3
|
+
import { Flow } from "./Flow.js";
|
4
|
+
import { Logger } from "./Logger.js";
|
5
|
+
export interface ModelFusionFastifyPluginOptions {
|
6
|
+
flow: Flow<any, any>;
|
7
|
+
baseUrl: string;
|
8
|
+
basePath: string;
|
9
|
+
assetStorage: AssetStorage;
|
10
|
+
logger: Logger;
|
11
|
+
}
|
12
|
+
export declare const modelFusionFastifyPlugin: FastifyPluginAsync<ModelFusionFastifyPluginOptions>;
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import { withRun } from "../../core/getRun.js";
|
2
|
+
import { FlowRun } from "./FlowRun.js";
|
3
|
+
import { PathProvider } from "./PathProvider.js";
|
4
|
+
export const modelFusionFastifyPlugin = async (fastify, { flow, baseUrl, basePath, assetStorage, logger, }) => {
|
5
|
+
const paths = new PathProvider({
|
6
|
+
baseUrl,
|
7
|
+
basePath,
|
8
|
+
});
|
9
|
+
const runs = {};
|
10
|
+
fastify.post(paths.basePath, async (request) => {
|
11
|
+
const run = new FlowRun({
|
12
|
+
paths,
|
13
|
+
assetStorage,
|
14
|
+
logger,
|
15
|
+
});
|
16
|
+
runs[run.runId] = run;
|
17
|
+
// body the request body is json, parse and validate it:
|
18
|
+
const input = flow.schema.input.parse(request.body);
|
19
|
+
// start longer-running process (no await):
|
20
|
+
withRun(run, async () => {
|
21
|
+
flow
|
22
|
+
.process({
|
23
|
+
input,
|
24
|
+
run,
|
25
|
+
})
|
26
|
+
.catch((error) => {
|
27
|
+
logger.logError({
|
28
|
+
run,
|
29
|
+
message: "Failed to process flow",
|
30
|
+
error,
|
31
|
+
});
|
32
|
+
})
|
33
|
+
.finally(async () => {
|
34
|
+
run.finish();
|
35
|
+
});
|
36
|
+
});
|
37
|
+
return {
|
38
|
+
id: run.runId,
|
39
|
+
url: paths.getEventsUrl(run.runId),
|
40
|
+
};
|
41
|
+
});
|
42
|
+
fastify.get(paths.getAssetPathTemplate(), async (request, reply) => {
|
43
|
+
const runId = request.params.runId; // eslint-disable-line @typescript-eslint/no-explicit-any
|
44
|
+
const assetName = request.params.assetName; // eslint-disable-line @typescript-eslint/no-explicit-any
|
45
|
+
const asset = await assetStorage.readAsset({
|
46
|
+
run: runs[runId],
|
47
|
+
assetName,
|
48
|
+
});
|
49
|
+
if (asset == null) {
|
50
|
+
logger.logError({
|
51
|
+
run: runs[runId],
|
52
|
+
message: `Asset ${assetName} not found`,
|
53
|
+
error: new Error(`Asset ${assetName} not found`),
|
54
|
+
});
|
55
|
+
reply.status(404);
|
56
|
+
return { error: `Asset ${assetName} not found` };
|
57
|
+
}
|
58
|
+
const headers = {
|
59
|
+
"Access-Control-Allow-Origin": "*",
|
60
|
+
"Content-Length": asset.data.length,
|
61
|
+
"Content-Type": asset.contentType,
|
62
|
+
"Cache-Control": "no-cache",
|
63
|
+
};
|
64
|
+
reply.raw.writeHead(200, headers);
|
65
|
+
reply.raw.write(asset.data);
|
66
|
+
reply.raw.end();
|
67
|
+
return;
|
68
|
+
});
|
69
|
+
fastify.get(paths.getEventsPathTemplate(), async (request, reply) => {
|
70
|
+
const runId = request.params.runId; // eslint-disable-line @typescript-eslint/no-explicit-any
|
71
|
+
const eventQueue = runs[runId]?.eventQueue;
|
72
|
+
if (!eventQueue) {
|
73
|
+
return {
|
74
|
+
error: `No event queue found for run ID ${runId}`,
|
75
|
+
};
|
76
|
+
}
|
77
|
+
const headers = {
|
78
|
+
"Access-Control-Allow-Origin": "*",
|
79
|
+
"Content-Type": "text/event-stream",
|
80
|
+
Connection: "keep-alive",
|
81
|
+
"Cache-Control": "no-cache",
|
82
|
+
"Content-Encoding": "none",
|
83
|
+
};
|
84
|
+
reply.raw.writeHead(200, headers);
|
85
|
+
const textEncoder = new TextEncoder();
|
86
|
+
for await (const event of eventQueue) {
|
87
|
+
if (reply.raw.destroyed) {
|
88
|
+
break; // client disconnected
|
89
|
+
}
|
90
|
+
reply.raw.write(textEncoder.encode(`data: ${JSON.stringify(event)}\n\n`));
|
91
|
+
}
|
92
|
+
if (!reply.raw.destroyed) {
|
93
|
+
reply.raw.write(textEncoder.encode(`data: [DONE]\n\n`));
|
94
|
+
}
|
95
|
+
reply.raw.end();
|
96
|
+
return;
|
97
|
+
});
|
98
|
+
};
|
package/ui/index.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export * from "./MediaSourceAppender.js";
|
package/ui/index.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export * from "./MediaSourceAppender.js";
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|