-
Notifications
You must be signed in to change notification settings - Fork 0
/
message.h
327 lines (317 loc) · 13.3 KB
/
message.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#ifndef MESSAGE_INCLUDED
#define MESSAGE_INCLUDED
#include <stdbool.h>
#include <openssl/ssl.h>
#define LLM_ADDITION \
"<script src=\"https://cdn.jsdelivr.net/npm/marked@latest/lib/marked.min.js\"></script>\n\
<style> \n\
.gray-box { \n\
background-color: #f0f0f0; /* Light gray background */ \n\
border: 1px solid #ccc; /* Thin gray border */ \n\
padding: 0px 15px; /* Space inside the box */ \n\
border-radius: 5px; /* Rounded corners */ \n\
margin: 15px 0; /* Spacing above and below */ \n\
} \n\
</style> \n\
<div class=\"gray-box\"> \n\
<div class=\"mw-heading mw-heading2\"> \n\
<h2 id=\"AI-Summary\">AI-Generated Summary</h2> \n\
</div> \n\
<p id=\"summary-text\">\n\
Loading summary...\n\
</p>\n\
</div>\n\
\n\
<script>\n\
async function fetchSummary() { \n\
try { \n\
const response = await fetch(\"%s\", {\n\
method: 'GET',\n\
headers: {\n\
'summary': 'true'\n\
}\n\
});\n\
if (!response.ok) {\n\
throw new Error(`Error: ${response.statusText}`);\n\
}\n\
const summary = await response.text(); /* assuming the summary is plain text */ \n\
const htmlFormattedSummary = marked.default(summary);\n\
document.getElementById('summary-text').innerHTML = htmlFormattedSummary;\n\
} catch (error) {\n\
document.getElementById('summary-text').textContent = 'Failed to load summary.';\n\
console.error('Summary fetch error:', error);\n\
}\n\
}\n\
async function fetchFAQ() {\n\
try {\n\
const response = await fetch(\"%s\", {\n\
method: 'GET',\n\
headers: {\n\
'faq': 'true'\n\
}\n\
});\n\
if (!response.ok) {\n\
throw new Error(`Error: ${response.statusText}`);\n\
}\n\
const threeQuestions = await response.text(); // Assuming the response is a JSON array of 3 questions\n\
const questions = threeQuestions.split('|').map(q => q.trim()).filter(q => q.length > 0);\n\
document.getElementById('faq-button-1').textContent = questions[0];\n\
document.getElementById('faq-button-1').setAttribute('onclick', \n\
`const input = document.getElementById('question-input');\n\
input.value = this.textContent.trim();\n\
input.focus();\n\
input.setSelectionRange(input.value.length, input.value.length);`);\n\
document.getElementById('faq-button-2').textContent = questions[1];\n\
document.getElementById('faq-button-2').setAttribute('onclick', \n\
`const input = document.getElementById('question-input');\n\
input.value = this.textContent.trim();\n\
input.focus();\n\
input.setSelectionRange(input.value.length, input.value.length);`);\n\
document.getElementById('faq-button-3').textContent = questions[2];\n\
document.getElementById('faq-button-3').setAttribute('onclick', \n\
`const input = document.getElementById('question-input');\n\
input.value = this.textContent.trim();\n\
input.focus();\n\
input.setSelectionRange(input.value.length, input.value.length);`);\n\
} catch (error) {\n\
console.error('Questions fetch error:', error);\n\
document.getElementById('faq-button-1').textContent = 'Failed to load faq 1';\n\
document.getElementById('faq-button-2').textContent = 'Failed to load faq 2';\n\
document.getElementById('faq-button-3').textContent = 'Failed to load faq 3';\n\
}\n\
}\n\
document.addEventListener('DOMContentLoaded', function() {\n\
console.log(marked)\n\
fetchSummary();\n\
fetchFAQ();\n\
});\n\
</script>\n\
<style>\n\
.qa-container {\n\
background-color: #f0f0f0; /* light gray background */\n\
border: 1px solid #ddd;\n\
padding: 15px;\n\
border-radius: 5px;\n\
margin-top: 10px;\n\
padding-top: 5px;\n\
}\n\
\n\
.qa-container h2 {\n\
margin-top: 0; /* Reduces the space above the heading */\n\
margin-bottom: 10px; /* Adjust space below the heading if needed */\n\
}\n\
\n\
.qa-input {\n\
width: 100%%; /* Full width minus padding */\n\
padding: 15px; /* Equal padding on left and right */\n\
margin-bottom: 10px;\n\
margin-top: 10px;\n\
border: 1px solid #ccc;\n\
border-radius: 4px;\n\
font-size: 14px;\n\
box-sizing: border-box; /* Ensures padding doesn't affect width calculation */\n\
height: auto;\n\
}\n\
\n\
.qa-button {\n\
padding: 10px 20px;\n\
background-color: #007bff;\n\
color: white;\n\
border: none;\n\
border-radius: 4px;\n\
cursor: pointer;\n\
font-size: 14px;\n\
height: 48px; /* Explicitly set height to match input field */\n\
display: flex;\n\
align-items: center; /* Vertically centers the button text */\n\
justify-content: center; /* Horizontally centers button text */\n\
margin-top: 10px; /* Aligns with input field's margin */\n\
}\n\
\n\
.qa-button:disabled {\n\
background-color: #aaa;\n\
cursor: not-allowed;\n\
}\n\
\n\
.faq-button {\n\
padding: 10px 20px;\n\
color: black;\n\
border: none;\n\
border-radius: 4px;\n\
cursor: pointer;\n\
font-size: 14px;\n\
width: 100%%;\n\
height: 48px; /* Explicitly set height to match input field */\n\
display: flex;\n\
align-items: center; /* Vertically centers the button text */\n\
justify-content: center; /* Horizontally centers button text */\n\
margin-top: 10px; /* Aligns with input field's margin */\n\
}\n\
\n\
.input-button-wrapper {\n\
display: flex;\n\
align-items: stretch;\n\
gap: 10px;\n\
}\n\
\n\
.loading-indicator {\n\
display: none;\n\
font-size: 14px;\n\
color: #555;\n\
}\n\
\n\
.qa-answer {\n\
margin-top: 10px;\n\
background-color: #f0f0f0;\n\
border-left: 4px solid #007bff;\n\
padding: 10px;\n\
border-radius: 4px;\n\
}\n\
</style>\n\
<div class=\"qa-container\">\n\
<div class=\"mw-heading mw-heading2\">\n\
<h2>Ask a Question</h2>\n\
</div>\n\
<div class=\"input-button-wrapper\">\n\
<input type=\"text\" id=\"question-input\" class=\"qa-input\" placeholder=\"Type your question here...\"/>\n\
<button id=\"submit-question\" class=\"qa-button\" onclick=\"askQuestion()\">Ask</button>\n\
</div>\n\
<p id=\"loading-indicator\" class=\"loading-indicator\">Loading answer...</p>\n\
<!-- Initially hidden -->\n\
<div id=\"qa-result\" class=\"qa-answer\" style=\"display:none;\"></div>\n\
<div id=\"predefined-questions\" style=\"margin-top: 15px;\">\n\
<h3>Common Questions:</h3>\n\
<button id=\"faq-button-1\" class=\"faq-button\">Loading FAQ #1...</button>\n\
<button id=\"faq-button-2\" class=\"faq-button\">Loading FAQ #2...</button>\n\
<button id=\"faq-button-3\" class=\"faq-button\">Loading FAQ #3...</button>\n\
</div>\n\
</div>\n\
<script>\n\
document.getElementById(\"question-input\").addEventListener(\"keypress\", function (event) { \n\
if (event.key === \"Enter\") { // Check if the key pressed is Enter \n\
event.preventDefault(); // Prevent the default action (form submission) \n\
document.getElementById(\"submit-question\").click(); // Trigger the button click \n\
} \n\
}); \n\
async function askQuestion() {\n\
const questionInput = document.getElementById('question-input');\n\
const question = questionInput.value.trim();\n\
const loadingIndicator = document.getElementById('loading-indicator');\n\
const qaResult = document.getElementById('qa-result');\n\
\n\
if (!question) {\n\
alert(\"Please type a question before asking!\");\n\
return;\n\
}\n\
\n\
// Show the loading indicator before sending the request\n\
loadingIndicator.style.display = 'block';\n\
qaResult.innerHTML = '';\n\
// Clear previous answer (if any)\n\
qaResult.style.display = 'none';\n\
// Hide the answer container\n\
\n\
try {\n\
const response = await fetch(\"%s\", {\n\
method: 'POST',\n\
headers: {\n\
'Content-Type': 'text/plain',\n\
'question': 'true'\n\
},\n\
body: question\n\
});\n\
\n\
if (!response.ok) {\n\
throw new Error(`Error: ${response.statusText}`);\n\
}\n\
\n\
const data = await response.text();\n\
const htmlFormattedAnswer = marked.default(data);\n\
// Hide the loading indicator\n\
loadingIndicator.style.display = 'none';\n\
\n\
// Display the question and answer\n\
qaResult.innerHTML = `\n\
<p><strong>Question:</strong> ${question}</p>\n\
<p><strong>Answer:</strong> ${htmlFormattedAnswer}</p>\n\
`;\n\
qaResult.style.display = 'block';\n\
// Show the answer section\n\
\n\
// Clear the input for new questions\n\
questionInput.value = '';\n\
} catch (error) {\n\
loadingIndicator.style.display = 'none';\n\
qaResult.innerHTML = `<p><strong>Error:</strong> Could not retrieve an answer.</p>`;\n\
qaResult.style.display = 'block';\n\
// Show error message\n\
console.error('Error fetching answer:', error);\n\
}\n\
}\n\
</script>\n"
#define LLM_ADDITION_SIZE strlen(LLM_ADDITION) - 8 /* - 6 for two %s's and -2 for 2 %%'s*/
#define SUMMARY_START "<style> \n\
.gray-box { \n\
background-color: #f0f0f0; /* Light gray background */ \n\
border: 1px solid #ccc; /* Thin gray border */ \n\
padding: 0px 15px; /* Space inside the box */ \n\
border-radius: 5px; /* Rounded corners */ \n\
margin: 15px 0; /* Spacing above and below */ \n\
} \n\
</style> \n\
<div class=\"gray-box\"> \n\
<div class=\"mw-heading mw-heading2\"> \n\
<h2 id=\"AI-Summary\">AI-Generated Summary</h2> \n\
</div> \n\
<p id=\"summary-text\">\n\
Loading summary...\n\
</p>\n\
</div>\n\
\n\
<script>\n\
async function fetchSummary() { \n\
try { \n\
const response = await fetch(\""
#define SUMMARY_END "\", {\n\
method: 'GET',\n\
headers: {\n\
'summary': 'true'\n\
}\n\
});\n\
if (!response.ok) {\n\
throw new Error(`Error: ${response.statusText}`);\n\
}\n\
const summary = await response.text(); /* assuming the summary is plain text */ \n\
document.getElementById('summary-text').textContent = summary;\n\
} catch (error) {\n\
document.getElementById('summary-text').textContent = 'Failed to load summary.';\n\
console.error('Summary fetch error:', error);\n\
}\n\
}\n\
window.onload = fetchSummary;\n\
</script>"
struct Message {
char *buffer;
int buffer_size;
int bytes_read;
bool header_read;
int total_length;
/* if use_llm is true then we want to read in the whole response before sending any data */
/* need to edit content length of response and/or just close the connection when we are done sending */
bool use_llm; /* set this for true for wikipedia requests/responses */
};
typedef struct Message Message;
struct ConnectionType {
bool isHTTPs;
bool isTunnel;
SSL *ssl;
};
typedef struct ConnectionType ConnectionType;
void create_Message(Message *msg);
int add_to_Message(Message *message, int sd, ConnectionType *ct);
void expand_buffer(Message *message);
int check_message(Message *message);
int update_Message(Message *message);
void remove_header(Message *message, char *header);
int make_llm_enhanced_response(Message *message, char *endpoint);
#endif