sonuprasad23 commited on
Commit
2f2874d
·
1 Parent(s): 217d6b6
Files changed (1) hide show
  1. server.js +23 -32
server.js CHANGED
@@ -50,18 +50,15 @@ async function updateSheetCache() {
50
  console.log('No data found in spreadsheet.');
51
  return;
52
  }
53
-
54
  rawSheetCache = rows;
55
  const headers = rows[0];
56
  const dataRows = rows.slice(1);
57
  let currentLocation = '';
58
  let currentOfficeExt = 'N/A';
59
  const allStaff = [];
60
-
61
  dataRows.forEach((row, rowIndex) => {
62
  const rowData = {};
63
  headers.forEach((header, index) => rowData[header] = row[index] || '');
64
-
65
  if (isValidName(rowData.Location)) {
66
  currentLocation = rowData.Location;
67
  if (currentLocation.toLowerCase().includes('liveoak')) {
@@ -73,27 +70,16 @@ async function updateSheetCache() {
73
  }
74
  rowData.Location = currentLocation;
75
  rowData.OfficeExtension = currentOfficeExt;
76
-
77
  const baseId = `r${rowIndex}`;
78
-
79
- if (isValidName(rowData.Provider)) {
80
- allStaff.push({ ...rowData, id: `${baseId}-p`, role: 'Provider' });
81
- }
82
- if (isValidName(rowData.MA)) {
83
- allStaff.push({ ...rowData, id: `${baseId}-ma`, role: 'Medical Assistant', Extension: rowData.Extension });
84
- }
85
- if (isValidName(rowData.VA)) {
86
- allStaff.push({ ...rowData, id: `${baseId}-va`, role: 'Virtual Assistant', Extension: rowData.Ext });
87
- }
88
- if (isValidName(rowData['Team Leads/Manager'])) {
89
- allStaff.push({ ...rowData, id: `${baseId}-tl`, role: 'Team Lead / Manager', Extension: rowData['Ext/Phone#'] });
90
- }
91
  if (isValidName(rowData['Ext/Phone#']) && /^[a-zA-Z]+-\s*\d+$/.test(rowData['Ext/Phone#'])) {
92
  const [name, ext] = rowData['Ext/Phone#'].split('-');
93
  allStaff.push({ ...rowData, id: `${baseId}-other`, role: 'Other Staff', OtherStaffName: name.trim(), Extension: ext.trim() });
94
  }
95
  });
96
-
97
  processedStaffCache = allStaff;
98
  console.log('Cache updated. Processed records:', processedStaffCache.length);
99
  } catch (error) {
@@ -120,21 +106,15 @@ async function generateWithRetry(model, prompt, maxRetries = 3) {
120
  }
121
  }
122
 
123
- app.get('/', (req, res) => {
124
- res.sendFile(path.join(__dirname, 'index.html'));
125
- });
126
 
127
  app.get('/api/data', (req, res) => {
128
- if (!processedStaffCache) {
129
- return res.status(503).json({ message: 'Data is being fetched.' });
130
- }
131
  res.json(processedStaffCache);
132
  });
133
 
134
  app.get('/api/raw-data', (req, res) => {
135
- if (!rawSheetCache) {
136
- return res.status(503).json({ message: 'Data is being fetched.' });
137
- }
138
  res.json(rawSheetCache);
139
  });
140
 
@@ -147,6 +127,7 @@ app.get('/api/ask-luis', async (req, res) => {
147
  res.setHeader('Cache-Control', 'no-cache');
148
  res.setHeader('Connection', 'keep-alive');
149
  res.flushHeaders();
 
150
  const prompt = `
151
  You are "Luis", an AI data analyst for the Hillside Medical Group staff directory.
152
  Your primary function is to answer questions about staff based ONLY on the JSON data provided.
@@ -165,18 +146,28 @@ app.get('/api/ask-luis', async (req, res) => {
165
  **User's Question:**
166
  "${question}"
167
  `;
 
 
 
 
 
 
168
  try {
169
- const result = await generateWithRetry(model, prompt);
 
 
170
  for await (const chunk of result.stream) {
171
  if (chunk.text()) {
172
  res.write(`data: ${JSON.stringify({ chunk: chunk.text() })}\n\n`);
173
  }
174
  }
175
  } catch (error) {
176
- const errorMessage = error.status === 503
177
- ? "The directory service is currently busy. Please try again in a few moments."
178
- : "I'm having a bit of trouble connecting right now.";
179
-
 
 
180
  res.write(`data: ${JSON.stringify({ error: errorMessage })}\n\n`);
181
  } finally {
182
  res.write('data: [DONE]\n\n');
 
50
  console.log('No data found in spreadsheet.');
51
  return;
52
  }
 
53
  rawSheetCache = rows;
54
  const headers = rows[0];
55
  const dataRows = rows.slice(1);
56
  let currentLocation = '';
57
  let currentOfficeExt = 'N/A';
58
  const allStaff = [];
 
59
  dataRows.forEach((row, rowIndex) => {
60
  const rowData = {};
61
  headers.forEach((header, index) => rowData[header] = row[index] || '');
 
62
  if (isValidName(rowData.Location)) {
63
  currentLocation = rowData.Location;
64
  if (currentLocation.toLowerCase().includes('liveoak')) {
 
70
  }
71
  rowData.Location = currentLocation;
72
  rowData.OfficeExtension = currentOfficeExt;
 
73
  const baseId = `r${rowIndex}`;
74
+ if (isValidName(rowData.Provider)) allStaff.push({ ...rowData, id: `${baseId}-p`, role: 'Provider' });
75
+ if (isValidName(rowData.MA)) allStaff.push({ ...rowData, id: `${baseId}-ma`, role: 'Medical Assistant', Extension: rowData.Extension });
76
+ if (isValidName(rowData.VA)) allStaff.push({ ...rowData, id: `${baseId}-va`, role: 'Virtual Assistant', Extension: rowData.Ext });
77
+ if (isValidName(rowData['Team Leads/Manager'])) allStaff.push({ ...rowData, id: `${baseId}-tl`, role: 'Team Lead / Manager', Extension: rowData['Ext/Phone#'] });
 
 
 
 
 
 
 
 
 
78
  if (isValidName(rowData['Ext/Phone#']) && /^[a-zA-Z]+-\s*\d+$/.test(rowData['Ext/Phone#'])) {
79
  const [name, ext] = rowData['Ext/Phone#'].split('-');
80
  allStaff.push({ ...rowData, id: `${baseId}-other`, role: 'Other Staff', OtherStaffName: name.trim(), Extension: ext.trim() });
81
  }
82
  });
 
83
  processedStaffCache = allStaff;
84
  console.log('Cache updated. Processed records:', processedStaffCache.length);
85
  } catch (error) {
 
106
  }
107
  }
108
 
109
+ app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
 
 
110
 
111
  app.get('/api/data', (req, res) => {
112
+ if (!processedStaffCache) return res.status(503).json({ message: 'Data is being fetched.' });
 
 
113
  res.json(processedStaffCache);
114
  });
115
 
116
  app.get('/api/raw-data', (req, res) => {
117
+ if (!rawSheetCache) return res.status(503).json({ message: 'Data is being fetched.' });
 
 
118
  res.json(rawSheetCache);
119
  });
120
 
 
127
  res.setHeader('Cache-Control', 'no-cache');
128
  res.setHeader('Connection', 'keep-alive');
129
  res.flushHeaders();
130
+
131
  const prompt = `
132
  You are "Luis", an AI data analyst for the Hillside Medical Group staff directory.
133
  Your primary function is to answer questions about staff based ONLY on the JSON data provided.
 
146
  **User's Question:**
147
  "${question}"
148
  `;
149
+
150
+ const AI_TIMEOUT = 20000; // 20 seconds
151
+ const timeoutPromise = new Promise((_, reject) =>
152
+ setTimeout(() => reject(new Error('AI_TIMEOUT')), AI_TIMEOUT)
153
+ );
154
+
155
  try {
156
+ const resultPromise = generateWithRetry(model, prompt);
157
+ const result = await Promise.race([resultPromise, timeoutPromise]);
158
+
159
  for await (const chunk of result.stream) {
160
  if (chunk.text()) {
161
  res.write(`data: ${JSON.stringify({ chunk: chunk.text() })}\n\n`);
162
  }
163
  }
164
  } catch (error) {
165
+ let errorMessage = "I'm having a bit of trouble connecting to my brain right now. Please try again in a moment.";
166
+ if (error.message === 'AI_TIMEOUT') {
167
+ errorMessage = "Sorry, my connection to the AI service timed out. The service may be busy. Please try your question again in a few moments.";
168
+ } else if (error.status === 503) {
169
+ errorMessage = "The directory AI service is currently busy. Please try again.";
170
+ }
171
  res.write(`data: ${JSON.stringify({ error: errorMessage })}\n\n`);
172
  } finally {
173
  res.write('data: [DONE]\n\n');