modelfusion 0.103.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.
Files changed (181) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/model-function/Delta.d.ts +1 -2
  3. package/model-function/executeStreamCall.cjs +6 -4
  4. package/model-function/executeStreamCall.d.ts +2 -2
  5. package/model-function/executeStreamCall.js +6 -4
  6. package/model-function/generate-speech/streamSpeech.cjs +1 -2
  7. package/model-function/generate-speech/streamSpeech.js +1 -2
  8. package/model-function/generate-structure/StructureFromTextStreamingModel.cjs +25 -29
  9. package/model-function/generate-structure/StructureFromTextStreamingModel.d.ts +3 -1
  10. package/model-function/generate-structure/StructureFromTextStreamingModel.js +25 -29
  11. package/model-function/generate-structure/StructureGenerationModel.d.ts +2 -0
  12. package/model-function/generate-structure/streamStructure.cjs +7 -8
  13. package/model-function/generate-structure/streamStructure.d.ts +1 -1
  14. package/model-function/generate-structure/streamStructure.js +7 -8
  15. package/model-function/generate-text/PromptTemplateFullTextModel.cjs +35 -0
  16. package/model-function/generate-text/PromptTemplateFullTextModel.d.ts +41 -0
  17. package/model-function/generate-text/PromptTemplateFullTextModel.js +31 -0
  18. package/model-function/generate-text/PromptTemplateTextStreamingModel.cjs +3 -0
  19. package/model-function/generate-text/PromptTemplateTextStreamingModel.d.ts +2 -1
  20. package/model-function/generate-text/PromptTemplateTextStreamingModel.js +3 -0
  21. package/model-function/generate-text/TextGenerationModel.d.ts +2 -1
  22. package/model-function/generate-text/index.cjs +1 -0
  23. package/model-function/generate-text/index.d.ts +1 -0
  24. package/model-function/generate-text/index.js +1 -0
  25. package/model-function/generate-text/prompt-template/AlpacaPromptTemplate.cjs +2 -1
  26. package/model-function/generate-text/prompt-template/AlpacaPromptTemplate.d.ts +2 -2
  27. package/model-function/generate-text/prompt-template/AlpacaPromptTemplate.js +2 -1
  28. package/model-function/generate-text/prompt-template/ChatMLPromptTemplate.cjs +9 -5
  29. package/model-function/generate-text/prompt-template/ChatMLPromptTemplate.d.ts +4 -4
  30. package/model-function/generate-text/prompt-template/ChatMLPromptTemplate.js +9 -5
  31. package/model-function/generate-text/prompt-template/ChatPrompt.cjs +38 -20
  32. package/model-function/generate-text/prompt-template/ChatPrompt.d.ts +33 -34
  33. package/model-function/generate-text/prompt-template/ChatPrompt.js +37 -18
  34. package/model-function/generate-text/prompt-template/ContentPart.cjs +11 -0
  35. package/model-function/generate-text/prompt-template/ContentPart.d.ts +30 -0
  36. package/model-function/generate-text/prompt-template/ContentPart.js +7 -0
  37. package/model-function/generate-text/prompt-template/InstructionPrompt.d.ts +7 -22
  38. package/model-function/generate-text/prompt-template/Llama2PromptTemplate.cjs +40 -6
  39. package/model-function/generate-text/prompt-template/Llama2PromptTemplate.d.ts +16 -4
  40. package/model-function/generate-text/prompt-template/Llama2PromptTemplate.js +38 -5
  41. package/model-function/generate-text/prompt-template/NeuralChatPromptTemplate.cjs +10 -5
  42. package/model-function/generate-text/prompt-template/NeuralChatPromptTemplate.d.ts +4 -4
  43. package/model-function/generate-text/prompt-template/NeuralChatPromptTemplate.js +10 -5
  44. package/model-function/generate-text/prompt-template/TextPromptTemplate.cjs +8 -5
  45. package/model-function/generate-text/prompt-template/TextPromptTemplate.d.ts +4 -4
  46. package/model-function/generate-text/prompt-template/TextPromptTemplate.js +8 -5
  47. package/model-function/generate-text/prompt-template/VicunaPromptTemplate.cjs +8 -4
  48. package/model-function/generate-text/prompt-template/VicunaPromptTemplate.d.ts +2 -2
  49. package/model-function/generate-text/prompt-template/VicunaPromptTemplate.js +8 -4
  50. package/model-function/generate-text/prompt-template/index.cjs +1 -1
  51. package/model-function/generate-text/prompt-template/index.d.ts +1 -1
  52. package/model-function/generate-text/prompt-template/index.js +1 -1
  53. package/model-function/generate-text/prompt-template/trimChatPrompt.cjs +0 -2
  54. package/model-function/generate-text/prompt-template/trimChatPrompt.d.ts +4 -4
  55. package/model-function/generate-text/prompt-template/trimChatPrompt.js +0 -2
  56. package/model-function/generate-text/streamText.cjs +27 -28
  57. package/model-function/generate-text/streamText.d.ts +1 -0
  58. package/model-function/generate-text/streamText.js +27 -28
  59. package/model-provider/anthropic/AnthropicPromptTemplate.cjs +9 -4
  60. package/model-provider/anthropic/AnthropicPromptTemplate.d.ts +4 -4
  61. package/model-provider/anthropic/AnthropicPromptTemplate.js +9 -4
  62. package/model-provider/anthropic/AnthropicTextGenerationModel.cjs +8 -14
  63. package/model-provider/anthropic/AnthropicTextGenerationModel.d.ts +13 -4
  64. package/model-provider/anthropic/AnthropicTextGenerationModel.js +8 -14
  65. package/model-provider/anthropic/AnthropicTextGenerationModel.test.cjs +44 -0
  66. package/model-provider/anthropic/AnthropicTextGenerationModel.test.js +42 -0
  67. package/model-provider/automatic1111/Automatic1111ImageGenerationModel.d.ts +1 -1
  68. package/model-provider/cohere/CohereTextGenerationModel.cjs +6 -44
  69. package/model-provider/cohere/CohereTextGenerationModel.d.ts +47 -13
  70. package/model-provider/cohere/CohereTextGenerationModel.js +7 -45
  71. package/model-provider/cohere/CohereTextGenerationModel.test.cjs +33 -0
  72. package/model-provider/cohere/CohereTextGenerationModel.test.js +31 -0
  73. package/model-provider/elevenlabs/ElevenLabsSpeechModel.cjs +1 -2
  74. package/model-provider/elevenlabs/ElevenLabsSpeechModel.js +1 -2
  75. package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.cjs +29 -17
  76. package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.d.ts +4 -4
  77. package/model-provider/llamacpp/LlamaCppBakLLaVA1PromptTemplate.js +29 -17
  78. package/model-provider/llamacpp/LlamaCppTextGenerationModel.cjs +7 -14
  79. package/model-provider/llamacpp/LlamaCppTextGenerationModel.d.ts +157 -6
  80. package/model-provider/llamacpp/LlamaCppTextGenerationModel.js +8 -15
  81. package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.cjs +37 -0
  82. package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.d.ts +1 -0
  83. package/model-provider/llamacpp/LlamaCppTextGenerationModel.test.js +35 -0
  84. package/model-provider/mistral/MistralChatModel.cjs +30 -104
  85. package/model-provider/mistral/MistralChatModel.d.ts +49 -16
  86. package/model-provider/mistral/MistralChatModel.js +30 -104
  87. package/model-provider/mistral/MistralChatModel.test.cjs +51 -0
  88. package/model-provider/mistral/MistralChatModel.test.d.ts +1 -0
  89. package/model-provider/mistral/MistralChatModel.test.js +49 -0
  90. package/model-provider/mistral/MistralPromptTemplate.cjs +13 -5
  91. package/model-provider/mistral/MistralPromptTemplate.d.ts +4 -4
  92. package/model-provider/mistral/MistralPromptTemplate.js +13 -5
  93. package/model-provider/ollama/OllamaChatModel.cjs +7 -43
  94. package/model-provider/ollama/OllamaChatModel.d.ts +63 -11
  95. package/model-provider/ollama/OllamaChatModel.js +7 -43
  96. package/model-provider/ollama/OllamaChatModel.test.cjs +27 -0
  97. package/model-provider/ollama/OllamaChatModel.test.d.ts +1 -0
  98. package/model-provider/ollama/OllamaChatModel.test.js +25 -0
  99. package/model-provider/ollama/OllamaChatPromptTemplate.cjs +43 -17
  100. package/model-provider/ollama/OllamaChatPromptTemplate.d.ts +4 -4
  101. package/model-provider/ollama/OllamaChatPromptTemplate.js +43 -17
  102. package/model-provider/ollama/OllamaCompletionModel.cjs +22 -43
  103. package/model-provider/ollama/OllamaCompletionModel.d.ts +65 -9
  104. package/model-provider/ollama/OllamaCompletionModel.js +23 -44
  105. package/model-provider/ollama/OllamaCompletionModel.test.cjs +101 -13
  106. package/model-provider/ollama/OllamaCompletionModel.test.js +78 -13
  107. package/model-provider/openai/{chat/AbstractOpenAIChatModel.cjs → AbstractOpenAIChatModel.cjs} +71 -15
  108. package/model-provider/openai/{chat/AbstractOpenAIChatModel.d.ts → AbstractOpenAIChatModel.d.ts} +273 -19
  109. package/model-provider/openai/{chat/AbstractOpenAIChatModel.js → AbstractOpenAIChatModel.js} +71 -15
  110. package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.cjs → OpenAIChatFunctionCallStructureGenerationModel.cjs} +18 -2
  111. package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.d.ts → OpenAIChatFunctionCallStructureGenerationModel.d.ts} +41 -11
  112. package/model-provider/openai/{chat/OpenAIChatFunctionCallStructureGenerationModel.js → OpenAIChatFunctionCallStructureGenerationModel.js} +18 -2
  113. package/model-provider/openai/{chat/OpenAIChatMessage.d.ts → OpenAIChatMessage.d.ts} +3 -3
  114. package/model-provider/openai/{chat/OpenAIChatModel.cjs → OpenAIChatModel.cjs} +5 -5
  115. package/model-provider/openai/{chat/OpenAIChatModel.d.ts → OpenAIChatModel.d.ts} +12 -12
  116. package/model-provider/openai/{chat/OpenAIChatModel.js → OpenAIChatModel.js} +5 -5
  117. package/model-provider/openai/OpenAIChatModel.test.cjs +94 -0
  118. package/model-provider/openai/OpenAIChatModel.test.d.ts +1 -0
  119. package/model-provider/openai/OpenAIChatModel.test.js +92 -0
  120. package/model-provider/openai/OpenAIChatPromptTemplate.cjs +114 -0
  121. package/model-provider/openai/OpenAIChatPromptTemplate.d.ts +20 -0
  122. package/model-provider/openai/OpenAIChatPromptTemplate.js +107 -0
  123. package/model-provider/openai/OpenAICompletionModel.cjs +32 -84
  124. package/model-provider/openai/OpenAICompletionModel.d.ts +29 -12
  125. package/model-provider/openai/OpenAICompletionModel.js +33 -85
  126. package/model-provider/openai/OpenAICompletionModel.test.cjs +53 -0
  127. package/model-provider/openai/OpenAICompletionModel.test.d.ts +1 -0
  128. package/model-provider/openai/OpenAICompletionModel.test.js +51 -0
  129. package/model-provider/openai/OpenAICostCalculator.cjs +1 -1
  130. package/model-provider/openai/OpenAICostCalculator.js +1 -1
  131. package/model-provider/openai/OpenAIFacade.cjs +2 -2
  132. package/model-provider/openai/OpenAIFacade.d.ts +3 -3
  133. package/model-provider/openai/OpenAIFacade.js +2 -2
  134. package/model-provider/openai/OpenAITranscriptionModel.d.ts +6 -6
  135. package/model-provider/openai/TikTokenTokenizer.d.ts +1 -1
  136. package/model-provider/openai/{chat/countOpenAIChatMessageTokens.cjs → countOpenAIChatMessageTokens.cjs} +2 -2
  137. package/model-provider/openai/{chat/countOpenAIChatMessageTokens.js → countOpenAIChatMessageTokens.js} +2 -2
  138. package/model-provider/openai/index.cjs +6 -6
  139. package/model-provider/openai/index.d.ts +5 -6
  140. package/model-provider/openai/index.js +5 -5
  141. package/model-provider/openai-compatible/OpenAICompatibleChatModel.cjs +4 -4
  142. package/model-provider/openai-compatible/OpenAICompatibleChatModel.d.ts +6 -6
  143. package/model-provider/openai-compatible/OpenAICompatibleChatModel.js +4 -4
  144. package/model-provider/stability/StabilityImageGenerationModel.d.ts +1 -1
  145. package/package.json +5 -5
  146. package/test/JsonTestServer.cjs +33 -0
  147. package/test/JsonTestServer.d.ts +7 -0
  148. package/test/JsonTestServer.js +29 -0
  149. package/test/StreamingTestServer.cjs +55 -0
  150. package/test/StreamingTestServer.d.ts +7 -0
  151. package/test/StreamingTestServer.js +51 -0
  152. package/test/arrayFromAsync.cjs +13 -0
  153. package/test/arrayFromAsync.d.ts +1 -0
  154. package/test/arrayFromAsync.js +9 -0
  155. package/util/streaming/createEventSourceResponseHandler.cjs +9 -0
  156. package/util/streaming/createEventSourceResponseHandler.d.ts +4 -0
  157. package/util/streaming/createEventSourceResponseHandler.js +5 -0
  158. package/util/streaming/createJsonStreamResponseHandler.cjs +9 -0
  159. package/util/streaming/createJsonStreamResponseHandler.d.ts +4 -0
  160. package/util/streaming/createJsonStreamResponseHandler.js +5 -0
  161. package/util/streaming/parseEventSourceStreamAsAsyncIterable.cjs +52 -0
  162. package/util/streaming/parseEventSourceStreamAsAsyncIterable.d.ts +6 -0
  163. package/util/streaming/parseEventSourceStreamAsAsyncIterable.js +48 -0
  164. package/util/streaming/parseJsonStreamAsAsyncIterable.cjs +21 -0
  165. package/util/streaming/parseJsonStreamAsAsyncIterable.d.ts +6 -0
  166. package/util/streaming/parseJsonStreamAsAsyncIterable.js +17 -0
  167. package/model-function/generate-text/prompt-template/Content.cjs +0 -2
  168. package/model-function/generate-text/prompt-template/Content.d.ts +0 -20
  169. package/model-provider/openai/chat/OpenAIChatModel.test.cjs +0 -61
  170. package/model-provider/openai/chat/OpenAIChatModel.test.js +0 -59
  171. package/model-provider/openai/chat/OpenAIChatPromptTemplate.cjs +0 -72
  172. package/model-provider/openai/chat/OpenAIChatPromptTemplate.d.ts +0 -20
  173. package/model-provider/openai/chat/OpenAIChatPromptTemplate.js +0 -65
  174. package/model-provider/openai/chat/OpenAIChatStreamIterable.cjs +0 -156
  175. package/model-provider/openai/chat/OpenAIChatStreamIterable.d.ts +0 -19
  176. package/model-provider/openai/chat/OpenAIChatStreamIterable.js +0 -152
  177. /package/{model-function/generate-text/prompt-template/Content.js → model-provider/anthropic/AnthropicTextGenerationModel.test.d.ts} +0 -0
  178. /package/model-provider/{openai/chat/OpenAIChatModel.test.d.ts → cohere/CohereTextGenerationModel.test.d.ts} +0 -0
  179. /package/model-provider/openai/{chat/OpenAIChatMessage.cjs → OpenAIChatMessage.cjs} +0 -0
  180. /package/model-provider/openai/{chat/OpenAIChatMessage.js → OpenAIChatMessage.js} +0 -0
  181. /package/model-provider/openai/{chat/countOpenAIChatMessageTokens.d.ts → countOpenAIChatMessageTokens.d.ts} +0 -0
