modelfusion 0.53.2 → 0.55.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.
Files changed (110) hide show
  1. package/README.md +71 -4
  2. package/browser/convertAudioChunksToBase64.cjs +8 -0
  3. package/browser/convertAudioChunksToBase64.d.ts +4 -0
  4. package/browser/convertAudioChunksToBase64.js +4 -0
  5. package/browser/convertBlobToBase64.cjs +23 -0
  6. package/browser/convertBlobToBase64.d.ts +1 -0
  7. package/browser/convertBlobToBase64.js +19 -0
  8. package/{event-source → browser}/index.cjs +4 -1
  9. package/browser/index.d.ts +6 -0
  10. package/browser/index.js +6 -0
  11. package/browser/invokeFlow.cjs +23 -0
  12. package/browser/invokeFlow.d.ts +8 -0
  13. package/browser/invokeFlow.js +19 -0
  14. package/{event-source → browser}/readEventSource.cjs +8 -3
  15. package/{event-source → browser}/readEventSource.d.ts +3 -1
  16. package/{event-source → browser}/readEventSource.js +8 -3
  17. package/{event-source → browser}/readEventSourceStream.cjs +1 -1
  18. package/{event-source → browser}/readEventSourceStream.js +1 -1
  19. package/index.cjs +0 -2
  20. package/index.d.ts +0 -2
  21. package/index.js +0 -2
  22. package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +1 -1
  23. package/model-provider/anthropic/AnthropicTextGenerationModel.js +1 -1
  24. package/model-provider/cohere/CohereTextGenerationModel.cjs +31 -50
  25. package/model-provider/cohere/CohereTextGenerationModel.js +31 -50
  26. package/model-provider/index.cjs +1 -0
  27. package/model-provider/index.d.ts +1 -0
  28. package/model-provider/index.js +1 -0
  29. package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +1 -1
  30. package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +1 -1
  31. package/model-provider/ollama/OllamaApiConfiguration.cjs +15 -0
  32. package/model-provider/ollama/OllamaApiConfiguration.d.ts +10 -0
  33. package/model-provider/ollama/OllamaApiConfiguration.js +11 -0
  34. package/model-provider/ollama/OllamaError.cjs +29 -0
  35. package/model-provider/ollama/OllamaError.d.ts +22 -0
  36. package/model-provider/ollama/OllamaError.js +24 -0
  37. package/model-provider/ollama/OllamaTextGenerationModel.cjs +216 -0
  38. package/model-provider/ollama/OllamaTextGenerationModel.d.ts +134 -0
  39. package/model-provider/ollama/OllamaTextGenerationModel.js +212 -0
  40. package/model-provider/ollama/index.cjs +21 -0
  41. package/model-provider/ollama/index.d.ts +3 -0
  42. package/model-provider/ollama/index.js +3 -0
  43. package/model-provider/openai/OpenAICompletionModel.cjs +2 -2
  44. package/model-provider/openai/OpenAICompletionModel.js +2 -2
  45. package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +1 -1
  46. package/model-provider/openai/chat/OpenAIChatStreamIterable.js +1 -1
  47. package/package.json +13 -4
  48. package/server/fastify/AssetStorage.cjs +2 -0
  49. package/server/fastify/AssetStorage.d.ts +17 -0
  50. package/server/fastify/AssetStorage.js +1 -0
  51. package/server/fastify/DefaultFlow.cjs +22 -0
  52. package/server/fastify/DefaultFlow.d.ts +16 -0
  53. package/server/fastify/DefaultFlow.js +18 -0
  54. package/server/fastify/FileSystemAssetStorage.cjs +60 -0
  55. package/server/fastify/FileSystemAssetStorage.d.ts +19 -0
  56. package/server/fastify/FileSystemAssetStorage.js +56 -0
  57. package/server/fastify/FileSystemLogger.cjs +48 -0
  58. package/server/fastify/FileSystemLogger.d.ts +18 -0
  59. package/server/fastify/FileSystemLogger.js +44 -0
  60. package/server/fastify/Flow.cjs +2 -0
  61. package/server/fastify/Flow.d.ts +9 -0
  62. package/server/fastify/Flow.js +1 -0
  63. package/server/fastify/FlowRun.cjs +71 -0
  64. package/server/fastify/FlowRun.d.ts +28 -0
  65. package/server/fastify/FlowRun.js +67 -0
  66. package/server/fastify/FlowSchema.cjs +2 -0
  67. package/server/fastify/FlowSchema.d.ts +5 -0
  68. package/server/fastify/FlowSchema.js +1 -0
  69. package/server/fastify/Logger.cjs +2 -0
  70. package/server/fastify/Logger.d.ts +13 -0
  71. package/server/fastify/Logger.js +1 -0
  72. package/server/fastify/PathProvider.cjs +34 -0
  73. package/server/fastify/PathProvider.d.ts +12 -0
  74. package/server/fastify/PathProvider.js +30 -0
  75. package/server/fastify/index.cjs +24 -0
  76. package/server/fastify/index.d.ts +8 -0
  77. package/server/fastify/index.js +8 -0
  78. package/server/fastify/modelFusionFlowPlugin.cjs +102 -0
  79. package/server/fastify/modelFusionFlowPlugin.d.ts +12 -0
  80. package/server/fastify/modelFusionFlowPlugin.js +98 -0
  81. package/util/index.cjs +1 -0
  82. package/util/index.d.ts +1 -0
  83. package/util/index.js +1 -0
  84. package/{event-source → util/streaming}/createEventSourceStream.cjs +7 -3
  85. package/util/streaming/createEventSourceStream.js +15 -0
  86. package/{ui → util/streaming}/index.cjs +1 -1
  87. package/util/streaming/index.d.ts +1 -0
  88. package/util/streaming/index.js +1 -0
  89. package/util/streaming/parseJsonStream.cjs +35 -0
  90. package/util/streaming/parseJsonStream.d.ts +6 -0
  91. package/util/streaming/parseJsonStream.js +31 -0
  92. package/event-source/createEventSourceStream.js +0 -11
  93. package/event-source/index.d.ts +0 -3
  94. package/event-source/index.js +0 -3
  95. package/ui/index.d.ts +0 -1
  96. package/ui/index.js +0 -1
  97. /package/{ui → browser}/MediaSourceAppender.cjs +0 -0
  98. /package/{ui → browser}/MediaSourceAppender.d.ts +0 -0
  99. /package/{ui → browser}/MediaSourceAppender.js +0 -0
  100. /package/{event-source → browser}/readEventSourceStream.d.ts +0 -0
  101. /package/{event-source → util/streaming}/EventSourceParserStream.cjs +0 -0
  102. /package/{event-source → util/streaming}/EventSourceParserStream.d.ts +0 -0
  103. /package/{event-source → util/streaming}/EventSourceParserStream.js +0 -0
  104. /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.cjs +0 -0
  105. /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.d.ts +0 -0
  106. /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.js +0 -0
  107. /package/{event-source → util/streaming}/createEventSourceStream.d.ts +0 -0
  108. /package/{event-source → util/streaming}/parseEventSourceStream.cjs +0 -0
  109. /package/{event-source → util/streaming}/parseEventSourceStream.d.ts +0 -0
  110. /package/{event-source → util/streaming}/parseEventSourceStream.js +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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { FlowRun } from "./FlowRun.js";
