UNPKG

@nuskin/chat-bot

Version:

React Chat Bot component for GenAI interaction with Amazon Bedrock

138 lines (125 loc) 4.58 kB
import { getRetryAxiosInstance } from '@nuskin/axios-util' import { stringToJSON } from '@nuskin/uncle-buck' import { v4 as uuidv4 } from 'uuid' const SESSION_ID = 'sessionId' let Cookies // Dynamically import js-cookie only on client side if (typeof window !== 'undefined') { import('js-cookie').then((module) => { Cookies = module.default }) } const getPath = () => { return typeof window !== 'undefined' ? window.location.pathname : '/' } const retryDelay = parseInt(process.env.AXIOS_RETRY_DELAY, 10) || 5000 /** * The retry configuration for the axios instance. */ export const retryConfig = { retries: 3, shouldResetTimeout: true, retryDelay: (retryCount) => retryCount * retryDelay, retryCondition: (error) => error.response?.status >= 500 || error.code === 'ECONNABORTED', onRetry: (retryCount, error, requestConfig) => { console.log( { retryCount, message: error.message, statusCode: error.response?.status, statusText: error.response?.statusText, responseData: error.response?.data }, requestConfig.metric ) return true } } /** * A configured Axios instance with retry functionality. * * @const {AxiosInstance} myAxios * @description Provides a pre-configured Axios instance with the following settings: * - Retries up to 3 times on failed requests * - Resets the timeout on each retry * - Exponential backoff for retry delay (starting at 5 seconds) * - Retries on 500-level status codes and connection aborted errors * - Logs retry information using the `@nuskin/logger` library */ const myAxiosInstance = getRetryAxiosInstance(retryConfig) myAxiosInstance.defaults.timeout = parseInt(process.env.AXIOS_TIMEOUT, 10) || 60000 export const myAxios = myAxiosInstance /** * Retrieves an answer from a conversational AI service via a proxy endpoint. * * @async * @function getProxyAnswer * @param {string} question - The question to be answered. * @param {string} agentId - The ID of the agent to use for answering. * @param {string} agentAliasId - The alias ID of the agent. * @param {string} apiEndpoint - The URL of the API endpoint to call. * @param {string} apiHeaders - Object String * @returns {Promise<{ value: object }|{ error: string }>} - An object containing either the agent's response or an error message. * @throws {Error} - Throws an error if there is an issue with the API request. * * @example * const answer = await getProxyAnswer( * 'What is the capital of France?', * 'agent-123', * 'alias-456', * 'https://api.example.com/chat', * '{"Authorization": "YOUR_KEY_OR_TOKEN"}' * ); * if (answer.value) { * console.log(answer.value); // Output: Response object from the API * } else { * console.error(answer.error); // Output: Error message if request failed * } */ export const getProxyAnswer = async (question, agentId, agentAliasId, apiEndpoint, apiHeaders) => { // Only perform cookie operations if we're on the client side let sessionId = uuidv4() // Default to new session ID if (typeof window !== 'undefined' && Cookies) { // Delete expired cookies if (Cookies.get(SESSION_ID)) { Cookies.remove(SESSION_ID, { path: getPath() }) } // Get existing or set new session const existingSession = Cookies.get(SESSION_ID) if (existingSession) { sessionId = existingSession } else { Cookies.set(SESSION_ID, sessionId, { expires: 0.5, // 12 hours in days path: getPath() }) } } try { const headers = stringToJSON(apiHeaders) const axiosConfig = { method: 'POST', url: apiEndpoint, headers, data: { agentId, agentAliasId, messages: [], inputText: question, sessionId } } console.log({ axiosConfig }) const response = await myAxios(axiosConfig) console.log({ response }) return { value: response.data } } catch (e) { console.error('API Error:', e.message, e.response?.data) return { error: `${e.message}${e.response?.data?.message ? `. ${e.response.data.message}` : ''}` } } } export const deleteSessionCookie = () => { if (typeof window !== 'undefined' && Cookies) { Cookies.remove(SESSION_ID, { path: getPath() }) } }