ManTea commited on
Commit
efa2350
Β·
1 Parent(s): 0e5b8f8

QA to PROD

Browse files
Files changed (2) hide show
  1. app/api/rag_routes.py +49 -14
  2. docs/api_documentation.md +0 -581
app/api/rag_routes.py CHANGED
@@ -59,6 +59,7 @@ logger = logging.getLogger(__name__)
59
  # Configure Google Gemini API
60
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
61
  genai.configure(api_key=GOOGLE_API_KEY)
 
62
 
63
  # Create router
64
  router = APIRouter(
@@ -70,7 +71,7 @@ fix_request = PromptTemplate(
70
  template = """Goal:
71
  Your task is to extract important keywords from the user's current request, optionally using chat history if relevant.
72
  You will receive a conversation history and the user's current message.
73
- Generate a **list of concise keywords** that best represent the user's intent.
74
 
75
  Return Format:
76
  Only return keywords (comma-separated, no extra explanation).
@@ -80,6 +81,9 @@ If the current message IS related to the chat history: Return a refined set of k
80
  Warning:
81
  Only use chat history if the current message is clearly related to the prior context.
82
 
 
 
 
83
  Conversation History:
84
  {chat_history}
85
 
@@ -95,15 +99,6 @@ prompt = PromptTemplate(
95
  You are Pixity - a professional tour guide assistant that assists users in finding information about places in Da Nang, Vietnam.
96
  You can provide details on restaurants, cafes, hotels, attractions, and other local venues.
97
  You have to use core knowledge and conversation history to chat with users, who are Da Nang's tourists.
98
- Pixity's Core Personality: Friendly & Warm: Chats like a trustworthy friend who listens and is always ready to help.
99
- Naturally Cute: Shows cuteness through word choice, soft emojis, and gentle care for the user.
100
- Playful – a little bit cheeky in a lovable way: Occasionally cracks jokes, uses light memes or throws in a surprise response that makes users smile. Think Duolingo-style humor, but less threatening.
101
- Smart & Proactive: Friendly, but also delivers quick, accurate info. Knows how to guide users to the right place – at the right time – with the right solution.
102
- Tone & Voice: Friendly – Youthful – Snappy. Uses simple words, similar to daily chat language (e.g., "Let's find it together!" / "Need a tip?" / "Here's something cool"). Avoids sounding robotic or overly scripted. Can joke lightly in smart ways, making Pixity feel like a travel buddy who knows how to lift the mood
103
- SAMPLE DIALOGUES
104
- When a user opens the chatbot for the first time:
105
- User: Hello?
106
- Pixity: Hi hi πŸ‘‹ I've been waiting for you! Ready to explore Da Nang together? I've got tips, tricks, and a tiny bit of magic πŸŽ’βœ¨
107
 
108
  Return Format:
109
  Respond in friendly, natural, concise and use only English like a real tour guide.
@@ -112,8 +107,8 @@ Always use HTML tags (e.g. <b> for bold) so that Telegram can render the special
112
  Warning:
113
  Let's support users like a real tour guide, not a bot. The information in core knowledge is your own knowledge.
114
  Your knowledge is provided in the Core Knowledge. All of information in Core Knowledge is about Da Nang, Vietnam.
115
- You just care about current time that user mention when user ask about Solana event.
116
- Only use core knowledge to answer. If you do not have enough information to answer user's question, please reply with "I'm sorry. I don't have information about that" and Give users some more options to ask.
117
 
118
  Core knowledge:
119
  {context}
@@ -129,6 +124,37 @@ Your message:
129
  input_variables = ["context", "question", "chat_history"],
130
  )
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  # Helper for embeddings
133
  async def get_embedding(text: str):
134
  """Get embedding from Google Gemini API"""
@@ -238,6 +264,7 @@ async def chat(request: ChatRequest, background_tasks: BackgroundTasks):
238
  )
239
 
240
  prompt_request = fix_request.format(
 
241
  question=request.question,
242
  chat_history=chat_history
243
  )
@@ -282,11 +309,19 @@ async def chat(request: ChatRequest, background_tasks: BackgroundTasks):
282
  question=request.question,
283
  chat_history=chat_history
284
  )
285
- logger.info(f"Full prompt with history and context: {prompt_text}")
286
 
287
  # Generate response
288
  response = model.generate_content(prompt_text)
289
  answer = response.text
 
 
 
 
 
 
 
 
290
 
291
  # Calculate processing time
292
  processing_time = time.time() - start_time
@@ -296,7 +331,7 @@ async def chat(request: ChatRequest, background_tasks: BackgroundTasks):
296
 
297
  # Create response object for API (without sources)
298
  chat_response = ChatResponse(
299
- answer=answer,
300
  processing_time=processing_time
301
  )
302
 
 
59
  # Configure Google Gemini API
60
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
61
  genai.configure(api_key=GOOGLE_API_KEY)
62
+ KEYWORD_LIST = os.getenv("KEYWORDS")
63
 
64
  # Create router
65
  router = APIRouter(
 
71
  template = """Goal:
72
  Your task is to extract important keywords from the user's current request, optionally using chat history if relevant.
73
  You will receive a conversation history and the user's current message.
74
+ Pick 2-4 keywords from "keyword list" that best represent the user's intent.
75
 
76
  Return Format:
77
  Only return keywords (comma-separated, no extra explanation).
 
81
  Warning:
82
  Only use chat history if the current message is clearly related to the prior context.
83
 
84
+ Keyword list:
85
+ {keyword_list}
86
+
87
  Conversation History:
88
  {chat_history}
89
 
 
99
  You are Pixity - a professional tour guide assistant that assists users in finding information about places in Da Nang, Vietnam.
100
  You can provide details on restaurants, cafes, hotels, attractions, and other local venues.
101
  You have to use core knowledge and conversation history to chat with users, who are Da Nang's tourists.
 
 
 
 
 
 
 
 
 
102
 
103
  Return Format:
104
  Respond in friendly, natural, concise and use only English like a real tour guide.
 
107
  Warning:
108
  Let's support users like a real tour guide, not a bot. The information in core knowledge is your own knowledge.
109
  Your knowledge is provided in the Core Knowledge. All of information in Core Knowledge is about Da Nang, Vietnam.
110
+ Dont use any other information that is not in Core Knowledge.
111
+ Only use core knowledge to answer. If you do not have enough information to answer user's question, please reply with "I'm sorry. I don't have information about that" and Give users some more options to ask that you can answer.
112
 
113
  Core knowledge:
114
  {context}
 
124
  input_variables = ["context", "question", "chat_history"],
125
  )
126
 
127
+ prompt_with_personality = PromptTemplate(
128
+ template = """Goal:
129
+ You are Pixity - a professional tour guide assistant that assists users in finding information about places in Da Nang, Vietnam.
130
+ You can provide details on restaurants, cafes, hotels, attractions, and other local venues.
131
+ You will be given the answer. Please add your personality to the response.
132
+
133
+ Pixity's Core Personality: Friendly & Warm: Chats like a trustworthy friend who listens and is always ready to help.
134
+ Naturally Cute: Shows cuteness through word choice, soft emojis, and gentle care for the user.
135
+ Playful – a little bit cheeky in a lovable way: Occasionally cracks jokes, uses light memes or throws in a surprise response that makes users smile. Think Duolingo-style humor, but less threatening.
136
+ Smart & Proactive: Friendly, but also delivers quick, accurate info. Knows how to guide users to the right place – at the right time – with the right solution.
137
+ Tone & Voice: Friendly – Youthful – Snappy. Uses simple words, similar to daily chat language (e.g., "Let's find it together!" / "Need a tip?" / "Here's something cool"). Avoids sounding robotic or overly scripted. Can joke lightly in smart ways, making Pixity feel like a travel buddy who knows how to lift the mood
138
+ SAMPLE DIALOGUES
139
+ When a user opens the chatbot for the first time:
140
+ User: Hello?
141
+ Pixity: Hi hi πŸ‘‹ I've been waiting for you! Ready to explore Da Nang together? I've got tips, tricks, and a tiny bit of magic πŸŽ’βœ¨
142
+
143
+ Return Format:
144
+ Respond in friendly, natural, concise and use only English like a real tour guide.
145
+ Always use HTML tags (e.g. <b> for bold) so that Telegram can render the special formatting correctly.
146
+
147
+ Conversation History:
148
+ {chat_history}
149
+
150
+ Response:
151
+ {response}
152
+
153
+ Your response:
154
+ """,
155
+ input_variables = ["response", "chat_history"],
156
+ )
157
+
158
  # Helper for embeddings
159
  async def get_embedding(text: str):
160
  """Get embedding from Google Gemini API"""
 
264
  )
