myavana-bot-test-core 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env CHANGED
@@ -1,8 +1,10 @@
1
1
  # PostgreSQL
2
2
  DB_HOST=34.55.140.120
3
+ MYAVANA_DB_HOST=34.60.246.147
3
4
  DB_USER=myavana
4
5
  DB_PASSWORD=higibertigibet
5
6
  DB_NAME=sienna-naturals-custom-bot
7
+ MYAVANA_DB_NAME=myavana-dashboard-bot
6
8
  DB_PORT=5432
7
9
 
8
10
  # Redis
package/index.js CHANGED
@@ -21,6 +21,7 @@ module.exports = {
21
21
  postResponseProcessing: require('./src/postResponseProcessing').postResponseProcessing,
22
22
  saveHairIssue: require('./src/hairIssues').saveHairIssue,
23
23
  getHairIssuesForUser: require('./src/hairIssues').getHairIssuesForUser,
24
+ postResponseProductCheck: require('./src/postResponseProcessing').postResponseProductCheck,
24
25
 
25
26
  // Utilities
26
27
  getAllProducts: require('./src/utils').getAllProducts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myavana-bot-test-core",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Shared bot functionality",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/config.js CHANGED
@@ -9,6 +9,13 @@ module.exports = {
9
9
  database: process.env.DB_NAME,
10
10
  port: parseInt(process.env.DB_PORT, 10) || 5432, // Default PostgreSQL port
11
11
  },
12
+ myavanaDbConfig: {
13
+ host: process.env.MYAVANA_DB_HOST,
14
+ user: process.env.DB_USER,
15
+ password: process.env.DB_PASSWORD,
16
+ database: process.env.MYAVANA_DB_NAME,
17
+ port: parseInt(process.env.DB_PORT, 10) || 5432, // Default PostgreSQL port
18
+ },
12
19
  redisConfig: {
13
20
  username: process.env.REDIS_USERNAME,
14
21
  password: process.env.REDIS_PASSWORD,
@@ -5,10 +5,11 @@ const DatabaseSessionStore = require("./session");
5
5
  const { pgClient, redisClient } = require('./database');
6
6
  const {generateAndSaveSummary, saveConversationSummary, saveConversation} = require("./conversation");
7
7
  const {saveHairIssue} = require("./hairIssues");
8
+ const {getProductByName, addProductRecommendation} = require("./utils");
8
9
 
9
10
  const postProcessingPrompt = (chatHistory, message) => {
10
11
  return `
11
- You are a Sienna Naturals expert AI assistant designed to analyze user conversations and user's name and extract structured information related to hair care.
12
+ You are a hair expert AI assistant designed to analyze user conversations and user's name and extract structured information related to hair care.
12
13
 
13
14
  **Task:** Analyze the following conversation history and the user's latest message to:
14
15
 
@@ -222,7 +223,7 @@ const postProcessConversation = async (chatHistory, message) => {
222
223
 
223
224
 
224
225
  const extractionPrompt = await postProcessingPrompt(chatHistory, message);
225
- console.log('Extraction prompt: ', extractionPrompt);
226
+ //console.log('Extraction prompt: ', extractionPrompt);
226
227
  try {
227
228
  const chat = ai.chat({
228
229
  model: gemini15Flash,
@@ -232,7 +233,7 @@ const postProcessConversation = async (chatHistory, message) => {
232
233
 
233
234
  });
234
235
  const { output } = await chat.send(extractionPrompt);
235
- console.log("Raw post-processing output:", JSON.stringify(output));
236
+ //console.log("Raw post-processing output:", JSON.stringify(output));
236
237
 
237
238
  if (!output) {
238
239
  console.warn("Post-processing output is empty. Returning default empty JSON.");
@@ -313,10 +314,9 @@ const updateUserProfile = async (userId, updates) => {
313
314
  }
314
315
  };
315
316
 
316
- const postResponseProcessing = async (postProcessData, userId, output, allchatsSummary, conversationId, chatHistory )=>{
317
+ const postResponseProcessing = async (postProcessData, userId, output, allchatsSummary, conversationId, chatHistory, botMessage )=>{
317
318
  if (postProcessData.user_profile_updates) {
318
- // TODO: Update user profile in database based on postProcessData.user_profile_updates
319
- console.log("User profile updates to be applied:", postProcessData.user_profile_updates);
319
+ //console.log("User profile updates to be applied:", postProcessData.user_profile_updates);
320
320
  await updateUserProfile(userId, postProcessData.user_profile_updates);
321
321
  }
322
322
 
@@ -331,14 +331,94 @@ const postResponseProcessing = async (postProcessData, userId, output, allchatsS
331
331
  if (!allchatsSummary) {
332
332
  await generateAndSaveSummary(userId, conversationId, chatHistory);
333
333
  }
334
+ const recommendedProductsData = await postResponseProductCheck(chatHistory, botMessage); // Get array of product objects
335
+ //console.log("Recommended Products (with reasons):", recommendedProductsData);
336
+
337
+ if (recommendedProductsData && recommendedProductsData.length > 0) {
338
+ // --- Loop through recommended products and save to DB (Corrected for reasons) ---
339
+ for (const productRecommendation of recommendedProductsData) { // Loop through objects
340
+ const { productName, reason } = productRecommendation; // Extract productName and reason
341
+ const product = await getProductByName(productName); // Lookup product by name
342
+
343
+ if (product) {
344
+ await addProductRecommendation(userId, conversationId, product.product_id, reason); // Pass the reason to addProductRecommendation
345
+ } else {
346
+ console.warn(`Product "${productName}" not found in database, cannot save recommendation.`);
347
+ }
348
+ }
349
+ }
334
350
 
335
351
  await saveConversationSummary(conversationId, userId, allchatsSummary);
336
352
  return await saveConversation(conversationId, userId, chatHistory, allchatsSummary);
337
353
  };
338
354
 
355
+ const postResponseProductCheckPrompt = async (chatHistory, message) => {
356
+ return `
357
+ Analyze the following chatbot conversation history and the bot's last response to identify if any specific products were recommended to the user.
358
+
359
+ Chat History:
360
+ ${JSON.stringify(chatHistory, null, 2)}
361
+
362
+ Bot's Last Response:
363
+ ${JSON.stringify(message, null, 2)}
364
+
365
+ Identify and list the names of the products recommended in the bot's last response AND provide a brief reason for each recommendation based on the conversation.
366
+ If no products were explicitly recommended, return an empty list.
367
+
368
+ Response Format:
369
+ [
370
+ { "productName": "Product Name 1", "reason": "Reason for recommendation 1" },
371
+ { "productName": "Product Name 2", "reason": "Reason for recommendation 2" },
372
+ ...
373
+ ] or [] if no products recommended.
374
+ `;
375
+ };
376
+
377
+ const postResponseProductCheck = async (chatHistory, message) => {
378
+ const extractionPrompt = await postResponseProductCheckPrompt(chatHistory, message);
379
+ //console.log('Extraction prompt for product check (with reason): ', extractionPrompt); // Updated log message
380
+ try {
381
+ const chat = ai.chat({
382
+ model: gemini15Flash, // or gemini20FlashExp
383
+ config: {
384
+ temperature: 0.9,
385
+ },
386
+ });
387
+ const { output } = await chat.send(extractionPrompt);
388
+ //console.log("Raw post-processing output for product check (with reason):", JSON.stringify(output)); // Updated log
389
+
390
+ if (!output) {
391
+ console.warn("Post-processing output for product check (with reason) is empty. Returning default empty array."); // Updated log
392
+ return [];
393
+ }
394
+
395
+ try {
396
+ // Attempt to parse the output as JSON (array of product objects)
397
+ const recommendedProductsData = JSON.parse(output); // Renamed variable
398
+ if (Array.isArray(recommendedProductsData)) {
399
+ return recommendedProductsData; // Return the array of product objects
400
+ } else {
401
+ console.warn("Post-processing output is not an array. Returning empty array.");
402
+ return [];
403
+ }
404
+ } catch (jsonError) {
405
+ console.error("Error parsing post-processing JSON output:", jsonError);
406
+ console.warn("Returning default empty array due to JSON parsing error.");
407
+ return [];
408
+ }
409
+
410
+ } catch (error) {
411
+ console.error("Error in postResponseProductCheck:", error);
412
+ return [];
413
+ }
414
+ };
415
+
416
+
339
417
  module.exports = {
340
418
  postResponseProcessing,
341
419
  postProcessConversation,
342
420
  processBotResponse,
343
- updateUserProfile
421
+ updateUserProfile,
422
+ postResponseProductCheckPrompt,
423
+ postResponseProductCheck
344
424
  }
package/src/utils.js CHANGED
@@ -54,7 +54,32 @@ async function getHairIssuesForUser(userId){
54
54
  //return empty for now
55
55
  return []
56
56
  }
57
+ async function getProductByName(productName) {
58
+ try {
59
+ const result = await pgClient.query('SELECT product_id FROM products WHERE product_name = $1', [productName]);
60
+ return result.rows[0]; // Returns the product object, or undefined if not found
61
+ } catch (error) {
62
+ console.error("Error fetching product by name:", error);
63
+ return null; // or undefined, depending on your preference
64
+ }
65
+ }
57
66
 
67
+ // Function to add product recommendation to the database
68
+ async function addProductRecommendation(userId, conversationId, productId, reasonForRecommending) {
69
+ try {
70
+ const query = `
71
+ INSERT INTO product_recommendations (user_id, conversation_id, product_id, reason_for_recommending)
72
+ VALUES ($1, $2, $3, $4)
73
+ RETURNING *;
74
+ `;
75
+ const values = [userId, conversationId, productId, reasonForRecommending];
76
+ const result = await pgClient.query(query, values);
77
+ return { success: true, recommendation: result.rows[0] }; // Return success and the new recommendation
78
+ } catch (error) {
79
+ console.error("Error adding product recommendation:", error);
80
+ return { success: false, error: error.message };
81
+ }
82
+ }
58
83
 
59
84
  module.exports = {
60
85
  getAllProducts,
@@ -62,5 +87,7 @@ module.exports = {
62
87
  getAllYoutubeVideos,
63
88
  getAllTestimonials,
64
89
  getAdditionalInstructions,
65
- getHairIssuesForUser
90
+ getHairIssuesForUser,
91
+ getProductByName,
92
+ addProductRecommendation
66
93
  };