Update app.py
Browse files
app.py
CHANGED
|
@@ -22,6 +22,8 @@ import openpyxl
|
|
| 22 |
import pptx
|
| 23 |
import PyPDF2
|
| 24 |
import requests
|
|
|
|
|
|
|
| 25 |
from youtube_transcript_api import YouTubeTranscriptApi
|
| 26 |
from youtube_transcript_api._errors import (
|
| 27 |
NoTranscriptFound,
|
|
@@ -46,9 +48,7 @@ def read_csv(file_path):
|
|
| 46 |
csv_reader = csv.reader(csvfile)
|
| 47 |
csv_data = [row for row in csv_reader]
|
| 48 |
|
| 49 |
-
return ' '.join(
|
| 50 |
-
[' '.join(row) for row in csv_data]
|
| 51 |
-
)
|
| 52 |
|
| 53 |
|
| 54 |
def read_text(file_path):
|
|
@@ -80,8 +80,7 @@ def read_docx(file_path):
|
|
| 80 |
doc = docx.Document(file_path)
|
| 81 |
|
| 82 |
return '\n'.join(
|
| 83 |
-
paragraph.text
|
| 84 |
-
for paragraph in doc.paragraphs
|
| 85 |
)
|
| 86 |
|
| 87 |
|
|
@@ -105,9 +104,7 @@ def read_xlsx(file_path):
|
|
| 105 |
for row in sheet.iter_rows(values_only=True):
|
| 106 |
text_data += (
|
| 107 |
' '.join(
|
| 108 |
-
str(cell)
|
| 109 |
-
for cell in row
|
| 110 |
-
if cell is not None
|
| 111 |
)
|
| 112 |
+ '\n'
|
| 113 |
)
|
|
@@ -119,10 +116,7 @@ def read_json(file_path):
|
|
| 119 |
with open(file_path, 'r', encoding='utf-8') as f:
|
| 120 |
json_data = json.load(f)
|
| 121 |
|
| 122 |
-
return json.dumps(
|
| 123 |
-
json_data,
|
| 124 |
-
ensure_ascii=False
|
| 125 |
-
)
|
| 126 |
|
| 127 |
|
| 128 |
def read_html(file_path):
|
|
@@ -154,50 +148,38 @@ def read_xml(file_path):
|
|
| 154 |
)
|
| 155 |
|
| 156 |
|
| 157 |
-
def
|
| 158 |
if not url:
|
| 159 |
-
return
|
| 160 |
|
| 161 |
url = str(url).strip()
|
| 162 |
|
| 163 |
url = url.replace('\\n', '')
|
| 164 |
url = url.replace('\n', '')
|
| 165 |
-
url = url.replace('\
|
| 166 |
-
|
| 167 |
-
markdown_match = re.search(
|
| 168 |
-
r'\]\((https?://[^)\s]+)\)',
|
| 169 |
-
url
|
| 170 |
-
)
|
| 171 |
-
|
| 172 |
-
if markdown_match:
|
| 173 |
-
url = markdown_match.group(1)
|
| 174 |
|
| 175 |
markdown_match = re.search(
|
| 176 |
-
r'\
|
| 177 |
-
url
|
|
|
|
| 178 |
)
|
| 179 |
|
| 180 |
if markdown_match:
|
| 181 |
url = markdown_match.group(1)
|
| 182 |
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
url = url.rstrip(
|
| 188 |
-
'.,!?;:)]}'
|
| 189 |
)
|
| 190 |
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
def extract_youtube_video_id(url):
|
| 195 |
-
if not url:
|
| 196 |
-
return None
|
| 197 |
|
| 198 |
-
url =
|
| 199 |
|
| 200 |
parsed = urlparse(url)
|
|
|
|
| 201 |
hostname = (
|
| 202 |
parsed.hostname or ''
|
| 203 |
).lower()
|
|
@@ -212,13 +194,7 @@ def extract_youtube_video_id(url):
|
|
| 212 |
.split('/')[0]
|
| 213 |
)
|
| 214 |
|
| 215 |
-
|
| 216 |
-
r'[A-Za-z0-9_-]{11}',
|
| 217 |
-
video_id
|
| 218 |
-
):
|
| 219 |
-
return video_id
|
| 220 |
-
|
| 221 |
-
return None
|
| 222 |
|
| 223 |
if hostname in (
|
| 224 |
'youtube.com',
|
|
@@ -227,43 +203,38 @@ def extract_youtube_video_id(url):
|
|
| 227 |
):
|
| 228 |
|
| 229 |
if parsed.path == '/watch':
|
|
|
|
| 230 |
video_ids = parse_qs(
|
| 231 |
parsed.query
|
| 232 |
).get('v')
|
| 233 |
|
| 234 |
-
if
|
| 235 |
-
return None
|
| 236 |
-
|
| 237 |
-
video_id = video_ids[0]
|
| 238 |
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
|
| 245 |
-
|
| 246 |
|
| 247 |
for prefix in (
|
| 248 |
'/shorts/',
|
| 249 |
'/embed/',
|
| 250 |
'/live/'
|
| 251 |
):
|
|
|
|
| 252 |
if parsed.path.startswith(prefix):
|
|
|
|
| 253 |
video_id = (
|
| 254 |
parsed.path[
|
| 255 |
len(prefix):
|
| 256 |
]
|
| 257 |
.split('/')[0]
|
|
|
|
| 258 |
)
|
| 259 |
|
| 260 |
-
|
| 261 |
-
r'[A-Za-z0-9_-]{11}',
|
| 262 |
-
video_id
|
| 263 |
-
):
|
| 264 |
-
return video_id
|
| 265 |
-
|
| 266 |
-
return None
|
| 267 |
|
| 268 |
return None
|
| 269 |
|
|
@@ -275,47 +246,108 @@ def is_youtube_url(url):
|
|
| 275 |
)
|
| 276 |
|
| 277 |
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
'
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
)
|
| 293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
return ' '.join(
|
| 295 |
-
|
| 296 |
-
for
|
| 297 |
)
|
| 298 |
|
| 299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
-
|
| 302 |
-
video_id,
|
| 303 |
-
languages=[lang]
|
| 304 |
-
)
|
| 305 |
|
| 306 |
-
|
| 307 |
-
snippet.text
|
| 308 |
-
for snippet in fetched
|
| 309 |
-
)
|
| 310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
):
|
| 316 |
video_id = extract_youtube_video_id(url)
|
| 317 |
|
| 318 |
if not video_id:
|
|
|
|
| 319 |
return (
|
| 320 |
'Invalid YouTube video URL. '
|
| 321 |
'Please provide a valid YouTube video link.'
|
|
@@ -326,67 +358,61 @@ def process_youtube_video(
|
|
| 326 |
repr(video_id)
|
| 327 |
)
|
| 328 |
|
| 329 |
-
|
| 330 |
-
errors = []
|
| 331 |
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
fetch_transcript_text(
|
| 336 |
-
video_id,
|
| 337 |
-
lang
|
| 338 |
-
)
|
| 339 |
-
)
|
| 340 |
|
| 341 |
-
|
| 342 |
-
transcript_data.append(
|
| 343 |
-
transcript
|
| 344 |
-
)
|
| 345 |
|
| 346 |
-
|
| 347 |
-
NoTranscriptFound,
|
| 348 |
-
TranscriptsDisabled,
|
| 349 |
-
VideoUnavailable
|
| 350 |
-
) as e:
|
| 351 |
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
|
|
|
| 355 |
|
| 356 |
-
|
| 357 |
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
|
| 363 |
-
|
| 364 |
-
f'{lang}: {str(e)}'
|
| 365 |
-
)
|
| 366 |
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
)
|
| 371 |
|
| 372 |
-
|
| 373 |
-
'YOUTUBE TRANSCRIPT ERRORS:',
|
| 374 |
-
repr(errors)
|
| 375 |
-
)
|
| 376 |
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
|
| 386 |
|
| 387 |
def read_web_page(url):
|
|
|
|
| 388 |
try:
|
| 389 |
-
|
|
|
|
| 390 |
|
| 391 |
response = requests.get(
|
| 392 |
url,
|
|
@@ -404,6 +430,7 @@ def read_web_page(url):
|
|
| 404 |
)
|
| 405 |
|
| 406 |
if response.status_code >= 400:
|
|
|
|
| 407 |
return (
|
| 408 |
'Unable to access webpage. '
|
| 409 |
f'HTTP status: {response.status_code}'
|
|
@@ -416,6 +443,7 @@ def read_web_page(url):
|
|
| 416 |
)
|
| 417 |
|
| 418 |
if 'text/plain' in content_type:
|
|
|
|
| 419 |
return response.text
|
| 420 |
|
| 421 |
src = response.text
|
|
@@ -431,6 +459,7 @@ def read_web_page(url):
|
|
| 431 |
'noscript',
|
| 432 |
'svg'
|
| 433 |
]):
|
|
|
|
| 434 |
element.decompose()
|
| 435 |
|
| 436 |
text_data = soup.get_text(
|
|
@@ -444,26 +473,27 @@ def read_web_page(url):
|
|
| 444 |
)
|
| 445 |
|
| 446 |
if not text_data:
|
|
|
|
| 447 |
return (
|
| 448 |
-
'The webpage was accessed '
|
| 449 |
-
'
|
| 450 |
-
'readable text.'
|
| 451 |
)
|
| 452 |
|
| 453 |
return text_data
|
| 454 |
|
| 455 |
except requests.exceptions.Timeout:
|
|
|
|
| 456 |
return (
|
| 457 |
'The webpage request timed out. '
|
| 458 |
'Please try another link.'
|
| 459 |
)
|
| 460 |
|
| 461 |
except requests.exceptions.RequestException as e:
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
)
|
| 465 |
|
| 466 |
except Exception as e:
|
|
|
|
| 467 |
return (
|
| 468 |
'An error occurred while reading '
|
| 469 |
f'the webpage: {e}'
|
|
@@ -474,7 +504,9 @@ def read_data(
|
|
| 474 |
file_path_or_url,
|
| 475 |
languages=['en', 'ar']
|
| 476 |
):
|
|
|
|
| 477 |
if not file_path_or_url:
|
|
|
|
| 478 |
return 'Unsupported type or format.'
|
| 479 |
|
| 480 |
file_path_or_url = str(
|
|
@@ -484,14 +516,15 @@ def read_data(
|
|
| 484 |
if is_youtube_url(
|
| 485 |
file_path_or_url
|
| 486 |
):
|
|
|
|
| 487 |
return process_youtube_video(
|
| 488 |
-
file_path_or_url
|
| 489 |
-
languages
|
| 490 |
)
|
| 491 |
|
| 492 |
if file_path_or_url.startswith(
|
| 493 |
('http://', 'https://')
|
| 494 |
):
|
|
|
|
| 495 |
return read_web_page(
|
| 496 |
file_path_or_url
|
| 497 |
)
|
|
@@ -501,46 +534,55 @@ def read_data(
|
|
| 501 |
)
|
| 502 |
|
| 503 |
if lower_path.endswith('.csv'):
|
|
|
|
| 504 |
return read_csv(
|
| 505 |
file_path_or_url
|
| 506 |
)
|
| 507 |
|
| 508 |
elif lower_path.endswith('.txt'):
|
|
|
|
| 509 |
return read_text(
|
| 510 |
file_path_or_url
|
| 511 |
)
|
| 512 |
|
| 513 |
elif lower_path.endswith('.pdf'):
|
|
|
|
| 514 |
return read_pdf(
|
| 515 |
file_path_or_url
|
| 516 |
)
|
| 517 |
|
| 518 |
elif lower_path.endswith('.docx'):
|
|
|
|
| 519 |
return read_docx(
|
| 520 |
file_path_or_url
|
| 521 |
)
|
| 522 |
|
| 523 |
elif lower_path.endswith('.pptx'):
|
|
|
|
| 524 |
return read_pptx(
|
| 525 |
file_path_or_url
|
| 526 |
)
|
| 527 |
|
| 528 |
elif lower_path.endswith('.xlsx'):
|
|
|
|
| 529 |
return read_xlsx(
|
| 530 |
file_path_or_url
|
| 531 |
)
|
| 532 |
|
| 533 |
elif lower_path.endswith('.json'):
|
|
|
|
| 534 |
return read_json(
|
| 535 |
file_path_or_url
|
| 536 |
)
|
| 537 |
|
| 538 |
elif lower_path.endswith('.html'):
|
|
|
|
| 539 |
return read_html(
|
| 540 |
file_path_or_url
|
| 541 |
)
|
| 542 |
|
| 543 |
elif lower_path.endswith('.xml'):
|
|
|
|
| 544 |
return read_xml(
|
| 545 |
file_path_or_url
|
| 546 |
)
|
|
@@ -549,11 +591,22 @@ def read_data(
|
|
| 549 |
|
| 550 |
|
| 551 |
def normalize_text(text):
|
| 552 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
text = str(text)
|
| 554 |
|
| 555 |
text = re.sub(
|
| 556 |
-
r'\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
'',
|
| 558 |
text
|
| 559 |
)
|
|
@@ -566,6 +619,7 @@ def normalize_text(text):
|
|
| 566 |
)
|
| 567 |
|
| 568 |
for punc in punctuation:
|
|
|
|
| 569 |
text = text.replace(
|
| 570 |
punc,
|
| 571 |
''
|
|
@@ -577,7 +631,9 @@ def normalize_text(text):
|
|
| 577 |
text
|
| 578 |
)
|
| 579 |
|
| 580 |
-
words = word_tokenize(
|
|
|
|
|
|
|
| 581 |
|
| 582 |
return ' '.join(words)
|
| 583 |
|
|
@@ -593,18 +649,22 @@ llm = HuggingFaceEndpoint(
|
|
| 593 |
do_sample=True,
|
| 594 |
)
|
| 595 |
|
|
|
|
| 596 |
chat_model = ChatHuggingFace(
|
| 597 |
llm=llm
|
| 598 |
)
|
| 599 |
|
|
|
|
| 600 |
model_name = (
|
| 601 |
'sentence-transformers/all-mpnet-base-v2'
|
| 602 |
)
|
| 603 |
|
|
|
|
| 604 |
embedding_llm = HuggingFaceEmbeddings(
|
| 605 |
model_name=model_name
|
| 606 |
)
|
| 607 |
|
|
|
|
| 608 |
db = FAISS.load_local(
|
| 609 |
'faiss_index',
|
| 610 |
embedding_llm,
|
|
@@ -612,7 +672,10 @@ db = FAISS.load_local(
|
|
| 612 |
)
|
| 613 |
|
| 614 |
|
| 615 |
-
def print_like_dislike(
|
|
|
|
|
|
|
|
|
|
| 616 |
print(
|
| 617 |
x.index,
|
| 618 |
x.value,
|
|
@@ -624,7 +687,9 @@ def user(
|
|
| 624 |
user_message,
|
| 625 |
history
|
| 626 |
):
|
|
|
|
| 627 |
if not len(user_message):
|
|
|
|
| 628 |
raise gr.Error(
|
| 629 |
'Chat messages cannot be empty'
|
| 630 |
)
|
|
@@ -642,24 +707,29 @@ def user2(
|
|
| 642 |
history,
|
| 643 |
link
|
| 644 |
):
|
| 645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 646 |
raise gr.Error(
|
| 647 |
'Chat messages or links cannot be empty'
|
| 648 |
)
|
| 649 |
|
| 650 |
-
link =
|
| 651 |
user_message = str(
|
| 652 |
user_message
|
| 653 |
).strip()
|
| 654 |
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
|
| 658 |
-
|
| 659 |
|
| 660 |
history.append({
|
| 661 |
'role': 'user',
|
| 662 |
-
'content':
|
| 663 |
})
|
| 664 |
|
| 665 |
return '', history, link
|
|
@@ -670,13 +740,19 @@ def user3(
|
|
| 670 |
history,
|
| 671 |
file_path
|
| 672 |
):
|
| 673 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 674 |
raise gr.Error(
|
| 675 |
'Chat messages or files cannot be empty'
|
| 676 |
)
|
| 677 |
|
| 678 |
combined_message = (
|
| 679 |
-
f'{file_path}\n
|
|
|
|
| 680 |
)
|
| 681 |
|
| 682 |
history.append({
|
|
@@ -707,6 +783,7 @@ def Chat_Message(
|
|
| 707 |
history,
|
| 708 |
messages1
|
| 709 |
):
|
|
|
|
| 710 |
user_msg_text = history[-1]['content']
|
| 711 |
|
| 712 |
message = HumanMessage(
|
|
@@ -717,19 +794,25 @@ def Chat_Message(
|
|
| 717 |
messages1[-1],
|
| 718 |
HumanMessage
|
| 719 |
):
|
|
|
|
| 720 |
messages1 = messages1[:-2]
|
| 721 |
|
| 722 |
-
messages1.append(
|
|
|
|
|
|
|
| 723 |
|
| 724 |
if len(messages1) >= 8:
|
|
|
|
| 725 |
messages1 = messages1[-8:]
|
| 726 |
|
| 727 |
try:
|
|
|
|
| 728 |
response = chat_model.invoke(
|
| 729 |
messages1
|
| 730 |
)
|
| 731 |
|
| 732 |
except Exception as e:
|
|
|
|
| 733 |
error_message = str(e)
|
| 734 |
|
| 735 |
print(
|
|
@@ -737,18 +820,23 @@ def Chat_Message(
|
|
| 737 |
repr(e)
|
| 738 |
)
|
| 739 |
|
| 740 |
-
start_index =
|
| 741 |
-
|
|
|
|
|
|
|
| 742 |
)
|
| 743 |
|
| 744 |
-
end_index =
|
| 745 |
-
|
|
|
|
|
|
|
| 746 |
)
|
| 747 |
|
| 748 |
if (
|
| 749 |
start_index != -1
|
| 750 |
and end_index != -1
|
| 751 |
):
|
|
|
|
| 752 |
raise gr.Error(
|
| 753 |
error_message[
|
| 754 |
start_index:end_index
|
|
@@ -771,9 +859,12 @@ def Chat_Message(
|
|
| 771 |
})
|
| 772 |
|
| 773 |
for character in response.content:
|
|
|
|
| 774 |
history[-1]['content'] += character
|
| 775 |
|
| 776 |
-
time.sleep(
|
|
|
|
|
|
|
| 777 |
|
| 778 |
yield history, messages1
|
| 779 |
|
|
@@ -782,6 +873,7 @@ def Internet_Search(
|
|
| 782 |
history,
|
| 783 |
messages2
|
| 784 |
):
|
|
|
|
| 785 |
message = str(
|
| 786 |
history[-1]['content']
|
| 787 |
)
|
|
@@ -790,6 +882,7 @@ def Internet_Search(
|
|
| 790 |
messages2[-1],
|
| 791 |
HumanMessage
|
| 792 |
):
|
|
|
|
| 793 |
messages2 = messages2[:-2]
|
| 794 |
|
| 795 |
similar_docs = db.similarity_search(
|
|
@@ -798,11 +891,16 @@ def Internet_Search(
|
|
| 798 |
)
|
| 799 |
|
| 800 |
if similar_docs:
|
|
|
|
| 801 |
source_knowledge = '\n'.join(
|
| 802 |
-
|
| 803 |
-
|
|
|
|
|
|
|
| 804 |
)
|
|
|
|
| 805 |
else:
|
|
|
|
| 806 |
source_knowledge = ''
|
| 807 |
|
| 808 |
augmented_prompt = f"""
|
|
@@ -827,17 +925,22 @@ information from other sources.
|
|
| 827 |
content=augmented_prompt
|
| 828 |
)
|
| 829 |
|
| 830 |
-
messages2.append(
|
|
|
|
|
|
|
| 831 |
|
| 832 |
if len(messages2) >= 4:
|
|
|
|
| 833 |
messages2 = messages2[-4:]
|
| 834 |
|
| 835 |
try:
|
|
|
|
| 836 |
response = chat_model.invoke(
|
| 837 |
messages2
|
| 838 |
)
|
| 839 |
|
| 840 |
except Exception as e:
|
|
|
|
| 841 |
error_message = str(e)
|
| 842 |
|
| 843 |
print(
|
|
@@ -845,18 +948,23 @@ information from other sources.
|
|
| 845 |
repr(e)
|
| 846 |
)
|
| 847 |
|
| 848 |
-
start_index =
|
| 849 |
-
|
|
|
|
|
|
|
| 850 |
)
|
| 851 |
|
| 852 |
-
end_index =
|
| 853 |
-
|
|
|
|
|
|
|
| 854 |
)
|
| 855 |
|
| 856 |
if (
|
| 857 |
start_index != -1
|
| 858 |
and end_index != -1
|
| 859 |
):
|
|
|
|
| 860 |
raise gr.Error(
|
| 861 |
error_message[
|
| 862 |
start_index:end_index
|
|
@@ -879,9 +987,12 @@ information from other sources.
|
|
| 879 |
})
|
| 880 |
|
| 881 |
for character in response.content:
|
|
|
|
| 882 |
history[-1]['content'] += character
|
| 883 |
|
| 884 |
-
time.sleep(
|
|
|
|
|
|
|
| 885 |
|
| 886 |
yield history, messages2
|
| 887 |
|
|
@@ -889,6 +1000,7 @@ information from other sources.
|
|
| 889 |
def generate_chart_config(
|
| 890 |
description
|
| 891 |
):
|
|
|
|
| 892 |
system_instructions = """
|
| 893 |
You are a Chart.js configuration generator.
|
| 894 |
|
|
@@ -980,7 +1092,11 @@ Rules:
|
|
| 980 |
start = raw.find('{')
|
| 981 |
end = raw.rfind('}')
|
| 982 |
|
| 983 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
| 984 |
raise ValueError(
|
| 985 |
'Model did not return a JSON object.\n'
|
| 986 |
f'Raw response:\n{raw}'
|
|
@@ -995,24 +1111,30 @@ Rules:
|
|
| 995 |
raw
|
| 996 |
)
|
| 997 |
|
| 998 |
-
config = json.loads(
|
|
|
|
|
|
|
| 999 |
|
| 1000 |
if 'type' not in config:
|
|
|
|
| 1001 |
raise ValueError(
|
| 1002 |
"Chart config missing 'type'"
|
| 1003 |
)
|
| 1004 |
|
| 1005 |
if 'data' not in config:
|
|
|
|
| 1006 |
raise ValueError(
|
| 1007 |
"Chart config missing 'data'"
|
| 1008 |
)
|
| 1009 |
|
| 1010 |
if 'labels' not in config['data']:
|
|
|
|
| 1011 |
raise ValueError(
|
| 1012 |
"Chart config missing 'data.labels'"
|
| 1013 |
)
|
| 1014 |
|
| 1015 |
if 'datasets' not in config['data']:
|
|
|
|
| 1016 |
raise ValueError(
|
| 1017 |
"Chart config missing 'data.datasets'"
|
| 1018 |
)
|
|
@@ -1021,6 +1143,7 @@ Rules:
|
|
| 1021 |
config['data']['datasets'],
|
| 1022 |
list
|
| 1023 |
):
|
|
|
|
| 1024 |
raise ValueError(
|
| 1025 |
"'data.datasets' must be a list"
|
| 1026 |
)
|
|
@@ -1032,6 +1155,7 @@ def Chart_Generator(
|
|
| 1032 |
history,
|
| 1033 |
messages3
|
| 1034 |
):
|
|
|
|
| 1035 |
message = str(
|
| 1036 |
history[-1]['content']
|
| 1037 |
)
|
|
@@ -1040,6 +1164,7 @@ def Chart_Generator(
|
|
| 1040 |
messages3[-1],
|
| 1041 |
HumanMessage
|
| 1042 |
):
|
|
|
|
| 1043 |
messages3 = messages3[:-2]
|
| 1044 |
|
| 1045 |
if '#chart' in message.lower():
|
|
@@ -1052,14 +1177,17 @@ def Chart_Generator(
|
|
| 1052 |
)[1].strip()
|
| 1053 |
|
| 1054 |
if not chart_description:
|
|
|
|
| 1055 |
combined_content = (
|
| 1056 |
'Please provide chart details after #chart.'
|
| 1057 |
)
|
| 1058 |
|
| 1059 |
else:
|
|
|
|
| 1060 |
chart_config = None
|
| 1061 |
|
| 1062 |
try:
|
|
|
|
| 1063 |
chart_config = (
|
| 1064 |
generate_chart_config(
|
| 1065 |
chart_description
|
|
@@ -1075,6 +1203,7 @@ def Chart_Generator(
|
|
| 1075 |
)
|
| 1076 |
|
| 1077 |
except Exception as e:
|
|
|
|
| 1078 |
print(
|
| 1079 |
'CHART GENERATION ERROR:',
|
| 1080 |
repr(e)
|
|
@@ -1085,10 +1214,10 @@ def Chart_Generator(
|
|
| 1085 |
f'Error: {str(e)}'
|
| 1086 |
)
|
| 1087 |
|
| 1088 |
-
chart_config = None
|
| 1089 |
-
|
| 1090 |
if chart_config:
|
|
|
|
| 1091 |
try:
|
|
|
|
| 1092 |
config_json = json.dumps(
|
| 1093 |
chart_config,
|
| 1094 |
separators=(',', ':')
|
|
@@ -1122,20 +1251,25 @@ def Chart_Generator(
|
|
| 1122 |
chart_response.status_code
|
| 1123 |
)
|
| 1124 |
|
| 1125 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1126 |
print(
|
| 1127 |
'QUICKCHART RESPONSE:',
|
| 1128 |
chart_response.text[:1000]
|
| 1129 |
)
|
| 1130 |
|
| 1131 |
combined_content = (
|
| 1132 |
-
'QuickChart failed to '
|
| 1133 |
-
'
|
| 1134 |
f'HTTP Status: '
|
| 1135 |
f'{chart_response.status_code}'
|
| 1136 |
)
|
| 1137 |
|
| 1138 |
else:
|
|
|
|
| 1139 |
image_html = (
|
| 1140 |
f'<img src="{chart_url}" '
|
| 1141 |
'alt="Generated Chart" '
|
|
@@ -1146,8 +1280,8 @@ def Chart_Generator(
|
|
| 1146 |
)
|
| 1147 |
|
| 1148 |
chart_summary_prompt = (
|
| 1149 |
-
'The following Chart.js '
|
| 1150 |
-
'
|
| 1151 |
f'{json.dumps(chart_config, indent=2)}\n\n'
|
| 1152 |
'Briefly describe what this chart '
|
| 1153 |
'represents.'
|
|
@@ -1167,6 +1301,7 @@ def Chart_Generator(
|
|
| 1167 |
]
|
| 1168 |
|
| 1169 |
try:
|
|
|
|
| 1170 |
response = (
|
| 1171 |
chat_model.invoke(
|
| 1172 |
analysis_messages
|
|
@@ -1178,6 +1313,7 @@ def Chart_Generator(
|
|
| 1178 |
)
|
| 1179 |
|
| 1180 |
except Exception as e:
|
|
|
|
| 1181 |
print(
|
| 1182 |
'CHART ANALYSIS ERROR:',
|
| 1183 |
repr(e)
|
|
@@ -1193,6 +1329,7 @@ def Chart_Generator(
|
|
| 1193 |
)
|
| 1194 |
|
| 1195 |
except Exception as e:
|
|
|
|
| 1196 |
print(
|
| 1197 |
'QUICKCHART REQUEST ERROR:',
|
| 1198 |
repr(e)
|
|
@@ -1205,21 +1342,27 @@ def Chart_Generator(
|
|
| 1205 |
)
|
| 1206 |
|
| 1207 |
else:
|
|
|
|
| 1208 |
prompt = HumanMessage(
|
| 1209 |
content=message
|
| 1210 |
)
|
| 1211 |
|
| 1212 |
-
messages3.append(
|
|
|
|
|
|
|
| 1213 |
|
| 1214 |
if len(messages3) >= 6:
|
|
|
|
| 1215 |
messages3 = messages3[-6:]
|
| 1216 |
|
| 1217 |
try:
|
|
|
|
| 1218 |
response = chat_model.invoke(
|
| 1219 |
messages3
|
| 1220 |
)
|
| 1221 |
|
| 1222 |
except Exception as e:
|
|
|
|
| 1223 |
error_message = str(e)
|
| 1224 |
|
| 1225 |
print(
|
|
@@ -1227,18 +1370,23 @@ def Chart_Generator(
|
|
| 1227 |
repr(e)
|
| 1228 |
)
|
| 1229 |
|
| 1230 |
-
start_index =
|
| 1231 |
-
|
|
|
|
|
|
|
| 1232 |
)
|
| 1233 |
|
| 1234 |
-
end_index =
|
| 1235 |
-
|
|
|
|
|
|
|
| 1236 |
)
|
| 1237 |
|
| 1238 |
if (
|
| 1239 |
start_index != -1
|
| 1240 |
and end_index != -1
|
| 1241 |
):
|
|
|
|
| 1242 |
raise gr.Error(
|
| 1243 |
error_message[
|
| 1244 |
start_index:end_index
|
|
@@ -1255,7 +1403,9 @@ def Chart_Generator(
|
|
| 1255 |
)
|
| 1256 |
)
|
| 1257 |
|
| 1258 |
-
combined_content =
|
|
|
|
|
|
|
| 1259 |
|
| 1260 |
history.append({
|
| 1261 |
'role': 'assistant',
|
|
@@ -1263,27 +1413,72 @@ def Chart_Generator(
|
|
| 1263 |
})
|
| 1264 |
|
| 1265 |
for character in combined_content:
|
|
|
|
| 1266 |
history[-1]['content'] += character
|
| 1267 |
|
| 1268 |
-
time.sleep(
|
|
|
|
|
|
|
| 1269 |
|
| 1270 |
yield history, messages3
|
| 1271 |
|
| 1272 |
|
| 1273 |
def extract_url_from_text(text):
|
|
|
|
| 1274 |
if not text:
|
|
|
|
| 1275 |
return None
|
| 1276 |
|
| 1277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1278 |
|
| 1279 |
-
|
| 1280 |
-
|
| 1281 |
-
|
| 1282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1283 |
|
| 1284 |
text = text.replace(
|
| 1285 |
-
'\n',
|
| 1286 |
-
''
|
| 1287 |
)
|
| 1288 |
|
| 1289 |
text = text.replace(
|
|
@@ -1291,53 +1486,160 @@ def extract_url_from_text(text):
|
|
| 1291 |
''
|
| 1292 |
)
|
| 1293 |
|
| 1294 |
-
|
| 1295 |
-
r'\]\((https?://[^)\s]+)
|
| 1296 |
-
text
|
|
|
|
| 1297 |
)
|
| 1298 |
|
| 1299 |
-
if
|
| 1300 |
-
|
| 1301 |
-
|
| 1302 |
-
.
|
| 1303 |
-
.rstrip('.,!?;:)]}')
|
| 1304 |
)
|
| 1305 |
|
| 1306 |
-
|
| 1307 |
r'https?://[^\s<>"\']+',
|
| 1308 |
-
text
|
|
|
|
| 1309 |
)
|
| 1310 |
|
| 1311 |
-
if
|
| 1312 |
-
|
| 1313 |
-
|
| 1314 |
-
|
| 1315 |
-
|
|
|
|
| 1316 |
)
|
| 1317 |
|
| 1318 |
return None
|
| 1319 |
|
| 1320 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1321 |
def Link_Scratch(
|
| 1322 |
history,
|
| 1323 |
-
messages4
|
| 1324 |
-
link
|
| 1325 |
):
|
| 1326 |
-
user_message = str(
|
| 1327 |
-
history[-1]['content']
|
| 1328 |
-
).strip()
|
| 1329 |
|
| 1330 |
-
|
|
|
|
|
|
|
| 1331 |
|
| 1332 |
if isinstance(
|
| 1333 |
messages4[-1],
|
| 1334 |
HumanMessage
|
| 1335 |
):
|
|
|
|
| 1336 |
messages4 = messages4[:-2]
|
| 1337 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1338 |
print(
|
| 1339 |
-
'
|
| 1340 |
-
repr(
|
| 1341 |
)
|
| 1342 |
|
| 1343 |
print(
|
|
@@ -1345,14 +1647,23 @@ def Link_Scratch(
|
|
| 1345 |
repr(link)
|
| 1346 |
)
|
| 1347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1348 |
if not link:
|
|
|
|
| 1349 |
response_message = (
|
| 1350 |
-
'Please provide a valid URL
|
| 1351 |
-
'with http:// or https://'
|
| 1352 |
)
|
| 1353 |
|
| 1354 |
else:
|
| 1355 |
-
|
|
|
|
|
|
|
|
|
|
| 1356 |
|
| 1357 |
print(
|
| 1358 |
'LINK READ RESULT TYPE:',
|
|
@@ -1373,7 +1684,10 @@ def Link_Scratch(
|
|
| 1373 |
]
|
| 1374 |
|
| 1375 |
if (
|
| 1376 |
-
isinstance(
|
|
|
|
|
|
|
|
|
|
| 1377 |
and (
|
| 1378 |
result in error_results
|
| 1379 |
or result.startswith(
|
|
@@ -1382,22 +1696,38 @@ def Link_Scratch(
|
|
| 1382 |
or result.startswith(
|
| 1383 |
'An error occurred while reading'
|
| 1384 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1385 |
)
|
| 1386 |
):
|
|
|
|
| 1387 |
response_message = result
|
| 1388 |
|
| 1389 |
else:
|
|
|
|
| 1390 |
content_data = normalize_text(
|
| 1391 |
result
|
| 1392 |
)
|
| 1393 |
|
| 1394 |
if not content_data:
|
|
|
|
| 1395 |
response_message = (
|
| 1396 |
'The provided link is empty or '
|
| 1397 |
'does not contain any meaningful words.'
|
| 1398 |
)
|
| 1399 |
|
| 1400 |
else:
|
|
|
|
| 1401 |
augmented_prompt = f"""
|
| 1402 |
You are an AI designed to help understand
|
| 1403 |
and extract information from provided Link Content.
|
|
@@ -1410,9 +1740,9 @@ Query:
|
|
| 1410 |
Link Content:
|
| 1411 |
{content_data}
|
| 1412 |
|
| 1413 |
-
|
| 1414 |
-
|
| 1415 |
-
|
| 1416 |
"""
|
| 1417 |
|
| 1418 |
message = HumanMessage(
|
|
@@ -1426,13 +1756,13 @@ information from other sources.
|
|
| 1426 |
messages4 = messages4[-1:]
|
| 1427 |
|
| 1428 |
try:
|
| 1429 |
-
|
| 1430 |
-
|
| 1431 |
-
|
| 1432 |
-
)
|
| 1433 |
)
|
| 1434 |
|
| 1435 |
except Exception as e:
|
|
|
|
| 1436 |
error_message = str(e)
|
| 1437 |
|
| 1438 |
print(
|
|
@@ -1456,6 +1786,7 @@ information from other sources.
|
|
| 1456 |
start_index != -1
|
| 1457 |
and end_index != -1
|
| 1458 |
):
|
|
|
|
| 1459 |
raise gr.Error(
|
| 1460 |
error_message[
|
| 1461 |
start_index:end_index
|
|
@@ -1482,9 +1813,12 @@ information from other sources.
|
|
| 1482 |
})
|
| 1483 |
|
| 1484 |
for character in response_message:
|
|
|
|
| 1485 |
history[-1]['content'] += character
|
| 1486 |
|
| 1487 |
-
time.sleep(
|
|
|
|
|
|
|
| 1488 |
|
| 1489 |
yield history, messages4
|
| 1490 |
|
|
@@ -1493,6 +1827,7 @@ def insert_line_breaks(
|
|
| 1493 |
text,
|
| 1494 |
every=8
|
| 1495 |
):
|
|
|
|
| 1496 |
return '\n'.join(
|
| 1497 |
text[i:i + every]
|
| 1498 |
for i in range(
|
|
@@ -1503,7 +1838,10 @@ def insert_line_breaks(
|
|
| 1503 |
)
|
| 1504 |
|
| 1505 |
|
| 1506 |
-
def display_file_name(
|
|
|
|
|
|
|
|
|
|
| 1507 |
supported_extensions = [
|
| 1508 |
'.csv',
|
| 1509 |
'.txt',
|
|
@@ -1524,6 +1862,7 @@ def display_file_name(file):
|
|
| 1524 |
file_extension.lower()
|
| 1525 |
in supported_extensions
|
| 1526 |
):
|
|
|
|
| 1527 |
file_name = os.path.basename(
|
| 1528 |
file.name
|
| 1529 |
)
|
|
@@ -1565,6 +1904,7 @@ def File_Interact(
|
|
| 1565 |
filepath,
|
| 1566 |
messages5
|
| 1567 |
):
|
|
|
|
| 1568 |
combined_message = str(
|
| 1569 |
history[-1]['content']
|
| 1570 |
)
|
|
@@ -1573,12 +1913,14 @@ def File_Interact(
|
|
| 1573 |
messages5[-1],
|
| 1574 |
HumanMessage
|
| 1575 |
):
|
|
|
|
| 1576 |
messages5 = messages5[:-2]
|
| 1577 |
|
| 1578 |
link = ''
|
| 1579 |
user_message = ''
|
| 1580 |
|
| 1581 |
if '\n' in combined_message:
|
|
|
|
| 1582 |
link, user_message = (
|
| 1583 |
combined_message.split(
|
| 1584 |
'\n',
|
|
@@ -1586,27 +1928,33 @@ def File_Interact(
|
|
| 1586 |
)
|
| 1587 |
)
|
| 1588 |
|
| 1589 |
-
user_message =
|
|
|
|
|
|
|
| 1590 |
|
| 1591 |
result = read_data(
|
| 1592 |
filepath
|
| 1593 |
)
|
| 1594 |
|
| 1595 |
if result == 'Unsupported type or format.':
|
|
|
|
| 1596 |
response_message = result
|
| 1597 |
|
| 1598 |
else:
|
|
|
|
| 1599 |
content_data = normalize_text(
|
| 1600 |
result
|
| 1601 |
)
|
| 1602 |
|
| 1603 |
if not content_data:
|
|
|
|
| 1604 |
response_message = (
|
| 1605 |
'The file is empty or does not '
|
| 1606 |
'contain any meaningful words.'
|
| 1607 |
)
|
| 1608 |
|
| 1609 |
else:
|
|
|
|
| 1610 |
augmented_prompt = f"""
|
| 1611 |
You are an AI designed to help understand
|
| 1612 |
and extract information from provided File Content.
|
|
@@ -1636,6 +1984,7 @@ information from other sources.
|
|
| 1636 |
messages5 = messages5[-1:]
|
| 1637 |
|
| 1638 |
try:
|
|
|
|
| 1639 |
response = (
|
| 1640 |
chat_model.invoke(
|
| 1641 |
messages5
|
|
@@ -1643,6 +1992,7 @@ information from other sources.
|
|
| 1643 |
)
|
| 1644 |
|
| 1645 |
except Exception as e:
|
|
|
|
| 1646 |
error_message = str(e)
|
| 1647 |
|
| 1648 |
print(
|
|
@@ -1666,6 +2016,7 @@ information from other sources.
|
|
| 1666 |
start_index != -1
|
| 1667 |
and end_index != -1
|
| 1668 |
):
|
|
|
|
| 1669 |
raise gr.Error(
|
| 1670 |
error_message[
|
| 1671 |
start_index:end_index
|
|
@@ -1692,9 +2043,12 @@ information from other sources.
|
|
| 1692 |
})
|
| 1693 |
|
| 1694 |
for character in response_message:
|
|
|
|
| 1695 |
history[-1]['content'] += character
|
| 1696 |
|
| 1697 |
-
time.sleep(
|
|
|
|
|
|
|
| 1698 |
|
| 1699 |
yield history, messages5
|
| 1700 |
|
|
@@ -1703,12 +2057,14 @@ def Explore_WebSite(
|
|
| 1703 |
history,
|
| 1704 |
messages6
|
| 1705 |
):
|
|
|
|
| 1706 |
message = history[-1]['content']
|
| 1707 |
|
| 1708 |
if isinstance(
|
| 1709 |
messages6[-1],
|
| 1710 |
HumanMessage
|
| 1711 |
):
|
|
|
|
| 1712 |
messages6 = messages6[:-2]
|
| 1713 |
|
| 1714 |
links = [
|
|
@@ -1716,8 +2072,10 @@ def Explore_WebSite(
|
|
| 1716 |
]
|
| 1717 |
|
| 1718 |
result = '\n'.join(
|
| 1719 |
-
|
| 1720 |
-
|
|
|
|
|
|
|
| 1721 |
)
|
| 1722 |
|
| 1723 |
content_data = normalize_text(
|
|
@@ -1746,17 +2104,22 @@ information from other sources.
|
|
| 1746 |
content=augmented_prompt
|
| 1747 |
)
|
| 1748 |
|
| 1749 |
-
messages6.append(
|
|
|
|
|
|
|
| 1750 |
|
| 1751 |
if len(messages6) >= 4:
|
|
|
|
| 1752 |
messages6 = messages6[-4:]
|
| 1753 |
|
| 1754 |
try:
|
|
|
|
| 1755 |
response = chat_model.invoke(
|
| 1756 |
messages6
|
| 1757 |
)
|
| 1758 |
|
| 1759 |
except Exception as e:
|
|
|
|
| 1760 |
error_message = str(e)
|
| 1761 |
|
| 1762 |
print(
|
|
@@ -1764,18 +2127,23 @@ information from other sources.
|
|
| 1764 |
repr(e)
|
| 1765 |
)
|
| 1766 |
|
| 1767 |
-
start_index =
|
| 1768 |
-
|
|
|
|
|
|
|
| 1769 |
)
|
| 1770 |
|
| 1771 |
-
end_index =
|
| 1772 |
-
|
|
|
|
|
|
|
| 1773 |
)
|
| 1774 |
|
| 1775 |
if (
|
| 1776 |
start_index != -1
|
| 1777 |
and end_index != -1
|
| 1778 |
):
|
|
|
|
| 1779 |
raise gr.Error(
|
| 1780 |
error_message[
|
| 1781 |
start_index:end_index
|
|
@@ -1798,9 +2166,12 @@ information from other sources.
|
|
| 1798 |
})
|
| 1799 |
|
| 1800 |
for character in response.content:
|
|
|
|
| 1801 |
history[-1]['content'] += character
|
| 1802 |
|
| 1803 |
-
time.sleep(
|
|
|
|
|
|
|
| 1804 |
|
| 1805 |
yield history, messages6
|
| 1806 |
|
|
@@ -2094,7 +2465,7 @@ with gr.Blocks() as demo:
|
|
| 2094 |
queue=True
|
| 2095 |
).then(
|
| 2096 |
Link_Scratch,
|
| 2097 |
-
[chatbot, messages4
|
| 2098 |
[chatbot, messages4]
|
| 2099 |
)
|
| 2100 |
|
|
@@ -2105,7 +2476,7 @@ with gr.Blocks() as demo:
|
|
| 2105 |
queue=True
|
| 2106 |
).then(
|
| 2107 |
Link_Scratch,
|
| 2108 |
-
[chatbot, messages4
|
| 2109 |
[chatbot, messages4]
|
| 2110 |
)
|
| 2111 |
|
|
@@ -2116,7 +2487,7 @@ with gr.Blocks() as demo:
|
|
| 2116 |
queue=True
|
| 2117 |
).then(
|
| 2118 |
Link_Scratch,
|
| 2119 |
-
[chatbot, messages4
|
| 2120 |
[chatbot, messages4]
|
| 2121 |
)
|
| 2122 |
|
|
|
|
| 22 |
import pptx
|
| 23 |
import PyPDF2
|
| 24 |
import requests
|
| 25 |
+
from requests.adapters import HTTPAdapter
|
| 26 |
+
from urllib3.util.retry import Retry
|
| 27 |
from youtube_transcript_api import YouTubeTranscriptApi
|
| 28 |
from youtube_transcript_api._errors import (
|
| 29 |
NoTranscriptFound,
|
|
|
|
| 48 |
csv_reader = csv.reader(csvfile)
|
| 49 |
csv_data = [row for row in csv_reader]
|
| 50 |
|
| 51 |
+
return ' '.join([' '.join(row) for row in csv_data])
|
|
|
|
|
|
|
| 52 |
|
| 53 |
|
| 54 |
def read_text(file_path):
|
|
|
|
| 80 |
doc = docx.Document(file_path)
|
| 81 |
|
| 82 |
return '\n'.join(
|
| 83 |
+
[paragraph.text for paragraph in doc.paragraphs]
|
|
|
|
| 84 |
)
|
| 85 |
|
| 86 |
|
|
|
|
| 104 |
for row in sheet.iter_rows(values_only=True):
|
| 105 |
text_data += (
|
| 106 |
' '.join(
|
| 107 |
+
[str(cell) for cell in row if cell is not None]
|
|
|
|
|
|
|
| 108 |
)
|
| 109 |
+ '\n'
|
| 110 |
)
|
|
|
|
| 116 |
with open(file_path, 'r', encoding='utf-8') as f:
|
| 117 |
json_data = json.load(f)
|
| 118 |
|
| 119 |
+
return json.dumps(json_data, ensure_ascii=False)
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
|
| 122 |
def read_html(file_path):
|
|
|
|
| 148 |
)
|
| 149 |
|
| 150 |
|
| 151 |
+
def extract_youtube_video_id(url):
|
| 152 |
if not url:
|
| 153 |
+
return None
|
| 154 |
|
| 155 |
url = str(url).strip()
|
| 156 |
|
| 157 |
url = url.replace('\\n', '')
|
| 158 |
url = url.replace('\n', '')
|
| 159 |
+
url = url.replace('\\', '')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
markdown_match = re.search(
|
| 162 |
+
r'\]\(\s*(https?://[^)\s]+)',
|
| 163 |
+
url,
|
| 164 |
+
flags=re.IGNORECASE
|
| 165 |
)
|
| 166 |
|
| 167 |
if markdown_match:
|
| 168 |
url = markdown_match.group(1)
|
| 169 |
|
| 170 |
+
url_match = re.search(
|
| 171 |
+
r'https?://(?:www\.)?(?:youtube\.com|youtu\.be)[^\s<>"\']+',
|
| 172 |
+
url,
|
| 173 |
+
flags=re.IGNORECASE
|
|
|
|
|
|
|
| 174 |
)
|
| 175 |
|
| 176 |
+
if url_match:
|
| 177 |
+
url = url_match.group(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
+
url = url.rstrip('.,!?;:)]}')
|
| 180 |
|
| 181 |
parsed = urlparse(url)
|
| 182 |
+
|
| 183 |
hostname = (
|
| 184 |
parsed.hostname or ''
|
| 185 |
).lower()
|
|
|
|
| 194 |
.split('/')[0]
|
| 195 |
)
|
| 196 |
|
| 197 |
+
return video_id or None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
|
| 199 |
if hostname in (
|
| 200 |
'youtube.com',
|
|
|
|
| 203 |
):
|
| 204 |
|
| 205 |
if parsed.path == '/watch':
|
| 206 |
+
|
| 207 |
video_ids = parse_qs(
|
| 208 |
parsed.query
|
| 209 |
).get('v')
|
| 210 |
|
| 211 |
+
if video_ids:
|
|
|
|
|
|
|
|
|
|
| 212 |
|
| 213 |
+
video_id = (
|
| 214 |
+
video_ids[0]
|
| 215 |
+
.split('&')[0]
|
| 216 |
+
.strip()
|
| 217 |
+
)
|
| 218 |
|
| 219 |
+
return video_id or None
|
| 220 |
|
| 221 |
for prefix in (
|
| 222 |
'/shorts/',
|
| 223 |
'/embed/',
|
| 224 |
'/live/'
|
| 225 |
):
|
| 226 |
+
|
| 227 |
if parsed.path.startswith(prefix):
|
| 228 |
+
|
| 229 |
video_id = (
|
| 230 |
parsed.path[
|
| 231 |
len(prefix):
|
| 232 |
]
|
| 233 |
.split('/')[0]
|
| 234 |
+
.strip()
|
| 235 |
)
|
| 236 |
|
| 237 |
+
return video_id or None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
|
| 239 |
return None
|
| 240 |
|
|
|
|
| 246 |
)
|
| 247 |
|
| 248 |
|
| 249 |
+
youtube_session = requests.Session()
|
| 250 |
+
|
| 251 |
+
youtube_session.headers.update({
|
| 252 |
+
'User-Agent': (
|
| 253 |
+
'Mozilla/5.0 '
|
| 254 |
+
'(X11; Linux x86_64) '
|
| 255 |
+
'AppleWebKit/537.36 '
|
| 256 |
+
'(KHTML, like Gecko) '
|
| 257 |
+
'Chrome/131.0.0.0 Safari/537.36'
|
| 258 |
+
),
|
| 259 |
+
'Accept-Language': 'en-US,en;q=0.9',
|
| 260 |
+
'Accept': (
|
| 261 |
+
'text/html,application/xhtml+xml,'
|
| 262 |
+
'application/xml;q=0.9,image/avif,'
|
| 263 |
+
'image/webp,*/*;q=0.8'
|
| 264 |
+
),
|
| 265 |
+
'Connection': 'close',
|
| 266 |
+
})
|
| 267 |
+
|
| 268 |
+
retry_strategy = Retry(
|
| 269 |
+
total=3,
|
| 270 |
+
connect=3,
|
| 271 |
+
read=3,
|
| 272 |
+
backoff_factor=1,
|
| 273 |
+
status_forcelist=[429, 500, 502, 503, 504],
|
| 274 |
+
allowed_methods=[
|
| 275 |
+
'GET',
|
| 276 |
+
'HEAD'
|
| 277 |
+
]
|
| 278 |
+
)
|
| 279 |
+
|
| 280 |
+
youtube_adapter = HTTPAdapter(
|
| 281 |
+
max_retries=retry_strategy
|
| 282 |
+
)
|
| 283 |
+
|
| 284 |
+
youtube_session.mount(
|
| 285 |
+
'https://',
|
| 286 |
+
youtube_adapter
|
| 287 |
+
)
|
| 288 |
+
|
| 289 |
+
youtube_session.mount(
|
| 290 |
+
'http://',
|
| 291 |
+
youtube_adapter
|
| 292 |
+
)
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
ytt_api = YouTubeTranscriptApi(
|
| 296 |
+
http_client=youtube_session
|
| 297 |
+
)
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
def fetch_transcript_text(video_id):
|
| 301 |
+
try:
|
| 302 |
+
|
| 303 |
+
print(
|
| 304 |
+
'FETCHING YOUTUBE TRANSCRIPT:',
|
| 305 |
+
repr(video_id)
|
| 306 |
)
|
| 307 |
|
| 308 |
+
transcript = ytt_api.fetch(
|
| 309 |
+
video_id,
|
| 310 |
+
languages=['en', 'ar']
|
| 311 |
+
)
|
| 312 |
+
|
| 313 |
+
if hasattr(
|
| 314 |
+
transcript,
|
| 315 |
+
'snippets'
|
| 316 |
+
):
|
| 317 |
+
|
| 318 |
+
return ' '.join(
|
| 319 |
+
snippet.text
|
| 320 |
+
for snippet in transcript.snippets
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
return ' '.join(
|
| 324 |
+
snippet.text
|
| 325 |
+
for snippet in transcript
|
| 326 |
)
|
| 327 |
|
| 328 |
+
except (
|
| 329 |
+
NoTranscriptFound,
|
| 330 |
+
TranscriptsDisabled,
|
| 331 |
+
VideoUnavailable
|
| 332 |
+
):
|
| 333 |
|
| 334 |
+
raise
|
|
|
|
|
|
|
|
|
|
| 335 |
|
| 336 |
+
except Exception as e:
|
|
|
|
|
|
|
|
|
|
| 337 |
|
| 338 |
+
print(
|
| 339 |
+
'YOUTUBE FETCH ERROR:',
|
| 340 |
+
repr(e)
|
| 341 |
+
)
|
| 342 |
|
| 343 |
+
raise
|
| 344 |
+
|
| 345 |
+
|
| 346 |
+
def process_youtube_video(url):
|
| 347 |
video_id = extract_youtube_video_id(url)
|
| 348 |
|
| 349 |
if not video_id:
|
| 350 |
+
|
| 351 |
return (
|
| 352 |
'Invalid YouTube video URL. '
|
| 353 |
'Please provide a valid YouTube video link.'
|
|
|
|
| 358 |
repr(video_id)
|
| 359 |
)
|
| 360 |
|
| 361 |
+
try:
|
|
|
|
| 362 |
|
| 363 |
+
transcript = fetch_transcript_text(
|
| 364 |
+
video_id
|
| 365 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
+
if transcript:
|
|
|
|
|
|
|
|
|
|
| 368 |
|
| 369 |
+
return transcript
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
|
| 371 |
+
return (
|
| 372 |
+
'The YouTube transcript was retrieved '
|
| 373 |
+
'but contains no readable text.'
|
| 374 |
+
)
|
| 375 |
|
| 376 |
+
except NoTranscriptFound:
|
| 377 |
|
| 378 |
+
return (
|
| 379 |
+
'No English or Arabic transcript '
|
| 380 |
+
'was found for this YouTube video.'
|
| 381 |
+
)
|
| 382 |
|
| 383 |
+
except TranscriptsDisabled:
|
|
|
|
|
|
|
| 384 |
|
| 385 |
+
return (
|
| 386 |
+
'Transcripts are disabled for this '
|
| 387 |
+
'YouTube video.'
|
| 388 |
)
|
| 389 |
|
| 390 |
+
except VideoUnavailable:
|
|
|
|
|
|
|
|
|
|
| 391 |
|
| 392 |
+
return (
|
| 393 |
+
'The YouTube video is unavailable.'
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
except Exception as e:
|
| 397 |
+
|
| 398 |
+
print(
|
| 399 |
+
'YOUTUBE TRANSCRIPT ERROR:',
|
| 400 |
+
repr(e)
|
| 401 |
+
)
|
| 402 |
+
|
| 403 |
+
return (
|
| 404 |
+
'Unable to retrieve the YouTube transcript '
|
| 405 |
+
'because the server could not establish a '
|
| 406 |
+
'successful connection with YouTube.\n\n'
|
| 407 |
+
f'Error: {str(e)}'
|
| 408 |
+
)
|
| 409 |
|
| 410 |
|
| 411 |
def read_web_page(url):
|
| 412 |
+
|
| 413 |
try:
|
| 414 |
+
|
| 415 |
+
url = str(url).strip()
|
| 416 |
|
| 417 |
response = requests.get(
|
| 418 |
url,
|
|
|
|
| 430 |
)
|
| 431 |
|
| 432 |
if response.status_code >= 400:
|
| 433 |
+
|
| 434 |
return (
|
| 435 |
'Unable to access webpage. '
|
| 436 |
f'HTTP status: {response.status_code}'
|
|
|
|
| 443 |
)
|
| 444 |
|
| 445 |
if 'text/plain' in content_type:
|
| 446 |
+
|
| 447 |
return response.text
|
| 448 |
|
| 449 |
src = response.text
|
|
|
|
| 459 |
'noscript',
|
| 460 |
'svg'
|
| 461 |
]):
|
| 462 |
+
|
| 463 |
element.decompose()
|
| 464 |
|
| 465 |
text_data = soup.get_text(
|
|
|
|
| 473 |
)
|
| 474 |
|
| 475 |
if not text_data:
|
| 476 |
+
|
| 477 |
return (
|
| 478 |
+
'The webpage was accessed successfully '
|
| 479 |
+
'but contains no readable text.'
|
|
|
|
| 480 |
)
|
| 481 |
|
| 482 |
return text_data
|
| 483 |
|
| 484 |
except requests.exceptions.Timeout:
|
| 485 |
+
|
| 486 |
return (
|
| 487 |
'The webpage request timed out. '
|
| 488 |
'Please try another link.'
|
| 489 |
)
|
| 490 |
|
| 491 |
except requests.exceptions.RequestException as e:
|
| 492 |
+
|
| 493 |
+
return f'Unable to access webpage: {e}'
|
|
|
|
| 494 |
|
| 495 |
except Exception as e:
|
| 496 |
+
|
| 497 |
return (
|
| 498 |
'An error occurred while reading '
|
| 499 |
f'the webpage: {e}'
|
|
|
|
| 504 |
file_path_or_url,
|
| 505 |
languages=['en', 'ar']
|
| 506 |
):
|
| 507 |
+
|
| 508 |
if not file_path_or_url:
|
| 509 |
+
|
| 510 |
return 'Unsupported type or format.'
|
| 511 |
|
| 512 |
file_path_or_url = str(
|
|
|
|
| 516 |
if is_youtube_url(
|
| 517 |
file_path_or_url
|
| 518 |
):
|
| 519 |
+
|
| 520 |
return process_youtube_video(
|
| 521 |
+
file_path_or_url
|
|
|
|
| 522 |
)
|
| 523 |
|
| 524 |
if file_path_or_url.startswith(
|
| 525 |
('http://', 'https://')
|
| 526 |
):
|
| 527 |
+
|
| 528 |
return read_web_page(
|
| 529 |
file_path_or_url
|
| 530 |
)
|
|
|
|
| 534 |
)
|
| 535 |
|
| 536 |
if lower_path.endswith('.csv'):
|
| 537 |
+
|
| 538 |
return read_csv(
|
| 539 |
file_path_or_url
|
| 540 |
)
|
| 541 |
|
| 542 |
elif lower_path.endswith('.txt'):
|
| 543 |
+
|
| 544 |
return read_text(
|
| 545 |
file_path_or_url
|
| 546 |
)
|
| 547 |
|
| 548 |
elif lower_path.endswith('.pdf'):
|
| 549 |
+
|
| 550 |
return read_pdf(
|
| 551 |
file_path_or_url
|
| 552 |
)
|
| 553 |
|
| 554 |
elif lower_path.endswith('.docx'):
|
| 555 |
+
|
| 556 |
return read_docx(
|
| 557 |
file_path_or_url
|
| 558 |
)
|
| 559 |
|
| 560 |
elif lower_path.endswith('.pptx'):
|
| 561 |
+
|
| 562 |
return read_pptx(
|
| 563 |
file_path_or_url
|
| 564 |
)
|
| 565 |
|
| 566 |
elif lower_path.endswith('.xlsx'):
|
| 567 |
+
|
| 568 |
return read_xlsx(
|
| 569 |
file_path_or_url
|
| 570 |
)
|
| 571 |
|
| 572 |
elif lower_path.endswith('.json'):
|
| 573 |
+
|
| 574 |
return read_json(
|
| 575 |
file_path_or_url
|
| 576 |
)
|
| 577 |
|
| 578 |
elif lower_path.endswith('.html'):
|
| 579 |
+
|
| 580 |
return read_html(
|
| 581 |
file_path_or_url
|
| 582 |
)
|
| 583 |
|
| 584 |
elif lower_path.endswith('.xml'):
|
| 585 |
+
|
| 586 |
return read_xml(
|
| 587 |
file_path_or_url
|
| 588 |
)
|
|
|
|
| 591 |
|
| 592 |
|
| 593 |
def normalize_text(text):
|
| 594 |
+
|
| 595 |
+
if not isinstance(
|
| 596 |
+
text,
|
| 597 |
+
str
|
| 598 |
+
):
|
| 599 |
+
|
| 600 |
text = str(text)
|
| 601 |
|
| 602 |
text = re.sub(
|
| 603 |
+
r'\\n',
|
| 604 |
+
' ',
|
| 605 |
+
text
|
| 606 |
+
)
|
| 607 |
+
|
| 608 |
+
text = re.sub(
|
| 609 |
+
r'\\',
|
| 610 |
'',
|
| 611 |
text
|
| 612 |
)
|
|
|
|
| 619 |
)
|
| 620 |
|
| 621 |
for punc in punctuation:
|
| 622 |
+
|
| 623 |
text = text.replace(
|
| 624 |
punc,
|
| 625 |
''
|
|
|
|
| 631 |
text
|
| 632 |
)
|
| 633 |
|
| 634 |
+
words = word_tokenize(
|
| 635 |
+
text
|
| 636 |
+
)
|
| 637 |
|
| 638 |
return ' '.join(words)
|
| 639 |
|
|
|
|
| 649 |
do_sample=True,
|
| 650 |
)
|
| 651 |
|
| 652 |
+
|
| 653 |
chat_model = ChatHuggingFace(
|
| 654 |
llm=llm
|
| 655 |
)
|
| 656 |
|
| 657 |
+
|
| 658 |
model_name = (
|
| 659 |
'sentence-transformers/all-mpnet-base-v2'
|
| 660 |
)
|
| 661 |
|
| 662 |
+
|
| 663 |
embedding_llm = HuggingFaceEmbeddings(
|
| 664 |
model_name=model_name
|
| 665 |
)
|
| 666 |
|
| 667 |
+
|
| 668 |
db = FAISS.load_local(
|
| 669 |
'faiss_index',
|
| 670 |
embedding_llm,
|
|
|
|
| 672 |
)
|
| 673 |
|
| 674 |
|
| 675 |
+
def print_like_dislike(
|
| 676 |
+
x: gr.LikeData
|
| 677 |
+
):
|
| 678 |
+
|
| 679 |
print(
|
| 680 |
x.index,
|
| 681 |
x.value,
|
|
|
|
| 687 |
user_message,
|
| 688 |
history
|
| 689 |
):
|
| 690 |
+
|
| 691 |
if not len(user_message):
|
| 692 |
+
|
| 693 |
raise gr.Error(
|
| 694 |
'Chat messages cannot be empty'
|
| 695 |
)
|
|
|
|
| 707 |
history,
|
| 708 |
link
|
| 709 |
):
|
| 710 |
+
|
| 711 |
+
if (
|
| 712 |
+
not len(user_message)
|
| 713 |
+
or not len(link)
|
| 714 |
+
):
|
| 715 |
+
|
| 716 |
raise gr.Error(
|
| 717 |
'Chat messages or links cannot be empty'
|
| 718 |
)
|
| 719 |
|
| 720 |
+
link = str(link).strip()
|
| 721 |
user_message = str(
|
| 722 |
user_message
|
| 723 |
).strip()
|
| 724 |
|
| 725 |
+
combined_message = (
|
| 726 |
+
f'URL: {link}\n'
|
| 727 |
+
f'QUESTION: {user_message}'
|
| 728 |
+
)
|
| 729 |
|
| 730 |
history.append({
|
| 731 |
'role': 'user',
|
| 732 |
+
'content': combined_message
|
| 733 |
})
|
| 734 |
|
| 735 |
return '', history, link
|
|
|
|
| 740 |
history,
|
| 741 |
file_path
|
| 742 |
):
|
| 743 |
+
|
| 744 |
+
if (
|
| 745 |
+
not len(user_message)
|
| 746 |
+
or not file_path
|
| 747 |
+
):
|
| 748 |
+
|
| 749 |
raise gr.Error(
|
| 750 |
'Chat messages or files cannot be empty'
|
| 751 |
)
|
| 752 |
|
| 753 |
combined_message = (
|
| 754 |
+
f'{file_path}\n'
|
| 755 |
+
f'{user_message}'
|
| 756 |
)
|
| 757 |
|
| 758 |
history.append({
|
|
|
|
| 783 |
history,
|
| 784 |
messages1
|
| 785 |
):
|
| 786 |
+
|
| 787 |
user_msg_text = history[-1]['content']
|
| 788 |
|
| 789 |
message = HumanMessage(
|
|
|
|
| 794 |
messages1[-1],
|
| 795 |
HumanMessage
|
| 796 |
):
|
| 797 |
+
|
| 798 |
messages1 = messages1[:-2]
|
| 799 |
|
| 800 |
+
messages1.append(
|
| 801 |
+
message
|
| 802 |
+
)
|
| 803 |
|
| 804 |
if len(messages1) >= 8:
|
| 805 |
+
|
| 806 |
messages1 = messages1[-8:]
|
| 807 |
|
| 808 |
try:
|
| 809 |
+
|
| 810 |
response = chat_model.invoke(
|
| 811 |
messages1
|
| 812 |
)
|
| 813 |
|
| 814 |
except Exception as e:
|
| 815 |
+
|
| 816 |
error_message = str(e)
|
| 817 |
|
| 818 |
print(
|
|
|
|
| 820 |
repr(e)
|
| 821 |
)
|
| 822 |
|
| 823 |
+
start_index = (
|
| 824 |
+
error_message.find(
|
| 825 |
+
'Input validation error:'
|
| 826 |
+
)
|
| 827 |
)
|
| 828 |
|
| 829 |
+
end_index = (
|
| 830 |
+
error_message.find(
|
| 831 |
+
'and 4096 `max_new_tokens`'
|
| 832 |
+
)
|
| 833 |
)
|
| 834 |
|
| 835 |
if (
|
| 836 |
start_index != -1
|
| 837 |
and end_index != -1
|
| 838 |
):
|
| 839 |
+
|
| 840 |
raise gr.Error(
|
| 841 |
error_message[
|
| 842 |
start_index:end_index
|
|
|
|
| 859 |
})
|
| 860 |
|
| 861 |
for character in response.content:
|
| 862 |
+
|
| 863 |
history[-1]['content'] += character
|
| 864 |
|
| 865 |
+
time.sleep(
|
| 866 |
+
0.0025
|
| 867 |
+
)
|
| 868 |
|
| 869 |
yield history, messages1
|
| 870 |
|
|
|
|
| 873 |
history,
|
| 874 |
messages2
|
| 875 |
):
|
| 876 |
+
|
| 877 |
message = str(
|
| 878 |
history[-1]['content']
|
| 879 |
)
|
|
|
|
| 882 |
messages2[-1],
|
| 883 |
HumanMessage
|
| 884 |
):
|
| 885 |
+
|
| 886 |
messages2 = messages2[:-2]
|
| 887 |
|
| 888 |
similar_docs = db.similarity_search(
|
|
|
|
| 891 |
)
|
| 892 |
|
| 893 |
if similar_docs:
|
| 894 |
+
|
| 895 |
source_knowledge = '\n'.join(
|
| 896 |
+
[
|
| 897 |
+
x.page_content
|
| 898 |
+
for x in similar_docs
|
| 899 |
+
]
|
| 900 |
)
|
| 901 |
+
|
| 902 |
else:
|
| 903 |
+
|
| 904 |
source_knowledge = ''
|
| 905 |
|
| 906 |
augmented_prompt = f"""
|
|
|
|
| 925 |
content=augmented_prompt
|
| 926 |
)
|
| 927 |
|
| 928 |
+
messages2.append(
|
| 929 |
+
msg
|
| 930 |
+
)
|
| 931 |
|
| 932 |
if len(messages2) >= 4:
|
| 933 |
+
|
| 934 |
messages2 = messages2[-4:]
|
| 935 |
|
| 936 |
try:
|
| 937 |
+
|
| 938 |
response = chat_model.invoke(
|
| 939 |
messages2
|
| 940 |
)
|
| 941 |
|
| 942 |
except Exception as e:
|
| 943 |
+
|
| 944 |
error_message = str(e)
|
| 945 |
|
| 946 |
print(
|
|
|
|
| 948 |
repr(e)
|
| 949 |
)
|
| 950 |
|
| 951 |
+
start_index = (
|
| 952 |
+
error_message.find(
|
| 953 |
+
'Input validation error:'
|
| 954 |
+
)
|
| 955 |
)
|
| 956 |
|
| 957 |
+
end_index = (
|
| 958 |
+
error_message.find(
|
| 959 |
+
'and 4096 `max_new_tokens`'
|
| 960 |
+
)
|
| 961 |
)
|
| 962 |
|
| 963 |
if (
|
| 964 |
start_index != -1
|
| 965 |
and end_index != -1
|
| 966 |
):
|
| 967 |
+
|
| 968 |
raise gr.Error(
|
| 969 |
error_message[
|
| 970 |
start_index:end_index
|
|
|
|
| 987 |
})
|
| 988 |
|
| 989 |
for character in response.content:
|
| 990 |
+
|
| 991 |
history[-1]['content'] += character
|
| 992 |
|
| 993 |
+
time.sleep(
|
| 994 |
+
0.0025
|
| 995 |
+
)
|
| 996 |
|
| 997 |
yield history, messages2
|
| 998 |
|
|
|
|
| 1000 |
def generate_chart_config(
|
| 1001 |
description
|
| 1002 |
):
|
| 1003 |
+
|
| 1004 |
system_instructions = """
|
| 1005 |
You are a Chart.js configuration generator.
|
| 1006 |
|
|
|
|
| 1092 |
start = raw.find('{')
|
| 1093 |
end = raw.rfind('}')
|
| 1094 |
|
| 1095 |
+
if (
|
| 1096 |
+
start == -1
|
| 1097 |
+
or end == -1
|
| 1098 |
+
):
|
| 1099 |
+
|
| 1100 |
raise ValueError(
|
| 1101 |
'Model did not return a JSON object.\n'
|
| 1102 |
f'Raw response:\n{raw}'
|
|
|
|
| 1111 |
raw
|
| 1112 |
)
|
| 1113 |
|
| 1114 |
+
config = json.loads(
|
| 1115 |
+
raw
|
| 1116 |
+
)
|
| 1117 |
|
| 1118 |
if 'type' not in config:
|
| 1119 |
+
|
| 1120 |
raise ValueError(
|
| 1121 |
"Chart config missing 'type'"
|
| 1122 |
)
|
| 1123 |
|
| 1124 |
if 'data' not in config:
|
| 1125 |
+
|
| 1126 |
raise ValueError(
|
| 1127 |
"Chart config missing 'data'"
|
| 1128 |
)
|
| 1129 |
|
| 1130 |
if 'labels' not in config['data']:
|
| 1131 |
+
|
| 1132 |
raise ValueError(
|
| 1133 |
"Chart config missing 'data.labels'"
|
| 1134 |
)
|
| 1135 |
|
| 1136 |
if 'datasets' not in config['data']:
|
| 1137 |
+
|
| 1138 |
raise ValueError(
|
| 1139 |
"Chart config missing 'data.datasets'"
|
| 1140 |
)
|
|
|
|
| 1143 |
config['data']['datasets'],
|
| 1144 |
list
|
| 1145 |
):
|
| 1146 |
+
|
| 1147 |
raise ValueError(
|
| 1148 |
"'data.datasets' must be a list"
|
| 1149 |
)
|
|
|
|
| 1155 |
history,
|
| 1156 |
messages3
|
| 1157 |
):
|
| 1158 |
+
|
| 1159 |
message = str(
|
| 1160 |
history[-1]['content']
|
| 1161 |
)
|
|
|
|
| 1164 |
messages3[-1],
|
| 1165 |
HumanMessage
|
| 1166 |
):
|
| 1167 |
+
|
| 1168 |
messages3 = messages3[:-2]
|
| 1169 |
|
| 1170 |
if '#chart' in message.lower():
|
|
|
|
| 1177 |
)[1].strip()
|
| 1178 |
|
| 1179 |
if not chart_description:
|
| 1180 |
+
|
| 1181 |
combined_content = (
|
| 1182 |
'Please provide chart details after #chart.'
|
| 1183 |
)
|
| 1184 |
|
| 1185 |
else:
|
| 1186 |
+
|
| 1187 |
chart_config = None
|
| 1188 |
|
| 1189 |
try:
|
| 1190 |
+
|
| 1191 |
chart_config = (
|
| 1192 |
generate_chart_config(
|
| 1193 |
chart_description
|
|
|
|
| 1203 |
)
|
| 1204 |
|
| 1205 |
except Exception as e:
|
| 1206 |
+
|
| 1207 |
print(
|
| 1208 |
'CHART GENERATION ERROR:',
|
| 1209 |
repr(e)
|
|
|
|
| 1214 |
f'Error: {str(e)}'
|
| 1215 |
)
|
| 1216 |
|
|
|
|
|
|
|
| 1217 |
if chart_config:
|
| 1218 |
+
|
| 1219 |
try:
|
| 1220 |
+
|
| 1221 |
config_json = json.dumps(
|
| 1222 |
chart_config,
|
| 1223 |
separators=(',', ':')
|
|
|
|
| 1251 |
chart_response.status_code
|
| 1252 |
)
|
| 1253 |
|
| 1254 |
+
if (
|
| 1255 |
+
chart_response.status_code
|
| 1256 |
+
!= 200
|
| 1257 |
+
):
|
| 1258 |
+
|
| 1259 |
print(
|
| 1260 |
'QUICKCHART RESPONSE:',
|
| 1261 |
chart_response.text[:1000]
|
| 1262 |
)
|
| 1263 |
|
| 1264 |
combined_content = (
|
| 1265 |
+
'QuickChart failed to generate '
|
| 1266 |
+
'the chart.\n\n'
|
| 1267 |
f'HTTP Status: '
|
| 1268 |
f'{chart_response.status_code}'
|
| 1269 |
)
|
| 1270 |
|
| 1271 |
else:
|
| 1272 |
+
|
| 1273 |
image_html = (
|
| 1274 |
f'<img src="{chart_url}" '
|
| 1275 |
'alt="Generated Chart" '
|
|
|
|
| 1280 |
)
|
| 1281 |
|
| 1282 |
chart_summary_prompt = (
|
| 1283 |
+
'The following Chart.js configuration '
|
| 1284 |
+
'was generated:\n\n'
|
| 1285 |
f'{json.dumps(chart_config, indent=2)}\n\n'
|
| 1286 |
'Briefly describe what this chart '
|
| 1287 |
'represents.'
|
|
|
|
| 1301 |
]
|
| 1302 |
|
| 1303 |
try:
|
| 1304 |
+
|
| 1305 |
response = (
|
| 1306 |
chat_model.invoke(
|
| 1307 |
analysis_messages
|
|
|
|
| 1313 |
)
|
| 1314 |
|
| 1315 |
except Exception as e:
|
| 1316 |
+
|
| 1317 |
print(
|
| 1318 |
'CHART ANALYSIS ERROR:',
|
| 1319 |
repr(e)
|
|
|
|
| 1329 |
)
|
| 1330 |
|
| 1331 |
except Exception as e:
|
| 1332 |
+
|
| 1333 |
print(
|
| 1334 |
'QUICKCHART REQUEST ERROR:',
|
| 1335 |
repr(e)
|
|
|
|
| 1342 |
)
|
| 1343 |
|
| 1344 |
else:
|
| 1345 |
+
|
| 1346 |
prompt = HumanMessage(
|
| 1347 |
content=message
|
| 1348 |
)
|
| 1349 |
|
| 1350 |
+
messages3.append(
|
| 1351 |
+
prompt
|
| 1352 |
+
)
|
| 1353 |
|
| 1354 |
if len(messages3) >= 6:
|
| 1355 |
+
|
| 1356 |
messages3 = messages3[-6:]
|
| 1357 |
|
| 1358 |
try:
|
| 1359 |
+
|
| 1360 |
response = chat_model.invoke(
|
| 1361 |
messages3
|
| 1362 |
)
|
| 1363 |
|
| 1364 |
except Exception as e:
|
| 1365 |
+
|
| 1366 |
error_message = str(e)
|
| 1367 |
|
| 1368 |
print(
|
|
|
|
| 1370 |
repr(e)
|
| 1371 |
)
|
| 1372 |
|
| 1373 |
+
start_index = (
|
| 1374 |
+
error_message.find(
|
| 1375 |
+
'Input validation error:'
|
| 1376 |
+
)
|
| 1377 |
)
|
| 1378 |
|
| 1379 |
+
end_index = (
|
| 1380 |
+
error_message.find(
|
| 1381 |
+
'and 4096 `max_new_tokens`'
|
| 1382 |
+
)
|
| 1383 |
)
|
| 1384 |
|
| 1385 |
if (
|
| 1386 |
start_index != -1
|
| 1387 |
and end_index != -1
|
| 1388 |
):
|
| 1389 |
+
|
| 1390 |
raise gr.Error(
|
| 1391 |
error_message[
|
| 1392 |
start_index:end_index
|
|
|
|
| 1403 |
)
|
| 1404 |
)
|
| 1405 |
|
| 1406 |
+
combined_content = (
|
| 1407 |
+
response.content
|
| 1408 |
+
)
|
| 1409 |
|
| 1410 |
history.append({
|
| 1411 |
'role': 'assistant',
|
|
|
|
| 1413 |
})
|
| 1414 |
|
| 1415 |
for character in combined_content:
|
| 1416 |
+
|
| 1417 |
history[-1]['content'] += character
|
| 1418 |
|
| 1419 |
+
time.sleep(
|
| 1420 |
+
0.0025
|
| 1421 |
+
)
|
| 1422 |
|
| 1423 |
yield history, messages3
|
| 1424 |
|
| 1425 |
|
| 1426 |
def extract_url_from_text(text):
|
| 1427 |
+
|
| 1428 |
if not text:
|
| 1429 |
+
|
| 1430 |
return None
|
| 1431 |
|
| 1432 |
+
if isinstance(
|
| 1433 |
+
text,
|
| 1434 |
+
list
|
| 1435 |
+
):
|
| 1436 |
+
|
| 1437 |
+
parts = []
|
| 1438 |
|
| 1439 |
+
for item in text:
|
| 1440 |
+
|
| 1441 |
+
if isinstance(
|
| 1442 |
+
item,
|
| 1443 |
+
dict
|
| 1444 |
+
):
|
| 1445 |
+
|
| 1446 |
+
value = item.get(
|
| 1447 |
+
'text',
|
| 1448 |
+
''
|
| 1449 |
+
)
|
| 1450 |
+
|
| 1451 |
+
parts.append(
|
| 1452 |
+
str(value)
|
| 1453 |
+
)
|
| 1454 |
+
|
| 1455 |
+
else:
|
| 1456 |
+
|
| 1457 |
+
parts.append(
|
| 1458 |
+
str(item)
|
| 1459 |
+
)
|
| 1460 |
+
|
| 1461 |
+
text = ' '.join(parts)
|
| 1462 |
+
|
| 1463 |
+
elif isinstance(
|
| 1464 |
+
text,
|
| 1465 |
+
dict
|
| 1466 |
+
):
|
| 1467 |
+
|
| 1468 |
+
text = str(
|
| 1469 |
+
text.get(
|
| 1470 |
+
'text',
|
| 1471 |
+
''
|
| 1472 |
+
)
|
| 1473 |
+
)
|
| 1474 |
+
|
| 1475 |
+
else:
|
| 1476 |
+
|
| 1477 |
+
text = str(text)
|
| 1478 |
|
| 1479 |
text = text.replace(
|
| 1480 |
+
'\\n',
|
| 1481 |
+
' '
|
| 1482 |
)
|
| 1483 |
|
| 1484 |
text = text.replace(
|
|
|
|
| 1486 |
''
|
| 1487 |
)
|
| 1488 |
|
| 1489 |
+
markdown_matches = re.findall(
|
| 1490 |
+
r'\]\(\s*(https?://[^)\s]+)',
|
| 1491 |
+
text,
|
| 1492 |
+
flags=re.IGNORECASE
|
| 1493 |
)
|
| 1494 |
|
| 1495 |
+
if markdown_matches:
|
| 1496 |
+
|
| 1497 |
+
return markdown_matches[0].rstrip(
|
| 1498 |
+
'.,!?;:)]}'
|
|
|
|
| 1499 |
)
|
| 1500 |
|
| 1501 |
+
url_matches = re.findall(
|
| 1502 |
r'https?://[^\s<>"\']+',
|
| 1503 |
+
text,
|
| 1504 |
+
flags=re.IGNORECASE
|
| 1505 |
)
|
| 1506 |
|
| 1507 |
+
if url_matches:
|
| 1508 |
+
|
| 1509 |
+
url = url_matches[0]
|
| 1510 |
+
|
| 1511 |
+
return url.rstrip(
|
| 1512 |
+
'.,!?;:)]}'
|
| 1513 |
)
|
| 1514 |
|
| 1515 |
return None
|
| 1516 |
|
| 1517 |
|
| 1518 |
+
def extract_user_query_from_link_message(
|
| 1519 |
+
content,
|
| 1520 |
+
link
|
| 1521 |
+
):
|
| 1522 |
+
|
| 1523 |
+
if isinstance(
|
| 1524 |
+
content,
|
| 1525 |
+
list
|
| 1526 |
+
):
|
| 1527 |
+
|
| 1528 |
+
parts = []
|
| 1529 |
+
|
| 1530 |
+
for item in content:
|
| 1531 |
+
|
| 1532 |
+
if isinstance(
|
| 1533 |
+
item,
|
| 1534 |
+
dict
|
| 1535 |
+
):
|
| 1536 |
+
|
| 1537 |
+
parts.append(
|
| 1538 |
+
str(
|
| 1539 |
+
item.get(
|
| 1540 |
+
'text',
|
| 1541 |
+
''
|
| 1542 |
+
)
|
| 1543 |
+
)
|
| 1544 |
+
)
|
| 1545 |
+
|
| 1546 |
+
else:
|
| 1547 |
+
|
| 1548 |
+
parts.append(
|
| 1549 |
+
str(item)
|
| 1550 |
+
)
|
| 1551 |
+
|
| 1552 |
+
content = ' '.join(parts)
|
| 1553 |
+
|
| 1554 |
+
elif isinstance(
|
| 1555 |
+
content,
|
| 1556 |
+
dict
|
| 1557 |
+
):
|
| 1558 |
+
|
| 1559 |
+
content = str(
|
| 1560 |
+
content.get(
|
| 1561 |
+
'text',
|
| 1562 |
+
''
|
| 1563 |
+
)
|
| 1564 |
+
)
|
| 1565 |
+
|
| 1566 |
+
else:
|
| 1567 |
+
|
| 1568 |
+
content = str(content)
|
| 1569 |
+
|
| 1570 |
+
content = content.replace(
|
| 1571 |
+
'\\n',
|
| 1572 |
+
'\n'
|
| 1573 |
+
)
|
| 1574 |
+
|
| 1575 |
+
content = content.replace(
|
| 1576 |
+
'\\',
|
| 1577 |
+
''
|
| 1578 |
+
)
|
| 1579 |
+
|
| 1580 |
+
content = content.strip()
|
| 1581 |
+
|
| 1582 |
+
question_match = re.search(
|
| 1583 |
+
r'QUESTION\s*:\s*(.*)$',
|
| 1584 |
+
content,
|
| 1585 |
+
flags=re.IGNORECASE | re.DOTALL
|
| 1586 |
+
)
|
| 1587 |
+
|
| 1588 |
+
if question_match:
|
| 1589 |
+
|
| 1590 |
+
return question_match.group(
|
| 1591 |
+
1
|
| 1592 |
+
).strip()
|
| 1593 |
+
|
| 1594 |
+
if link:
|
| 1595 |
+
|
| 1596 |
+
question = content.replace(
|
| 1597 |
+
link,
|
| 1598 |
+
''
|
| 1599 |
+
)
|
| 1600 |
+
|
| 1601 |
+
question = re.sub(
|
| 1602 |
+
r'URL\s*:\s*',
|
| 1603 |
+
'',
|
| 1604 |
+
question,
|
| 1605 |
+
flags=re.IGNORECASE
|
| 1606 |
+
)
|
| 1607 |
+
|
| 1608 |
+
return question.strip()
|
| 1609 |
+
|
| 1610 |
+
return content
|
| 1611 |
+
|
| 1612 |
+
|
| 1613 |
def Link_Scratch(
|
| 1614 |
history,
|
| 1615 |
+
messages4
|
|
|
|
| 1616 |
):
|
|
|
|
|
|
|
|
|
|
| 1617 |
|
| 1618 |
+
combined_message = (
|
| 1619 |
+
history[-1]['content']
|
| 1620 |
+
)
|
| 1621 |
|
| 1622 |
if isinstance(
|
| 1623 |
messages4[-1],
|
| 1624 |
HumanMessage
|
| 1625 |
):
|
| 1626 |
+
|
| 1627 |
messages4 = messages4[:-2]
|
| 1628 |
|
| 1629 |
+
link = extract_url_from_text(
|
| 1630 |
+
combined_message
|
| 1631 |
+
)
|
| 1632 |
+
|
| 1633 |
+
user_message = (
|
| 1634 |
+
extract_user_query_from_link_message(
|
| 1635 |
+
combined_message,
|
| 1636 |
+
link
|
| 1637 |
+
)
|
| 1638 |
+
)
|
| 1639 |
+
|
| 1640 |
print(
|
| 1641 |
+
'RAW LINK REQUEST:',
|
| 1642 |
+
repr(combined_message)
|
| 1643 |
)
|
| 1644 |
|
| 1645 |
print(
|
|
|
|
| 1647 |
repr(link)
|
| 1648 |
)
|
| 1649 |
|
| 1650 |
+
print(
|
| 1651 |
+
'USER QUERY:',
|
| 1652 |
+
repr(user_message)
|
| 1653 |
+
)
|
| 1654 |
+
|
| 1655 |
if not link:
|
| 1656 |
+
|
| 1657 |
response_message = (
|
| 1658 |
+
'Please provide a valid URL '
|
| 1659 |
+
'starting with http:// or https://'
|
| 1660 |
)
|
| 1661 |
|
| 1662 |
else:
|
| 1663 |
+
|
| 1664 |
+
result = read_data(
|
| 1665 |
+
link
|
| 1666 |
+
)
|
| 1667 |
|
| 1668 |
print(
|
| 1669 |
'LINK READ RESULT TYPE:',
|
|
|
|
| 1684 |
]
|
| 1685 |
|
| 1686 |
if (
|
| 1687 |
+
isinstance(
|
| 1688 |
+
result,
|
| 1689 |
+
str
|
| 1690 |
+
)
|
| 1691 |
and (
|
| 1692 |
result in error_results
|
| 1693 |
or result.startswith(
|
|
|
|
| 1696 |
or result.startswith(
|
| 1697 |
'An error occurred while reading'
|
| 1698 |
)
|
| 1699 |
+
or result.startswith(
|
| 1700 |
+
'Unable to retrieve the YouTube transcript'
|
| 1701 |
+
)
|
| 1702 |
+
or result.startswith(
|
| 1703 |
+
'No English or Arabic transcript'
|
| 1704 |
+
)
|
| 1705 |
+
or result.startswith(
|
| 1706 |
+
'Transcripts are disabled'
|
| 1707 |
+
)
|
| 1708 |
+
or result.startswith(
|
| 1709 |
+
'The YouTube video is unavailable'
|
| 1710 |
+
)
|
| 1711 |
)
|
| 1712 |
):
|
| 1713 |
+
|
| 1714 |
response_message = result
|
| 1715 |
|
| 1716 |
else:
|
| 1717 |
+
|
| 1718 |
content_data = normalize_text(
|
| 1719 |
result
|
| 1720 |
)
|
| 1721 |
|
| 1722 |
if not content_data:
|
| 1723 |
+
|
| 1724 |
response_message = (
|
| 1725 |
'The provided link is empty or '
|
| 1726 |
'does not contain any meaningful words.'
|
| 1727 |
)
|
| 1728 |
|
| 1729 |
else:
|
| 1730 |
+
|
| 1731 |
augmented_prompt = f"""
|
| 1732 |
You are an AI designed to help understand
|
| 1733 |
and extract information from provided Link Content.
|
|
|
|
| 1740 |
Link Content:
|
| 1741 |
{content_data}
|
| 1742 |
|
| 1743 |
+
Answer the user's query using the Link Content.
|
| 1744 |
+
Do not treat the URL itself or the word "what"
|
| 1745 |
+
as part of the URL.
|
| 1746 |
"""
|
| 1747 |
|
| 1748 |
message = HumanMessage(
|
|
|
|
| 1756 |
messages4 = messages4[-1:]
|
| 1757 |
|
| 1758 |
try:
|
| 1759 |
+
|
| 1760 |
+
response = chat_model.invoke(
|
| 1761 |
+
messages4
|
|
|
|
| 1762 |
)
|
| 1763 |
|
| 1764 |
except Exception as e:
|
| 1765 |
+
|
| 1766 |
error_message = str(e)
|
| 1767 |
|
| 1768 |
print(
|
|
|
|
| 1786 |
start_index != -1
|
| 1787 |
and end_index != -1
|
| 1788 |
):
|
| 1789 |
+
|
| 1790 |
raise gr.Error(
|
| 1791 |
error_message[
|
| 1792 |
start_index:end_index
|
|
|
|
| 1813 |
})
|
| 1814 |
|
| 1815 |
for character in response_message:
|
| 1816 |
+
|
| 1817 |
history[-1]['content'] += character
|
| 1818 |
|
| 1819 |
+
time.sleep(
|
| 1820 |
+
0.0025
|
| 1821 |
+
)
|
| 1822 |
|
| 1823 |
yield history, messages4
|
| 1824 |
|
|
|
|
| 1827 |
text,
|
| 1828 |
every=8
|
| 1829 |
):
|
| 1830 |
+
|
| 1831 |
return '\n'.join(
|
| 1832 |
text[i:i + every]
|
| 1833 |
for i in range(
|
|
|
|
| 1838 |
)
|
| 1839 |
|
| 1840 |
|
| 1841 |
+
def display_file_name(
|
| 1842 |
+
file
|
| 1843 |
+
):
|
| 1844 |
+
|
| 1845 |
supported_extensions = [
|
| 1846 |
'.csv',
|
| 1847 |
'.txt',
|
|
|
|
| 1862 |
file_extension.lower()
|
| 1863 |
in supported_extensions
|
| 1864 |
):
|
| 1865 |
+
|
| 1866 |
file_name = os.path.basename(
|
| 1867 |
file.name
|
| 1868 |
)
|
|
|
|
| 1904 |
filepath,
|
| 1905 |
messages5
|
| 1906 |
):
|
| 1907 |
+
|
| 1908 |
combined_message = str(
|
| 1909 |
history[-1]['content']
|
| 1910 |
)
|
|
|
|
| 1913 |
messages5[-1],
|
| 1914 |
HumanMessage
|
| 1915 |
):
|
| 1916 |
+
|
| 1917 |
messages5 = messages5[:-2]
|
| 1918 |
|
| 1919 |
link = ''
|
| 1920 |
user_message = ''
|
| 1921 |
|
| 1922 |
if '\n' in combined_message:
|
| 1923 |
+
|
| 1924 |
link, user_message = (
|
| 1925 |
combined_message.split(
|
| 1926 |
'\n',
|
|
|
|
| 1928 |
)
|
| 1929 |
)
|
| 1930 |
|
| 1931 |
+
user_message = (
|
| 1932 |
+
user_message.strip()
|
| 1933 |
+
)
|
| 1934 |
|
| 1935 |
result = read_data(
|
| 1936 |
filepath
|
| 1937 |
)
|
| 1938 |
|
| 1939 |
if result == 'Unsupported type or format.':
|
| 1940 |
+
|
| 1941 |
response_message = result
|
| 1942 |
|
| 1943 |
else:
|
| 1944 |
+
|
| 1945 |
content_data = normalize_text(
|
| 1946 |
result
|
| 1947 |
)
|
| 1948 |
|
| 1949 |
if not content_data:
|
| 1950 |
+
|
| 1951 |
response_message = (
|
| 1952 |
'The file is empty or does not '
|
| 1953 |
'contain any meaningful words.'
|
| 1954 |
)
|
| 1955 |
|
| 1956 |
else:
|
| 1957 |
+
|
| 1958 |
augmented_prompt = f"""
|
| 1959 |
You are an AI designed to help understand
|
| 1960 |
and extract information from provided File Content.
|
|
|
|
| 1984 |
messages5 = messages5[-1:]
|
| 1985 |
|
| 1986 |
try:
|
| 1987 |
+
|
| 1988 |
response = (
|
| 1989 |
chat_model.invoke(
|
| 1990 |
messages5
|
|
|
|
| 1992 |
)
|
| 1993 |
|
| 1994 |
except Exception as e:
|
| 1995 |
+
|
| 1996 |
error_message = str(e)
|
| 1997 |
|
| 1998 |
print(
|
|
|
|
| 2016 |
start_index != -1
|
| 2017 |
and end_index != -1
|
| 2018 |
):
|
| 2019 |
+
|
| 2020 |
raise gr.Error(
|
| 2021 |
error_message[
|
| 2022 |
start_index:end_index
|
|
|
|
| 2043 |
})
|
| 2044 |
|
| 2045 |
for character in response_message:
|
| 2046 |
+
|
| 2047 |
history[-1]['content'] += character
|
| 2048 |
|
| 2049 |
+
time.sleep(
|
| 2050 |
+
0.0025
|
| 2051 |
+
)
|
| 2052 |
|
| 2053 |
yield history, messages5
|
| 2054 |
|
|
|
|
| 2057 |
history,
|
| 2058 |
messages6
|
| 2059 |
):
|
| 2060 |
+
|
| 2061 |
message = history[-1]['content']
|
| 2062 |
|
| 2063 |
if isinstance(
|
| 2064 |
messages6[-1],
|
| 2065 |
HumanMessage
|
| 2066 |
):
|
| 2067 |
+
|
| 2068 |
messages6 = messages6[:-2]
|
| 2069 |
|
| 2070 |
links = [
|
|
|
|
| 2072 |
]
|
| 2073 |
|
| 2074 |
result = '\n'.join(
|
| 2075 |
+
[
|
| 2076 |
+
read_data(link)
|
| 2077 |
+
for link in links
|
| 2078 |
+
]
|
| 2079 |
)
|
| 2080 |
|
| 2081 |
content_data = normalize_text(
|
|
|
|
| 2104 |
content=augmented_prompt
|
| 2105 |
)
|
| 2106 |
|
| 2107 |
+
messages6.append(
|
| 2108 |
+
msg
|
| 2109 |
+
)
|
| 2110 |
|
| 2111 |
if len(messages6) >= 4:
|
| 2112 |
+
|
| 2113 |
messages6 = messages6[-4:]
|
| 2114 |
|
| 2115 |
try:
|
| 2116 |
+
|
| 2117 |
response = chat_model.invoke(
|
| 2118 |
messages6
|
| 2119 |
)
|
| 2120 |
|
| 2121 |
except Exception as e:
|
| 2122 |
+
|
| 2123 |
error_message = str(e)
|
| 2124 |
|
| 2125 |
print(
|
|
|
|
| 2127 |
repr(e)
|
| 2128 |
)
|
| 2129 |
|
| 2130 |
+
start_index = (
|
| 2131 |
+
error_message.find(
|
| 2132 |
+
'Input validation error:'
|
| 2133 |
+
)
|
| 2134 |
)
|
| 2135 |
|
| 2136 |
+
end_index = (
|
| 2137 |
+
error_message.find(
|
| 2138 |
+
'and 4096 `max_new_tokens`'
|
| 2139 |
+
)
|
| 2140 |
)
|
| 2141 |
|
| 2142 |
if (
|
| 2143 |
start_index != -1
|
| 2144 |
and end_index != -1
|
| 2145 |
):
|
| 2146 |
+
|
| 2147 |
raise gr.Error(
|
| 2148 |
error_message[
|
| 2149 |
start_index:end_index
|
|
|
|
| 2166 |
})
|
| 2167 |
|
| 2168 |
for character in response.content:
|
| 2169 |
+
|
| 2170 |
history[-1]['content'] += character
|
| 2171 |
|
| 2172 |
+
time.sleep(
|
| 2173 |
+
0.0025
|
| 2174 |
+
)
|
| 2175 |
|
| 2176 |
yield history, messages6
|
| 2177 |
|
|
|
|
| 2465 |
queue=True
|
| 2466 |
).then(
|
| 2467 |
Link_Scratch,
|
| 2468 |
+
[chatbot, messages4],
|
| 2469 |
[chatbot, messages4]
|
| 2470 |
)
|
| 2471 |
|
|
|
|
| 2476 |
queue=True
|
| 2477 |
).then(
|
| 2478 |
Link_Scratch,
|
| 2479 |
+
[chatbot, messages4],
|
| 2480 |
[chatbot, messages4]
|
| 2481 |
)
|
| 2482 |
|
|
|
|
| 2487 |
queue=True
|
| 2488 |
).then(
|
| 2489 |
Link_Scratch,
|
| 2490 |
+
[chatbot, messages4],
|
| 2491 |
[chatbot, messages4]
|
| 2492 |
)
|
| 2493 |
|