@@ -0,0 +1,35 @@
1
+ import { streamText } from "../../model-function/generate-text/streamText.js";
2
+ import { StreamingTestServer } from "../../test/StreamingTestServer.js";
3
+ import { arrayFromAsync } from "../../test/arrayFromAsync.js";
4
+ import { LlamaCppTextGenerationModel } from "./LlamaCppTextGenerationModel.js";
5
+ describe("streamText", () => {
6
+ const server = new StreamingTestServer("http://127.0.0.1:8080/completion");
7
+ server.setupTestEnvironment();
8
+ it("should return a text stream", async () => {
9
+ server.responseChunks = [
10
+ `data: {"content":"Hello","multimodal":false,"slot_id":0,"stop":false}\n\n`,
11
+ `data: {"content":", ","multimodal":false,"slot_id":0,"stop":false}\n\n`,
12
+ `data: {"content":"world!","multimodal":false,"slot_id":0,"stop":false}\n\n`,
13
+ `data: {"content":"","generation_settings":{"frequency_penalty":0.0,"grammar":"",` +
14
+ `"ignore_eos":false,"logit_bias":[],"min_p":0.05000000074505806,"mirostat":0,` +
15
+ `"mirostat_eta":0.10000000149011612,"mirostat_tau":5.0,"model":"models/llama-2-7b-chat.Q4_K_M.gguf",` +
16
+ `"n_ctx":4096,"n_keep":0,"n_predict":-1,"n_probs":0,"penalize_nl":true,"penalty_prompt_tokens":[],` +
17
+ `"presence_penalty":0.0,"repeat_last_n":64,"repeat_penalty":1.100000023841858,"seed":4294967295,` +
18
+ `"stop":[],"stream":true,"temp":0.800000011920929,"tfs_z":1.0,"top_k":40,"top_p":0.949999988079071,` +
19
+ `"typical_p":1.0,"use_penalty_prompt_tokens":false},"model":"models/llama-2-7b-chat.Q4_K_M.gguf",` +
20
+ `"prompt":"hello","slot_id":0,"stop":true,"stopped_eos":true,"stopped_limit":false,` +
21
+ `"stopped_word":false,"stopping_word":"","timings":{"predicted_ms":1054.704,"predicted_n":69,` +
22
+ `"predicted_per_second":65.421198743913,"predicted_per_token_ms":15.285565217391303,` +
23
+ `"prompt_ms":244.228,"prompt_n":5,"prompt_per_second":20.472673075978186,` +
24
+ `"prompt_per_token_ms":48.845600000000005},"tokens_cached":74,"tokens_evaluated":5,` +
25
+ `"tokens_predicted":69,"truncated":false}\n\n`,
26
+ ];
27
+ const stream = await streamText(new LlamaCppTextGenerationModel().withTextPrompt(), "hello");
28
+ // note: space moved to last chunk bc of trimming
29
+ expect(await arrayFromAsync(stream)).toStrictEqual([
30
+ "Hello",
31
+ ",",
32
+ " world!",
33
+ ]);
34
+ });
35
+ });
@@ -5,11 +5,10 @@ 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
7
  const ZodSchema_js_1 = require("../../core/schema/ZodSchema.cjs");
