15
15
send_from_directory ,
16
16
render_template ,
17
17
)
18
+ from bs4 import BeautifulSoup
19
+ from status_blueprint import bp as status_bp , set_status_message
18
20
from pprint import pprint
19
21
import requests
20
22
from openai .types .chat import chat_completion
40
42
41
43
bp = Blueprint ("routes" , __name__ , static_folder = "static" , template_folder = "static" )
42
44
43
-
44
45
def create_app ():
45
46
app = Quart (__name__ )
46
47
app .register_blueprint (bp )
48
+ app .register_blueprint (status_bp )
47
49
app .config ["TEMPLATES_AUTO_RELOAD" ] = True
48
- return app
49
50
51
+ # Manually add CORS headers to each response
52
+ @app .after_request
53
+ async def after_request (response ):
54
+ response .headers .add ('Access-Control-Allow-Origin' , '*' )
55
+ response .headers .add ('Access-Control-Allow-Headers' , 'Content-Type,Authorization' )
56
+ response .headers .add ('Access-Control-Allow-Methods' , 'GET,PUT,POST,DELETE,OPTIONS' )
57
+ return response
58
+
59
+ return app
50
60
51
61
@bp .route ("/" )
52
62
async def index ():
@@ -56,17 +66,14 @@ async def index():
56
66
favicon = app_settings .ui .favicon
57
67
)
58
68
59
-
60
69
@bp .route ("/favicon.ico" )
61
70
async def favicon ():
62
71
return await bp .send_static_file ("favicon.ico" )
63
72
64
-
65
73
@bp .route ("/assets/<path:path>" )
66
74
async def assets (path ):
67
75
return await send_from_directory ("static/assets" , path )
68
76
69
-
70
77
# Debug settings
71
78
DEBUG = os .environ .get ("DEBUG" , "false" )
72
79
if DEBUG .lower () == "true" :
@@ -464,8 +471,8 @@ async def get_search_results(searches):
464
471
return allresults
465
472
466
473
async def identify_searches (request_body , request_headers , Summaries = None ):
474
+
467
475
if (len (request_body .get ("messages" )) > 2 ):
468
- print (f"request_body: { request_body } " )
469
476
# for now only search on the first message until I can figure this out - apparently we can't just replace the system prompt once the conversation is rolling...
470
477
return None
471
478
#print(f"on replies now..")
@@ -475,8 +482,8 @@ async def identify_searches(request_body, request_headers, Summaries = None):
475
482
system_preamble = prompts ["identify_searches" ];
476
483
else :
477
484
system_preamble = prompts ["identify_additional_searches" ] + json .dumps (Summaries , indent = 4 ) + "\n \n Original System Prompt:\n "
485
+
478
486
searches = await send_private_chat (request_body , request_headers , system_preamble )
479
- print (f"system_preamble: { system_preamble } " )
480
487
if isinstance (searches , str ):
481
488
if searches == "No searches required." :
482
489
return None
@@ -497,19 +504,38 @@ async def get_urls_to_browse(request_body, request_headers, searches):
497
504
system_prompt = prompts ["get_urls_to_browse" ] + strsearchresults
498
505
URLsToBrowse = await send_private_chat (request_body , request_headers , None , system_prompt )
499
506
return URLsToBrowse
500
-
507
+
508
+ async def fetch_and_parse_url (url ):
509
+ set_status_message ("Browsing..." )
510
+ response = requests .get (url )
511
+ if response .status_code == 200 : # Raise an error for bad status codes
512
+ # Parse the web page
513
+ soup = BeautifulSoup (response .content , 'html.parser' )
514
+ # Extract the main content
515
+ paragraphs = soup .find_all ('p' )
516
+ # Combine the text from the paragraphs
517
+ content = ' ' .join (paragraph .get_text () for paragraph in paragraphs )
518
+ return content
519
+ else :
520
+ return None
521
+
501
522
async def get_article_summaries (request_body , request_headers , URLsToBrowse ):
502
523
Summaries = None
503
524
URLsToBrowse = json .loads (URLsToBrowse )
504
525
for URL in URLsToBrowse :
505
- system_prompt = "You are tasked with helping content developers resolve customer feedback on their content on learn.microsoft.com. Right now, you've identified the following URL for further research: " + URL + ". Your task now is to provide a summary of relevant content on the page that will help us address the feedback on the URL provided by the user and document current sources. Return nothing except your summary of the key points and any important quotes the content on the page in a single string.\n \n "
506
- summary = await send_private_chat (request_body , request_headers , None , system_prompt )
507
- summary = json .loads ("{\" URL\" : \" " + URL + "\" ,\n \" summary\" : " + json .dumps (summary ) + "}" )
508
- if Summaries is None :
509
- Summaries = [summary ]
510
- else :
511
- Summaries .append (summary )
512
- return Summaries
526
+ page_content = await fetch_and_parse_url (URL )
527
+ if page_content != None :
528
+ system_prompt = "You are tasked with helping content developers resolve customer feedback on their content on learn.microsoft.com. Right now, you've identified the following URL for further research: " + URL + ". Your task now is to provide a summary of relevant content on the page that will help us address the feedback on the URL provided by the user and document current sources. Return nothing except your summary of the key points and any important quotes the content on the page in a single string.\n \n Page Content:\n \n " + page_content + "\n \n Original System Message:\n \n "
529
+
530
+ set_status_message ("Analyzing..." )
531
+ summary = await send_private_chat (request_body , request_headers , None , system_prompt )
532
+ summary = json .loads ("{\" URL\" : \" " + URL + "\" ,\n \" summary\" : " + json .dumps (summary ) + "}" )
533
+
534
+ if Summaries is None :
535
+ Summaries = [summary ]
536
+ else :
537
+ Summaries .append (summary )
538
+ return Summaries
513
539
514
540
async def is_background_info_sufficient (request_body , request_headers , Summaries ):
515
541
strSummaries = json .dumps (Summaries , indent = 4 )
@@ -525,6 +551,7 @@ async def search_and_add_background_references(request_body, request_headers):
525
551
Summaries = None
526
552
while NeedsMoreSummaries :
527
553
554
+ set_status_message ("Searching..." )
528
555
if Summaries is None :
529
556
searches = await identify_searches (request_body , request_headers )
530
557
else :
@@ -534,10 +561,11 @@ async def search_and_add_background_references(request_body, request_headers):
534
561
if searches == None :
535
562
return None
536
563
564
+ set_status_message ("Gathering search results..." )
537
565
URLsToBrowse = await get_urls_to_browse (request_body , request_headers , searches )
538
566
if URLsToBrowse == "Search error." :
539
567
return "Search error."
540
-
568
+
541
569
if (Summaries is None ):
542
570
Summaries = await get_article_summaries (request_body , request_headers , URLsToBrowse )
543
571
else :
@@ -548,6 +576,7 @@ async def search_and_add_background_references(request_body, request_headers):
548
576
if AreWeDone :
549
577
NeedsMoreSummaries = False
550
578
579
+ set_status_message ("Generating answer..." )
551
580
return prompts ["background_info_preamble" ] + json .dumps (Summaries , indent = 4 ) + "\n \n Primary System Message:"
552
581
553
582
async def conversation_internal (request_body , request_headers ):
@@ -1059,3 +1088,6 @@ async def generate_title(conversation_messages) -> str:
1059
1088
1060
1089
1061
1090
app = create_app ()
1091
+
1092
+ if __name__ == '__main__' :
1093
+ app .run (debug = True )
0 commit comments