mistralai / client-js

JS Client library for Mistral AI platform
Apache License 2.0
185 stars 47 forks source link

Remove node-fetch as a dependency #83

Closed jwerre closed 3 weeks ago

jwerre commented 4 months ago

I see that node-fetch is used to make request to the Mistral API. Since node-fetch doesn't support CommonJs it would be pretty easy to remove it as a dependency. And, even better, you'd have zero dependencies. All you need to do is import the native https module and replace _request with this:

import { request } from 'https';

async _request<T, U>(
    method: string,
    path: string,
    body?: U,
    retries: number = 0
): Promise<T> {
    const options = {
        method,
        port: 443,
        body: method !== 'get' && body ? JSON.stringify(body) : null,
        headers: {
            'User-Agent': `mistral/mistral-client`,
            Accept: 'application/json',
            'Content-Type': 'application/json',
            Authorization: `Bearer ${this.apiKey}`,
        },
    };
    const url = new URL(`${this.endpoint}/${path}`);

    return new Promise((resolve, reject) => {
        const req = request(url, options, (res) => {
            let data = '';

            res.on('data', (chunk) => {
                data += chunk;
            });

            res.on('end', () => {
                if (
                    RETRY_STATUS_CODES.includes(res.statusCode ?? 500) &&
                    retries < this.maxRetries
                ) {
                    console.debug(
                        `Retry ${retries + 1}/${
                            this.maxRetries
                        } - Status Code: ${res.statusCode}`
                    );
                    setTimeout(() => {
                        resolve(
                            this._request<T, U>(
                                method,
                                path,
                                body,
                                retries + 1
                            )
                        );
                    }, RETRY_DELAY_MS);
                } else {
                    resolve(JSON.parse(data) as T);
                }
            });
        });

        req.on('error', (err) => {
            if (retries < this.maxRetries) {
                console.debug(
                    `Retry ${retries + 1}/${this.maxRetries} - Error: ${
                        err.message
                    }`
                );
                setTimeout(() => {
                    resolve(
                        this._request<T, U>(method, path, body, retries + 1)
                    );
                }, RETRY_DELAY_MS);
            } else {
                reject(new MistralAPIError(err.message));
            }
        });

        if (options.body) {
            req.write(options.body);
        }

        req.setTimeout(this.timeout, () => {
            req.destroy();
            if (retries < this.maxRetries) {
                console.log(
                    `Retry ${retries + 1}/${this.maxRetries} - Timeout`
                );
                setTimeout(() => {
                    resolve(
                        this._request<T, U>(method, path, body, retries + 1)
                    );
                }, RETRY_DELAY_MS);
            } else {
                reject(new MistralAPIError('Request timed out'));
            }
        });

        req.end();
    });
}

Happy to make a PR once #73 is merged

alex-shortt commented 3 months ago

Yeah had to make my own api wrapper, this was killing my builds. Was able to swap node-fetch with https://www.npmjs.com/package/node-fetch-commonjs

jwerre commented 3 months ago

Yeah had to make my own api wrapper, this was killing my builds. Was able to swap node-fetch with https://www.npmjs.com/package/node-fetch-commonjs

You could try using Fetch v2

GaspardBT commented 3 weeks ago

Thanks for reporting this issue. We have deprecated this package in favor of mistralai/client-ts, which is the new official Mistral client, compatible with both TypeScript and JavaScript.

You can find all installation information here.

This change is effective starting with version 1.0.0 of the npm package.

Let us know if your issue persists with the new package by opening an issue there.