8
- const parseJSON_js_1 = require("../../core/schema/parseJSON.cjs");
9
8
  const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs");
10
9
  const PromptTemplateTextStreamingModel_js_1 = require("../../model-function/generate-text/PromptTemplateTextStreamingModel.cjs");
11
- const AsyncQueue_js_1 = require("../../util/AsyncQueue.cjs");
12
- const parseEventSourceStream_js_1 = require("../../util/streaming/parseEventSourceStream.cjs");
10
+ const TextGenerationModel_js_1 = require("../../model-function/generate-text/TextGenerationModel.cjs");
11
+ const createEventSourceResponseHandler_js_1 = require("../../util/streaming/createEventSourceResponseHandler.cjs");
13
12
  const MistralApiConfiguration_js_1 = require("./MistralApiConfiguration.cjs");
14
13
  const MistralError_js_1 = require("./MistralError.cjs");
15
14
  const MistralPromptTemplate_js_1 = require("./MistralPromptTemplate.cjs");
@@ -45,7 +44,6 @@ class MistralChatModel extends AbstractModel_js_1.AbstractModel {
45
44
  return this.settings.model;
46
45
  }
47
46
  async callAPI(prompt, options) {
48
- const { model, temperature, topP, safeMode, randomSeed, maxGenerationTokens, } = this.settings;
49
47
  const api = this.settings.api ?? new MistralApiConfiguration_js_1.MistralApiConfiguration();
50
48
  const abortSignal = options.run?.abortSignal;
51
49
  const stream = options.responseFormat.stream;
@@ -59,12 +57,12 @@ class MistralChatModel extends AbstractModel_js_1.AbstractModel {
59
57
  body: {
60
58
  stream,
61
59
  messages: prompt,
62
- model,
63
- temperature,
64
- top_p: topP,
65
- max_tokens: maxGenerationTokens,
66
- safe_mode: safeMode,
67
- random_seed: randomSeed,
60
+ model: this.settings.model,
61
+ temperature: this.settings.temperature,
62
+ top_p: this.settings.topP,
63
+ max_tokens: this.settings.maxGenerationTokens,
64
+ safe_mode: this.settings.safeMode,
65
+ random_seed: this.settings.randomSeed,
68
66
  },
69
67
  failedResponseHandler: MistralError_js_1.failedMistralCallResponseHandler,
70
68
  successfulResponseHandler,
@@ -74,10 +72,7 @@ class MistralChatModel extends AbstractModel_js_1.AbstractModel {
74
72
  }
75
73
  get settingsForEvent() {
76
74
  const eventSettingProperties = [
77
- "maxGenerationTokens",
78
- "stopSequences",
79
- "numberOfGenerations",
80
- "trimWhitespace",
75
+ ...TextGenerationModel_js_1.textGenerationModelProperties,
81
76
  "temperature",
82
77
  "topP",
83
78
  "safeMode",
@@ -115,6 +110,10 @@ class MistralChatModel extends AbstractModel_js_1.AbstractModel {
115
110
  responseFormat: exports.MistralChatResponseFormat.textDeltaIterable,
116
111
  });
117
112
  }
113
+ extractTextDelta(delta) {
114
+ const chunk = delta;
115
+ return chunk.choices[0].delta.content ?? undefined;
116
+ }
118
117
  /**
119
118
  * Returns this model with a text prompt template.
120
119
  */
@@ -163,23 +162,7 @@ const mistralChatResponseSchema = zod_1.z.object({
163
162
  total_tokens: zod_1.z.number(),
164
163
  }),
165
164
  });
