modelfusion 0.126.0 → 0.128.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/CHANGELOG.md +84 -0
- package/README.md +6 -11
- package/core/api/postToApi.cjs +2 -2
- package/core/api/postToApi.d.ts +2 -3
- package/core/api/postToApi.js +2 -2
- package/core/getFunctionCallLogger.cjs +2 -2
- package/core/getFunctionCallLogger.js +2 -2
- package/model-function/generate-image/generateImage.cjs +2 -1
- package/model-function/generate-image/generateImage.d.ts +4 -5
- package/model-function/generate-image/generateImage.js +2 -1
- package/model-function/generate-speech/SpeechGenerationEvent.d.ts +1 -2
- package/model-function/generate-speech/SpeechGenerationModel.d.ts +3 -4
- package/model-function/generate-speech/generateSpeech.d.ts +3 -4
- package/model-function/generate-speech/streamSpeech.d.ts +3 -4
- package/model-function/generate-structure/StructureFromTextGenerationModel.cjs +2 -2
- package/model-function/generate-structure/StructureFromTextGenerationModel.js +2 -2
- package/model-function/generate-structure/StructureFromTextStreamingModel.cjs +1 -1
- package/model-function/generate-structure/StructureFromTextStreamingModel.js +1 -1
- package/model-function/generate-structure/streamStructure.cjs +14 -12
- package/model-function/generate-structure/streamStructure.d.ts +11 -29
- package/model-function/generate-structure/streamStructure.js +14 -12
- package/model-function/generate-text/prompt-template/ContentPart.cjs +9 -1
- package/model-function/generate-text/prompt-template/ContentPart.d.ts +3 -2
- package/model-function/generate-text/prompt-template/ContentPart.js +7 -0
- package/model-function/generate-text/streamText.cjs +1 -1
- package/model-function/generate-text/streamText.d.ts +1 -1
- package/model-function/generate-text/streamText.js +1 -1
- package/model-provider/elevenlabs/ElevenLabsSpeechModel.cjs +2 -1
- package/model-provider/elevenlabs/ElevenLabsSpeechModel.d.ts +2 -3
- package/model-provider/elevenlabs/ElevenLabsSpeechModel.js +2 -1
- package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.cjs +2 -2
- package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.js +3 -3
- package/model-provider/lmnt/LmntSpeechModel.cjs +2 -1
- package/model-provider/lmnt/LmntSpeechModel.d.ts +1 -2
- package/model-provider/lmnt/LmntSpeechModel.js +2 -1
- package/model-provider/mistral/MistralChatModel.test.cjs +2 -2
- package/model-provider/mistral/MistralChatModel.test.js +2 -2
- package/model-provider/ollama/OllamaChatModel.cjs +1 -1
- package/model-provider/ollama/OllamaChatModel.d.ts +5 -5
- package/model-provider/ollama/OllamaChatModel.js +1 -1
- package/model-provider/ollama/OllamaChatPromptTemplate.cjs +1 -1
- package/model-provider/ollama/OllamaChatPromptTemplate.js +2 -2
- package/model-provider/ollama/OllamaCompletionModel.cjs +2 -2
- package/model-provider/ollama/OllamaCompletionModel.d.ts +5 -5
- package/model-provider/ollama/OllamaCompletionModel.js +2 -2
- package/model-provider/ollama/OllamaCompletionModel.test.cjs +4 -6
- package/model-provider/ollama/OllamaCompletionModel.test.js +4 -6
- package/model-provider/openai/OpenAIChatMessage.cjs +5 -4
- package/model-provider/openai/OpenAIChatMessage.js +5 -4
- package/model-provider/openai/OpenAIChatModel.test.cjs +4 -6
- package/model-provider/openai/OpenAIChatModel.test.js +4 -6
- package/model-provider/openai/OpenAISpeechModel.d.ts +1 -2
- package/model-provider/openai/OpenAITranscriptionModel.d.ts +1 -2
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.cjs +6 -0
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.d.ts +3 -1
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.js +6 -0
- package/model-provider/openai-compatible/OpenAICompatibleApiConfiguration.d.ts +5 -0
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.cjs +1 -1
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.d.ts +2 -3
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.js +1 -1
- package/model-provider/openai-compatible/OpenAICompatibleCompletionModel.cjs +1 -1
- package/model-provider/openai-compatible/OpenAICompatibleCompletionModel.d.ts +2 -3
- package/model-provider/openai-compatible/OpenAICompatibleCompletionModel.js +1 -1
- package/model-provider/openai-compatible/OpenAICompatibleTextEmbeddingModel.cjs +1 -1
- package/model-provider/openai-compatible/OpenAICompatibleTextEmbeddingModel.d.ts +2 -3
- package/model-provider/openai-compatible/OpenAICompatibleTextEmbeddingModel.js +1 -1
- package/model-provider/openai-compatible/PerplexityApiConfiguration.cjs +6 -0
- package/model-provider/openai-compatible/PerplexityApiConfiguration.d.ts +3 -1
- package/model-provider/openai-compatible/PerplexityApiConfiguration.js +6 -0
- package/model-provider/openai-compatible/TogetherAIApiConfiguration.cjs +6 -0
- package/model-provider/openai-compatible/TogetherAIApiConfiguration.d.ts +3 -1
- package/model-provider/openai-compatible/TogetherAIApiConfiguration.js +6 -0
- package/model-provider/openai-compatible/index.cjs +1 -1
- package/model-provider/openai-compatible/index.d.ts +1 -1
- package/model-provider/openai-compatible/index.js +1 -1
- package/model-provider/stability/StabilityImageGenerationModel.d.ts +5 -5
- package/model-provider/whispercpp/WhisperCppTranscriptionModel.d.ts +1 -2
- package/package.json +3 -2
- package/util/UInt8Utils.cjs +50 -0
- package/util/UInt8Utils.d.ts +3 -0
- package/util/UInt8Utils.js +44 -0
- package/model-provider/openai-compatible/OpenAICompatibleProviderName.d.ts +0 -1
- /package/model-provider/openai-compatible/{OpenAICompatibleProviderName.cjs → OpenAICompatibleApiConfiguration.cjs} +0 -0
- /package/model-provider/openai-compatible/{OpenAICompatibleProviderName.js → OpenAICompatibleApiConfiguration.js} +0 -0
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,89 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.128.0 - 2024-01-20
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
- **breaking change**: ModelFusion uses `Uint8Array` instead of `Buffer` for better cross-platform compatibility (see also ["Goodbye, Node.js Buffer"](https://sindresorhus.com/blog/goodbye-nodejs-buffer)). This can lead to breaking changes in your code if you use `Buffer`-specific methods.
|
8
|
+
- **breaking change**: Image content in multi-modal instruction and chat inputs (e.g. for GPT Vision) is passed in the `image` property (instead of `base64Image`) and supports both base64 strings and `Uint8Array` inputs:
|
9
|
+
|
10
|
+
```ts
|
11
|
+
const image = fs.readFileSync(path.join("data", "example-image.png"), {
|
12
|
+
encoding: "base64",
|
13
|
+
});
|
14
|
+
|
15
|
+
const textStream = await streamText({
|
16
|
+
model: openai.ChatTextGenerator({
|
17
|
+
model: "gpt-4-vision-preview",
|
18
|
+
maxGenerationTokens: 1000,
|
19
|
+
}),
|
20
|
+
|
21
|
+
prompt: [
|
22
|
+
openai.ChatMessage.user([
|
23
|
+
{ type: "text", text: "Describe the image in detail:\n\n" },
|
24
|
+
{ type: "image", image, mimeType: "image/png" },
|
25
|
+
]),
|
26
|
+
],
|
27
|
+
});
|
28
|
+
```
|
29
|
+
|
30
|
+
- OpenAI-compatible providers with predefined API configurations have a customized provider name that shows up in the events.
|
31
|
+
|
32
|
+
## v0.127.0 - 2024-01-15
|
33
|
+
|
34
|
+
### Changed
|
35
|
+
|
36
|
+
- **breaking change**: `streamStructure` returns an async iterable over deep partial objects. If you need to get the fully validated final result, you can use the `fullResponse: true` option and await the `structurePromise` value. Example:
|
37
|
+
|
38
|
+
```ts
|
39
|
+
const { structureStream, structurePromise } = await streamStructure({
|
40
|
+
model: ollama
|
41
|
+
.ChatTextGenerator({
|
42
|
+
model: "openhermes2.5-mistral",
|
43
|
+
maxGenerationTokens: 1024,
|
44
|
+
temperature: 0,
|
45
|
+
})
|
46
|
+
.asStructureGenerationModel(jsonStructurePrompt.text()),
|
47
|
+
|
48
|
+
schema: zodSchema(
|
49
|
+
z.object({
|
50
|
+
characters: z.array(
|
51
|
+
z.object({
|
52
|
+
name: z.string(),
|
53
|
+
class: z
|
54
|
+
.string()
|
55
|
+
.describe("Character class, e.g. warrior, mage, or thief."),
|
56
|
+
description: z.string(),
|
57
|
+
})
|
58
|
+
),
|
59
|
+
})
|
60
|
+
),
|
61
|
+
|
62
|
+
prompt:
|
63
|
+
"Generate 3 character descriptions for a fantasy role playing game.",
|
64
|
+
|
65
|
+
fullResponse: true,
|
66
|
+
});
|
67
|
+
|
68
|
+
for await (const partialStructure of structureStream) {
|
69
|
+
console.clear();
|
70
|
+
console.log(partialStructure);
|
71
|
+
}
|
72
|
+
|
73
|
+
const structure = await structurePromise;
|
74
|
+
|
75
|
+
console.clear();
|
76
|
+
console.log("FINAL STRUCTURE");
|
77
|
+
console.log(structure);
|
78
|
+
```
|
79
|
+
|
80
|
+
- **breaking change**: Renamed `text` value in `streamText` with `fullResponse: true` to `textPromise`.
|
81
|
+
|
82
|
+
### Fixed
|
83
|
+
|
84
|
+
- Ollama streaming.
|
85
|
+
- Ollama structure generation and streaming.
|
86
|
+
|
3
87
|
## v0.126.0 - 2024-01-15
|
4
88
|
|
5
89
|
### Changed
|
package/README.md
CHANGED
@@ -93,7 +93,7 @@ const textStream = await streamText({
|
|
93
93
|
prompt: [
|
94
94
|
openai.ChatMessage.user([
|
95
95
|
{ type: "text", text: "Describe the image in detail:" },
|
96
|
-
{ type: "image",
|
96
|
+
{ type: "image", image, mimeType: "image/png" },
|
97
97
|
]),
|
98
98
|
],
|
99
99
|
});
|
@@ -184,14 +184,9 @@ const structureStream = await streamStructure({
|
|
184
184
|
prompt: "Generate 3 character descriptions for a fantasy role playing game.",
|
185
185
|
});
|
186
186
|
|
187
|
-
for await (const
|
188
|
-
|
189
|
-
|
190
|
-
console.log("partial value", unknownPartialStructure);
|
191
|
-
} else {
|
192
|
-
const fullyTypedStructure = part.value;
|
193
|
-
console.log("final value", fullyTypedStructure);
|
194
|
-
}
|
187
|
+
for await (const partialStructure of structureStream) {
|
188
|
+
console.clear();
|
189
|
+
console.log(partialStructure);
|
195
190
|
}
|
196
191
|
```
|
197
192
|
|
@@ -580,8 +575,8 @@ modelfusion.setLogFormat("detailed-object"); // log full events
|
|
580
575
|
- [Embed Value](https://modelfusion.dev/guide/function/embed)
|
581
576
|
- [Classify Value](https://modelfusion.dev/guide/function/classify)
|
582
577
|
- [Tools](https://modelfusion.dev/guide/tools)
|
583
|
-
- [
|
584
|
-
- [
|
578
|
+
- [Run Tool](https://modelfusion.dev/guide/tools/run-tool)
|
579
|
+
- [Run Tools](https://modelfusion.dev/guide/tools/run-tools)
|
585
580
|
- [Agent Loop](https://modelfusion.dev/guide/tools/agent-loop)
|
586
581
|
- [Available Tools](https://modelfusion.dev/guide/tools/available-tools/)
|
587
582
|
- [Custom Tools](https://modelfusion.dev/guide/tools/custom-tools)
|
package/core/api/postToApi.cjs
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.postToApi = exports.postJsonToApi = exports.createAudioMpegResponseHandler = exports.createTextResponseHandler = exports.createJsonResponseHandler = exports.createTextErrorResponseHandler = exports.createJsonErrorResponseHandler = void 0;
|
4
|
+
const UInt8Utils_js_1 = require("../../util/UInt8Utils.cjs");
|
4
5
|
const parseJSON_js_1 = require("../schema/parseJSON.cjs");
|
5
6
|
const ApiCallError_js_1 = require("./ApiCallError.cjs");
|
6
7
|
const createJsonErrorResponseHandler = ({ errorSchema, errorToMessage, isRetryable, }) => async ({ response, url, requestBodyValues }) => {
|
@@ -86,8 +87,7 @@ const createAudioMpegResponseHandler = () => async ({ response, url, requestBody
|
|
86
87
|
requestBodyValues,
|
87
88
|
});
|
88
89
|
}
|
89
|
-
|
90
|
-
return Buffer.from(arrayBuffer);
|
90
|
+
return (0, UInt8Utils_js_1.toUint8Array)(await response.arrayBuffer());
|
91
91
|
};
|
92
92
|
exports.createAudioMpegResponseHandler = createAudioMpegResponseHandler;
|
93
93
|
const postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, }) => (0, exports.postToApi)({
|
package/core/api/postToApi.d.ts
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { Schema } from "../schema/Schema.js";
|
3
2
|
import { ApiCallError } from "./ApiCallError.js";
|
4
3
|
export type ResponseHandler<T> = (options: {
|
@@ -16,7 +15,7 @@ export declare const createTextErrorResponseHandler: ({ isRetryable, }?: {
|
|
16
15
|
}) => ResponseHandler<ApiCallError>;
|
17
16
|
export declare const createJsonResponseHandler: <T>(responseSchema: Schema<T>) => ResponseHandler<T>;
|
18
17
|
export declare const createTextResponseHandler: () => ResponseHandler<string>;
|
19
|
-
export declare const createAudioMpegResponseHandler: () => ResponseHandler<
|
18
|
+
export declare const createAudioMpegResponseHandler: () => ResponseHandler<Uint8Array>;
|
20
19
|
export declare const postJsonToApi: <T>({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, }: {
|
21
20
|
url: string;
|
22
21
|
headers?: Record<string, string> | undefined;
|
@@ -29,7 +28,7 @@ export declare const postToApi: <T>({ url, headers, body, successfulResponseHand
|
|
29
28
|
url: string;
|
30
29
|
headers?: Record<string, string> | undefined;
|
31
30
|
body: {
|
32
|
-
content: string | FormData |
|
31
|
+
content: string | FormData | Uint8Array;
|
33
32
|
values: unknown;
|
34
33
|
};
|
35
34
|
failedResponseHandler: ResponseHandler<Error>;
|
package/core/api/postToApi.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { toUint8Array } from "../../util/UInt8Utils.js";
|
1
2
|
import { parseJSON, safeParseJSON } from "../schema/parseJSON.js";
|
2
3
|
import { ApiCallError } from "./ApiCallError.js";
|
3
4
|
export const createJsonErrorResponseHandler = ({ errorSchema, errorToMessage, isRetryable, }) => async ({ response, url, requestBodyValues }) => {
|
@@ -79,8 +80,7 @@ export const createAudioMpegResponseHandler = () => async ({ response, url, requ
|
|
79
80
|
requestBodyValues,
|
80
81
|
});
|
81
82
|
}
|
82
|
-
|
83
|
-
return Buffer.from(arrayBuffer);
|
83
|
+
return toUint8Array(await response.arrayBuffer());
|
84
84
|
};
|
85
85
|
export const postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, }) => postToApi({
|
86
86
|
url,
|
@@ -61,8 +61,8 @@ const detailedObjectObserver = {
|
|
61
61
|
if (v === undefined) {
|
62
62
|
return [k, undefined];
|
63
63
|
}
|
64
|
-
else if (v instanceof
|
65
|
-
return [k, "omitted<
|
64
|
+
else if (v instanceof Uint8Array) {
|
65
|
+
return [k, "omitted<Uint8Array>"];
|
66
66
|
}
|
67
67
|
else if (Array.isArray(v) &&
|
68
68
|
v.length > 20 &&
|
@@ -57,8 +57,8 @@ const detailedObjectObserver = {
|
|
57
57
|
if (v === undefined) {
|
58
58
|
return [k, undefined];
|
59
59
|
}
|
60
|
-
else if (v instanceof
|
61
|
-
return [k, "omitted<
|
60
|
+
else if (v instanceof Uint8Array) {
|
61
|
+
return [k, "omitted<Uint8Array>"];
|
62
62
|
}
|
63
63
|
else if (Array.isArray(v) &&
|
64
64
|
v.length > 20 &&
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.generateImage = void 0;
|
4
|
+
const UInt8Utils_js_1 = require("../../util/UInt8Utils.cjs");
|
4
5
|
const executeStandardCall_js_1 = require("../executeStandardCall.cjs");
|
5
6
|
async function generateImage({ model, prompt, fullResponse, ...options }) {
|
6
7
|
const callResponse = await (0, executeStandardCall_js_1.executeStandardCall)({
|
@@ -17,7 +18,7 @@ async function generateImage({ model, prompt, fullResponse, ...options }) {
|
|
17
18
|
},
|
18
19
|
});
|
19
20
|
const imagesBase64 = callResponse.value;
|
20
|
-
const images = imagesBase64.map(
|
21
|
+
const images = imagesBase64.map(UInt8Utils_js_1.base64ToUint8Array);
|
21
22
|
return fullResponse
|
22
23
|
? {
|
23
24
|
image: images[0],
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { FunctionOptions } from "../../core/FunctionOptions.js";
|
3
2
|
import { ModelCallMetadata } from "../ModelCallMetadata.js";
|
4
3
|
import { ImageGenerationModel, ImageGenerationModelSettings } from "./ImageGenerationModel.js";
|
@@ -23,21 +22,21 @@ import { ImageGenerationModel, ImageGenerationModelSettings } from "./ImageGener
|
|
23
22
|
* @param {PROMPT} prompt - The prompt to be used for image generation.
|
24
23
|
*
|
25
24
|
* @returns {Promise} - Returns a promise that resolves to the generated image.
|
26
|
-
* The image is a
|
25
|
+
* The image is a Uint8Array containing the image data in PNG format.
|
27
26
|
*/
|
28
27
|
export declare function generateImage<PROMPT>(args: {
|
29
28
|
model: ImageGenerationModel<PROMPT, ImageGenerationModelSettings>;
|
30
29
|
prompt: PROMPT;
|
31
30
|
fullResponse?: false;
|
32
|
-
} & FunctionOptions): Promise<
|
31
|
+
} & FunctionOptions): Promise<Uint8Array>;
|
33
32
|
export declare function generateImage<PROMPT>(args: {
|
34
33
|
model: ImageGenerationModel<PROMPT, ImageGenerationModelSettings>;
|
35
34
|
prompt: PROMPT;
|
36
35
|
fullResponse: true;
|
37
36
|
} & FunctionOptions): Promise<{
|
38
|
-
image:
|
37
|
+
image: Uint8Array;
|
39
38
|
imageBase64: string;
|
40
|
-
images:
|
39
|
+
images: Uint8Array[];
|
41
40
|
imagesBase64: string[];
|
42
41
|
rawResponse: unknown;
|
43
42
|
metadata: ModelCallMetadata;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { base64ToUint8Array } from "../../util/UInt8Utils.js";
|
1
2
|
import { executeStandardCall } from "../executeStandardCall.js";
|
2
3
|
export async function generateImage({ model, prompt, fullResponse, ...options }) {
|
3
4
|
const callResponse = await executeStandardCall({
|
@@ -14,7 +15,7 @@ export async function generateImage({ model, prompt, fullResponse, ...options })
|
|
14
15
|
},
|
15
16
|
});
|
16
17
|
const imagesBase64 = callResponse.value;
|
17
|
-
const images = imagesBase64.map(
|
18
|
+
const images = imagesBase64.map(base64ToUint8Array);
|
18
19
|
return fullResponse
|
19
20
|
? {
|
20
21
|
image: images[0],
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { BaseModelCallFinishedEvent, BaseModelCallStartedEvent } from "../ModelCallEvent.js";
|
3
2
|
export interface SpeechGenerationStartedEvent extends BaseModelCallStartedEvent {
|
4
3
|
functionType: "generate-speech";
|
@@ -7,7 +6,7 @@ export interface SpeechGenerationStartedEvent extends BaseModelCallStartedEvent
|
|
7
6
|
export type SpeechGenerationFinishedEventResult = {
|
8
7
|
status: "success";
|
9
8
|
rawResponse: unknown;
|
10
|
-
value:
|
9
|
+
value: Uint8Array;
|
11
10
|
} | {
|
12
11
|
status: "error";
|
13
12
|
error: unknown;
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { FunctionCallOptions } from "../../core/FunctionOptions.js";
|
3
2
|
import { Delta } from "../Delta.js";
|
4
3
|
import { Model, ModelSettings } from "../Model.js";
|
@@ -6,10 +5,10 @@ export interface SpeechGenerationModelSettings extends ModelSettings {
|
|
6
5
|
}
|
7
6
|
export interface SpeechGenerationModel<SETTINGS extends SpeechGenerationModelSettings = SpeechGenerationModelSettings> extends Model<SETTINGS> {
|
8
7
|
/**
|
9
|
-
* Generates an mp3 audio
|
8
|
+
* Generates an mp3 audio Uint8Array that contains the speech for the given text.
|
10
9
|
*/
|
11
|
-
doGenerateSpeechStandard(text: string, options: FunctionCallOptions): PromiseLike<
|
10
|
+
doGenerateSpeechStandard(text: string, options: FunctionCallOptions): PromiseLike<Uint8Array>;
|
12
11
|
}
|
13
12
|
export interface StreamingSpeechGenerationModel<SETTINGS extends SpeechGenerationModelSettings = SpeechGenerationModelSettings> extends SpeechGenerationModel<SETTINGS> {
|
14
|
-
doGenerateSpeechStreamDuplex(textStream: AsyncIterable<string>, options: FunctionCallOptions): PromiseLike<AsyncIterable<Delta<
|
13
|
+
doGenerateSpeechStreamDuplex(textStream: AsyncIterable<string>, options: FunctionCallOptions): PromiseLike<AsyncIterable<Delta<Uint8Array>>>;
|
15
14
|
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { FunctionOptions } from "../../core/FunctionOptions.js";
|
3
2
|
import { ModelCallMetadata } from "../ModelCallMetadata.js";
|
4
3
|
import { SpeechGenerationModel, SpeechGenerationModelSettings } from "./SpeechGenerationModel.js";
|
@@ -17,19 +16,19 @@ import { SpeechGenerationModel, SpeechGenerationModelSettings } from "./SpeechGe
|
|
17
16
|
* @param {SpeechGenerationModel<SpeechGenerationModelSettings>} model - The speech generation model.
|
18
17
|
* @param {string} text - The text to be converted to speech.
|
19
18
|
*
|
20
|
-
* @returns {Promise<
|
19
|
+
* @returns {Promise<Uint8Array>} - A promise that resolves to a Uint8Array containing the synthesized speech.
|
21
20
|
*/
|
22
21
|
export declare function generateSpeech(args: {
|
23
22
|
model: SpeechGenerationModel<SpeechGenerationModelSettings>;
|
24
23
|
text: string;
|
25
24
|
fullResponse?: false;
|
26
|
-
} & FunctionOptions): Promise<
|
25
|
+
} & FunctionOptions): Promise<Uint8Array>;
|
27
26
|
export declare function generateSpeech(args: {
|
28
27
|
model: SpeechGenerationModel<SpeechGenerationModelSettings>;
|
29
28
|
text: string;
|
30
29
|
fullResponse: true;
|
31
30
|
} & FunctionOptions): Promise<{
|
32
|
-
speech:
|
31
|
+
speech: Uint8Array;
|
33
32
|
rawResponse: unknown;
|
34
33
|
metadata: ModelCallMetadata;
|
35
34
|
}>;
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { FunctionOptions } from "../../core/FunctionOptions.js";
|
3
2
|
import { ModelCallMetadata } from "../ModelCallMetadata.js";
|
4
3
|
import { SpeechGenerationModelSettings, StreamingSpeechGenerationModel } from "./SpeechGenerationModel.js";
|
@@ -24,18 +23,18 @@ import { SpeechGenerationModelSettings, StreamingSpeechGenerationModel } from ".
|
|
24
23
|
* @param {AsyncIterable<string> | string} text - The text to be converted to speech. Can be a string or an async iterable of strings.
|
25
24
|
* @param {FunctionOptions} [options] - Optional function options.
|
26
25
|
*
|
27
|
-
* @returns {AsyncIterableResultPromise<
|
26
|
+
* @returns {AsyncIterableResultPromise<Uint8Array>} An async iterable promise that contains the synthesized speech chunks.
|
28
27
|
*/
|
29
28
|
export declare function streamSpeech(args: {
|
30
29
|
model: StreamingSpeechGenerationModel<SpeechGenerationModelSettings>;
|
31
30
|
text: AsyncIterable<string> | string;
|
32
31
|
fullResponse?: false;
|
33
|
-
} & FunctionOptions): Promise<AsyncIterable<
|
32
|
+
} & FunctionOptions): Promise<AsyncIterable<Uint8Array>>;
|
34
33
|
export declare function streamSpeech(args: {
|
35
34
|
model: StreamingSpeechGenerationModel<SpeechGenerationModelSettings>;
|
36
35
|
text: AsyncIterable<string> | string;
|
37
36
|
fullResponse: true;
|
38
37
|
} & FunctionOptions): Promise<{
|
39
|
-
speechStream: AsyncIterable<
|
38
|
+
speechStream: AsyncIterable<Uint8Array>;
|
40
39
|
metadata: Omit<ModelCallMetadata, "durationInMs" | "finishTimestamp">;
|
41
40
|
}>;
|
@@ -31,7 +31,7 @@ class StructureFromTextGenerationModel {
|
|
31
31
|
}
|
32
32
|
getModelWithJsonOutput(schema) {
|
33
33
|
if (this.template.withJsonOutput != null) {
|
34
|
-
return this.template.withJsonOutput
|
34
|
+
return this.template.withJsonOutput({
|
35
35
|
model: this.model,
|
36
36
|
schema,
|
37
37
|
});
|
@@ -40,7 +40,7 @@ class StructureFromTextGenerationModel {
|
|
40
40
|
}
|
41
41
|
async doGenerateStructure(schema, prompt, options) {
|
42
42
|
const { rawResponse, text } = await (0, generateText_js_1.generateText)({
|
43
|
-
model: this.
|
43
|
+
model: this.getModelWithJsonOutput(schema),
|
44
44
|
prompt: this.template.createPrompt(prompt, schema),
|
45
45
|
fullResponse: true,
|
46
46
|
...options,
|
@@ -28,7 +28,7 @@ export class StructureFromTextGenerationModel {
|
|
28
28
|
}
|
29
29
|
getModelWithJsonOutput(schema) {
|
30
30
|
if (this.template.withJsonOutput != null) {
|
31
|
-
return this.template.withJsonOutput
|
31
|
+
return this.template.withJsonOutput({
|
32
32
|
model: this.model,
|
33
33
|
schema,
|
34
34
|
});
|
@@ -37,7 +37,7 @@ export class StructureFromTextGenerationModel {
|
|
37
37
|
}
|
38
38
|
async doGenerateStructure(schema, prompt, options) {
|
39
39
|
const { rawResponse, text } = await generateText({
|
40
|
-
model: this.
|
40
|
+
model: this.getModelWithJsonOutput(schema),
|
41
41
|
prompt: this.template.createPrompt(prompt, schema),
|
42
42
|
fullResponse: true,
|
43
43
|
...options,
|
@@ -11,7 +11,7 @@ class StructureFromTextStreamingModel extends StructureFromTextGenerationModel_j
|
|
11
11
|
}
|
12
12
|
async doStreamStructure(schema, prompt, options) {
|
13
13
|
const textStream = await (0, streamText_js_1.streamText)({
|
14
|
-
model: this.
|
14
|
+
model: this.getModelWithJsonOutput(schema),
|
15
15
|
prompt: this.template.createPrompt(prompt, schema),
|
16
16
|
...options,
|
17
17
|
});
|
@@ -8,7 +8,7 @@ export class StructureFromTextStreamingModel extends StructureFromTextGeneration
|
|
8
8
|
}
|
9
9
|
async doStreamStructure(schema, prompt, options) {
|
10
10
|
const textStream = await streamText({
|
11
|
-
model: this.
|
11
|
+
model: this.getModelWithJsonOutput(schema),
|
12
12
|
prompt: this.template.createPrompt(prompt, schema),
|
13
13
|
...options,
|
14
14
|
});
|
@@ -10,6 +10,12 @@ async function streamStructure({ model, schema, prompt, fullResponse, ...options
|
|
10
10
|
: prompt;
|
11
11
|
let accumulatedText = "";
|
12
12
|
let lastStructure;
|
13
|
+
let resolveStructure;
|
14
|
+
let rejectStructure;
|
15
|
+
const structurePromise = new Promise((resolve, reject) => {
|
16
|
+
resolveStructure = resolve;
|
17
|
+
rejectStructure = reject;
|
18
|
+
});
|
13
19
|
const callResponse = await (0, executeStreamCall_js_1.executeStreamCall)({
|
14
20
|
functionType: "stream-structure",
|
15
21
|
input: {
|
@@ -29,29 +35,25 @@ async function streamStructure({ model, schema, prompt, fullResponse, ...options
|
|
29
35
|
// only send a new part into the stream when the partial structure has changed:
|
30
36
|
if (!(0, isDeepEqualData_js_1.isDeepEqualData)(lastStructure, latestStructure)) {
|
31
37
|
lastStructure = latestStructure;
|
32
|
-
return
|
33
|
-
isComplete: false,
|
34
|
-
value: lastStructure,
|
35
|
-
};
|
38
|
+
return lastStructure;
|
36
39
|
}
|
37
40
|
return undefined;
|
38
41
|
},
|
39
|
-
|
42
|
+
onDone: () => {
|
40
43
|
// process the final result (full type validation):
|
41
44
|
const parseResult = schema.validate(lastStructure);
|
42
|
-
if (
|
43
|
-
|
44
|
-
|
45
|
+
if (parseResult.success) {
|
46
|
+
resolveStructure(parseResult.data);
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
rejectStructure(parseResult.error);
|
45
50
|
}
|
46
|
-
return {
|
47
|
-
isComplete: true,
|
48
|
-
value: parseResult.data,
|
49
|
-
};
|
50
51
|
},
|
51
52
|
});
|
52
53
|
return fullResponse
|
53
54
|
? {
|
54
55
|
structureStream: callResponse.value,
|
56
|
+
structurePromise,
|
55
57
|
metadata: callResponse.metadata,
|
56
58
|
}
|
57
59
|
: callResponse.value;
|
@@ -1,25 +1,12 @@
|
|
1
|
+
import type { PartialDeep } from "type-fest";
|
1
2
|
import { FunctionOptions } from "../../core/FunctionOptions.js";
|
2
3
|
import { JsonSchemaProducer } from "../../core/schema/JsonSchemaProducer.js";
|
3
4
|
import { Schema } from "../../core/schema/Schema.js";
|
4
5
|
import { ModelCallMetadata } from "../ModelCallMetadata.js";
|
5
6
|
import { StructureStreamingModel } from "./StructureGenerationModel.js";
|
6
|
-
export type StructureStreamPart<STRUCTURE> = {
|
7
|
-
isComplete: false;
|
8
|
-
value: unknown;
|
9
|
-
} | {
|
10
|
-
isComplete: true;
|
11
|
-
value: STRUCTURE;
|
12
|
-
};
|
13
7
|
/**
|
14
8
|
* Generate and stream an object for a prompt and a structure definition.
|
15
9
|
*
|
16
|
-
* The final object is typed according to the structure definition.
|
17
|
-
* The partial objects are of unknown type,
|
18
|
-
* but are supposed to be partial version of the final object
|
19
|
-
* (unless the underlying model returns invalid data).
|
20
|
-
*
|
21
|
-
* The structure definition is used as part of the final prompt.
|
22
|
-
*
|
23
10
|
* For the OpenAI chat model, this generates and parses a function call with a single function.
|
24
11
|
*
|
25
12
|
* @see https://modelfusion.dev/guide/function/generate-structure
|
@@ -44,15 +31,8 @@ export type StructureStreamPart<STRUCTURE> = {
|
|
44
31
|
* ]
|
45
32
|
* });
|
46
33
|
*
|
47
|
-
* for await (const
|
48
|
-
*
|
49
|
-
* const unknownPartialStructure = part.value;
|
50
|
-
* // use your own logic to handle partial structures, e.g. with Zod .deepPartial()
|
51
|
-
* // it depends on your application at which points you want to act on the partial structures
|
52
|
-
* } else {
|
53
|
-
* const fullyTypedStructure = part.value;
|
54
|
-
* // ...
|
55
|
-
* }
|
34
|
+
* for await (const partialStructure of structureStream) {
|
35
|
+
* // ...
|
56
36
|
* }
|
57
37
|
*
|
58
38
|
* @param {StructureStreamingModel<PROMPT>} structureGenerator - The model to use for streaming
|
@@ -60,26 +40,28 @@ export type StructureStreamPart<STRUCTURE> = {
|
|
60
40
|
* @param {PROMPT | ((schema: Schema<STRUCTURE>) => PROMPT)} prompt
|
61
41
|
* The prompt to be used.
|
62
42
|
* You can also pass a function that takes the schema as an argument and returns the prompt.
|
63
|
-
* @param {FunctionOptions} [options] - Optional function options
|
64
43
|
*
|
65
44
|
* @returns {AsyncIterableResultPromise<StructureStreamPart<STRUCTURE>>}
|
66
45
|
* The async iterable result promise.
|
67
|
-
* Each part of the stream is
|
68
|
-
* It contains a isComplete flag to indicate whether the structure is complete,
|
69
|
-
* and a value that is either the partial structure or the final structure.
|
46
|
+
* Each part of the stream is a partial structure.
|
70
47
|
*/
|
71
48
|
export declare function streamStructure<STRUCTURE, PROMPT>(args: {
|
72
49
|
model: StructureStreamingModel<PROMPT>;
|
73
50
|
schema: Schema<STRUCTURE> & JsonSchemaProducer;
|
74
51
|
prompt: PROMPT | ((schema: Schema<STRUCTURE>) => PROMPT);
|
75
52
|
fullResponse?: false;
|
76
|
-
} & FunctionOptions): Promise<AsyncIterable<
|
53
|
+
} & FunctionOptions): Promise<AsyncIterable<PartialDeep<STRUCTURE, {
|
54
|
+
recurseIntoArrays: true;
|
55
|
+
}>>>;
|
77
56
|
export declare function streamStructure<STRUCTURE, PROMPT>(args: {
|
78
57
|
model: StructureStreamingModel<PROMPT>;
|
79
58
|
schema: Schema<STRUCTURE> & JsonSchemaProducer;
|
80
59
|
prompt: PROMPT | ((schema: Schema<STRUCTURE>) => PROMPT);
|
81
60
|
fullResponse: true;
|
82
61
|
} & FunctionOptions): Promise<{
|
83
|
-
structureStream: AsyncIterable<
|
62
|
+
structureStream: AsyncIterable<PartialDeep<STRUCTURE, {
|
63
|
+
recurseIntoArrays: true;
|
64
|
+
}>>;
|
65
|
+
structurePromise: PromiseLike<STRUCTURE>;
|
84
66
|
metadata: Omit<ModelCallMetadata, "durationInMs" | "finishTimestamp">;
|
85
67
|
}>;
|
@@ -7,6 +7,12 @@ export async function streamStructure({ model, schema, prompt, fullResponse, ...
|
|
7
7
|
: prompt;
|
8
8
|
let accumulatedText = "";
|
9
9
|
let lastStructure;
|
10
|
+
let resolveStructure;
|
11
|
+
let rejectStructure;
|
12
|
+
const structurePromise = new Promise((resolve, reject) => {
|
13
|
+
resolveStructure = resolve;
|
14
|
+
rejectStructure = reject;
|
15
|
+
});
|
10
16
|
const callResponse = await executeStreamCall({
|
11
17
|
functionType: "stream-structure",
|
12
18
|
input: {
|
@@ -26,29 +32,25 @@ export async function streamStructure({ model, schema, prompt, fullResponse, ...
|
|
26
32
|
// only send a new part into the stream when the partial structure has changed:
|
27
33
|
if (!isDeepEqualData(lastStructure, latestStructure)) {
|
28
34
|
lastStructure = latestStructure;
|
29
|
-
return
|
30
|
-
isComplete: false,
|
31
|
-
value: lastStructure,
|
32
|
-
};
|
35
|
+
return lastStructure;
|
33
36
|
}
|
34
37
|
return undefined;
|
35
38
|
},
|
36
|
-
|
39
|
+
onDone: () => {
|
37
40
|
// process the final result (full type validation):
|
38
41
|
const parseResult = schema.validate(lastStructure);
|
39
|
-
if (
|
40
|
-
|
41
|
-
|
42
|
+
if (parseResult.success) {
|
43
|
+
resolveStructure(parseResult.data);
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
rejectStructure(parseResult.error);
|
42
47
|
}
|
43
|
-
return {
|
44
|
-
isComplete: true,
|
45
|
-
value: parseResult.data,
|
46
|
-
};
|
47
48
|
},
|
48
49
|
});
|
49
50
|
return fullResponse
|
50
51
|
? {
|
51
52
|
structureStream: callResponse.value,
|
53
|
+
structurePromise,
|
52
54
|
metadata: callResponse.metadata,
|
53
55
|
}
|
54
56
|
: callResponse.value;
|
@@ -1,7 +1,15 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.validateContentIsString = void 0;
|
3
|
+
exports.validateContentIsString = exports.getImageAsBase64 = void 0;
|
4
|
+
const UInt8Utils_js_1 = require("../../../util/UInt8Utils.cjs");
|
4
5
|
const InvalidPromptError_js_1 = require("./InvalidPromptError.cjs");
|
6
|
+
function getImageAsBase64(image) {
|
7
|
+
if (typeof image === "string") {
|
8
|
+
return image;
|
9
|
+
}
|
10
|
+
return (0, UInt8Utils_js_1.uint8ArrayToBase64)(image);
|
11
|
+
}
|
12
|
+
exports.getImageAsBase64 = getImageAsBase64;
|
5
13
|
function validateContentIsString(content, prompt) {
|
6
14
|
if (typeof content !== "string") {
|
7
15
|
throw new InvalidPromptError_js_1.InvalidPromptError("Only text prompts are are supported by this prompt template.", prompt);
|
@@ -8,9 +8,9 @@ export interface TextPart {
|
|
8
8
|
export interface ImagePart {
|
9
9
|
type: "image";
|
10
10
|
/**
|
11
|
-
*
|
11
|
+
* Image data. Can either be a base64-encoded string or a Uint8Array.
|
12
12
|
*/
|
13
|
-
|
13
|
+
image: string | Uint8Array;
|
14
14
|
/**
|
15
15
|
* Optional mime type of the image.
|
16
16
|
*/
|
@@ -27,4 +27,5 @@ export interface ToolResponsePart {
|
|
27
27
|
id: string;
|
28
28
|
response: unknown;
|
29
29
|
}
|
30
|
+
export declare function getImageAsBase64(image: string | Uint8Array): string;
|
30
31
|
export declare function validateContentIsString(content: string | unknown, prompt: unknown): string;
|
@@ -1,4 +1,11 @@
|
|
1
|
+
import { uint8ArrayToBase64 } from "../../../util/UInt8Utils.js";
|
1
2
|
import { InvalidPromptError } from "./InvalidPromptError.js";
|
3
|
+
export function getImageAsBase64(image) {
|
4
|
+
if (typeof image === "string") {
|
5
|
+
return image;
|
6
|
+
}
|
7
|
+
return uint8ArrayToBase64(image);
|
8
|
+
}
|
2
9
|
export function validateContentIsString(content, prompt) {
|
3
10
|
if (typeof content !== "string") {
|
4
11
|
throw new InvalidPromptError("Only text prompts are are supported by this prompt template.", prompt);
|