2
+ import { FlowSchema } from "./FlowSchema.js";
3
+ export interface Flow<INPUT, EVENT> {
4
+ readonly schema: FlowSchema<INPUT, EVENT>;
5
+ process: (options: {
6
+ input: INPUT;
7
+ run: FlowRun<EVENT>;
8
+ }) => Promise<void>;
9
+ }
@@ -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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ export interface FlowSchema<INPUT, EVENT> {
3
+ input: z.ZodType<INPUT>;
4
+ events: z.ZodType<EVENT>;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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/util/index.cjs CHANGED
@@ -20,3 +20,4 @@ __exportStar(require("./cosineSimilarity.cjs"), exports);
20
20
  __exportStar(require("./delay.cjs"), exports);
21
21
  __exportStar(require("./getAudioFileExtension.cjs"), exports);
22
22
  __exportStar(require("./parseJSON.cjs"), exports);
23
+ __exportStar(require("./streaming/index.cjs"), exports);
package/util/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export * from "./cosineSimilarity.js";
4
4
  export * from "./delay.js";
5
5
  export * from "./getAudioFileExtension.js";
6
6
  export * from "./parseJSON.js";
7
+ export * from "./streaming/index.js";
package/util/index.js CHANGED
@@ -4,3 +4,4 @@ export * from "./cosineSimilarity.js";
4
4
  export * from "./delay.js";
5
5
  export * from "./getAudioFileExtension.js";
6
6
  export * from "./parseJSON.js";
7
+ export * from "./streaming/index.js";
@@ -5,10 +5,14 @@ const textEncoder = new TextEncoder();
5
5
  function createEventSourceStream(events) {
6
6
  return new ReadableStream({
7
7
  async start(controller) {
8
- for await (const event of events) {
9
- controller.enqueue(textEncoder.encode(`data: ${JSON.stringify(event)}\n\n`));
8
+ try {
9
+ for await (const event of events) {
10
+ controller.enqueue(textEncoder.encode(`data: ${JSON.stringify(event)}\n\n`));
11
+ }
12
+ }
13
+ finally {
14
+ controller.close();
10
15
  }
11
- controller.close();
12
16
  },
13
17
  });
14
18
  }
@@ -0,0 +1,15 @@
1
+ const textEncoder = new TextEncoder();
2
+ export function createEventSourceStream(events) {
3
+ return new ReadableStream({
4
+ async start(controller) {
5
+ try {
6
+ for await (const event of events) {
7
+ controller.enqueue(textEncoder.encode(`data: ${JSON.stringify(event)}\n\n`));
8
+ }
9
+ }
10
+ finally {
11
+ controller.close();
12
+ }
13
+ },
14
+ });
15
+ }
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./MediaSourceAppender.cjs"), exports);
17
+ __exportStar(require("./createEventSourceStream.cjs"), exports);
@@ -0,0 +1 @@
1
+ export * from "./createEventSourceStream.js";