UNPKG

@microsoft/botbuilder-m365

Version:

M365 extensions for Microsoft BotBuilder, Alpha release.

114 lines (95 loc) 4.03 kB
/** * @module botbuilder-m365 */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import axios, { AxiosInstance, AxiosRequestHeaders } from 'axios'; import { CreateChatCompletionRequest, CreateChatCompletionResponse, CreateCompletionRequest, CreateCompletionResponse, CreateEmbeddingRequest, CreateEmbeddingResponse, CreateModerationRequest, CreateModerationResponse } from './schema'; export interface OpenAIClientResponse<TData> { status: number; statusText: string; headers: Record<string, string>; data?: TData; } export interface OpenAIClientOptions { apiKey: string; organization?: string; endpoint?: string; } export class OpenAIClient { private _httpClient: AxiosInstance; private readonly DefaultEndpoint = 'https://api.openai.com'; private readonly UserAgent = 'Microsoft Teams Conversational AI SDK'; public constructor(options: OpenAIClientOptions) { this.options = options; // Cleanup and validate endpoint if (options.endpoint) { options.endpoint = options.endpoint.trim(); if (options.endpoint.endsWith('/')) { options.endpoint = options.endpoint.substring(0, options.endpoint.length - 1); } if (!options.endpoint.toLowerCase().startsWith('https://')) { throw new Error( `OpenAIClient initialized with an invalid endpoint of '${options.endpoint}'. The endpoint must be a valid HTTPS url.` ); } } // Validate API key if (!options.apiKey) { throw new Error(`OpenAIClient initialized without an 'apiKey'.`); } // Create client and set headers this._httpClient = axios.create({ validateStatus: (status) => status < 400 || status == 429 }); } public readonly options: OpenAIClientOptions; public createCompletion(request: CreateCompletionRequest): Promise<OpenAIClientResponse<CreateCompletionResponse>> { const url = `${this.options.endpoint ?? this.DefaultEndpoint}/v1/completions`; return this.post(url, request); } public createChatCompletion( request: CreateChatCompletionRequest ): Promise<OpenAIClientResponse<CreateChatCompletionResponse>> { const url = `${this.options.endpoint ?? this.DefaultEndpoint}/v1/chat/completions`; return this.post(url, request); } public createEmbedding(request: CreateEmbeddingRequest): Promise<OpenAIClientResponse<CreateEmbeddingResponse>> { const url = `${this.options.endpoint ?? this.DefaultEndpoint}/v1/embeddings`; return this.post(url, request); } public createModeration(request: CreateModerationRequest): Promise<OpenAIClientResponse<CreateModerationResponse>> { const url = `${this.options.endpoint ?? this.DefaultEndpoint}/v1/moderations`; return this.post(url, request); } protected addRequestHeaders(headers: Record<string, string>, options: OpenAIClientOptions): void { headers['Authorization'] = `Bearer ${options.apiKey}`; if (options.organization) { headers['OpenAI-Organization'] = options.organization; } } protected async post<TData>(url: string, body: object): Promise<OpenAIClientResponse<TData>> { // Initialize request headers const requestHeaders: Record<string, string> = { 'Content-Type': 'application/json', 'User-Agent': this.UserAgent }; this.addRequestHeaders(requestHeaders, this.options); // Send request const { status, statusText, data, headers } = await this._httpClient.post(url, body, { headers: requestHeaders }); return { status, statusText, data, headers: headers as any }; } }