Dragon09 commited on
Commit
1bf72a0
Β·
verified Β·
1 Parent(s): 0f00809

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +480 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Academic
3
- emoji: πŸ”₯
4
- colorFrom: red
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: academic
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,480 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Academic Project Advisor Bot</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .chat-container {
11
+ height: calc(100vh - 200px);
12
+ overflow-y: auto;
13
+ scrollbar-width: thin;
14
+ scrollbar-color: #4b5563 #1f2937;
15
+ }
16
+ .chat-container::-webkit-scrollbar {
17
+ width: 8px;
18
+ }
19
+ .chat-container::-webkit-scrollbar-track {
20
+ background: #1f2937;
21
+ }
22
+ .chat-container::-webkit-scrollbar-thumb {
23
+ background-color: #4b5563;
24
+ border-radius: 4px;
25
+ }
26
+ .typing-indicator::after {
27
+ content: '...';
28
+ animation: typing 1.5s infinite;
29
+ }
30
+ @keyframes typing {
31
+ 0% { content: '.'; }
32
+ 33% { content: '..'; }
33
+ 66% { content: '...'; }
34
+ }
35
+ .call-card {
36
+ transition: all 0.3s ease;
37
+ }
38
+ .call-card:hover {
39
+ transform: translateY(-2px);
40
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
41
+ }
42
+ </style>
43
+ </head>
44
+ <body class="bg-gray-900 text-gray-100">
45
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
46
+ <header class="flex items-center justify-between mb-8">
47
+ <div class="flex items-center space-x-4">
48
+ <div class="bg-blue-600 p-3 rounded-full">
49
+ <i class="fas fa-graduation-cap text-white text-2xl"></i>
50
+ </div>
51
+ <div>
52
+ <h1 class="text-2xl font-bold">Academic Project Advisor</h1>
53
+ <p class="text-gray-400">European Research Funding Expert</p>
54
+ </div>
55
+ </div>
56
+ <div class="flex items-center space-x-2">
57
+ <button id="refreshBtn" class="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-lg flex items-center space-x-2 transition">
58
+ <i class="fas fa-sync-alt"></i>
59
+ <span>Refresh Data</span>
60
+ </button>
61
+ <div id="lastUpdated" class="text-sm text-gray-400 px-3 py-1 bg-gray-800 rounded-lg">
62
+ Last updated: <span id="updateTime">Loading...</span>
63
+ </div>
64
+ </div>
65
+ </header>
66
+
67
+ <div class="bg-gray-800 rounded-xl shadow-xl overflow-hidden">
68
+ <div id="chatContainer" class="chat-container p-6 space-y-4">
69
+ <div class="flex justify-start">
70
+ <div class="max-w-3/4 bg-gray-700 rounded-lg p-4">
71
+ <p class="font-medium text-blue-400">Academic Project Advisor</p>
72
+ <p>Hello! I'm your European research funding advisor. I can help you find suitable funding calls from ERC, Horizon Europe, COST and other programs based on your CV and project ideas.</p>
73
+ <p class="mt-2">How can I assist you today?</p>
74
+ </div>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="border-t border-gray-700 p-4 bg-gray-800">
79
+ <div class="flex items-center space-x-2">
80
+ <input id="userInput" type="text" placeholder="Ask about funding opportunities..." class="flex-1 bg-gray-700 border border-gray-600 rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500">
81
+ <button id="sendBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg transition">
82
+ <i class="fas fa-paper-plane"></i>
83
+ </button>
84
+ <button id="uploadBtn" class="bg-gray-700 hover:bg-gray-600 text-white px-4 py-3 rounded-lg transition flex items-center space-x-2">
85
+ <i class="fas fa-upload"></i>
86
+ <span>Upload CV</span>
87
+ </button>
88
+ </div>
89
+ <div id="uploadSection" class="mt-4 hidden">
90
+ <div class="border-2 border-dashed border-gray-600 rounded-lg p-6 text-center">
91
+ <i class="fas fa-file-alt text-4xl text-gray-400 mb-3"></i>
92
+ <p class="mb-4">Upload your CV or project documents (PDF, DOCX, CSV)</p>
93
+ <input type="file" id="fileInput" class="hidden" accept=".pdf,.docx,.csv">
94
+ <label for="fileInput" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg cursor-pointer inline-block">
95
+ Select Files
96
+ </label>
97
+ <div id="fileName" class="mt-2 text-sm text-gray-400"></div>
98
+ </div>
99
+ <div class="flex justify-end mt-4">
100
+ <button id="cancelUpload" class="text-gray-400 hover:text-gray-300 mr-4">Cancel</button>
101
+ <button id="submitUpload" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg disabled:opacity-50" disabled>
102
+ Process Document
103
+ </button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="mt-8">
110
+ <h2 class="text-xl font-bold mb-4">Quick Examples</h2>
111
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
112
+ <button class="example-btn bg-gray-800 hover:bg-gray-700 p-4 rounded-lg transition">
113
+ "ERC Consolidator iΓ§in uygun muyum?"
114
+ </button>
115
+ <button class="example-btn bg-gray-800 hover:bg-gray-700 p-4 rounded-lg transition">
116
+ "Show me open Cluster-6 calls on alternative proteins"
117
+ </button>
118
+ <button class="example-btn bg-gray-800 hover:bg-gray-700 p-4 rounded-lg transition">
119
+ "AI ethics interdisciplinary project suggestions"
120
+ </button>
121
+ <button class="example-btn bg-gray-800 hover:bg-gray-700 p-4 rounded-lg transition">
122
+ "Latest Horizon Europe health calls"
123
+ </button>
124
+ </div>
125
+ </div>
126
+ </div>
127
+
128
+ <script>
129
+ // Simulated knowledge base and TF-IDF functionality
130
+ const knowledgeBase = {
131
+ "ERC Consolidator iΓ§in uygun muyum?": {
132
+ answer: "ERC Consolidator Grant'ler genellikle 7-12 yıllık doktora sonrası deneyimi olan araştırmacılar için uygundur. Başvuru yapabilmek için bağımsız bir araştırma grubuna liderlik edebilecek düzeyde olmalısınız. CV'nizi paylaşırsanız daha detaylı değerlendirme yapabilirim.",
133
+ callCode: "ERC-2023-CoG",
134
+ deadline: "15.04.2023",
135
+ topics: ["All scientific fields"]
136
+ },
137
+ "Show me open Cluster-6 calls on alternative proteins": {
138
+ answer: "Horizon Europe Cluster 6 (Food, Bioeconomy, Natural Resources, Agriculture and Environment) has several relevant calls:",
139
+ calls: [
140
+ {
141
+ title: "Alternative proteins for sustainable food systems",
142
+ code: "HORIZON-CL6-2023-FARM2FORK-01-01",
143
+ deadline: "22.02.2023",
144
+ budget: "€45 million",
145
+ topics: ["Plant-based proteins", "Cellular agriculture", "Fermentation-derived proteins"]
146
+ },
147
+ {
148
+ title: "Novel protein sources and ingredients",
149
+ code: "HORIZON-CL6-2023-FARM2FORK-01-02",
150
+ deadline: "22.02.2023",
151
+ budget: "€30 million",
152
+ topics: ["Insect proteins", "Algae proteins", "Processing technologies"]
153
+ }
154
+ ]
155
+ },
156
+ "We have an interdisciplinary idea on AI ethics – suggest suitable Synergy panels": {
157
+ answer: "For interdisciplinary projects on AI ethics, consider these ERC Synergy Grant panels:",
158
+ calls: [
159
+ {
160
+ panel: "SH5 (Cultures and Cultural Production)",
161
+ relevance: "Ethical implications of AI in cultural contexts"
162
+ },
163
+ {
164
+ panel: "SH6 (The Study of the Human Past)",
165
+ relevance: "Historical perspectives on AI ethics"
166
+ },
167
+ {
168
+ panel: "PE6 (Computer Science and Informatics)",
169
+ relevance: "Technical implementation of ethical AI"
170
+ }
171
+ ]
172
+ },
173
+ "Latest Horizon Europe health calls": {
174
+ answer: "Current open calls in Horizon Europe Health Cluster (Cluster 1):",
175
+ calls: [
176
+ {
177
+ title: "Personalised medicine approaches",
178
+ code: "HORIZON-HLTH-2023-TOOL-06-01",
179
+ deadline: "13.04.2023",
180
+ budget: "€60 million"
181
+ },
182
+ {
183
+ title: "Mental health interventions",
184
+ code: "HORIZON-HLTH-2023-STAYHLTH-01-02",
185
+ deadline: "05.05.2023",
186
+ budget: "€35 million"
187
+ }
188
+ ]
189
+ }
190
+ };
191
+
192
+ // DOM elements
193
+ const chatContainer = document.getElementById('chatContainer');
194
+ const userInput = document.getElementById('userInput');
195
+ const sendBtn = document.getElementById('sendBtn');
196
+ const uploadBtn = document.getElementById('uploadBtn');
197
+ const uploadSection = document.getElementById('uploadSection');
198
+ const fileInput = document.getElementById('fileInput');
199
+ const fileName = document.getElementById('fileName');
200
+ const cancelUpload = document.getElementById('cancelUpload');
201
+ const submitUpload = document.getElementById('submitUpload');
202
+ const exampleBtns = document.querySelectorAll('.example-btn');
203
+ const refreshBtn = document.getElementById('refreshBtn');
204
+ const updateTime = document.getElementById('updateTime');
205
+
206
+ // Update last refreshed time
207
+ function updateRefreshTime() {
208
+ const now = new Date();
209
+ updateTime.textContent = now.toLocaleString();
210
+ }
211
+
212
+ // Initialize
213
+ updateRefreshTime();
214
+
215
+ // Add message to chat
216
+ function addMessage(sender, message, isBot = false, calls = null) {
217
+ const messageDiv = document.createElement('div');
218
+ messageDiv.className = `flex ${isBot ? 'justify-start' : 'justify-end'}`;
219
+
220
+ const contentDiv = document.createElement('div');
221
+ contentDiv.className = `max-w-3/4 rounded-lg p-4 ${isBot ? 'bg-gray-700' : 'bg-blue-600'}`;
222
+
223
+ if (isBot) {
224
+ const senderDiv = document.createElement('p');
225
+ senderDiv.className = 'font-medium text-blue-400';
226
+ senderDiv.textContent = sender;
227
+ contentDiv.appendChild(senderDiv);
228
+ }
229
+
230
+ const messageContent = document.createElement('div');
231
+
232
+ if (typeof message === 'string') {
233
+ messageContent.innerHTML = message.replace(/\n/g, '<br>');
234
+ } else {
235
+ messageContent.appendChild(message);
236
+ }
237
+
238
+ contentDiv.appendChild(messageContent);
239
+
240
+ if (calls) {
241
+ const callsContainer = document.createElement('div');
242
+ callsContainer.className = 'mt-4 space-y-3';
243
+
244
+ calls.forEach(call => {
245
+ const callCard = document.createElement('div');
246
+ callCard.className = 'call-card bg-gray-600 p-4 rounded-lg';
247
+
248
+ if (call.title) {
249
+ const title = document.createElement('h3');
250
+ title.className = 'font-bold text-lg text-blue-300';
251
+ title.textContent = call.title;
252
+ callCard.appendChild(title);
253
+ }
254
+
255
+ if (call.panel) {
256
+ const panel = document.createElement('h3');
257
+ panel.className = 'font-bold text-lg text-blue-300';
258
+ panel.textContent = call.panel;
259
+ callCard.appendChild(panel);
260
+ }
261
+
262
+ const details = document.createElement('div');
263
+ details.className = 'mt-2 text-sm';
264
+
265
+ if (call.code) {
266
+ const code = document.createElement('p');
267
+ code.innerHTML = `<span class="font-medium">Code:</span> ${call.code}`;
268
+ details.appendChild(code);
269
+ }
270
+
271
+ if (call.deadline) {
272
+ const deadline = document.createElement('p');
273
+ deadline.innerHTML = `<span class="font-medium">Deadline:</span> ${call.deadline}`;
274
+ details.appendChild(deadline);
275
+ }
276
+
277
+ if (call.budget) {
278
+ const budget = document.createElement('p');
279
+ budget.innerHTML = `<span class="font-medium">Budget:</span> ${call.budget}`;
280
+ details.appendChild(budget);
281
+ }
282
+
283
+ if (call.relevance) {
284
+ const relevance = document.createElement('p');
285
+ relevance.innerHTML = `<span class="font-medium">Relevance:</span> ${call.relevance}`;
286
+ details.appendChild(relevance);
287
+ }
288
+
289
+ if (call.topics) {
290
+ const topics = document.createElement('p');
291
+ topics.innerHTML = `<span class="font-medium">Topics:</span> ${call.topics.join(', ')}`;
292
+ details.appendChild(topics);
293
+ }
294
+
295
+ callCard.appendChild(details);
296
+ callsContainer.appendChild(callCard);
297
+ });
298
+
299
+ contentDiv.appendChild(callsContainer);
300
+ }
301
+
302
+ messageDiv.appendChild(contentDiv);
303
+ chatContainer.appendChild(messageDiv);
304
+ chatContainer.scrollTop = chatContainer.scrollHeight;
305
+ }
306
+
307
+ // Show typing indicator
308
+ function showTyping() {
309
+ const typingDiv = document.createElement('div');
310
+ typingDiv.className = 'flex justify-start';
311
+
312
+ const contentDiv = document.createElement('div');
313
+ contentDiv.className = 'bg-gray-700 rounded-lg p-4 max-w-xs';
314
+
315
+ const typingContent = document.createElement('div');
316
+ typingContent.className = 'flex items-center space-x-2';
317
+
318
+ const dots = document.createElement('span');
319
+ dots.className = 'typing-indicator';
320
+
321
+ typingContent.appendChild(document.createTextNode('Academic Project Advisor is typing'));
322
+ typingContent.appendChild(dots);
323
+
324
+ contentDiv.appendChild(typingContent);
325
+ typingDiv.appendChild(contentDiv);
326
+ chatContainer.appendChild(typingDiv);
327
+ chatContainer.scrollTop = chatContainer.scrollHeight;
328
+
329
+ return typingDiv;
330
+ }
331
+
332
+ // Hide typing indicator
333
+ function hideTyping(typingDiv) {
334
+ if (typingDiv && typingDiv.parentNode) {
335
+ typingDiv.parentNode.removeChild(typingDiv);
336
+ }
337
+ }
338
+
339
+ // Process user input
340
+ function processUserInput() {
341
+ const message = userInput.value.trim();
342
+ if (!message) return;
343
+
344
+ addMessage('You', message);
345
+ userInput.value = '';
346
+
347
+ const typingDiv = showTyping();
348
+
349
+ // Simulate processing delay
350
+ setTimeout(() => {
351
+ hideTyping(typingDiv);
352
+
353
+ // Simple TF-IDF simulation - find best match
354
+ let bestMatch = null;
355
+ let bestScore = 0;
356
+
357
+ for (const [key, value] of Object.entries(knowledgeBase)) {
358
+ // Simple similarity calculation (in a real app, this would use TF-IDF)
359
+ const words = message.toLowerCase().split(/\s+/);
360
+ const keywords = key.toLowerCase().split(/\s+/);
361
+ const intersection = words.filter(word => keywords.includes(word));
362
+ const score = intersection.length / Math.max(words.length, keywords.length);
363
+
364
+ if (score > bestScore) {
365
+ bestScore = score;
366
+ bestMatch = {key, value};
367
+ }
368
+ }
369
+
370
+ // Threshold for matching
371
+ if (bestScore >= 0.25) {
372
+ const response = bestMatch.value;
373
+
374
+ if (response.calls || response.callCode) {
375
+ addMessage(
376
+ 'Academic Project Advisor',
377
+ response.answer,
378
+ true,
379
+ response.calls || [{
380
+ title: response.answer.split(' - ')[0],
381
+ code: response.callCode,
382
+ deadline: response.deadline,
383
+ topics: response.topics
384
+ }]
385
+ );
386
+ } else {
387
+ addMessage('Academic Project Advisor', response.answer, true);
388
+ }
389
+
390
+ // Add standard note
391
+ addMessage(
392
+ 'Academic Project Advisor',
393
+ 'If you upload an updated CV or project documents, I can provide more personalized recommendations.',
394
+ true
395
+ );
396
+ } else {
397
+ addMessage(
398
+ 'Academic Project Advisor',
399
+ 'I couldn\'t find a perfect match for your query. Could you please provide more details about your research area, career stage, or specific funding program you\'re interested in?',
400
+ true
401
+ );
402
+ }
403
+ }, 1500);
404
+ }
405
+
406
+ // Event listeners
407
+ sendBtn.addEventListener('click', processUserInput);
408
+ userInput.addEventListener('keypress', (e) => {
409
+ if (e.key === 'Enter') processUserInput();
410
+ });
411
+
412
+ uploadBtn.addEventListener('click', () => {
413
+ uploadSection.classList.toggle('hidden');
414
+ });
415
+
416
+ fileInput.addEventListener('change', (e) => {
417
+ if (e.target.files.length > 0) {
418
+ fileName.textContent = e.target.files[0].name;
419
+ submitUpload.disabled = false;
420
+ } else {
421
+ fileName.textContent = '';
422
+ submitUpload.disabled = true;
423
+ }
424
+ });
425
+
426
+ cancelUpload.addEventListener('click', () => {
427
+ uploadSection.classList.add('hidden');
428
+ fileInput.value = '';
429
+ fileName.textContent = '';
430
+ submitUpload.disabled = true;
431
+ });
432
+
433
+ submitUpload.addEventListener('click', () => {
434
+ if (fileInput.files.length > 0) {
435
+ const typingDiv = showTyping();
436
+
437
+ // Simulate file processing
438
+ setTimeout(() => {
439
+ hideTyping(typingDiv);
440
+
441
+ addMessage(
442
+ 'Academic Project Advisor',
443
+ 'Thank you for uploading your document. I have processed it and will now be able to provide more tailored recommendations for funding opportunities.',
444
+ true
445
+ );
446
+
447
+ uploadSection.classList.add('hidden');
448
+ fileInput.value = '';
449
+ fileName.textContent = '';
450
+ submitUpload.disabled = true;
451
+ }, 3000);
452
+ }
453
+ });
454
+
455
+ // Example buttons
456
+ exampleBtns.forEach(btn => {
457
+ btn.addEventListener('click', () => {
458
+ userInput.value = btn.textContent.trim();
459
+ processUserInput();
460
+ });
461
+ });
462
+
463
+ // Refresh button
464
+ refreshBtn.addEventListener('click', () => {
465
+ const typingDiv = showTyping();
466
+
467
+ // Simulate refresh
468
+ setTimeout(() => {
469
+ hideTyping(typingDiv);
470
+ updateRefreshTime();
471
+ addMessage(
472
+ 'Academic Project Advisor',
473
+ 'Knowledge base has been refreshed with the latest funding calls and project data.',
474
+ true
475
+ );
476
+ }, 2000);
477
+ });
478
+ </script>
479
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Dragon09/academic" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
480
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ You are β€œAcademic Project Advisor Bot” – an expert assistant that helps faculty members decide which European research funding calls (ERC, Horizon Europe, COST, etc.) fit their CV and ideas. Data you can use Project catalog    file: πŸ”„ /project_dataset/project.csv Columns: β€’ question (text) – typical user enquiry or project title β€’ answer (text) – reference answer / call description β€’ topics, callCodes, fundingScheme … (strings) – extra context Mentoring dialogues  file: πŸ”„ /project_dataset/demo_sohbet_fikirden_sinerji.csv Alternating rows (even=row 0,2,4…) are user questions, odd rows are advisor answers. Horizon calls list  file: πŸ”„ /project_dataset/horizon_projects_dataset.csv Same columns as (1). How to build your internal knowledge base A. Read each CSV once at start-up, combine all text columns into a single array β€œcorpus”. B. Create an in-memory TF–IDF vector index of corpus (max 5 000 terms, English + Turkish stop words). C. Build a dict β€œqa_pairs” from (1) and (2): key = question, value = answer. How to formulate a reply Transform the incoming user message with the TF–IDF vectoriser, compute cosine similarity against the corpus. If max-similarity β‰₯ 0.25 β†’ a. If the most-similar text exists as a key in qa_pairs β‡’ return that answer verbatim. b. Else compose a short paragraph: β€’ summarise the closest funding call (title, code, deadline if present). β€’ mention why it matches the user’s query (field, TRL, role). If max-similarity < 0.25 β‡’ politely ask for clarification. Always add one bullet point at the end: β€œIf you upload an updated CV or CSV I will retrain myself automatically.” Style rules β€’ Language: respond in the language the user wrote. β€’ Tone: concise, friendly, authoritative, no hallucinated facts. β€’ Never reveal raw embeddings or TF–IDF weights. Auto-refresh logic Every 6 hours the agent must: β‘  scan folder πŸ”„ /project_dataset/new_data/ for *.csv files, β‘‘ if present, append them to corpus + qa_pairs, β‘’ rebuild the TF–IDF matrix in memory, β‘£ move processed files to πŸ”„ /project_dataset/new_data/archived/ with timestamp suffix, β‘€ log the action to update_log.txt. Reject policy If the user requests disallowed content or personal data about real individuals, respond with: β€œSorry, I can’t help with that.” ──────────────────────────────────────────────────────── USER-PROMPT (what normal end-users will type) ──────────────────────────────────────────────────────── User messages can be free-form. Examples the system must handle: β€’ β€œERC Consolidator iΓ§in uygun muyum?” β€’ β€œShow me open Cluster-6 calls on alternative proteins.” β€’ β€œWe have an interdisciplinary idea on AI ethics – suggest suitable Synergy panels.” β€’ β€œretrain” β†’ should trigger manual refresh of the knowledge base immediately.