@core-ai/mistral 0.4.0 → 0.5.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 (2) hide show
  1. package/dist/index.js +118 -20
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -31,11 +31,15 @@ function convertMessage(message) {
31
31
  };
32
32
  }
33
33
  if (message.role === "assistant") {
34
+ const text = message.parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
35
+ const toolCalls = message.parts.flatMap(
36
+ (part) => part.type === "tool-call" ? [part.toolCall] : []
37
+ );
34
38
  return {
35
39
  role: "assistant",
36
- content: message.content,
37
- ...message.toolCalls && message.toolCalls.length > 0 ? {
38
- toolCalls: message.toolCalls.map((toolCall) => ({
40
+ content: text.length > 0 ? text : null,
41
+ ...toolCalls.length > 0 ? {
42
+ toolCalls: toolCalls.map((toolCall) => ({
39
43
  id: toolCall.id,
40
44
  type: "function",
41
45
  function: {
@@ -117,6 +121,7 @@ function createStructuredOutputOptions(options) {
117
121
  type: "tool",
118
122
  toolName
119
123
  },
124
+ reasoning: options.reasoning,
120
125
  config: options.config,
121
126
  providerOptions: options.providerOptions,
122
127
  signal: options.signal
@@ -164,16 +169,25 @@ function mapGenerateResponse(response) {
164
169
  const firstChoice = response.choices[0];
165
170
  if (!firstChoice) {
166
171
  return {
172
+ parts: [],
167
173
  content: null,
174
+ reasoning: null,
168
175
  toolCalls: [],
169
176
  finishReason: "unknown",
170
177
  usage: mapUsage(response.usage)
171
178
  };
172
179
  }
173
- const toolCalls = parseToolCalls(firstChoice.message.toolCalls);
180
+ const parts = extractAssistantParts(firstChoice.message);
181
+ const toolCalls = parts.flatMap(
182
+ (part) => part.type === "tool-call" ? [part.toolCall] : []
183
+ );
184
+ const content = parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
185
+ const reasoning = parts.flatMap((part) => part.type === "reasoning" ? [part.text] : []).join("");
174
186
  const mappedFinishReason = mapFinishReason(firstChoice.finishReason);
175
187
  return {
176
- content: extractTextContent(firstChoice.message.content),
188
+ parts,
189
+ content: content.length > 0 ? content : null,
190
+ reasoning: reasoning.length > 0 ? reasoning : null,
177
191
  toolCalls,
178
192
  finishReason: toolCalls.length > 0 && mappedFinishReason !== "content-filter" ? "tool-calls" : mappedFinishReason,
179
193
  usage: mapUsage(response.usage)
@@ -183,6 +197,7 @@ async function* transformStream(stream) {
183
197
  const bufferedToolCalls = /* @__PURE__ */ new Map();
184
198
  const emittedToolCalls = /* @__PURE__ */ new Set();
185
199
  let finishReason = "unknown";
200
+ let reasoningOpen = false;
186
201
  let usage = {
187
202
  inputTokens: 0,
188
203
  outputTokens: 0,
@@ -190,9 +205,7 @@ async function* transformStream(stream) {
190
205
  cacheReadTokens: 0,
191
206
  cacheWriteTokens: 0
192
207
  },
193
- outputTokenDetails: {
194
- reasoningTokens: 0
195
- }
208
+ outputTokenDetails: {}
196
209
  };
197
210
  for await (const event of stream) {
198
211
  const chunk = event.data;
@@ -203,13 +216,40 @@ async function* transformStream(stream) {
203
216
  if (!choice) {
204
217
  continue;
205
218
  }
219
+ const thinkingDeltas = extractThinkingDeltas(choice.delta.content);
220
+ if (thinkingDeltas.length > 0) {
221
+ if (!reasoningOpen) {
222
+ reasoningOpen = true;
223
+ yield {
224
+ type: "reasoning-start"
225
+ };
226
+ }
227
+ for (const thinkingDelta of thinkingDeltas) {
228
+ yield {
229
+ type: "reasoning-delta",
230
+ text: thinkingDelta
231
+ };
232
+ }
233
+ }
206
234
  for (const textDelta of extractTextDeltas(choice.delta.content)) {
235
+ if (reasoningOpen) {
236
+ reasoningOpen = false;
237
+ yield {
238
+ type: "reasoning-end"
239
+ };
240
+ }
207
241
  yield {
208
- type: "content-delta",
242
+ type: "text-delta",
209
243
  text: textDelta
210
244
  };
211
245
  }
212
246
  if (choice.delta.toolCalls) {
247
+ if (reasoningOpen) {
248
+ reasoningOpen = false;
249
+ yield {
250
+ type: "reasoning-end"
251
+ };
252
+ }
213
253
  for (const [
214
254
  position,
215
255
  partialToolCall
@@ -263,6 +303,11 @@ async function* transformStream(stream) {
263
303
  yield* emitBufferedToolCalls(bufferedToolCalls, emittedToolCalls);
264
304
  }
265
305
  }
306
+ if (reasoningOpen) {
307
+ yield {
308
+ type: "reasoning-end"
309
+ };
310
+ }
266
311
  yield* emitBufferedToolCalls(bufferedToolCalls, emittedToolCalls);
267
312
  yield {
268
313
  type: "finish",
@@ -316,20 +361,43 @@ function mapUsage(usage) {
316
361
  cacheReadTokens: 0,
317
362
  cacheWriteTokens: 0
318
363
  },
319
- outputTokenDetails: {
320
- reasoningTokens: 0
321
- }
364
+ outputTokenDetails: {}
322
365
  };
323
366
  }
324
- function extractTextContent(content) {
325
- if (typeof content === "string") {
326
- return content;
367
+ function extractAssistantParts(message) {
368
+ const parts = [];
369
+ if (typeof message.content === "string") {
370
+ if (message.content.length > 0) {
371
+ parts.push({
372
+ type: "text",
373
+ text: message.content
374
+ });
375
+ }
376
+ } else if (Array.isArray(message.content)) {
377
+ for (const chunk of message.content) {
378
+ if (chunk.type === "text") {
379
+ parts.push({
380
+ type: "text",
381
+ text: chunk.text
382
+ });
383
+ continue;
384
+ }
385
+ if (chunk.type === "thinking") {
386
+ const thinkingText = extractThinkingText(chunk.thinking);
387
+ parts.push({
388
+ type: "reasoning",
389
+ text: thinkingText
390
+ });
391
+ }
392
+ }
327
393
  }
328
- if (!content || content.length === 0) {
329
- return null;
394
+ for (const toolCall of parseToolCalls(message.toolCalls)) {
395
+ parts.push({
396
+ type: "tool-call",
397
+ toolCall
398
+ });
330
399
  }
331
- const text = content.flatMap((chunk) => chunk.type === "text" ? [chunk.text] : []).join("");
332
- return text.length > 0 ? text : null;
400
+ return parts;
333
401
  }
334
402
  function extractTextDeltas(content) {
335
403
  if (typeof content === "string") {
@@ -342,6 +410,36 @@ function extractTextDeltas(content) {
342
410
  (chunk) => chunk.type === "text" ? [chunk.text] : []
343
411
  );
344
412
  }
413
+ function extractThinkingDeltas(content) {
414
+ if (!content || typeof content === "string") {
415
+ return [];
416
+ }
417
+ return content.flatMap((chunk) => {
418
+ if (chunk.type !== "thinking") {
419
+ return [];
420
+ }
421
+ const thinkingText = extractThinkingText(chunk.thinking);
422
+ if (thinkingText.length === 0) {
423
+ return [];
424
+ }
425
+ return [thinkingText];
426
+ });
427
+ }
428
+ function extractThinkingText(value) {
429
+ if (typeof value === "string") {
430
+ return value;
431
+ }
432
+ if (!Array.isArray(value)) {
433
+ return "";
434
+ }
435
+ return value.flatMap((part) => {
436
+ if (!part || typeof part !== "object") {
437
+ return [];
438
+ }
439
+ const text = part.text;
440
+ return typeof text === "string" ? [text] : [];
441
+ }).join("");
442
+ }
345
443
  function serializeJsonObject(value) {
346
444
  const objectValue = asObject(value);
347
445
  return Object.keys(objectValue).length > 0 ? JSON.stringify(objectValue) : "";
@@ -472,7 +570,7 @@ async function* transformStructuredOutputStream(stream, schema, provider, toolNa
472
570
  let contentBuffer = "";
473
571
  const toolArgumentDeltas = /* @__PURE__ */ new Map();
474
572
  for await (const event of stream) {
475
- if (event.type === "content-delta") {
573
+ if (event.type === "text-delta") {
476
574
  contentBuffer += event.text;
477
575
  yield {
478
576
  type: "object-delta",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@core-ai/mistral",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Mistral provider package for @core-ai/core-ai",
5
5
  "license": "MIT",
6
6
  "author": "Omnifact (https://omnifact.ai)",
@@ -42,7 +42,7 @@
42
42
  "test:watch": "vitest"
43
43
  },
44
44
  "dependencies": {
45
- "@core-ai/core-ai": "^0.4.0",
45
+ "@core-ai/core-ai": "^0.5.0",
46
46
  "@mistralai/mistralai": "^1.14.0",
47
47
  "zod-to-json-schema": "^3.25.1"
48
48
  },