modelfusion 0.104.0 → 0.105.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 +49 -0
- package/model-function/Delta.d.ts +1 -2
- package/model-function/executeStreamCall.cjs +6 -4
- package/model-function/executeStreamCall.d.ts +2 -2
- package/model-function/executeStreamCall.js +6 -4
- package/model-function/generate-speech/streamSpeech.cjs +1 -2
- package/model-function/generate-speech/streamSpeech.js +1 -2
- package/model-function/generate-structure/StructureFromTextStreamingModel.cjs +25 -29
- package/model-function/generate-structure/StructureFromTextStreamingModel.d.ts +3 -1
- package/model-function/generate-structure/StructureFromTextStreamingModel.js +25 -29
- package/model-function/generate-structure/StructureGenerationModel.d.ts +2 -0
- package/model-function/generate-structure/streamStructure.cjs +7 -8
- package/model-function/generate-structure/streamStructure.d.ts +1 -1
- package/model-function/generate-structure/streamStructure.js +7 -8
- package/model-function/generate-text/PromptTemplateFullTextModel.cjs +35 -0
- package/model-function/generate-text/PromptTemplateFullTextModel.d.ts +41 -0
- package/model-function/generate-text/PromptTemplateFullTextModel.js +31 -0
- package/model-function/generate-text/PromptTemplateTextStreamingModel.cjs +3 -0
- package/model-function/generate-text/PromptTemplateTextStreamingModel.d.ts +2 -1
- package/model-function/generate-text/PromptTemplateTextStreamingModel.js +3 -0
- package/model-function/generate-text/TextGenerationModel.d.ts +2 -1
- package/model-function/generate-text/index.cjs +1 -0
- package/model-function/generate-text/index.d.ts +1 -0
- package/model-function/generate-text/index.js +1 -0
- package/model-function/generate-text/prompt-template/AlpacaPromptTemplate.cjs +2 -2
- package/model-function/generate-text/prompt-template/AlpacaPromptTemplate.js +1 -1
- package/model-function/generate-text/prompt-template/ChatMLPromptTemplate.cjs +8 -5
- package/model-function/generate-text/prompt-template/ChatMLPromptTemplate.js +7 -4
- package/model-function/generate-text/prompt-template/ChatPrompt.cjs +42 -0
- package/model-function/generate-text/prompt-template/ChatPrompt.d.ts +27 -5
- package/model-function/generate-text/prompt-template/ChatPrompt.js +41 -1
- package/model-function/generate-text/prompt-template/{Content.cjs → ContentPart.cjs} +1 -1
- package/model-function/generate-text/prompt-template/ContentPart.d.ts +30 -0
- package/model-function/generate-text/prompt-template/{Content.js → ContentPart.js} +1 -1
- package/model-function/generate-text/prompt-template/InstructionPrompt.d.ts +3 -2
- package/model-function/generate-text/prompt-template/Llama2PromptTemplate.cjs +7 -4
- package/model-function/generate-text/prompt-template/Llama2PromptTemplate.js +5 -2
- package/model-function/generate-text/prompt-template/NeuralChatPromptTemplate.cjs +8 -4
- package/model-function/generate-text/prompt-template/NeuralChatPromptTemplate.js +6 -2
- package/model-function/generate-text/prompt-template/TextPromptTemplate.cjs +8 -4
- package/model-function/generate-text/prompt-template/TextPromptTemplate.js +6 -2
- package/model-function/generate-text/prompt-template/VicunaPromptTemplate.cjs +7 -3
- package/model-function/generate-text/prompt-template/VicunaPromptTemplate.js +6 -2
- package/model-function/generate-text/prompt-template/index.cjs +1 -1
- package/model-function/generate-text/prompt-template/index.d.ts +1 -1
- package/model-function/generate-text/prompt-template/index.js +1 -1
- package/model-function/generate-text/streamText.cjs +27 -28
- package/model-function/generate-text/streamText.d.ts +1 -0
- package/model-function/generate-text/streamText.js +27 -28
- package/model-provider/anthropic/AnthropicPromptTemplate.cjs +7 -3
- package/model-provider/anthropic/AnthropicPromptTemplate.js +5 -1
- package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +8 -14
- package/model-provider/anthropic/AnthropicTextGenerationModel.d.ts +11 -2
- package/model-provider/anthropic/AnthropicTextGenerationModel.js +8 -14
- package/model-provider/anthropic/AnthropicTextGenerationModel.test.cjs +44 -0
- package/model-provider/anthropic/AnthropicTextGenerationModel.test.js +42 -0
- package/model-provider/cohere/CohereTextGenerationModel.cjs +6 -44
- package/model-provider/cohere/CohereTextGenerationModel.d.ts +45 -11
- package/model-provider/cohere/CohereTextGenerationModel.js +7 -45
- package/model-provider/cohere/CohereTextGenerationModel.test.cjs +33 -0
- package/model-provider/cohere/CohereTextGenerationModel.test.d.ts +1 -0
- package/model-provider/cohere/CohereTextGenerationModel.test.js +31 -0
- package/model-provider/elevenlabs/ElevenLabsSpeechModel.cjs +1 -2
- package/model-provider/elevenlabs/ElevenLabsSpeechModel.js +1 -2
- package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.cjs +6 -1
- package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.js +6 -1
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +7 -14
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.d.ts +157 -6
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +8 -15
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.cjs +37 -0
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.d.ts +1 -0
- package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.js +35 -0
- package/model-provider/mistral/MistralChatModel.cjs +30 -104
- package/model-provider/mistral/MistralChatModel.d.ts +47 -14
- package/model-provider/mistral/MistralChatModel.js +30 -104
- package/model-provider/mistral/MistralChatModel.test.cjs +51 -0
- package/model-provider/mistral/MistralChatModel.test.d.ts +1 -0
- package/model-provider/mistral/MistralChatModel.test.js +49 -0
- package/model-provider/mistral/MistralPromptTemplate.cjs +11 -4
- package/model-provider/mistral/MistralPromptTemplate.js +9 -2
- package/model-provider/ollama/OllamaChatModel.cjs +7 -43
- package/model-provider/ollama/OllamaChatModel.d.ts +61 -9
- package/model-provider/ollama/OllamaChatModel.js +7 -43
- package/model-provider/ollama/OllamaChatModel.test.cjs +27 -0
- package/model-provider/ollama/OllamaChatModel.test.d.ts +1 -0
- package/model-provider/ollama/OllamaChatModel.test.js +25 -0
- package/model-provider/ollama/OllamaChatPromptTemplate.cjs +34 -4
- package/model-provider/ollama/OllamaChatPromptTemplate.js +34 -4
- package/model-provider/ollama/OllamaCompletionModel.cjs +22 -43
- package/model-provider/ollama/OllamaCompletionModel.d.ts +65 -9
- package/model-provider/ollama/OllamaCompletionModel.js +23 -44
- package/model-provider/ollama/OllamaCompletionModel.test.cjs +101 -13
- package/model-provider/ollama/OllamaCompletionModel.test.js +78 -13
- package/model-provider/openai/{chat/AbstractOpenAIChatModel.cjs → AbstractOpenAIChatModel.cjs} +71 -15
- package/model-provider/openai/{chat/AbstractOpenAIChatModel.d.ts → AbstractOpenAIChatModel.d.ts} +273 -19
- package/model-provider/openai/{chat/AbstractOpenAIChatModel.js → AbstractOpenAIChatModel.js} +71 -15
- package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.cjs → OpenAIChatFunctionCallStructureGenerationModel.cjs} +18 -2
- package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.d.ts → OpenAIChatFunctionCallStructureGenerationModel.d.ts} +41 -11
- package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.js → OpenAIChatFunctionCallStructureGenerationModel.js} +18 -2
- package/model-provider/openai/{chat/OpenAIChatMessage.d.ts → OpenAIChatMessage.d.ts} +3 -3
- package/model-provider/openai/{chat/OpenAIChatModel.cjs → OpenAIChatModel.cjs} +5 -5
- package/model-provider/openai/{chat/OpenAIChatModel.d.ts → OpenAIChatModel.d.ts} +12 -12
- package/model-provider/openai/{chat/OpenAIChatModel.js → OpenAIChatModel.js} +5 -5
- package/model-provider/openai/OpenAIChatModel.test.cjs +94 -0
- package/model-provider/openai/OpenAIChatModel.test.d.ts +1 -0
- package/model-provider/openai/OpenAIChatModel.test.js +92 -0
- package/model-provider/openai/OpenAIChatPromptTemplate.cjs +114 -0
- package/model-provider/openai/{chat/OpenAIChatPromptTemplate.d.ts → OpenAIChatPromptTemplate.d.ts} +3 -3
- package/model-provider/openai/OpenAIChatPromptTemplate.js +107 -0
- package/model-provider/openai/OpenAICompletionModel.cjs +32 -84
- package/model-provider/openai/OpenAICompletionModel.d.ts +27 -10
- package/model-provider/openai/OpenAICompletionModel.js +33 -85
- package/model-provider/openai/OpenAICompletionModel.test.cjs +53 -0
- package/model-provider/openai/OpenAICompletionModel.test.d.ts +1 -0
- package/model-provider/openai/OpenAICompletionModel.test.js +51 -0
- package/model-provider/openai/OpenAICostCalculator.cjs +1 -1
- package/model-provider/openai/OpenAICostCalculator.js +1 -1
- package/model-provider/openai/OpenAIFacade.cjs +2 -2
- package/model-provider/openai/OpenAIFacade.d.ts +3 -3
- package/model-provider/openai/OpenAIFacade.js +2 -2
- package/model-provider/openai/OpenAITranscriptionModel.d.ts +6 -6
- package/model-provider/openai/TikTokenTokenizer.d.ts +1 -1
- package/model-provider/openai/{chat/countOpenAIChatMessageTokens.cjs → countOpenAIChatMessageTokens.cjs} +2 -2
- package/model-provider/openai/{chat/countOpenAIChatMessageTokens.js → countOpenAIChatMessageTokens.js} +2 -2
- package/model-provider/openai/index.cjs +6 -6
- package/model-provider/openai/index.d.ts +5 -6
- package/model-provider/openai/index.js +5 -5
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.cjs +4 -4
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.d.ts +6 -6
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.js +4 -4
- package/package.json +5 -5
- package/test/JsonTestServer.cjs +33 -0
- package/test/JsonTestServer.d.ts +7 -0
- package/test/JsonTestServer.js +29 -0
- package/test/StreamingTestServer.cjs +55 -0
- package/test/StreamingTestServer.d.ts +7 -0
- package/test/StreamingTestServer.js +51 -0
- package/test/arrayFromAsync.cjs +13 -0
- package/test/arrayFromAsync.d.ts +1 -0
- package/test/arrayFromAsync.js +9 -0
- package/util/streaming/createEventSourceResponseHandler.cjs +9 -0
- package/util/streaming/createEventSourceResponseHandler.d.ts +4 -0
- package/util/streaming/createEventSourceResponseHandler.js +5 -0
- package/util/streaming/createJsonStreamResponseHandler.cjs +9 -0
- package/util/streaming/createJsonStreamResponseHandler.d.ts +4 -0
- package/util/streaming/createJsonStreamResponseHandler.js +5 -0
- package/util/streaming/parseEventSourceStreamAsAsyncIterable.cjs +52 -0
- package/util/streaming/parseEventSourceStreamAsAsyncIterable.d.ts +6 -0
- package/util/streaming/parseEventSourceStreamAsAsyncIterable.js +48 -0
- package/util/streaming/parseJsonStreamAsAsyncIterable.cjs +21 -0
- package/util/streaming/parseJsonStreamAsAsyncIterable.d.ts +6 -0
- package/util/streaming/parseJsonStreamAsAsyncIterable.js +17 -0
- package/model-function/generate-text/prompt-template/Content.d.ts +0 -25
- package/model-provider/openai/chat/OpenAIChatModel.test.cjs +0 -61
- package/model-provider/openai/chat/OpenAIChatModel.test.js +0 -59
- package/model-provider/openai/chat/OpenAIChatPromptTemplate.cjs +0 -70
- package/model-provider/openai/chat/OpenAIChatPromptTemplate.js +0 -63
- package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +0 -156
- package/model-provider/openai/chat/OpenAIChatStreamIterable.d.ts +0 -19
- package/model-provider/openai/chat/OpenAIChatStreamIterable.js +0 -152
- /package/model-provider/{openai/chat/OpenAIChatModel.test.d.ts → anthropic/AnthropicTextGenerationModel.test.d.ts} +0 -0
- /package/model-provider/openai/{chat/OpenAIChatMessage.cjs → OpenAIChatMessage.cjs} +0 -0
- /package/model-provider/openai/{chat/OpenAIChatMessage.js → OpenAIChatMessage.js} +0 -0
- /package/model-provider/openai/{chat/countOpenAIChatMessageTokens.d.ts → countOpenAIChatMessageTokens.d.ts} +0 -0
@@ -2,15 +2,14 @@ import { z } from "zod";
|
|
2
2
|
import { ApiCallError } from "../../core/api/ApiCallError.js";
|
3
3
|
import { callWithRetryAndThrottle } from "../../core/api/callWithRetryAndThrottle.js";
|
4
4
|
import { postJsonToApi } from "../../core/api/postToApi.js";
|
5
|
-
import { ZodSchema } from "../../core/schema/ZodSchema.js";
|
5
|
+
import { ZodSchema, zodSchema } from "../../core/schema/ZodSchema.js";
|
6
6
|
import { safeParseJSON } from "../../core/schema/parseJSON.js";
|
7
7
|
import { AbstractModel } from "../../model-function/AbstractModel.js";
|
8
8
|
import { PromptTemplateTextStreamingModel } from "../../model-function/generate-text/PromptTemplateTextStreamingModel.js";
|
9
9
|
import { textGenerationModelProperties, } from "../../model-function/generate-text/TextGenerationModel.js";
|
10
10
|
import { TextGenerationToolCallModel, } from "../../tool/generate-tool-call/TextGenerationToolCallModel.js";
|
11
11
|
import { TextGenerationToolCallsOrGenerateTextModel, } from "../../tool/generate-tool-calls-or-text/TextGenerationToolCallsOrGenerateTextModel.js";
|
12
|
-
import {
|
13
|
-
import { parseJsonStream } from "../../util/streaming/parseJsonStream.js";
|
12
|
+
import { createJsonStreamResponseHandler } from "../../util/streaming/createJsonStreamResponseHandler.js";
|
14
13
|
import { OllamaApiConfiguration } from "./OllamaApiConfiguration.js";
|
15
14
|
import { failedOllamaCallResponseHandler } from "./OllamaError.js";
|
16
15
|
export class OllamaCompletionModel extends AbstractModel {
|
@@ -132,6 +131,10 @@ export class OllamaCompletionModel extends AbstractModel {
|
|
132
131
|
responseFormat: OllamaCompletionResponseFormat.deltaIterable,
|
133
132
|
});
|
134
133
|
}
|
134
|
+
extractTextDelta(delta) {
|
135
|
+
const chunk = delta;
|
136
|
+
return chunk.done === true ? undefined : chunk.response;
|
137
|
+
}
|
135
138
|
asToolCallGenerationModel(promptTemplate) {
|
136
139
|
return new TextGenerationToolCallModel({
|
137
140
|
model: this,
|
@@ -147,11 +150,25 @@ export class OllamaCompletionModel extends AbstractModel {
|
|
147
150
|
withTextPrompt() {
|
148
151
|
return this.withPromptTemplate({
|
149
152
|
format(prompt) {
|
150
|
-
return { prompt
|
153
|
+
return { prompt };
|
151
154
|
},
|
152
155
|
stopSequences: [],
|
153
156
|
});
|
154
157
|
}
|
158
|
+
/**
|
159
|
+
* Maps the prompt for a text version of the Ollama completion prompt template (without image support).
|
160
|
+
*/
|
161
|
+
withTextPromptTemplate(promptTemplate) {
|
162
|
+
return new PromptTemplateTextStreamingModel({
|
163
|
+
model: this.withTextPrompt().withSettings({
|
164
|
+
stopSequences: [
|
165
|
+
...(this.settings.stopSequences ?? []),
|
166
|
+
...promptTemplate.stopSequences,
|
167
|
+
],
|
168
|
+
}),
|
169
|
+
promptTemplate,
|
170
|
+
});
|
171
|
+
}
|
155
172
|
withPromptTemplate(promptTemplate) {
|
156
173
|
return new PromptTemplateTextStreamingModel({
|
157
174
|
model: this.withSettings({
|
@@ -180,7 +197,7 @@ const ollamaCompletionResponseSchema = z.object({
|
|
180
197
|
eval_duration: z.number(),
|
181
198
|
context: z.array(z.number()).optional(),
|
182
199
|
});
|
183
|
-
const
|
200
|
+
const ollamaCompletionStreamChunkSchema = zodSchema(z.discriminatedUnion("done", [
|
184
201
|
z.object({
|
185
202
|
done: z.literal(false),
|
186
203
|
model: z.string(),
|
@@ -202,44 +219,6 @@ const ollamaCompletionStreamSchema = new ZodSchema(z.discriminatedUnion("done",
|
|
202
219
|
context: z.array(z.number()).optional(),
|
203
220
|
}),
|
204
221
|
]));
|
205
|
-
async function createOllamaFullDeltaIterableQueue(stream) {
|
206
|
-
const queue = new AsyncQueue();
|
207
|
-
let accumulatedText = "";
|
208
|
-
// process the stream asynchonously (no 'await' on purpose):
|
209
|
-
parseJsonStream({
|
210
|
-
stream,
|
211
|
-
schema: ollamaCompletionStreamSchema,
|
212
|
-
process(event) {
|
213
|
-
if (event.done === true) {
|
214
|
-
queue.push({
|
215
|
-
type: "delta",
|
216
|
-
fullDelta: {
|
217
|
-
content: accumulatedText,
|
218
|
-
isComplete: true,
|
219
|
-
delta: "",
|
220
|
-
},
|
221
|
-
valueDelta: "",
|
222
|
-
});
|
223
|
-
}
|
224
|
-
else {
|
225
|
-
accumulatedText += event.response;
|
226
|
-
queue.push({
|
227
|
-
type: "delta",
|
228
|
-
fullDelta: {
|
229
|
-
content: accumulatedText,
|
230
|
-
isComplete: false,
|
231
|
-
delta: event.response,
|
232
|
-
},
|
233
|
-
valueDelta: event.response,
|
234
|
-
});
|
235
|
-
}
|
236
|
-
},
|
237
|
-
onDone() {
|
238
|
-
queue.close();
|
239
|
-
},
|
240
|
-
});
|
241
|
-
return queue;
|
242
|
-
}
|
243
222
|
export const OllamaCompletionResponseFormat = {
|
244
223
|
/**
|
245
224
|
* Returns the response as a JSON object.
|
@@ -289,6 +268,6 @@ export const OllamaCompletionResponseFormat = {
|
|
289
268
|
*/
|
290
269
|
deltaIterable: {
|
291
270
|
stream: true,
|
292
|
-
handler:
|
271
|
+
handler: createJsonStreamResponseHandler(ollamaCompletionStreamChunkSchema),
|
293
272
|
},
|
294
273
|
};
|
@@ -1,25 +1,48 @@
|
|
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
26
|
const assert_1 = require("assert");
|
4
|
-
const
|
5
|
-
const node_1 = require("msw/node");
|
27
|
+
const zod_1 = require("zod");
|
6
28
|
const ApiCallError_js_1 = require("../../core/api/ApiCallError.cjs");
|
7
29
|
const retryNever_js_1 = require("../../core/api/retryNever.cjs");
|
30
|
+
const ZodSchema_js_1 = require("../../core/schema/ZodSchema.cjs");
|
31
|
+
const jsonStructurePrompt_js_1 = require("../../model-function/generate-structure/jsonStructurePrompt.cjs");
|
32
|
+
const streamStructure_js_1 = require("../../model-function/generate-structure/streamStructure.cjs");
|
8
33
|
const generateText_js_1 = require("../../model-function/generate-text/generateText.cjs");
|
34
|
+
const TextPrompt = __importStar(require("../../model-function/generate-text/prompt-template/TextPromptTemplate.cjs"));
|
35
|
+
const streamText_js_1 = require("../../model-function/generate-text/streamText.cjs");
|
36
|
+
const JsonTestServer_js_1 = require("../../test/JsonTestServer.cjs");
|
37
|
+
const StreamingTestServer_js_1 = require("../../test/StreamingTestServer.cjs");
|
38
|
+
const arrayFromAsync_js_1 = require("../../test/arrayFromAsync.cjs");
|
9
39
|
const OllamaApiConfiguration_js_1 = require("./OllamaApiConfiguration.cjs");
|
10
40
|
const OllamaCompletionModel_js_1 = require("./OllamaCompletionModel.cjs");
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
12
|
-
let responseBodyJson = {};
|
13
|
-
const server = (0, node_1.setupServer)(msw_1.http.post("http://127.0.0.1:11434/api/generate", () => msw_1.HttpResponse.json(responseBodyJson)));
|
14
|
-
beforeAll(() => server.listen());
|
15
|
-
beforeEach(() => {
|
16
|
-
responseBodyJson = {};
|
17
|
-
});
|
18
|
-
afterEach(() => server.resetHandlers());
|
19
|
-
afterAll(() => server.close());
|
20
41
|
describe("generateText", () => {
|
42
|
+
const server = new JsonTestServer_js_1.JsonTestServer("http://127.0.0.1:11434/api/generate");
|
43
|
+
server.setupTestEnvironment();
|
21
44
|
it("should return the generated text", async () => {
|
22
|
-
responseBodyJson = {
|
45
|
+
server.responseBodyJson = {
|
23
46
|
model: "test-model",
|
24
47
|
created_at: "2023-08-04T19:22:45.499127Z",
|
25
48
|
response: "test response",
|
@@ -40,7 +63,7 @@ describe("generateText", () => {
|
|
40
63
|
expect(result).toEqual("test response");
|
41
64
|
});
|
42
65
|
it("should throw retryable ApiCallError when Ollama is overloaded", async () => {
|
43
|
-
responseBodyJson = {
|
66
|
+
server.responseBodyJson = {
|
44
67
|
model: "",
|
45
68
|
created_at: "0001-01-01T00:00:00Z",
|
46
69
|
response: "",
|
@@ -61,3 +84,68 @@ describe("generateText", () => {
|
|
61
84
|
}
|
62
85
|
});
|
63
86
|
});
|
87
|
+
describe("streamText", () => {
|
88
|
+
const server = new StreamingTestServer_js_1.StreamingTestServer("http://127.0.0.1:11434/api/generate");
|
89
|
+
server.setupTestEnvironment();
|
90
|
+
it("should return a text stream", async () => {
|
91
|
+
server.responseChunks = [
|
92
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":"Hello","done":false}\n`,
|
93
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":", ","done":false}\n`,
|
94
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":"world!","done":false}\n`,
|
95
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:19.697067Z","response":"",` +
|
96
|
+
`"done":true,"context":[123,456,789],"total_duration":2165354041,"load_duration":1293958,` +
|
97
|
+
`"prompt_eval_count":5,"prompt_eval_duration":193273000,"eval_count":136,"eval_duration":1966852000}\n`,
|
98
|
+
];
|
99
|
+
const stream = await (0, streamText_js_1.streamText)(new OllamaCompletionModel_js_1.OllamaCompletionModel({ model: "mistral:text" }).withTextPrompt(), "hello");
|
100
|
+
// note: space moved to last chunk bc of trimming
|
101
|
+
expect(await (0, arrayFromAsync_js_1.arrayFromAsync)(stream)).toStrictEqual([
|
102
|
+
"Hello",
|
103
|
+
",",
|
104
|
+
" world!",
|
105
|
+
]);
|
106
|
+
});
|
107
|
+
});
|
108
|
+
describe("streamStructure", () => {
|
109
|
+
const server = new StreamingTestServer_js_1.StreamingTestServer("http://127.0.0.1:11434/api/generate");
|
110
|
+
server.setupTestEnvironment();
|
111
|
+
it("should return a text stream", async () => {
|
112
|
+
server.responseChunks = [
|
113
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.253175Z","response":"{","done":false}\n`,
|
114
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.273505Z","response":"\\n","done":false}\n`,
|
115
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.293192Z","response":" ","done":false}\n`,
|
116
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.312446Z","response":" \\"","done":false}\n`,
|
117
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.332021Z","response":"name","done":false}\n`,
|
118
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.351128Z","response":"\\":","done":false}\n`,
|
119
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.372082Z","response":" \\"","done":false}\n`,
|
120
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.391903Z","response":"M","done":false}\n`,
|
121
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.411056Z","response":"ike","done":false}\n`,
|
122
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.430789Z","response":"\\"","done":false}\n`,
|
123
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.450216Z","response":"\\n","done":false}\n`,
|
124
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.47009Z","response":"}","done":false}\n`,
|
125
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.48885Z","response":"","done":true,` +
|
126
|
+
`"total_duration":521893000,"load_duration":957666,"prompt_eval_count":74,"prompt_eval_duration":302508000,` +
|
127
|
+
`"eval_count":12,"eval_duration":215282000}\n`,
|
128
|
+
];
|
129
|
+
const stream = await (0, streamStructure_js_1.streamStructure)(new OllamaCompletionModel_js_1.OllamaCompletionModel({
|
130
|
+
model: "mistral:text",
|
131
|
+
format: "json",
|
132
|
+
raw: true,
|
133
|
+
})
|
134
|
+
.withTextPromptTemplate(TextPrompt.instruction())
|
135
|
+
.asStructureGenerationModel((0, jsonStructurePrompt_js_1.jsonStructurePrompt)((instruction, schema) => ({
|
136
|
+
system: "JSON schema: \n" +
|
137
|
+
JSON.stringify(schema.getJsonSchema()) +
|
138
|
+
"\n\n" +
|
139
|
+
"Respond only using JSON that matches the above schema.",
|
140
|
+
instruction,
|
141
|
+
}))), (0, ZodSchema_js_1.zodSchema)(zod_1.z.object({ name: zod_1.z.string() })), "generate a name");
|
142
|
+
// note: space moved to last chunk bc of trimming
|
143
|
+
expect(await (0, arrayFromAsync_js_1.arrayFromAsync)(stream)).toStrictEqual([
|
144
|
+
{ isComplete: false, value: {} },
|
145
|
+
{ isComplete: false, value: { name: "" } },
|
146
|
+
{ isComplete: false, value: { name: "M" } },
|
147
|
+
{ isComplete: false, value: { name: "Mike" } },
|
148
|
+
{ isComplete: true, value: { name: "Mike" } },
|
149
|
+
]);
|
150
|
+
});
|
151
|
+
});
|
@@ -1,23 +1,23 @@
|
|
1
1
|
import { fail } from "assert";
|
2
|
-
import {
|
3
|
-
import { setupServer } from "msw/node";
|
2
|
+
import { z } from "zod";
|
4
3
|
import { ApiCallError } from "../../core/api/ApiCallError.js";
|
5
4
|
import { retryNever } from "../../core/api/retryNever.js";
|
5
|
+
import { zodSchema } from "../../core/schema/ZodSchema.js";
|
6
|
+
import { jsonStructurePrompt } from "../../model-function/generate-structure/jsonStructurePrompt.js";
|
7
|
+
import { streamStructure } from "../../model-function/generate-structure/streamStructure.js";
|
6
8
|
import { generateText } from "../../model-function/generate-text/generateText.js";
|
9
|
+
import * as TextPrompt from "../../model-function/generate-text/prompt-template/TextPromptTemplate.js";
|
10
|
+
import { streamText } from "../../model-function/generate-text/streamText.js";
|
11
|
+
import { JsonTestServer } from "../../test/JsonTestServer.js";
|
12
|
+
import { StreamingTestServer } from "../../test/StreamingTestServer.js";
|
13
|
+
import { arrayFromAsync } from "../../test/arrayFromAsync.js";
|
7
14
|
import { OllamaApiConfiguration } from "./OllamaApiConfiguration.js";
|
8
15
|
import { OllamaCompletionModel } from "./OllamaCompletionModel.js";
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
10
|
-
let responseBodyJson = {};
|
11
|
-
const server = setupServer(http.post("http://127.0.0.1:11434/api/generate", () => HttpResponse.json(responseBodyJson)));
|
12
|
-
beforeAll(() => server.listen());
|
13
|
-
beforeEach(() => {
|
14
|
-
responseBodyJson = {};
|
15
|
-
});
|
16
|
-
afterEach(() => server.resetHandlers());
|
17
|
-
afterAll(() => server.close());
|
18
16
|
describe("generateText", () => {
|
17
|
+
const server = new JsonTestServer("http://127.0.0.1:11434/api/generate");
|
18
|
+
server.setupTestEnvironment();
|
19
19
|
it("should return the generated text", async () => {
|
20
|
-
responseBodyJson = {
|
20
|
+
server.responseBodyJson = {
|
21
21
|
model: "test-model",
|
22
22
|
created_at: "2023-08-04T19:22:45.499127Z",
|
23
23
|
response: "test response",
|
@@ -38,7 +38,7 @@ describe("generateText", () => {
|
|
38
38
|
expect(result).toEqual("test response");
|
39
39
|
});
|
40
40
|
it("should throw retryable ApiCallError when Ollama is overloaded", async () => {
|
41
|
-
responseBodyJson = {
|
41
|
+
server.responseBodyJson = {
|
42
42
|
model: "",
|
43
43
|
created_at: "0001-01-01T00:00:00Z",
|
44
44
|
response: "",
|
@@ -59,3 +59,68 @@ describe("generateText", () => {
|
|
59
59
|
}
|
60
60
|
});
|
61
61
|
});
|
62
|
+
describe("streamText", () => {
|
63
|
+
const server = new StreamingTestServer("http://127.0.0.1:11434/api/generate");
|
64
|
+
server.setupTestEnvironment();
|
65
|
+
it("should return a text stream", async () => {
|
66
|
+
server.responseChunks = [
|
67
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":"Hello","done":false}\n`,
|
68
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":", ","done":false}\n`,
|
69
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:17.715003Z","response":"world!","done":false}\n`,
|
70
|
+
`{"model":"mistral:text","created_at":"2023-12-24T16:11:19.697067Z","response":"",` +
|
71
|
+
`"done":true,"context":[123,456,789],"total_duration":2165354041,"load_duration":1293958,` +
|
72
|
+
`"prompt_eval_count":5,"prompt_eval_duration":193273000,"eval_count":136,"eval_duration":1966852000}\n`,
|
73
|
+
];
|
74
|
+
const stream = await streamText(new OllamaCompletionModel({ model: "mistral:text" }).withTextPrompt(), "hello");
|
75
|
+
// note: space moved to last chunk bc of trimming
|
76
|
+
expect(await arrayFromAsync(stream)).toStrictEqual([
|
77
|
+
"Hello",
|
78
|
+
",",
|
79
|
+
" world!",
|
80
|
+
]);
|
81
|
+
});
|
82
|
+
});
|
83
|
+
describe("streamStructure", () => {
|
84
|
+
const server = new StreamingTestServer("http://127.0.0.1:11434/api/generate");
|
85
|
+
server.setupTestEnvironment();
|
86
|
+
it("should return a text stream", async () => {
|
87
|
+
server.responseChunks = [
|
88
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.253175Z","response":"{","done":false}\n`,
|
89
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.273505Z","response":"\\n","done":false}\n`,
|
90
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.293192Z","response":" ","done":false}\n`,
|
91
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.312446Z","response":" \\"","done":false}\n`,
|
92
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.332021Z","response":"name","done":false}\n`,
|
93
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.351128Z","response":"\\":","done":false}\n`,
|
94
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.372082Z","response":" \\"","done":false}\n`,
|
95
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.391903Z","response":"M","done":false}\n`,
|
96
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.411056Z","response":"ike","done":false}\n`,
|
97
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.430789Z","response":"\\"","done":false}\n`,
|
98
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.450216Z","response":"\\n","done":false}\n`,
|
99
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.47009Z","response":"}","done":false}\n`,
|
100
|
+
`{"model":"mistral:text","created_at":"2023-12-25T11:48:02.48885Z","response":"","done":true,` +
|
101
|
+
`"total_duration":521893000,"load_duration":957666,"prompt_eval_count":74,"prompt_eval_duration":302508000,` +
|
102
|
+
`"eval_count":12,"eval_duration":215282000}\n`,
|
103
|
+
];
|
104
|
+
const stream = await streamStructure(new OllamaCompletionModel({
|
105
|
+
model: "mistral:text",
|
106
|
+
format: "json",
|
107
|
+
raw: true,
|
108
|
+
})
|
109
|
+
.withTextPromptTemplate(TextPrompt.instruction())
|
110
|
+
.asStructureGenerationModel(jsonStructurePrompt((instruction, schema) => ({
|
111
|
+
system: "JSON schema: \n" +
|
112
|
+
JSON.stringify(schema.getJsonSchema()) +
|
113
|
+
"\n\n" +
|
114
|
+
"Respond only using JSON that matches the above schema.",
|
115
|
+
instruction,
|
116
|
+
}))), zodSchema(z.object({ name: z.string() })), "generate a name");
|
117
|
+
// note: space moved to last chunk bc of trimming
|
118
|
+
expect(await arrayFromAsync(stream)).toStrictEqual([
|
119
|
+
{ isComplete: false, value: {} },
|
120
|
+
{ isComplete: false, value: { name: "" } },
|
121
|
+
{ isComplete: false, value: { name: "M" } },
|
122
|
+
{ isComplete: false, value: { name: "Mike" } },
|
123
|
+
{ isComplete: true, value: { name: "Mike" } },
|
124
|
+
]);
|
125
|
+
});
|
126
|
+
});
|
package/model-provider/openai/{chat/AbstractOpenAIChatModel.cjs → AbstractOpenAIChatModel.cjs}
RENAMED
@@ -2,14 +2,14 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.OpenAIChatResponseFormat = exports.AbstractOpenAIChatModel = void 0;
|
4
4
|
const zod_1 = require("zod");
|
5
|
-
const callWithRetryAndThrottle_js_1 = require("
|
6
|
-
const postToApi_js_1 = require("
|
7
|
-
const
|
8
|
-
const
|
9
|
-
const
|
10
|
-
const
|
11
|
-
const
|
12
|
-
const
|
5
|
+
const callWithRetryAndThrottle_js_1 = require("../../core/api/callWithRetryAndThrottle.cjs");
|
6
|
+
const postToApi_js_1 = require("../../core/api/postToApi.cjs");
|
7
|
+
const ZodSchema_js_1 = require("../../core/schema/ZodSchema.cjs");
|
8
|
+
const parseJSON_js_1 = require("../../core/schema/parseJSON.cjs");
|
9
|
+
const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs");
|
10
|
+
const createEventSourceResponseHandler_js_1 = require("../../util/streaming/createEventSourceResponseHandler.cjs");
|
11
|
+
const OpenAIApiConfiguration_js_1 = require("./OpenAIApiConfiguration.cjs");
|
12
|
+
const OpenAIError_js_1 = require("./OpenAIError.cjs");
|
13
13
|
/**
|
14
14
|
* Abstract text generation model that calls an API that is compatible with the OpenAI chat API.
|
15
15
|
*
|
@@ -105,9 +105,21 @@ class AbstractOpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
105
105
|
doStreamText(prompt, options) {
|
106
106
|
return this.callAPI(prompt, {
|
107
107
|
...options,
|
108
|
-
responseFormat: exports.OpenAIChatResponseFormat.
|
108
|
+
responseFormat: exports.OpenAIChatResponseFormat.deltaIterable,
|
109
109
|
});
|
110
110
|
}
|
111
|
+
extractTextDelta(delta) {
|
112
|
+
const chunk = delta;
|
113
|
+
if (chunk.object !== "chat.completion.chunk") {
|
114
|
+
return undefined;
|
115
|
+
}
|
116
|
+
const chatChunk = chunk;
|
117
|
+
const firstChoice = chatChunk.choices[0];
|
118
|
+
if (firstChoice.index > 0) {
|
119
|
+
return undefined;
|
120
|
+
}
|
121
|
+
return firstChoice.delta.content ?? undefined;
|
122
|
+
}
|
111
123
|
async doGenerateToolCall(tool, prompt, options) {
|
112
124
|
const response = await this.callAPI(prompt, {
|
113
125
|
...options,
|
@@ -220,6 +232,54 @@ const openAIChatResponseSchema = zod_1.z.object({
|
|
220
232
|
total_tokens: zod_1.z.number(),
|
221
233
|
}),
|
222
234
|
});
|
235
|
+
const chatCompletionChunkSchema = zod_1.z.object({
|
236
|
+
object: zod_1.z.literal("chat.completion.chunk"),
|
237
|
+
id: zod_1.z.string(),
|
238
|
+
choices: zod_1.z.array(zod_1.z.object({
|
239
|
+
delta: zod_1.z.object({
|
240
|
+
role: zod_1.z.enum(["assistant", "user"]).optional(),
|
241
|
+
content: zod_1.z.string().nullable().optional(),
|
242
|
+
function_call: zod_1.z
|
243
|
+
.object({
|
244
|
+
name: zod_1.z.string().optional(),
|
245
|
+
arguments: zod_1.z.string().optional(),
|
246
|
+
})
|
247
|
+
.optional(),
|
248
|
+
tool_calls: zod_1.z
|
249
|
+
.array(zod_1.z.object({
|
250
|
+
id: zod_1.z.string(),
|
251
|
+
type: zod_1.z.literal("function"),
|
252
|
+
function: zod_1.z.object({
|
253
|
+
name: zod_1.z.string(),
|
254
|
+
arguments: zod_1.z.string(),
|
255
|
+
}),
|
256
|
+
}))
|
257
|
+
.optional(),
|
258
|
+
}),
|
259
|
+
finish_reason: zod_1.z
|
260
|
+
.enum([
|
261
|
+
"stop",
|
262
|
+
"length",
|
263
|
+
"tool_calls",
|
264
|
+
"content_filter",
|
265
|
+
"function_call",
|
266
|
+
])
|
267
|
+
.nullable()
|
268
|
+
.optional(),
|
269
|
+
index: zod_1.z.number(),
|
270
|
+
})),
|
271
|
+
created: zod_1.z.number(),
|
272
|
+
model: zod_1.z.string(),
|
273
|
+
system_fingerprint: zod_1.z.string().optional().nullable(),
|
274
|
+
});
|
275
|
+
const openaiChatChunkSchema = (0, ZodSchema_js_1.zodSchema)(zod_1.z.union([
|
276
|
+
chatCompletionChunkSchema,
|
277
|
+
zod_1.z.object({
|
278
|
+
object: zod_1.z.string().refine((obj) => obj !== "chat.completion.chunk", {
|
279
|
+
message: "Object must be 'chat.completion.chunk'",
|
280
|
+
}),
|
281
|
+
}),
|
282
|
+
]));
|
223
283
|
exports.OpenAIChatResponseFormat = {
|
224
284
|
/**
|
225
285
|
* Returns the response as a JSON object.
|
@@ -231,12 +291,8 @@ exports.OpenAIChatResponseFormat = {
|
|
231
291
|
/**
|
232
292
|
* Returns an async iterable over the text deltas (only the tex different of the first choice).
|
233
293
|
*/
|
234
|
-
|
235
|
-
stream: true,
|
236
|
-
handler: async ({ response }) => (0, OpenAIChatStreamIterable_js_1.createOpenAIChatDeltaIterableQueue)(response.body, (delta) => delta[0]?.delta?.content ?? ""),
|
237
|
-
},
|
238
|
-
structureDeltaIterable: {
|
294
|
+
deltaIterable: {
|
239
295
|
stream: true,
|
240
|
-
handler:
|
296
|
+
handler: (0, createEventSourceResponseHandler_js_1.createEventSourceResponseHandler)(openaiChatChunkSchema),
|
241
297
|
},
|
242
298
|
};
|