UNPKG

@microsoft/teams-ai

Version:

SDK focused on building AI based applications for Microsoft Teams.

166 lines 6.67 kB
"use strict"; /** * @module teams-ai */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenAIEmbeddings = void 0; const axios_1 = __importDefault(require("axios")); const internals_1 = require("../internals"); /** * A `EmbeddingsModel` for calling OpenAI and Azure OpenAI hosted models. */ class OpenAIEmbeddings { _httpClient; _useAzure; UserAgent = '@microsoft/teams-ai-v1'; /** * Options the client was configured with. */ options; /** * Creates a new `OpenAIEmbeddings` instance. * @param {OpenAIEmbeddingsOptions | AzureOpenAIEmbeddingsOptions | OpenAILikeEmbeddingsOptions} options Options for configuring the embeddings client. */ constructor(options) { // Check for azure config if (options.azureApiKey) { this._useAzure = true; this.options = Object.assign({ retryPolicy: [2000, 5000], azureApiVersion: '2023-05-15' }, options); // Cleanup and validate endpoint let endpoint = this.options.azureEndpoint.trim(); if (endpoint.endsWith('/')) { endpoint = endpoint.substring(0, endpoint.length - 1); } this.options.azureEndpoint = endpoint; } else { this._useAzure = false; this.options = Object.assign({ retryPolicy: [2000, 5000] }, options); } // Create client this._httpClient = axios_1.default.create({ validateStatus: (status) => status < 400 || status == 429 }); } /** * Creates embeddings for the given inputs using the OpenAI API. * @param {string} model Name of the model to use (or deployment for Azure). * @param {string | string[]} inputs Text inputs to create embeddings for. * @returns {Promise<EmbeddingsResponse>} A `EmbeddingsResponse` with a status and the generated embeddings or a message when an error occurs. */ async createEmbeddings(model, inputs) { if (this.options.logRequests) { console.log(internals_1.Colorize.title('EMBEDDINGS REQUEST:')); console.log(internals_1.Colorize.output(inputs)); } const request = { model: model, input: inputs }; if (this.options.dimensions) { request.dimensions = this.options.dimensions; } const startTime = Date.now(); const response = await this.createEmbeddingRequest(request); if (this.options.logRequests) { console.log(internals_1.Colorize.title('RESPONSE:')); console.log(internals_1.Colorize.value('status', response.status)); console.log(internals_1.Colorize.value('duration', Date.now() - startTime, 'ms')); console.log(internals_1.Colorize.output(response.data)); } // Process response if (response.status < 300) { return { status: 'success', output: response.data.data.sort((a, b) => a.index - b.index).map((item) => item.embedding) }; } else if (response.status == 429) { return { status: 'rate_limited', message: `The embeddings API returned a rate limit error.` }; } else { return { status: 'error', message: `The embeddings API returned an error status of ${response.status}: ${response.statusText}` }; } } /** * @private * @param {CreateEmbeddingRequest} request The request to send to the OpenAI API. * @returns {Promise<AxiosResponse<CreateEmbeddingResponse>>} A promise that resolves to the response from the OpenAI API. */ createEmbeddingRequest(request) { if (this._useAzure) { const options = this.options; const url = `${options.azureEndpoint}/openai/deployments/${options.azureDeployment}/embeddings?api-version=${options.azureApiVersion}`; return this.post(url, request); } else { const options = this.options; const url = `${options.endpoint ?? 'https://api.openai.com'}/v1/embeddings`; request.model = options.model; return this.post(url, request); } } /** * @private * @template TData Optional. Type of the data associated with the action. * @param {string} url The URL to send the request to. * @param {object} body The body of the request. * @param {number} retryCount The number of times the request has been retried. * @returns {Promise<AxiosResponse<TData>>} A promise that resolves to the response from the OpenAI API. */ async post(url, body, retryCount = 0) { // Initialize request config const requestConfig = Object.assign({}, this.options.requestConfig); // Initialize request headers if (!requestConfig.headers) { requestConfig.headers = {}; } if (!requestConfig.headers['Content-Type']) { requestConfig.headers['Content-Type'] = 'application/json'; } if (!requestConfig.headers['User-Agent']) { requestConfig.headers['User-Agent'] = this.UserAgent; } if (this._useAzure) { const options = this.options; requestConfig.headers['api-key'] = options.azureApiKey; } else if (this.options.apiKey) { const options = this.options; requestConfig.headers['Authorization'] = `Bearer ${options.apiKey}`; if (options.organization) { requestConfig.headers['OpenAI-Organization'] = options.organization; } } // Send request const response = await this._httpClient.post(url, body, requestConfig); // Check for rate limit error if (response.status == 429 && Array.isArray(this.options.retryPolicy) && retryCount < this.options.retryPolicy.length) { const delay = this.options.retryPolicy[retryCount]; await new Promise((resolve) => setTimeout(resolve, delay)); return this.post(url, body, retryCount + 1); } else { return response; } } } exports.OpenAIEmbeddings = OpenAIEmbeddings; //# sourceMappingURL=OpenAIEmbeddings.js.map