@nuskin/chat-bot
Version:
React Chat Bot component for GenAI interaction with Amazon Bedrock
138 lines (125 loc) • 4.58 kB
JavaScript
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() })
}
}