@mistralai/mistralai 0.2.0 → 0.4.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.
@@ -6,9 +6,13 @@ const apiKey = process.env.MISTRAL_API_KEY;
6
6
  const data = {
7
7
  transactionId: ['T1001', 'T1002', 'T1003', 'T1004', 'T1005'],
8
8
  customerId: ['C001', 'C002', 'C003', 'C002', 'C001'],
9
- paymentAmount: [125.50, 89.99, 120.00, 54.30, 210.20],
9
+ paymentAmount: [125.5, 89.99, 120.0, 54.3, 210.2],
10
10
  paymentDate: [
11
- '2021-10-05', '2021-10-06', '2021-10-07', '2021-10-05', '2021-10-08',
11
+ '2021-10-05',
12
+ '2021-10-06',
13
+ '2021-10-07',
14
+ '2021-10-05',
15
+ '2021-10-08',
12
16
  ],
13
17
  paymentStatus: ['Paid', 'Unpaid', 'Paid', 'Paid', 'Pending'],
14
18
  };
@@ -22,7 +26,7 @@ const data = {
22
26
  function retrievePaymentStatus({data, transactionId}) {
23
27
  const transactionIndex = data.transactionId.indexOf(transactionId);
24
28
  if (transactionIndex != -1) {
25
- return JSON.stringify({status: data.payment_status[transactionIndex]});
29
+ return JSON.stringify({status: data.paymentStatus[transactionIndex]});
26
30
  } else {
27
31
  return JSON.stringify({status: 'error - transaction id not found.'});
28
32
  }
@@ -60,8 +64,8 @@ const tools = [
60
64
  parameters: {
61
65
  type: 'object',
62
66
  required: ['transactionId'],
63
- properties: {transactionId:
64
- {type: 'string', description: 'The transaction id.'},
67
+ properties: {
68
+ transactionId: {type: 'string', description: 'The transaction id.'},
65
69
  },
66
70
  },
67
71
  },
@@ -74,38 +78,43 @@ const tools = [
74
78
  parameters: {
75
79
  type: 'object',
76
80
  required: ['transactionId'],
77
- properties: {transactionId:
78
- {type: 'string', description: 'The transaction id.'},
81
+ properties: {
82
+ transactionId: {type: 'string', description: 'The transaction id.'},
79
83
  },
80
84
  },
81
85
  },
82
86
  },
83
87
  ];
84
88
 
89
+ const model = 'mistral-small-latest';
85
90
 
86
- const model = 'mistral-large';
87
-
88
- const client = new MistralClient(apiKey, 'https://api-2.aurocloud.net');
91
+ const client = new MistralClient(apiKey);
89
92
 
90
93
  const messages = [
91
94
  {role: 'user', content: 'What\'s the status of my transaction?'},
92
95
  ];
93
96
 
94
97
  let response = await client.chat({
95
- model: model, messages: messages, tools: tools,
98
+ model: model,
99
+ messages: messages,
100
+ tools: tools,
96
101
  });
97
102
 
98
-
99
103
  console.log(response.choices[0].message.content);
100
104
 
101
- messages.push(
102
- {role: 'assistant', content: response.choices[0].message.content},
103
- );
105
+ messages.push({
106
+ role: 'assistant',
107
+ content: response.choices[0].message.content,
108
+ });
104
109
  messages.push({role: 'user', content: 'My transaction ID is T1001.'});
105
110
 
106
- response = await client.chat({model: model, messages: messages, tools: tools});
111
+ response = await client.chat({
112
+ model: model,
113
+ messages: messages,
114
+ tools: tools,
115
+ });
107
116
 
108
- const toolCall = response.choices[0].message.toolCalls[0];
117
+ const toolCall = response.choices[0].message.tool_calls[0];
109
118
  const functionName = toolCall.function.name;
110
119
  const functionParams = JSON.parse(toolCall.function.arguments);
111
120
 
@@ -115,8 +124,17 @@ console.log(`functionParams: ${toolCall.function.arguments}`);
115
124
  const functionResult = namesToFunctions[functionName](functionParams);
116
125
 
117
126
  messages.push(response.choices[0].message);
118
- messages.push({role: 'tool', name: functionName, content: functionResult});
127
+ messages.push({
128
+ role: 'tool',
129
+ name: functionName,
130
+ content: functionResult,
131
+ tool_call_id: toolCall.id,
132
+ });
119
133
 
120
- response = await client.chat({model: model, messages: messages, tools: tools});
134
+ response = await client.chat({
135
+ model: model,
136
+ messages: messages,
137
+ tools: tools,
138
+ });
121
139
 
122
140
  console.log(response.choices[0].message.content);
@@ -5,7 +5,7 @@ const apiKey = process.env.MISTRAL_API_KEY;
5
5
  const client = new MistralClient(apiKey);
6
6
 
7
7
  const chatResponse = await client.chat({
8
- model: 'mistral-large',
8
+ model: 'mistral-large-latest',
9
9
  messages: [{role: 'user', content: 'What is the best French cheese?'}],
10
10
  responseFormat: {type: 'json_object'},
11
11
  });
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "..": {
15
15
  "name": "@mistralai/mistralai",
16
- "version": "0.0.1",
16
+ "version": "0.4.0",
17
17
  "license": "ISC",
18
18
  "dependencies": {
19
19
  "node-fetch": "^2.6.7"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mistralai/mistralai",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "",
5
5
  "author": "bam4d@mistral.ai",
6
6
  "license": "ISC",
package/src/client.d.ts CHANGED
@@ -107,10 +107,17 @@ declare module "@mistralai/mistralai" {
107
107
  usage: TokenUsage;
108
108
  }
109
109
 
110
- export interface Message {
111
- role: string;
112
- content: string | string[];
113
- }
110
+ export type Message =
111
+ | {
112
+ role: "system" | "user" | "assistant";
113
+ content: string | string[];
114
+ }
115
+ | {
116
+ role: "tool";
117
+ content: string | string[];
118
+ name: string;
119
+ tool_call_id: string;
120
+ };
114
121
 
115
122
  export interface Tool {
116
123
  type: "function";
@@ -134,6 +141,17 @@ declare module "@mistralai/mistralai" {
134
141
  responseFormat?: ResponseFormat;
135
142
  }
136
143
 
144
+ export interface CompletionRequest {
145
+ model: string;
146
+ prompt: string;
147
+ suffix?: string;
148
+ temperature?: number;
149
+ maxTokens?: number;
150
+ topP?: number;
151
+ randomSeed?: number;
152
+ stop?: string | string[];
153
+ }
154
+
137
155
  export interface ChatRequestOptions {
138
156
  signal?: AbortSignal;
139
157
  }
@@ -163,6 +181,17 @@ declare module "@mistralai/mistralai" {
163
181
  options?: ChatRequestOptions
164
182
  ): AsyncGenerator<ChatCompletionResponseChunk, void>;
165
183
 
184
+ completion(
185
+ request: CompletionRequest,
186
+ options?: ChatRequestOptions
187
+ ): Promise<ChatCompletionResponse>;
188
+
189
+ completionStream(
190
+ request: CompletionRequest,
191
+ options?: ChatRequestOptions
192
+ ): AsyncGenerator<ChatCompletionResponseChunk, void>;
193
+
194
+
166
195
  embeddings(options: {
167
196
  model: string;
168
197
  input: string | string[];
package/src/client.js CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = '0.2.0';
1
+ const VERSION = '0.3.0';
2
2
  const RETRY_STATUS_CODES = [429, 500, 502, 503, 504];
3
3
  const ENDPOINT = 'https://api.mistral.ai';
4
4
 
@@ -161,7 +161,7 @@ class MistralClient {
161
161
  } else {
162
162
  throw new MistralAPIError(
163
163
  `HTTP error! status: ${response.status} ` +
164
- `Response: \n${await response.text()}`,
164
+ `Response: \n${await response.text()}`,
165
165
  );
166
166
  }
167
167
  } catch (error) {
@@ -228,6 +228,47 @@ class MistralClient {
228
228
  };
229
229
  };
230
230
 
231
+ /**
232
+ * Creates a completion request
233
+ * @param {*} model
234
+ * @param {*} prompt
235
+ * @param {*} suffix
236
+ * @param {*} temperature
237
+ * @param {*} maxTokens
238
+ * @param {*} topP
239
+ * @param {*} randomSeed
240
+ * @param {*} stop
241
+ * @param {*} stream
242
+ * @return {Promise<Object>}
243
+ */
244
+ _makeCompletionRequest = function(
245
+ model,
246
+ prompt,
247
+ suffix,
248
+ temperature,
249
+ maxTokens,
250
+ topP,
251
+ randomSeed,
252
+ stop,
253
+ stream,
254
+ ) {
255
+ // if modelDefault and model are undefined, throw an error
256
+ if (!model && !this.modelDefault) {
257
+ throw new MistralAPIError('You must provide a model name');
258
+ }
259
+ return {
260
+ model: model ?? this.modelDefault,
261
+ prompt: prompt,
262
+ suffix: suffix ?? undefined,
263
+ temperature: temperature ?? undefined,
264
+ max_tokens: maxTokens ?? undefined,
265
+ top_p: topP ?? undefined,
266
+ random_seed: randomSeed ?? undefined,
267
+ stop: stop ?? undefined,
268
+ stream: stream ?? undefined,
269
+ };
270
+ };
271
+
231
272
  /**
232
273
  * Returns a list of the available models
233
274
  * @return {Promise<Object>}
@@ -401,6 +442,134 @@ class MistralClient {
401
442
  const response = await this._request('post', 'v1/embeddings', request);
402
443
  return response;
403
444
  };
445
+
446
+ /**
447
+ * A completion endpoint without streaming.
448
+ *
449
+ * @param {Object} data - The main completion configuration.
450
+ * @param {*} data.model - the name of the model to chat with,
451
+ * e.g. mistral-tiny
452
+ * @param {*} data.prompt - the prompt to complete,
453
+ * e.g. 'def fibonacci(n: int):'
454
+ * @param {*} data.temperature - the temperature to use for sampling, e.g. 0.5
455
+ * @param {*} data.maxTokens - the maximum number of tokens to generate,
456
+ * e.g. 100
457
+ * @param {*} data.topP - the cumulative probability of tokens to generate,
458
+ * e.g. 0.9
459
+ * @param {*} data.randomSeed - the random seed to use for sampling, e.g. 42
460
+ * @param {*} data.stop - the stop sequence to use, e.g. ['\n']
461
+ * @param {*} data.suffix - the suffix to append to the prompt,
462
+ * e.g. 'n = int(input(\'Enter a number: \'))'
463
+ * @param {Object} options - Additional operational options.
464
+ * @param {*} [options.signal] - optional AbortSignal instance to control
465
+ * request The signal will be combined with
466
+ * default timeout signal
467
+ * @return {Promise<Object>}
468
+ */
469
+ completion = async function(
470
+ {
471
+ model,
472
+ prompt,
473
+ suffix,
474
+ temperature,
475
+ maxTokens,
476
+ topP,
477
+ randomSeed,
478
+ stop,
479
+ },
480
+ {signal} = {},
481
+ ) {
482
+ const request = this._makeCompletionRequest(
483
+ model,
484
+ prompt,
485
+ suffix,
486
+ temperature,
487
+ maxTokens,
488
+ topP,
489
+ randomSeed,
490
+ stop,
491
+ false,
492
+ );
493
+ const response = await this._request(
494
+ 'post',
495
+ 'v1/fim/completions',
496
+ request,
497
+ signal,
498
+ );
499
+ return response;
500
+ };
501
+
502
+ /**
503
+ * A completion endpoint that streams responses.
504
+ *
505
+ * @param {Object} data - The main completion configuration.
506
+ * @param {*} data.model - the name of the model to chat with,
507
+ * e.g. mistral-tiny
508
+ * @param {*} data.prompt - the prompt to complete,
509
+ * e.g. 'def fibonacci(n: int):'
510
+ * @param {*} data.temperature - the temperature to use for sampling, e.g. 0.5
511
+ * @param {*} data.maxTokens - the maximum number of tokens to generate,
512
+ * e.g. 100
513
+ * @param {*} data.topP - the cumulative probability of tokens to generate,
514
+ * e.g. 0.9
515
+ * @param {*} data.randomSeed - the random seed to use for sampling, e.g. 42
516
+ * @param {*} data.stop - the stop sequence to use, e.g. ['\n']
517
+ * @param {*} data.suffix - the suffix to append to the prompt,
518
+ * e.g. 'n = int(input(\'Enter a number: \'))'
519
+ * @param {Object} options - Additional operational options.
520
+ * @param {*} [options.signal] - optional AbortSignal instance to control
521
+ * request The signal will be combined with
522
+ * default timeout signal
523
+ * @return {Promise<Object>}
524
+ */
525
+ completionStream = async function* (
526
+ {
527
+ model,
528
+ prompt,
529
+ suffix,
530
+ temperature,
531
+ maxTokens,
532
+ topP,
533
+ randomSeed,
534
+ stop,
535
+ },
536
+ {signal} = {},
537
+ ) {
538
+ const request = this._makeCompletionRequest(
539
+ model,
540
+ prompt,
541
+ suffix,
542
+ temperature,
543
+ maxTokens,
544
+ topP,
545
+ randomSeed,
546
+ stop,
547
+ true,
548
+ );
549
+ const response = await this._request(
550
+ 'post',
551
+ 'v1/fim/completions',
552
+ request,
553
+ signal,
554
+ );
555
+
556
+ let buffer = '';
557
+ const decoder = new TextDecoder();
558
+ for await (const chunk of response) {
559
+ buffer += decoder.decode(chunk, {stream: true});
560
+ let firstNewline;
561
+ while ((firstNewline = buffer.indexOf('\n')) !== -1) {
562
+ const chunkLine = buffer.substring(0, firstNewline);
563
+ buffer = buffer.substring(firstNewline + 1);
564
+ if (chunkLine.startsWith('data:')) {
565
+ const json = chunkLine.substring(6).trim();
566
+ if (json !== '[DONE]') {
567
+ yield JSON.parse(json);
568
+ }
569
+ }
570
+ }
571
+ }
572
+ };
404
573
  }
405
574
 
406
575
  export default MistralClient;
@@ -23,7 +23,7 @@ describe('Mistral Client', () => {
23
23
  client._fetch = mockFetch(200, mockResponse);
24
24
 
25
25
  const response = await client.chat({
26
- model: 'mistral-small',
26
+ model: 'mistral-small-latest',
27
27
  messages: [
28
28
  {
29
29
  role: 'user',
@@ -40,7 +40,7 @@ describe('Mistral Client', () => {
40
40
  client._fetch = mockFetch(200, mockResponse);
41
41
 
42
42
  const response = await client.chat({
43
- model: 'mistral-small',
43
+ model: 'mistral-small-latest',
44
44
  messages: [
45
45
  {
46
46
  role: 'user',
@@ -58,7 +58,7 @@ describe('Mistral Client', () => {
58
58
  client._fetch = mockFetch(200, mockResponse);
59
59
 
60
60
  const response = await client.chat({
61
- model: 'mistral-small',
61
+ model: 'mistral-small-latest',
62
62
  messages: [
63
63
  {
64
64
  role: 'user',
@@ -78,7 +78,7 @@ describe('Mistral Client', () => {
78
78
  client._fetch = mockFetchStream(200, mockResponse);
79
79
 
80
80
  const response = await client.chatStream({
81
- model: 'mistral-small',
81
+ model: 'mistral-small-latest',
82
82
  messages: [
83
83
  {
84
84
  role: 'user',
@@ -101,7 +101,7 @@ describe('Mistral Client', () => {
101
101
  client._fetch = mockFetchStream(200, mockResponse);
102
102
 
103
103
  const response = await client.chatStream({
104
- model: 'mistral-small',
104
+ model: 'mistral-small-latest',
105
105
  messages: [
106
106
  {
107
107
  role: 'user',
@@ -125,7 +125,7 @@ describe('Mistral Client', () => {
125
125
  client._fetch = mockFetchStream(200, mockResponse);
126
126
 
127
127
  const response = await client.chatStream({
128
- model: 'mistral-small',
128
+ model: 'mistral-small-latest',
129
129
  messages: [
130
130
  {
131
131
  role: 'user',
@@ -176,4 +176,18 @@ describe('Mistral Client', () => {
176
176
  expect(response).toEqual(mockResponse);
177
177
  });
178
178
  });
179
+
180
+ describe('completion()', () => {
181
+ it('should return a chat response object', async() => {
182
+ // Mock the fetch function
183
+ const mockResponse = mockChatResponsePayload();
184
+ client._fetch = mockFetch(200, mockResponse);
185
+
186
+ const response = await client.completion({
187
+ model: 'mistral-small-latest',
188
+ prompt: '# this is a',
189
+ });
190
+ expect(response).toEqual(mockResponse);
191
+ });
192
+ });
179
193
  });
package/tests/utils.js CHANGED
@@ -78,7 +78,7 @@ export function mockListModels() {
78
78
  ],
79
79
  },
80
80
  {
81
- id: 'mistral-small',
81
+ id: 'mistral-small-latest',
82
82
  object: 'model',
83
83
  created: 1703186988,
84
84
  owned_by: 'mistralai',
@@ -172,7 +172,7 @@ export function mockChatResponsePayload() {
172
172
  index: 0,
173
173
  },
174
174
  ],
175
- model: 'mistral-small',
175
+ model: 'mistral-small-latest',
176
176
  usage: {prompt_tokens: 90, total_tokens: 90, completion_tokens: 0},
177
177
  };
178
178
  }
@@ -187,7 +187,7 @@ export function mockChatResponseStreamingPayload() {
187
187
  [encoder.encode('data: ' +
188
188
  JSON.stringify({
189
189
  id: 'cmpl-8cd9019d21ba490aa6b9740f5d0a883e',
190
- model: 'mistral-small',
190
+ model: 'mistral-small-latest',
191
191
  choices: [
192
192
  {
193
193
  index: 0,
@@ -207,7 +207,7 @@ export function mockChatResponseStreamingPayload() {
207
207
  id: 'cmpl-8cd9019d21ba490aa6b9740f5d0a883e',
208
208
  object: 'chat.completion.chunk',
209
209
  created: 1703168544,
210
- model: 'mistral-small',
210
+ model: 'mistral-small-latest',
211
211
  choices: [
212
212
  {
213
213
  index: i,