166
- exports.MistralChatResponseFormat = {
167
- /**
168
- * Returns the response as a JSON object.
169
- */
170
- json: {
171
- stream: false,
172
- handler: (0, postToApi_js_1.createJsonResponseHandler)(mistralChatResponseSchema),
173
- },
174
- /**
175
- * Returns an async iterable over the text deltas (only the tex different of the first choice).
176
- */
177
- textDeltaIterable: {
178
- stream: true,
179
- handler: async ({ response }) => createMistralChatDeltaIterableQueue(response.body, (delta) => delta[0]?.delta.content ?? ""),
180
- },
181
- };
182
- const mistralChatChunkSchema = new ZodSchema_js_1.ZodSchema(zod_1.z.object({
165
+ const mistralChatStreamChunkSchema = new ZodSchema_js_1.ZodSchema(zod_1.z.object({
183
166
  id: zod_1.z.string(),
184
167
  object: zod_1.z.string().optional(),
185
168
  created: zod_1.z.number().optional(),
@@ -196,76 +179,19 @@ const mistralChatChunkSchema = new ZodSchema_js_1.ZodSchema(zod_1.z.object({
196
179
  .optional(),
197
180
  })),
198
181
  }));
199
- async function createMistralChatDeltaIterableQueue(stream, extractDeltaValue) {
200
- const queue = new AsyncQueue_js_1.AsyncQueue();
201
- const streamDelta = [];
202
- // process the stream asynchonously (no 'await' on purpose):
203
- (0, parseEventSourceStream_js_1.parseEventSourceStream)({ stream })
204
- .then(async (events) => {
205
- try {
206
- for await (const event of events) {
207
- const data = event.data;
208
- if (data === "[DONE]") {
209
- queue.close();
210
- return;
211
- }
212
- const parseResult = (0, parseJSON_js_1.safeParseJSON)({
213
- text: data,
214
- schema: mistralChatChunkSchema,
215
- });
216
- if (!parseResult.success) {
217
- queue.push({
218
- type: "error",
219
- error: parseResult.error,
220
- });
221
- // Note: the queue is not closed on purpose. Some providers might add additional
222
- // chunks that are not parsable, and ModelFusion should be resilient to that.
223
- continue;
224
- }
225
- const completionChunk = parseResult.data;
226
- for (let i = 0; i < completionChunk.choices.length; i++) {
227
- const eventChoice = completionChunk.choices[i];
228
- const delta = eventChoice.delta;
229
- if (streamDelta[i] == null) {
230
- streamDelta[i] = {
231
- role: undefined,
232
- content: "",
233
- isComplete: false,
234
- delta,
235
- };
236
- }
237
- const choice = streamDelta[i];
238
- choice.delta = delta;
239
- if (eventChoice.finish_reason != null) {
240
- choice.isComplete = true;
241
- }
242
- if (delta.content != undefined) {
243
- choice.content += delta.content;
244
- }
245
- if (delta.role != undefined) {
246
- choice.role = delta.role;
247
- }
248
- }
249
- // Since we're mutating the choices array in an async scenario,
250
- // we need to make a deep copy:
251
- const streamDeltaDeepCopy = JSON.parse(JSON.stringify(streamDelta));
252
- queue.push({
253
- type: "delta",
254
- fullDelta: streamDeltaDeepCopy,
255
- valueDelta: extractDeltaValue(streamDeltaDeepCopy),
256
- });
257
- }
258
- }
259
- catch (error) {
260
- queue.push({ type: "error", error });
261
- queue.close();
262
- return;
263
- }
264
- })
265
- .catch((error) => {
266
- queue.push({ type: "error", error });
267
- queue.close();
268
- return;
269
- });
270
- return queue;
271
- }
182
+ exports.MistralChatResponseFormat = {
183
+ /**
184
+ * Returns the response as a JSON object.
185
+ */
186
+ json: {
187
+ stream: false,
188
+ handler: (0, postToApi_js_1.createJsonResponseHandler)(mistralChatResponseSchema),
189
+ },
190
+ /**
191
+ * Returns an async iterable over the text deltas (only the tex different of the first choice).
192
+ */
193
+ textDeltaIterable: {
194
+ stream: true,
195
+ handler: (0, createEventSourceResponseHandler_js_1.createEventSourceResponseHandler)(mistralChatStreamChunkSchema),
196
+ },
197
+ };
@@ -2,8 +2,8 @@ import { z } from "zod";
2
2
  import { FunctionOptions } from "../../core/FunctionOptions.js";
3
3
  import { ApiConfiguration } from "../../core/api/ApiConfiguration.js";
4
4
  import { ResponseHandler } from "../../core/api/postToApi.js";
5
+ import { ZodSchema } from "../../core/schema/ZodSchema.js";
5
6
  import { AbstractModel } from "../../model-function/AbstractModel.js";
6
- import { Delta } from "../../model-function/Delta.js";
7
7
  import { PromptTemplateTextStreamingModel } from "../../model-function/generate-text/PromptTemplateTextStreamingModel.js";
8
8
  import { TextGenerationModelSettings, TextStreamingModel } from "../../model-function/generate-text/TextGenerationModel.js";
9
9
  import { TextGenerationPromptTemplate } from "../../model-function/generate-text/TextGenerationPromptTemplate.js";
@@ -85,7 +85,21 @@ export declare class MistralChatModel extends AbstractModel<MistralChatModelSett
85
85
  }[];
86
86
  }>;
87
87
  private translateFinishReason;
88
- doStreamText(prompt: MistralChatPrompt, options?: FunctionOptions): Promise<AsyncIterable<Delta<string>>>;
88
+ doStreamText(prompt: MistralChatPrompt, options?: FunctionOptions): Promise<AsyncIterable<import("../../index.js").Delta<{
89
+ model: string;
90
+ id: string;
91
+ choices: {
92
+ delta: {
93
+ role?: "user" | "assistant" | null | undefined;
94
+ content?: string | null | undefined;
95
+ };
96
+ index: number;
97
+ finish_reason?: "length" | "stop" | "model_length" | null | undefined;
98
+ }[];
99
+ object?: string | undefined;
100
+ created?: number | undefined;
101
+ }>>>;
102
+ extractTextDelta(delta: unknown): string | undefined;
89
103
  /**
90
104
  * Returns this model with a text prompt template.
91
105
  */
@@ -93,11 +107,11 @@ export declare class MistralChatModel extends AbstractModel<MistralChatModelSett
93
107
  /**
94
108
  * Returns this model with an instruction prompt template.
95
109
  */
96
- withInstructionPrompt(): PromptTemplateTextStreamingModel<import("../../index.js").TextInstructionPrompt, MistralChatPrompt, MistralChatModelSettings, this>;
110
+ withInstructionPrompt(): PromptTemplateTextStreamingModel<import("../../index.js").InstructionPrompt, MistralChatPrompt, MistralChatModelSettings, this>;
97
111
  /**
98
112
  * Returns this model with a chat prompt template.
99
113
  */
100
- withChatPrompt(): PromptTemplateTextStreamingModel<import("../../index.js").TextChatPrompt, MistralChatPrompt, MistralChatModelSettings, this>;
114
+ withChatPrompt(): PromptTemplateTextStreamingModel<import("../../index.js").ChatPrompt, MistralChatPrompt, MistralChatModelSettings, this>;
101
115
  withPromptTemplate<INPUT_PROMPT>(promptTemplate: TextGenerationPromptTemplate<INPUT_PROMPT, MistralChatPrompt>): PromptTemplateTextStreamingModel<INPUT_PROMPT, MistralChatPrompt, MistralChatModelSettings, this>;
102
116
  withSettings(additionalSettings: Partial<MistralChatModelSettings>): this;
103
117
  }