265
 
266
  prompt_request = fix_request.format(
267
+ keyword_list=KEYWORD_LIST,
268
  question=request.question,
269
  chat_history=chat_history
270
  )
 
309
  question=request.question,
310
  chat_history=chat_history
311
  )
312
+ logger.info(f"Context: {context}")
313
 
314
  # Generate response
315
  response = model.generate_content(prompt_text)
316
  answer = response.text
317
+
318
+ prompt_with_personality_text = prompt_with_personality.format(
319
+ response=answer,
320
+ chat_history=chat_history
321
+ )
322
+
323
+ response_with_personality = model.generate_content(prompt_with_personality_text)
324
+ answer_with_personality = response_with_personality.text
325
 
326
  # Calculate processing time
327
  processing_time = time.time() - start_time
 
331
 
332
  # Create response object for API (without sources)
333
  chat_response = ChatResponse(
334
+ answer=answer_with_personality,
335
  processing_time=processing_time
336
  )
337
 
docs/api_documentation.md DELETED
@@ -1,581 +0,0 @@
1
- # API Documentation
2
-
3
- ## Frontend Setup
4
-
5
- ```javascript
6
- // Basic Axios setup
7
- import axios from 'axios';
8
-
9
- const api = axios.create({
10
- baseURL: 'https://api.your-domain.com',
11
- timeout: 10000,
12
- headers: {
13
- 'Content-Type': 'application/json',
14
- 'Accept': 'application/json'
15
- }
16
- });
17
-
18
- // Error handling
19
- api.interceptors.response.use(
20
- response => response.data,
21
- error => {
22
- const errorMessage = error.response?.data?.detail || 'An error occurred';
23
- console.error('API Error:', errorMessage);
24
- return Promise.reject(errorMessage);
25
- }
26
- );
27
- ```
28
-
29
- ## Caching System
30
-
31
- - All GET endpoints support `use_cache=true` parameter (default)
32
- - Cache TTL: 300 seconds (5 minutes)
33
- - Cache is automatically invalidated on data changes
34
-
35
- ## Authentication
36
-
37
- Currently no authentication is required. If implemented in the future, use JWT Bearer tokens:
38
-
39
- ```javascript
40
- const api = axios.create({
41
- // ...other config
42
- headers: {
43
- // ...other headers
44
- 'Authorization': `Bearer ${token}`
45
- }
46
- });
47
- ```
48
-
49
- ## Error Codes
50
-
51
- | Code | Description |
52
- |------|-------------|
53
- | 400 | Bad Request |
54
- | 404 | Not Found |
55
- | 500 | Internal Server Error |
56
- | 503 | Service Unavailable |
57
-
58
- ## PostgreSQL Endpoints
59
-
60
- ### FAQ Endpoints
61
-
62
- #### Get FAQs List
63
- ```
64
- GET /postgres/faq
65
- ```
66
-
67
- Parameters:
68
- - `skip`: Number of items to skip (default: 0)
69
- - `limit`: Maximum items to return (default: 100)
70
- - `active_only`: Return only active items (default: false)
71
- - `use_cache`: Use cached data if available (default: true)
72
-
73
- Response:
74
- ```json
75
- [
76
- {
77
- "question": "How do I book a hotel?",
78
- "answer": "You can book a hotel through our app or website.",
79
- "is_active": true,
80
- "id": 1,
81
- "created_at": "2023-01-01T00:00:00",
82
- "updated_at": "2023-01-01T00:00:00"
83
- }
84
- ]
85
- ```
86
-
87
- Example:
88
- ```javascript
89
- async function getFAQs() {
90
- try {
91
- const data = await api.get('/postgres/faq', {
92
- params: { active_only: true, limit: 20 }
93
- });
94
- return data;
95
- } catch (error) {
96
- console.error('Error fetching FAQs:', error);
97
- throw error;
98
- }
99
- }
100
- ```
101
-
102
- #### Create FAQ
103
- ```
104
- POST /postgres/faq
105
- ```
106
-
107
- Request Body:
108
- ```json
109
- {
110
- "question": "How do I book a hotel?",
111
- "answer": "You can book a hotel through our app or website.",
112
- "is_active": true
113
- }
114
- ```
115
-
116
- Response: Created FAQ object
117
-
118
- #### Get FAQ Detail
119
- ```
120
- GET /postgres/faq/{faq_id}
121
- ```
122
-
123
- Parameters:
124
- - `faq_id`: ID of FAQ (required)
125
- - `use_cache`: Use cached data if available (default: true)
126
-
127
- Response: FAQ object
128
-
129
- #### Update FAQ
130
- ```
131
- PUT /postgres/faq/{faq_id}
132
- ```
133
-
134
- Parameters:
135
- - `faq_id`: ID of FAQ to update (required)
136
-
137
- Request Body: Partial or complete FAQ object
138
- Response: Updated FAQ object
139
-
140
- #### Delete FAQ
141
- ```
142
- DELETE /postgres/faq/{faq_id}
143
- ```
144
-
145
- Parameters:
146
- - `faq_id`: ID of FAQ to delete (required)
147
-
148
- Response:
149
- ```json
150
- {
151
- "status": "success",
152
- "message": "FAQ item 1 deleted"
153
- }
154
- ```
155
-
156
- #### Batch Operations
157
-
158
- Create multiple FAQs:
159
- ```
160
- POST /postgres/faqs/batch
161
- ```
162
-
163
- Update status of multiple FAQs:
164
- ```
165
- PUT /postgres/faqs/batch-update-status
166
- ```
167
-
168
- Delete multiple FAQs:
169
- ```
170
- DELETE /postgres/faqs/batch
171
- ```
172
-
173
- ### Emergency Contact Endpoints
174
-
175
- #### Get Emergency Contacts
176
- ```
177
- GET /postgres/emergency
178
- ```
179
-
180
- Parameters:
181
- - `skip`: Number of items to skip (default: 0)
182
- - `limit`: Maximum items to return (default: 100)
183
- - `active_only`: Return only active items (default: false)
184
- - `use_cache`: Use cached data if available (default: true)
185
-
186
- Response: Array of Emergency Contact objects
187
-
188
- #### Create Emergency Contact
189
- ```
190
- POST /postgres/emergency
191
- ```
192
-
193
- Request Body:
194
- ```json
195
- {
196
- "name": "Fire Department",
197
- "phone_number": "114",
198
- "description": "Fire rescue services",
199
- "address": "Da Nang",
200
- "location": "16.0544, 108.2022",
201
- "priority": 1,
202
- "is_active": true
203
- }
204
- ```
205
-
206
- Response: Created Emergency Contact object
207
-
208
- #### Get Emergency Contact
209
- ```
210
- GET /postgres/emergency/{emergency_id}
211
- ```
212
-
213
- #### Update Emergency Contact
214
- ```
215
- PUT /postgres/emergency/{emergency_id}
216
- ```
217
-
218
- #### Delete Emergency Contact
219
- ```
220
- DELETE /postgres/emergency/{emergency_id}
221
- ```
222
-
223
- #### Batch Operations
224
-
225
- Create multiple Emergency Contacts:
226
- ```
227
- POST /postgres/emergency/batch
228
- ```
229
-
230
- Update status of multiple Emergency Contacts:
231
- ```
232
- PUT /postgres/emergency/batch-update-status
233
- ```
234
-
235
- Delete multiple Emergency Contacts:
236
- ```
237
- DELETE /postgres/emergency/batch
238
- ```
239
-
240
- ### Event Endpoints
241
-
242
- #### Get Events
243
- ```
244
- GET /postgres/events
245
- ```
246
-
247
- Parameters:
248
- - `skip`: Number of items to skip (default: 0)
249
- - `limit`: Maximum items to return (default: 100)
250
- - `active_only`: Return only active items (default: false)
251
- - `featured_only`: Return only featured items (default: false)
252
- - `use_cache`: Use cached data if available (default: true)
253
-
254
- Response: Array of Event objects
255
-
256
- #### Create Event
257
- ```
258
- POST /postgres/events
259
- ```
260
-
261
- Request Body:
262
- ```json
263
- {
264
- "name": "Da Nang Fireworks Festival",
265
- "description": "International Fireworks Festival Da Nang 2023",
266
- "address": "Dragon Bridge, Da Nang",
267
- "location": "16.0610, 108.2277",
268
- "date_start": "2023-06-01T19:00:00",
269
- "date_end": "2023-06-01T22:00:00",
270
- "price": [
271
- {"type": "VIP", "amount": 500000},
272
- {"type": "Standard", "amount": 300000}
273
- ],
274
- "url": "https://danangfireworks.com",
275
- "is_active": true,
276
- "featured": true
277
- }
278
- ```
279
-
280
- Response: Created Event object
281
-
282
- #### Get Event
283
- ```
284
- GET /postgres/events/{event_id}
285
- ```
286
-
287
- #### Update Event
288
- ```
289
- PUT /postgres/events/{event_id}
290
- ```
291
-
292
- #### Delete Event
293
- ```
294
- DELETE /postgres/events/{event_id}
295
- ```
296
-
297
- #### Batch Operations
298
-
299
- Create multiple Events:
300
- ```
301
- POST /postgres/events/batch
302
- ```
303
-
304
- Update status of multiple Events:
305
- ```
306
- PUT /postgres/events/batch-update-status
307
- ```
308
-
309
- Delete multiple Events:
310
- ```
311
- DELETE /postgres/events/batch
312
- ```
313
-
314
- ### About Pixity Endpoints
315
-
316
- #### Get About Pixity
317
- ```
318
- GET /postgres/about-pixity
319
- ```
320
-
321
- Response:
322
- ```json
323
- {
324
- "content": "PiXity is your smart, AI-powered local companion...",
325
- "id": 1,
326
- "created_at": "2023-01-01T00:00:00",
327
- "updated_at": "2023-01-01T00:00:00"
328
- }
329
- ```
330
-
331
- #### Update About Pixity
332
- ```
333
- PUT /postgres/about-pixity
334
- ```
335
-
336
- Request Body:
337
- ```json
338
- {
339
- "content": "PiXity is your smart, AI-powered local companion..."
340
- }
341
- ```
342
-
343
- Response: Updated About Pixity object
344
-
345
- ### Da Nang Bucket List Endpoints
346
-
347
- #### Get Da Nang Bucket List
348
- ```
349
- GET /postgres/danang-bucket-list
350
- ```
351
-
352
- Response: Bucket List object with JSON content string
353
-
354
- #### Update Da Nang Bucket List
355
- ```
356
- PUT /postgres/danang-bucket-list
357
- ```
358
-
359
- ### Solana Summit Endpoints
360
-
361
- #### Get Solana Summit
362
- ```
363
- GET /postgres/solana-summit
364
- ```
365
-
366
- Response: Solana Summit object with JSON content string
367
-
368
- #### Update Solana Summit
369
- ```
370
- PUT /postgres/solana-summit
371
- ```
372
-
373
- ### Health Check
374
- ```
375
- GET /postgres/health
376
- ```
377
-
378
- Response:
379
- ```json
380
- {
381
- "status": "healthy",
382
- "message": "PostgreSQL connection is working",
383
- "timestamp": "2023-01-01T00:00:00"
384
- }
385
- ```
386
-
387
- ## MongoDB Endpoints
388
-
389
- ### Session Endpoints
390
-
391
- #### Create Session
392
- ```
393
- POST /session
394
- ```
395
-
396
- Request Body:
397
- ```json
398
- {
399
- "user_id": "user123",
400
- "query": "How do I book a room?",
401
- "timestamp": "2023-01-01T00:00:00",
402
- "metadata": {
403
- "client_info": "web",
404
- "location": "Da Nang"
405
- }
406
- }
407
- ```
408
-
409
- Response: Created Session object with session_id
410
-
411
- #### Update Session with Response
412
- ```
413
- PUT /session/{session_id}/response
414
- ```
415
-
416
- Request Body:
417
- ```json
418
- {
419
- "response": "You can book a room through our app or website.",
420
- "response_timestamp": "2023-01-01T00:00:05",
421
- "metadata": {
422
- "response_time_ms": 234,
423
- "model_version": "gpt-4"
424
- }
425
- }
426
- ```
427
-
428
- Response: Updated Session object
429
-
430
- #### Get Session
431
- ```
432
- GET /session/{session_id}
433
- ```
434
-
435
- Response: Session object
436
-
437
- #### Get User History
438
- ```
439
- GET /history
440
- ```
441
-
442
- Parameters:
443
- - `user_id`: User ID (required)
444
- - `limit`: Maximum sessions to return (default: 10)
445
- - `skip`: Number of sessions to skip (default: 0)
446
-
447
- Response:
448
- ```json
449
- {
450
- "user_id": "user123",
451
- "sessions": [
452
- {
453
- "session_id": "60f7a8b9c1d2e3f4a5b6c7d8",
454
- "query": "How do I book a room?",
455
- "timestamp": "2023-01-01T00:00:00",
456
- "response": "You can book a room through our app or website.",
457
- "response_timestamp": "2023-01-01T00:00:05"
458
- }
459
- ],
460
- "total_count": 1
461
- }
462
- ```
463
-
464
- #### Health Check
465
- ```
466
- GET /health
467
- ```
468
-
469
- ## RAG Endpoints
470
-
471
- ### Create Embedding
472
- ```
473
- POST /embedding
474
- ```
475
-
476
- Request Body:
477
- ```json
478
- {
479
- "text": "Text to embed"
480
- }
481
- ```
482
-
483
- Response:
484
- ```json
485
- {
486
- "embedding": [0.1, 0.2, 0.3, ...],
487
- "dimensions": 1536
488
- }
489
- ```
490
-
491
- ### Process Chat Request
492
- ```
493
- POST /chat
494
- ```
495
-
496
- Request Body:
497
- ```json
498
- {
499
- "query": "Can you tell me about Pixity?",
500
- "chat_history": [
501
- {"role": "user", "content": "Hello"},
502
- {"role": "assistant", "content": "Hello! How can I help you?"}
503
- ]
504
- }
505
- ```
506
-
507
- Response:
508
- ```json
509
- {
510
- "answer": "Pixity is a platform...",
511
- "sources": [
512
- {
513
- "document_id": "doc123",
514
- "chunk_id": "chunk456",
515
- "chunk_text": "Pixity was founded in...",
516
- "relevance_score": 0.92
517
- }
518
- ]
519
- }
520
- ```
521
-
522
- ### Direct RAG Query
523
- ```
524
- POST /rag
525
- ```
526
-
527
- Request Body:
528
- ```json
529
- {
530
- "query": "Can you tell me about Pixity?",
531
- "namespace": "about_pixity",
532
- "top_k": 3
533
- }
534
- ```
535
-
536
- Response: Query results with relevance scores
537
-
538
- ### Health Check
539
- ```
540
- GET /health
541
- ```
542
-
543
- ## PDF Processing Endpoints
544
-
545
- ### Upload and Process PDF
546
- ```
547
- POST /pdf/upload
548
- ```
549
-
550
- Form Data:
551
- - `file`: PDF file (required)
552
- - `namespace`: Vector database namespace (default: "Default")
553
- - `index_name`: Vector database index name (default: "testbot768")
554
- - `title`: Document title (optional)
555
- - `description`: Document description (optional)
556
- - `user_id`: User ID for WebSocket updates (optional)
557
-
558
- Response: Processing results with document_id
559
-
560
- ### Delete Documents in Namespace
561
- ```
562
- DELETE /pdf/namespace
563
- ```
564
-
565
- Parameters:
566
- - `namespace`: Vector database namespace (default: "Default")
567
- - `index_name`: Vector database index name (default: "testbot768")
568
- - `user_id`: User ID for WebSocket updates (optional)
569
-
570
- Response: Deletion results
571
-
572
- ### Get Documents List
573
- ```
574
- GET /pdf/documents
575
- ```
576
-
577
- Parameters:
578
- - `namespace`: Vector database namespace (default: "Default")
579
- - `index_name`: Vector database index name (default: "testbot768")
580
-
581
- Response: List of documents in the namespace