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.
- package/README.md +71 -4
- 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/{event-source → browser}/index.cjs +4 -1
- 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/index.cjs +0 -2
- package/index.d.ts +0 -2
- package/index.js +0 -2
- package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +1 -1
- package/model-provider/anthropic/AnthropicTextGenerationModel.js +1 -1
- package/model-provider/cohere/CohereTextGenerationModel.cjs +31 -50
- package/model-provider/cohere/CohereTextGenerationModel.js +31 -50
- package/model-provider/index.cjs +1 -0
- package/model-provider/index.d.ts +1 -0
- package/model-provider/index.js +1 -0
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +1 -1
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +1 -1
- package/model-provider/ollama/OllamaApiConfiguration.cjs +15 -0
- package/model-provider/ollama/OllamaApiConfiguration.d.ts +10 -0
- package/model-provider/ollama/OllamaApiConfiguration.js +11 -0
- package/model-provider/ollama/OllamaError.cjs +29 -0
- package/model-provider/ollama/OllamaError.d.ts +22 -0
- package/model-provider/ollama/OllamaError.js +24 -0
- package/model-provider/ollama/OllamaTextGenerationModel.cjs +216 -0
- package/model-provider/ollama/OllamaTextGenerationModel.d.ts +134 -0
- package/model-provider/ollama/OllamaTextGenerationModel.js +212 -0
- package/model-provider/ollama/index.cjs +21 -0
- package/model-provider/ollama/index.d.ts +3 -0
- package/model-provider/ollama/index.js +3 -0
- package/model-provider/openai/OpenAICompletionModel.cjs +2 -2
- package/model-provider/openai/OpenAICompletionModel.js +2 -2
- package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +1 -1
- package/model-provider/openai/chat/OpenAIChatStreamIterable.js +1 -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/util/index.cjs +1 -0
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/{event-source → util/streaming}/createEventSourceStream.cjs +7 -3
- package/util/streaming/createEventSourceStream.js +15 -0
- package/{ui → util/streaming}/index.cjs +1 -1
- package/util/streaming/index.d.ts +1 -0
- package/util/streaming/index.js +1 -0
- package/util/streaming/parseJsonStream.cjs +35 -0
- package/util/streaming/parseJsonStream.d.ts +6 -0
- package/util/streaming/parseJsonStream.js +31 -0
- package/event-source/createEventSourceStream.js +0 -11
- package/event-source/index.d.ts +0 -3
- package/event-source/index.js +0 -3
- 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
- /package/{event-source → util/streaming}/EventSourceParserStream.cjs +0 -0
- /package/{event-source → util/streaming}/EventSourceParserStream.d.ts +0 -0
- /package/{event-source → util/streaming}/EventSourceParserStream.js +0 -0
- /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.cjs +0 -0
- /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.d.ts +0 -0
- /package/{event-source → util/streaming}/convertReadableStreamToAsyncIterable.js +0 -0
- /package/{event-source → util/streaming}/createEventSourceStream.d.ts +0 -0
- /package/{event-source → util/streaming}/parseEventSourceStream.cjs +0 -0
- /package/{event-source → util/streaming}/parseEventSourceStream.d.ts +0 -0
- /package/{event-source → util/streaming}/parseEventSourceStream.js +0 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
import { callWithRetryAndThrottle } from "../../core/api/callWithRetryAndThrottle.js";
|
3
|
+
import { createJsonResponseHandler, postJsonToApi, } from "../../core/api/postToApi.js";
|
4
|
+
import { AbstractModel } from "../../model-function/AbstractModel.js";
|
5
|
+
import { PromptFormatTextStreamingModel } from "../../model-function/generate-text/PromptFormatTextStreamingModel.js";
|
6
|
+
import { AsyncQueue } from "../../util/AsyncQueue.js";
|
7
|
+
import { parseJsonStream } from "../../util/streaming/parseJsonStream.js";
|
8
|
+
import { OllamaApiConfiguration } from "./OllamaApiConfiguration.js";
|
9
|
+
import { failedOllamaCallResponseHandler } from "./OllamaError.js";
|
10
|
+
export class OllamaTextGenerationModel extends AbstractModel {
|
11
|
+
constructor(settings) {
|
12
|
+
super({ settings });
|
13
|
+
Object.defineProperty(this, "provider", {
|
14
|
+
enumerable: true,
|
15
|
+
configurable: true,
|
16
|
+
writable: true,
|
17
|
+
value: "ollama"
|
18
|
+
});
|
19
|
+
Object.defineProperty(this, "tokenizer", {
|
20
|
+
enumerable: true,
|
21
|
+
configurable: true,
|
22
|
+
writable: true,
|
23
|
+
value: undefined
|
24
|
+
});
|
25
|
+
Object.defineProperty(this, "countPromptTokens", {
|
26
|
+
enumerable: true,
|
27
|
+
configurable: true,
|
28
|
+
writable: true,
|
29
|
+
value: undefined
|
30
|
+
});
|
31
|
+
}
|
32
|
+
get modelName() {
|
33
|
+
return this.settings.model;
|
34
|
+
}
|
35
|
+
get contextWindowSize() {
|
36
|
+
return this.settings.contextWindowSize;
|
37
|
+
}
|
38
|
+
async callAPI(prompt, options) {
|
39
|
+
return callWithRetryAndThrottle({
|
40
|
+
retry: this.settings.api?.retry,
|
41
|
+
throttle: this.settings.api?.throttle,
|
42
|
+
call: async () => callOllamaTextGenerationAPI({
|
43
|
+
...this.settings,
|
44
|
+
// other
|
45
|
+
abortSignal: options.run?.abortSignal,
|
46
|
+
prompt,
|
47
|
+
responseFormat: options.responseFormat,
|
48
|
+
}),
|
49
|
+
});
|
50
|
+
}
|
51
|
+
get settingsForEvent() {
|
52
|
+
const eventSettingProperties = [
|
53
|
+
// "maxCompletionTokens",
|
54
|
+
// "stopSequences",
|
55
|
+
"contextWindowSize",
|
56
|
+
];
|
57
|
+
return Object.fromEntries(Object.entries(this.settings).filter(([key]) => eventSettingProperties.includes(key)));
|
58
|
+
}
|
59
|
+
async doGenerateText(prompt, options) {
|
60
|
+
const response = await this.callAPI(prompt, {
|
61
|
+
...options,
|
62
|
+
responseFormat: OllamaTextGenerationResponseFormat.json,
|
63
|
+
});
|
64
|
+
return {
|
65
|
+
response,
|
66
|
+
text: response.response,
|
67
|
+
};
|
68
|
+
}
|
69
|
+
doStreamText(prompt, options) {
|
70
|
+
return this.callAPI(prompt, {
|
71
|
+
...options,
|
72
|
+
responseFormat: OllamaTextGenerationResponseFormat.deltaIterable,
|
73
|
+
});
|
74
|
+
}
|
75
|
+
withPromptFormat(promptFormat) {
|
76
|
+
return new PromptFormatTextStreamingModel({
|
77
|
+
model: this.withSettings({
|
78
|
+
stopSequences: [
|
79
|
+
...(this.settings.stopSequences ?? []),
|
80
|
+
...promptFormat.stopSequences,
|
81
|
+
],
|
82
|
+
}),
|
83
|
+
promptFormat,
|
84
|
+
});
|
85
|
+
}
|
86
|
+
withSettings(additionalSettings) {
|
87
|
+
return new OllamaTextGenerationModel(Object.assign({}, this.settings, additionalSettings));
|
88
|
+
}
|
89
|
+
}
|
90
|
+
const ollamaTextGenerationResponseSchema = z.object({
|
91
|
+
done: z.literal(true),
|
92
|
+
model: z.string(),
|
93
|
+
response: z.string(),
|
94
|
+
total_duration: z.number(),
|
95
|
+
load_duration: z.number(),
|
96
|
+
prompt_eval_count: z.number(),
|
97
|
+
eval_count: z.number(),
|
98
|
+
eval_duration: z.number(),
|
99
|
+
context: z.array(z.number()),
|
100
|
+
});
|
101
|
+
const ollamaTextStreamingResponseSchema = z.discriminatedUnion("done", [
|
102
|
+
z.object({
|
103
|
+
done: z.literal(false),
|
104
|
+
model: z.string(),
|
105
|
+
created_at: z.string(),
|
106
|
+
response: z.string(),
|
107
|
+
}),
|
108
|
+
z.object({
|
109
|
+
done: z.literal(true),
|
110
|
+
model: z.string(),
|
111
|
+
created_at: z.string(),
|
112
|
+
total_duration: z.number(),
|
113
|
+
load_duration: z.number(),
|
114
|
+
sample_count: z.number().optional(),
|
115
|
+
sample_duration: z.number().optional(),
|
116
|
+
prompt_eval_count: z.number(),
|
117
|
+
prompt_eval_duration: z.number().optional(),
|
118
|
+
eval_count: z.number(),
|
119
|
+
eval_duration: z.number(),
|
120
|
+
context: z.array(z.number()),
|
121
|
+
}),
|
122
|
+
]);
|
123
|
+
async function callOllamaTextGenerationAPI({ api = new OllamaApiConfiguration(), abortSignal, responseFormat, prompt, model, contextWindowSize, maxCompletionTokens, mirostat, mirostat_eta, mirostat_tau, num_gpu, num_gqa, num_threads, repeat_last_n, repeat_penalty, seed, stopSequences, temperature, tfs_z, top_k, top_p, system, template, context, }) {
|
124
|
+
return postJsonToApi({
|
125
|
+
url: api.assembleUrl(`/api/generate`),
|
126
|
+
headers: api.headers,
|
127
|
+
body: {
|
128
|
+
stream: responseFormat.stream,
|
129
|
+
model,
|
130
|
+
prompt,
|
131
|
+
options: {
|
132
|
+
mirostat,
|
133
|
+
mirostat_eta,
|
134
|
+
mirostat_tau,
|
135
|
+
num_ctx: contextWindowSize,
|
136
|
+
num_gpu,
|
137
|
+
num_gqa,
|
138
|
+
num_predict: maxCompletionTokens,
|
139
|
+
num_threads,
|
140
|
+
repeat_last_n,
|
141
|
+
repeat_penalty,
|
142
|
+
seed,
|
143
|
+
stop: stopSequences,
|
144
|
+
temperature,
|
145
|
+
tfs_z,
|
146
|
+
top_k,
|
147
|
+
top_p,
|
148
|
+
},
|
149
|
+
system,
|
150
|
+
template,
|
151
|
+
context,
|
152
|
+
},
|
153
|
+
failedResponseHandler: failedOllamaCallResponseHandler,
|
154
|
+
successfulResponseHandler: responseFormat.handler,
|
155
|
+
abortSignal,
|
156
|
+
});
|
157
|
+
}
|
158
|
+
async function createOllamaFullDeltaIterableQueue(stream) {
|
159
|
+
const queue = new AsyncQueue();
|
160
|
+
let accumulatedText = "";
|
161
|
+
// process the stream asynchonously (no 'await' on purpose):
|
162
|
+
parseJsonStream({
|
163
|
+
stream,
|
164
|
+
schema: ollamaTextStreamingResponseSchema,
|
165
|
+
process(event) {
|
166
|
+
if (event.done === true) {
|
167
|
+
queue.push({
|
168
|
+
type: "delta",
|
169
|
+
fullDelta: {
|
170
|
+
content: accumulatedText,
|
171
|
+
isComplete: true,
|
172
|
+
delta: "",
|
173
|
+
},
|
174
|
+
valueDelta: "",
|
175
|
+
});
|
176
|
+
}
|
177
|
+
else {
|
178
|
+
accumulatedText += event.response;
|
179
|
+
queue.push({
|
180
|
+
type: "delta",
|
181
|
+
fullDelta: {
|
182
|
+
content: accumulatedText,
|
183
|
+
isComplete: false,
|
184
|
+
delta: event.response,
|
185
|
+
},
|
186
|
+
valueDelta: event.response,
|
187
|
+
});
|
188
|
+
}
|
189
|
+
},
|
190
|
+
onDone() {
|
191
|
+
queue.close();
|
192
|
+
},
|
193
|
+
});
|
194
|
+
return queue;
|
195
|
+
}
|
196
|
+
export const OllamaTextGenerationResponseFormat = {
|
197
|
+
/**
|
198
|
+
* Returns the response as a JSON object.
|
199
|
+
*/
|
200
|
+
json: {
|
201
|
+
stream: false,
|
202
|
+
handler: createJsonResponseHandler(ollamaTextGenerationResponseSchema),
|
203
|
+
},
|
204
|
+
/**
|
205
|
+
* Returns an async iterable over the full deltas (all choices, including full current state at time of event)
|
206
|
+
* of the response stream.
|
207
|
+
*/
|
208
|
+
deltaIterable: {
|
209
|
+
stream: true,
|
210
|
+
handler: async ({ response }) => createOllamaFullDeltaIterableQueue(response.body),
|
211
|
+
},
|
212
|
+
};
|
@@ -0,0 +1,21 @@
|
|
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
|
+
exports.OllamaError = void 0;
|
18
|
+
__exportStar(require("./OllamaApiConfiguration.cjs"), exports);
|
19
|
+
var OllamaError_js_1 = require("./OllamaError.cjs");
|
20
|
+
Object.defineProperty(exports, "OllamaError", { enumerable: true, get: function () { return OllamaError_js_1.OllamaError; } });
|
21
|
+
__exportStar(require("./OllamaTextGenerationModel.cjs"), exports);
|
@@ -4,13 +4,13 @@ exports.OpenAITextResponseFormat = exports.OpenAICompletionModel = exports.calcu
|
|
4
4
|
const zod_1 = require("zod");
|
5
5
|
const callWithRetryAndThrottle_js_1 = require("../../core/api/callWithRetryAndThrottle.cjs");
|
6
6
|
const postToApi_js_1 = require("../../core/api/postToApi.cjs");
|
7
|
-
const AsyncQueue_js_1 = require("../../util/AsyncQueue.cjs");
|
8
|
-
const parseEventSourceStream_js_1 = require("../../event-source/parseEventSourceStream.cjs");
|
9
7
|
const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs");
|
10
8
|
const PromptFormatTextStreamingModel_js_1 = require("../../model-function/generate-text/PromptFormatTextStreamingModel.cjs");
|
11
9
|
const TextPromptFormat_js_1 = require("../../model-function/generate-text/TextPromptFormat.cjs");
|
12
10
|
const countTokens_js_1 = require("../../model-function/tokenize-text/countTokens.cjs");
|
11
|
+
const AsyncQueue_js_1 = require("../../util/AsyncQueue.cjs");
|
13
12
|
const parseJSON_js_1 = require("../../util/parseJSON.cjs");
|
13
|
+
const parseEventSourceStream_js_1 = require("../../util/streaming/parseEventSourceStream.cjs");
|
14
14
|
const OpenAIApiConfiguration_js_1 = require("./OpenAIApiConfiguration.cjs");
|
15
15
|
const OpenAIError_js_1 = require("./OpenAIError.cjs");
|
16
16
|
const TikTokenTokenizer_js_1 = require("./TikTokenTokenizer.cjs");
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { z } from "zod";
|
2
2
|
import { callWithRetryAndThrottle } from "../../core/api/callWithRetryAndThrottle.js";
|
3
3
|
import { createJsonResponseHandler, postJsonToApi, } from "../../core/api/postToApi.js";
|
4
|
-
import { AsyncQueue } from "../../util/AsyncQueue.js";
|
5
|
-
import { parseEventSourceStream } from "../../event-source/parseEventSourceStream.js";
|
6
4
|
import { AbstractModel } from "../../model-function/AbstractModel.js";
|
7
5
|
import { PromptFormatTextStreamingModel } from "../../model-function/generate-text/PromptFormatTextStreamingModel.js";
|
8
6
|
import { mapChatPromptToTextFormat, mapInstructionPromptToTextFormat, } from "../../model-function/generate-text/TextPromptFormat.js";
|
9
7
|
import { countTokens } from "../../model-function/tokenize-text/countTokens.js";
|
8
|
+
import { AsyncQueue } from "../../util/AsyncQueue.js";
|
10
9
|
import { parseJsonWithZod } from "../../util/parseJSON.js";
|
10
|
+
import { parseEventSourceStream } from "../../util/streaming/parseEventSourceStream.js";
|
11
11
|
import { OpenAIApiConfiguration } from "./OpenAIApiConfiguration.js";
|
12
12
|
import { failedOpenAICallResponseHandler } from "./OpenAIError.js";
|
13
13
|
import { TikTokenTokenizer } from "./TikTokenTokenizer.js";
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createOpenAIChatDeltaIterableQueue = void 0;
|
4
4
|
const zod_1 = require("zod");
|
5
5
|
const AsyncQueue_js_1 = require("../../../util/AsyncQueue.cjs");
|
6
|
-
const parseEventSourceStream_js_1 = require("../../../
|
6
|
+
const parseEventSourceStream_js_1 = require("../../../util/streaming/parseEventSourceStream.cjs");
|
7
7
|
const parseJSON_js_1 = require("../../../util/parseJSON.cjs");
|
8
8
|
const chatResponseStreamEventSchema = zod_1.z.object({
|
9
9
|
choices: zod_1.z.array(zod_1.z.object({
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { z } from "zod";
|
2
2
|
import { AsyncQueue } from "../../../util/AsyncQueue.js";
|
3
|
-
import { parseEventSourceStream } from "../../../
|
3
|
+
import { parseEventSourceStream } from "../../../util/streaming/parseEventSourceStream.js";
|
4
4
|
import { safeParseJsonWithZod } from "../../../util/parseJSON.js";
|
5
5
|
const chatResponseStreamEventSchema = z.object({
|
6
6
|
choices: z.array(z.object({
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "modelfusion",
|
3
3
|
"description": "Build multimodal applications, chatbots, and agents with JavaScript and TypeScript.",
|
4
|
-
"version": "0.
|
4
|
+
"version": "0.55.0",
|
5
5
|
"author": "Lars Grammel",
|
6
6
|
"license": "MIT",
|
7
7
|
"keywords": [
|
@@ -38,6 +38,16 @@
|
|
38
38
|
"types": "./index.d.ts",
|
39
39
|
"import": "./index.js",
|
40
40
|
"require": "./index.cjs"
|
41
|
+
},
|
42
|
+
"./browser": {
|
43
|
+
"types": "./browser/index.d.ts",
|
44
|
+
"import": "./browser/index.js",
|
45
|
+
"require": "./browser/index.cjs"
|
46
|
+
},
|
47
|
+
"./fastify-server": {
|
48
|
+
"types": "./server/fastify/index.d.ts",
|
49
|
+
"import": "./server/fastify/index.js",
|
50
|
+
"require": "./server/fastify/index.cjs"
|
41
51
|
}
|
42
52
|
},
|
43
53
|
"scripts": {
|
@@ -62,8 +72,6 @@
|
|
62
72
|
"zod-to-json-schema": "3.21.4"
|
63
73
|
},
|
64
74
|
"devDependencies": {
|
65
|
-
"@tsconfig/recommended": "1.0.3",
|
66
|
-
"@types/deep-equal": "^1.0.2",
|
67
75
|
"@types/node": "18.11.9",
|
68
76
|
"@types/ws": "^8.5.7",
|
69
77
|
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
@@ -71,8 +79,9 @@
|
|
71
79
|
"copyfiles": "2.4.1",
|
72
80
|
"eslint": "^8.45.0",
|
73
81
|
"eslint-config-prettier": "9.0.0",
|
82
|
+
"fastify": "^4.0.0",
|
74
83
|
"husky": "^8.0.3",
|
75
|
-
"lint-staged": "
|
84
|
+
"lint-staged": "15.0.2",
|
76
85
|
"prettier": "3.0.3",
|
77
86
|
"rimraf": "5.0.5",
|
78
87
|
"typescript": "5.2.2",
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import { FlowRun } from "./FlowRun.js";
|
3
|
+
export type Asset = {
|
4
|
+
data: Buffer;
|
5
|
+
contentType: string;
|
6
|
+
name: string;
|
7
|
+
};
|
8
|
+
export interface AssetStorage {
|
9
|
+
storeAsset(options: {
|
10
|
+
run: FlowRun<unknown>;
|
11
|
+
asset: Asset;
|
12
|
+
}): Promise<void>;
|
13
|
+
readAsset(options: {
|
14
|
+
run: FlowRun<unknown>;
|
15
|
+
assetName: string;
|
16
|
+
}): Promise<Asset | null>;
|
17
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.DefaultFlow = void 0;
|
4
|
+
class DefaultFlow {
|
5
|
+
constructor({ schema, process, }) {
|
6
|
+
Object.defineProperty(this, "schema", {
|
7
|
+
enumerable: true,
|
8
|
+
configurable: true,
|
9
|
+
writable: true,
|
10
|
+
value: void 0
|
11
|
+
});
|
12
|
+
Object.defineProperty(this, "process", {
|
13
|
+
enumerable: true,
|
14
|
+
configurable: true,
|
15
|
+
writable: true,
|
16
|
+
value: void 0
|
17
|
+
});
|
18
|
+
this.schema = schema;
|
19
|
+
this.process = process;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
exports.DefaultFlow = DefaultFlow;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { FlowRun } from "./FlowRun.js";
|
2
|
+
import { FlowSchema } from "./FlowSchema.js";
|
3
|
+
export declare class DefaultFlow<INPUT, EVENT> {
|
4
|
+
readonly schema: FlowSchema<INPUT, EVENT>;
|
5
|
+
constructor({ schema, process, }: {
|
6
|
+
schema: FlowSchema<INPUT, EVENT>;
|
7
|
+
process: (options: {
|
8
|
+
input: INPUT;
|
9
|
+
run: FlowRun<EVENT>;
|
10
|
+
}) => Promise<void>;
|
11
|
+
});
|
12
|
+
process: (options: {
|
13
|
+
input: INPUT;
|
14
|
+
run: FlowRun<EVENT>;
|
15
|
+
}) => Promise<void>;
|
16
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
export class DefaultFlow {
|
2
|
+
constructor({ schema, process, }) {
|
3
|
+
Object.defineProperty(this, "schema", {
|
4
|
+
enumerable: true,
|
5
|
+
configurable: true,
|
6
|
+
writable: true,
|
7
|
+
value: void 0
|
8
|
+
});
|
9
|
+
Object.defineProperty(this, "process", {
|
10
|
+
enumerable: true,
|
11
|
+
configurable: true,
|
12
|
+
writable: true,
|
13
|
+
value: void 0
|
14
|
+
});
|
15
|
+
this.schema = schema;
|
16
|
+
this.process = process;
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.FileSystemAssetStorage = void 0;
|
4
|
+
const node_fs_1 = require("node:fs");
|
5
|
+
const node_path_1 = require("node:path");
|
6
|
+
class FileSystemAssetStorage {
|
7
|
+
constructor({ path, logger, }) {
|
8
|
+
Object.defineProperty(this, "path", {
|
9
|
+
enumerable: true,
|
10
|
+
configurable: true,
|
11
|
+
writable: true,
|
12
|
+
value: void 0
|
13
|
+
});
|
14
|
+
Object.defineProperty(this, "logger", {
|
15
|
+
enumerable: true,
|
16
|
+
configurable: true,
|
17
|
+
writable: true,
|
18
|
+
value: void 0
|
19
|
+
});
|
20
|
+
this.path = path;
|
21
|
+
this.logger = logger;
|
22
|
+
}
|
23
|
+
async storeAsset({ run, asset, }) {
|
24
|
+
try {
|
25
|
+
const assetPath = this.path(run);
|
26
|
+
await node_fs_1.promises.mkdir(assetPath, { recursive: true });
|
27
|
+
await node_fs_1.promises.writeFile((0, node_path_1.join)(assetPath, asset.name), asset.data);
|
28
|
+
await node_fs_1.promises.writeFile((0, node_path_1.join)(assetPath, `${asset.name}.meta.json`), JSON.stringify({
|
29
|
+
name: asset.name,
|
30
|
+
contentType: asset.contentType,
|
31
|
+
}));
|
32
|
+
}
|
33
|
+
catch (error) {
|
34
|
+
this.logger.logError({
|
35
|
+
run,
|
36
|
+
message: `Failed to store asset ${asset.name}`,
|
37
|
+
error,
|
38
|
+
});
|
39
|
+
throw error;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
async readAsset(options) {
|
43
|
+
try {
|
44
|
+
const assetPath = this.path(options.run);
|
45
|
+
const data = await node_fs_1.promises.readFile((0, node_path_1.join)(assetPath, options.assetName));
|
46
|
+
const meta = await node_fs_1.promises.readFile((0, node_path_1.join)(assetPath, `${options.assetName}.meta.json`));
|
47
|
+
const { name, contentType } = JSON.parse(meta.toString());
|
48
|
+
return { data, name, contentType };
|
49
|
+
}
|
50
|
+
catch (error) {
|
51
|
+
this.logger.logError({
|
52
|
+
run: options.run,
|
53
|
+
message: `Failed to read asset ${options.assetName}`,
|
54
|
+
error,
|
55
|
+
});
|
56
|
+
throw error;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
exports.FileSystemAssetStorage = FileSystemAssetStorage;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import type { Asset, AssetStorage } from "./AssetStorage.js";
|
2
|
+
import { FlowRun } from "./FlowRun.js";
|
3
|
+
import { Logger } from "./Logger.js";
|
4
|
+
export declare class FileSystemAssetStorage implements AssetStorage {
|
5
|
+
private readonly path;
|
6
|
+
private readonly logger;
|
7
|
+
constructor({ path, logger, }: {
|
8
|
+
path: (run: FlowRun<unknown>) => string;
|
9
|
+
logger: Logger;
|
10
|
+
});
|
11
|
+
storeAsset({ run, asset, }: {
|
12
|
+
run: FlowRun<unknown>;
|
13
|
+
asset: Asset;
|
14
|
+
}): Promise<void>;
|
15
|
+
readAsset(options: {
|
16
|
+
run: FlowRun<unknown>;
|
17
|
+
assetName: string;
|
18
|
+
}): Promise<Asset | null>;
|
19
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { promises as fs } from "node:fs";
|
2
|
+
import { join } from "node:path";
|
3
|
+
export class FileSystemAssetStorage {
|
4
|
+
constructor({ path, logger, }) {
|
5
|
+
Object.defineProperty(this, "path", {
|
6
|
+
enumerable: true,
|
7
|
+
configurable: true,
|
8
|
+
writable: true,
|
9
|
+
value: void 0
|
10
|
+
});
|
11
|
+
Object.defineProperty(this, "logger", {
|
12
|
+
enumerable: true,
|
13
|
+
configurable: true,
|
14
|
+
writable: true,
|
15
|
+
value: void 0
|
16
|
+
});
|
17
|
+
this.path = path;
|
18
|
+
this.logger = logger;
|
19
|
+
}
|
20
|
+
async storeAsset({ run, asset, }) {
|
21
|
+
try {
|
22
|
+
const assetPath = this.path(run);
|
23
|
+
await fs.mkdir(assetPath, { recursive: true });
|
24
|
+
await fs.writeFile(join(assetPath, asset.name), asset.data);
|
25
|
+
await fs.writeFile(join(assetPath, `${asset.name}.meta.json`), JSON.stringify({
|
26
|
+
name: asset.name,
|
27
|
+
contentType: asset.contentType,
|
28
|
+
}));
|
29
|
+
}
|
30
|
+
catch (error) {
|
31
|
+
this.logger.logError({
|
32
|
+
run,
|
33
|
+
message: `Failed to store asset ${asset.name}`,
|
34
|
+
error,
|
35
|
+
});
|
36
|
+
throw error;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
async readAsset(options) {
|
40
|
+
try {
|
41
|
+
const assetPath = this.path(options.run);
|
42
|
+
const data = await fs.readFile(join(assetPath, options.assetName));
|
43
|
+
const meta = await fs.readFile(join(assetPath, `${options.assetName}.meta.json`));
|
44
|
+
const { name, contentType } = JSON.parse(meta.toString());
|
45
|
+
return { data, name, contentType };
|
46
|
+
}
|
47
|
+
catch (error) {
|
48
|
+
this.logger.logError({
|
49
|
+
run: options.run,
|
50
|
+
message: `Failed to read asset ${options.assetName}`,
|
51
|
+
error,
|
52
|
+
});
|
53
|
+
throw error;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.FileSystemLogger = void 0;
|
4
|
+
const node_fs_1 = require("node:fs");
|
5
|
+
const node_path_1 = require("node:path");
|
6
|
+
class FileSystemLogger {
|
7
|
+
constructor({ path }) {
|
8
|
+
Object.defineProperty(this, "logPath", {
|
9
|
+
enumerable: true,
|
10
|
+
configurable: true,
|
11
|
+
writable: true,
|
12
|
+
value: void 0
|
13
|
+
});
|
14
|
+
this.logPath = path;
|
15
|
+
}
|
16
|
+
async logFunctionEvent({ run, event, }) {
|
17
|
+
const timestamp = event.startTimestamp.getTime();
|
18
|
+
try {
|
19
|
+
const logPath = this.logPath(run);
|
20
|
+
await node_fs_1.promises.mkdir(logPath, { recursive: true });
|
21
|
+
await node_fs_1.promises.writeFile((0, node_path_1.join)(logPath, `${timestamp}-${event.callId}-${event.functionId ?? event.functionType}-${event.eventType}.json`), JSON.stringify(event));
|
22
|
+
}
|
23
|
+
catch (error) {
|
24
|
+
this.logError({
|
25
|
+
run,
|
26
|
+
message: `Failed to write function event ${event.callId}`,
|
27
|
+
error,
|
28
|
+
});
|
29
|
+
}
|
30
|
+
}
|
31
|
+
async logError(options) {
|
32
|
+
const timestamp = Date.now();
|
33
|
+
try {
|
34
|
+
const logPath = this.logPath(options.run);
|
35
|
+
return node_fs_1.promises.writeFile((0, node_path_1.join)(logPath, `${timestamp}-error.json`), JSON.stringify({
|
36
|
+
timestamp: new Date(timestamp).toISOString(),
|
37
|
+
runId: options.run.runId,
|
38
|
+
message: options.message,
|
39
|
+
error: options.error,
|
40
|
+
}));
|
41
|
+
}
|
42
|
+
catch (error) {
|
43
|
+
console.error(`Failed to write error log`);
|
44
|
+
console.error(error);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
exports.FileSystemLogger = FileSystemLogger;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { FunctionEvent } from "../../core/FunctionEvent.js";
|
2
|
+
import { FlowRun } from "./FlowRun.js";
|
3
|
+
import { Logger } from "./Logger.js";
|
4
|
+
export declare class FileSystemLogger implements Logger {
|
5
|
+
private readonly logPath;
|
6
|
+
constructor({ path }: {
|
7
|
+
path: (run: FlowRun<unknown>) => string;
|
8
|
+
});
|
9
|
+
logFunctionEvent({ run, event, }: {
|
10
|
+
run: FlowRun<unknown>;
|
11
|
+
event: FunctionEvent;
|
12
|
+
}): Promise<void>;
|
13
|
+
logError(options: {
|
14
|
+
run: FlowRun<unknown>;
|
15
|
+
message: string;
|
16
|
+
error: unknown;
|
17
|
+
}): Promise<void>;
|
18
|
+
}
|