@@ -185,6 +199,21 @@ declare const mistralChatResponseSchema: z.ZodObject<{
185
199
  }[];
186
200
  }>;
187
201
  export type MistralChatResponse = z.infer<typeof mistralChatResponseSchema>;
202
+ declare const mistralChatStreamChunkSchema: ZodSchema<{
203
+ model: string;
204
+ id: string;
205
+ choices: {
206
+ delta: {
207
+ role?: "user" | "assistant" | null | undefined;
208
+ content?: string | null | undefined;
209
+ };
210
+ index: number;
211
+ finish_reason?: "length" | "stop" | "model_length" | null | undefined;
212
+ }[];
213
+ object?: string | undefined;
214
+ created?: number | undefined;
215
+ }>;
216
+ export type MistralChatStreamChunk = (typeof mistralChatStreamChunkSchema)["_type"];
188
217
  export type MistralChatResponseFormatType<T> = {
189
218
  stream: boolean;
190
219
  handler: ResponseHandler<T>;
@@ -194,7 +223,7 @@ export declare const MistralChatResponseFormat: {
194
223
  * Returns the response as a JSON object.
195
224
  */
196
225
  json: {
197
- stream: false;
226
+ stream: boolean;
198
227
  handler: ResponseHandler<{
199
228
  object: string;
200
229
  usage: {
@@ -219,19 +248,23 @@ export declare const MistralChatResponseFormat: {
219
248
  * Returns an async iterable over the text deltas (only the tex different of the first choice).
220
249
  */
221
250
  textDeltaIterable: {
222
- stream: true;
251
+ stream: boolean;
223
252
  handler: ({ response }: {
224
253
  response: Response;
225
- }) => Promise<AsyncIterable<Delta<string>>>;
254
+ }) => Promise<AsyncIterable<import("../../index.js").Delta<{
255
+ model: string;
256
+ id: string;
257
+ choices: {
258
+ delta: {
259
+ role?: "user" | "assistant" | null | undefined;
260
+ content?: string | null | undefined;
261
+ };
262
+ index: number;
263
+ finish_reason?: "length" | "stop" | "model_length" | null | undefined;
264
+ }[];
265
+ object?: string | undefined;
266
+ created?: number | undefined;
267
+ }>>>;
226
268
  };
227
269
  };
228
- export type MistralChatDelta = Array<{
229
- role: "assistant" | "user" | undefined;
230
- content: string;
231
- isComplete: boolean;
232
- delta: {
233
- role?: "assistant" | "user" | null;
234
- content?: string | null;
235
- };
236
- }>;
237
270
  export {};
@@ -2,11 +2,10 @@ import { z } from "zod";
2
2
  import { callWithRetryAndThrottle } from "../../core/api/callWithRetryAndThrottle.js";
3
3
  import { createJsonResponseHandler, postJsonToApi, } from "../../core/api/postToApi.js";
4
4
  import { ZodSchema } from "../../core/schema/ZodSchema.js";
5
- import { safeParseJSON } from "../../core/schema/parseJSON.js";
6
5
  import { AbstractModel } from "../../model-function/AbstractModel.js";
7
6
  import { PromptTemplateTextStreamingModel } from "../../model-function/generate-text/PromptTemplateTextStreamingModel.js";
8
- import { AsyncQueue } from "../../util/AsyncQueue.js";
9
- import { parseEventSourceStream } from "../../util/streaming/parseEventSourceStream.js";
7
+ import { textGenerationModelProperties, } from "../../model-function/generate-text/TextGenerationModel.js";
8
+ import { createEventSourceResponseHandler } from "../../util/streaming/createEventSourceResponseHandler.js";
10
9
  import { MistralApiConfiguration } from "./MistralApiConfiguration.js";
11
10
  import { failedMistralCallResponseHandler } from "./MistralError.js";
12
11
  import { chat, instruction, text } from "./MistralPromptTemplate.js";
@@ -42,7 +41,6 @@ export class MistralChatModel extends AbstractModel {
42
41
  return this.settings.model;
43
42
  }
44
43
  async callAPI(prompt, options) {
45
- const { model, temperature, topP, safeMode, randomSeed, maxGenerationTokens, } = this.settings;
46
44
  const api = this.settings.api ?? new MistralApiConfiguration();
47
45
  const abortSignal = options.run?.abortSignal;
48
46
  const stream = options.responseFormat.stream;
@@ -56,12 +54,12 @@ export class MistralChatModel extends AbstractModel {
56
54
  body: {
57
55
  stream,
58
56
  messages: prompt,
59
- model,
60
- temperature,
61
- top_p: topP,
62
- max_tokens: maxGenerationTokens,
63
- safe_mode: safeMode,
64
- random_seed: randomSeed,
57
+ model: this.settings.model,
58
+ temperature: this.settings.temperature,
59
+ top_p: this.settings.topP,
60
+ max_tokens: this.settings.maxGenerationTokens,
61
+ safe_mode: this.settings.safeMode,
62
+ random_seed: this.settings.randomSeed,
65
63
  },
66
64
  failedResponseHandler: failedMistralCallResponseHandler,
67
65
  successfulResponseHandler,
@@ -71,10 +69,7 @@ export class MistralChatModel extends AbstractModel {
71
69
  }
72
70
  get settingsForEvent() {
73
71
  const eventSettingProperties = [
74
- "maxGenerationTokens",
75
- "stopSequences",
76
- "numberOfGenerations",
77
- "trimWhitespace",
72
+ ...textGenerationModelProperties,
78
73
  "temperature",
79
74
  "topP",
80
75
  "safeMode",
@@ -112,6 +107,10 @@ export class MistralChatModel extends AbstractModel {
112
107
  responseFormat: MistralChatResponseFormat.textDeltaIterable,
113
108
  });
114
109
  }
110
+ extractTextDelta(delta) {
111
+ const chunk = delta;
112
+ return chunk.choices[0].delta.content ?? undefined;
113
+ }
115
114
  /**
116
115
  * Returns this model with a text prompt template.
117
116
  */
@@ -159,23 +158,7 @@ const mistralChatResponseSchema = z.object({
159
158
  total_tokens: z.number(),
160
159
  }),
161
160
  });
162
- export const MistralChatResponseFormat = {
163
- /**
164
- * Returns the response as a JSON object.
165
- */
166
- json: {
167
- stream: false,
168
- handler: createJsonResponseHandler(mistralChatResponseSchema),
169
- },
170
- /**
171
- * Returns an async iterable over the text deltas (only the tex different of the first choice).
172
- */
173
- textDeltaIterable: {
174
- stream: true,
175
- handler: async ({ response }) => createMistralChatDeltaIterableQueue(response.body, (delta) => delta[0]?.delta.content ?? ""),
176
- },
177
- };
178
- const mistralChatChunkSchema = new ZodSchema(z.object({
161
+ const mistralChatStreamChunkSchema = new ZodSchema(z.object({
179
162
  id: z.string(),
180
163
  object: z.string().optional(),
181
164
  created: z.number().optional(),
@@ -192,76 +175,19 @@ const mistralChatChunkSchema = new ZodSchema(z.object({
192
175
  .optional(),
193
176
  })),
194
177
  }));
195
- async function createMistralChatDeltaIterableQueue(stream, extractDeltaValue) {
196
- const queue = new AsyncQueue();
197
- const streamDelta = [];
198
- // process the stream asynchonously (no 'await' on purpose):
199
- parseEventSourceStream({ stream })
200
- .then(async (events) => {
201
- try {
202
- for await (const event of events) {
203
- const data = event.data;
204
- if (data === "[DONE]") {
205
- queue.close();
206
- return;
207
- }
208
- const parseResult = safeParseJSON({
209
- text: data,
210
- schema: mistralChatChunkSchema,
211
- });
212
- if (!parseResult.success) {
213
- queue.push({
214
- type: "error",
215
- error: parseResult.error,
216
- });
217
- // Note: the queue is not closed on purpose. Some providers might add additional
218
- // chunks that are not parsable, and ModelFusion should be resilient to that.
219
- continue;
220
- }
221
- const completionChunk = parseResult.data;
222
- for (let i = 0; i < completionChunk.choices.length; i++) {
223
- const eventChoice = completionChunk.choices[i];
224
- const delta = eventChoice.delta;
225
- if (streamDelta[i] == null) {
226
- streamDelta[i] = {
227
- role: undefined,
228
- content: "",
229
- isComplete: false,
230
- delta,
231
- };
232
- }
233
- const choice = streamDelta[i];
234
- choice.delta = delta;
235
- if (eventChoice.finish_reason != null) {
236
- choice.isComplete = true;
237
- }
238
- if (delta.content != undefined) {
239
- choice.content += delta.content;
240
- }
241
- if (delta.role != undefined) {
242
- choice.role = delta.role;
243
- }
244
- }
245
- // Since we're mutating the choices array in an async scenario,
246
- // we need to make a deep copy:
247
- const streamDeltaDeepCopy = JSON.parse(JSON.stringify(streamDelta));
248
- queue.push({
249
- type: "delta",
250
- fullDelta: streamDeltaDeepCopy,
251
- valueDelta: extractDeltaValue(streamDeltaDeepCopy),
252
- });
253
- }
254
- }
255
- catch (error) {
256
- queue.push({ type: "error", error });
257
- queue.close();
258
- return;
259
- }
260
- })
261
- .catch((error) => {
262
- queue.push({ type: "error", error });
263
- queue.close();
264
- return;
265
- });
266
- return queue;
267
- }
178
+ export const MistralChatResponseFormat = {
179
+ /**
180
+ * Returns the response as a JSON object.
181
+ */
182
+ json: {
183
+ stream: false,
184
+ handler: createJsonResponseHandler(mistralChatResponseSchema),
185
+ },
186
+ /**
187
+ * Returns an async iterable over the text deltas (only the tex different of the first choice).
188
+ */
189
+ textDeltaIterable: {
190
+ stream: true,
191
+ handler: createEventSourceResponseHandler(mistralChatStreamChunkSchema),
192
+ },
193
+ };
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const streamText_js_1 = require("../../model-function/generate-text/streamText.cjs");
4
+ const StreamingTestServer_js_1 = require("../../test/StreamingTestServer.cjs");
5
+ const arrayFromAsync_js_1 = require("../../test/arrayFromAsync.cjs");
6
+ const MistralApiConfiguration_js_1 = require("./MistralApiConfiguration.cjs");
7
+ const MistralChatModel_js_1 = require("./MistralChatModel.cjs");
8
+ describe("streamText", () => {
9
+ const server = new StreamingTestServer_js_1.StreamingTestServer("https://api.mistral.ai/v1/chat/completions");
10
+ server.setupTestEnvironment();
11
+ describe("simple hello world stream", () => {
12
+ beforeEach(() => {
13
+ server.responseChunks = [
14
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "model": "mistral-tiny", ` +
15
+ `"choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": null}]}\n\n`,
16
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
17
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
18
+ `"delta": {"role": null, "content": "Hello"}, "finish_reason": null}]}\n\n`,
19
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
20
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
21
+ `"delta": {"role": null, "content": ", "}, "finish_reason": null}]}\n\n`,
22
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
23
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
24
+ `"delta": {"role": null, "content": "world!"}, "finish_reason": null}]}\n\n`,
25
+ `{"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
26
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
27
+ `"delta": {"role": null, "content": ""}, "finish_reason": "stop"}]}\n\n`,
28
+ `data: [DONE]\n\n`,
29
+ ];
30
+ });
31
+ it("should return a text stream", async () => {
32
+ const stream = await (0, streamText_js_1.streamText)(new MistralChatModel_js_1.MistralChatModel({
33
+ api: new MistralApiConfiguration_js_1.MistralApiConfiguration({ apiKey: "test-key" }),
34
+ model: "mistral-tiny",
35
+ }).withTextPrompt(), "hello");
36
+ // note: space moved to last chunk bc of trimming
37
+ expect(await (0, arrayFromAsync_js_1.arrayFromAsync)(stream)).toStrictEqual([
38
+ "Hello",
39
+ ",",
40
+ " world!",
41
+ ]);
42
+ });
43
+ it("should return text", async () => {
44
+ const { text } = await (0, streamText_js_1.streamText)(new MistralChatModel_js_1.MistralChatModel({
45
+ api: new MistralApiConfiguration_js_1.MistralApiConfiguration({ apiKey: "test-key" }),
46
+ model: "mistral-tiny",
47
+ }).withTextPrompt(), "hello", { fullResponse: true });
48
+ expect(await text).toStrictEqual("Hello, world!");
49
+ });
50
+ });
51
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import { streamText } from "../../model-function/generate-text/streamText.js";
2
+ import { StreamingTestServer } from "../../test/StreamingTestServer.js";
3
+ import { arrayFromAsync } from "../../test/arrayFromAsync.js";
4
+ import { MistralApiConfiguration } from "./MistralApiConfiguration.js";
5
+ import { MistralChatModel } from "./MistralChatModel.js";
6
+ describe("streamText", () => {
7
+ const server = new StreamingTestServer("https://api.mistral.ai/v1/chat/completions");
8
+ server.setupTestEnvironment();
9
+ describe("simple hello world stream", () => {
10
+ beforeEach(() => {
11
+ server.responseChunks = [
12
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "model": "mistral-tiny", ` +
13
+ `"choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": null}]}\n\n`,
14
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
15
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
16
+ `"delta": {"role": null, "content": "Hello"}, "finish_reason": null}]}\n\n`,
17
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
18
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
19
+ `"delta": {"role": null, "content": ", "}, "finish_reason": null}]}\n\n`,
20
+ `data: {"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
21
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
22
+ `"delta": {"role": null, "content": "world!"}, "finish_reason": null}]}\n\n`,
23
+ `{"id": "cmpl-6c5f9bc8be6540cc9cc41c075f199e96", "object": "chat.completion.chunk",` +
24
+ `"created": 1703439030, "model": "mistral-tiny", "choices": [{"index": 0, ` +
25
+ `"delta": {"role": null, "content": ""}, "finish_reason": "stop"}]}\n\n`,
26
+ `data: [DONE]\n\n`,
27
+ ];
28
+ });
29
+ it("should return a text stream", async () => {
30
+ const stream = await streamText(new MistralChatModel({
31
+ api: new MistralApiConfiguration({ apiKey: "test-key" }),
32
+ model: "mistral-tiny",
33
+ }).withTextPrompt(), "hello");
34
+ // note: space moved to last chunk bc of trimming
35
+ expect(await arrayFromAsync(stream)).toStrictEqual([
36
+ "Hello",
37
+ ",",
38
+ " world!",
39
+ ]);
40
+ });
41
+ it("should return text", async () => {
42
+ const { text } = await streamText(new MistralChatModel({
43
+ api: new MistralApiConfiguration({ apiKey: "test-key" }),
44
+ model: "mistral-tiny",
45
+ }).withTextPrompt(), "hello", { fullResponse: true });
46
+ expect(await text).toStrictEqual("Hello, world!");
47
+ });
48
+ });
49
+ });