File size: 32,818 Bytes
d50a675 e1b3ed6 f56bf7c d3b7d4e f56bf7c 2032a70 925113b 2e5b1f6 f56bf7c d3b7d4e f56bf7c d3b7d4e 31ecd77 d3b7d4e f56bf7c c0ccc4f f56bf7c c0ccc4f f56bf7c c0ccc4f f56bf7c c0ccc4f f56bf7c d3b7d4e 049d943 c0ccc4f 44a2029 c0ccc4f 44a2029 c0ccc4f 44a2029 ef8b5e6 150cc6e 44a2029 150cc6e f56bf7c 2e5b1f6 16ad07f d8185d2 33bcb2d d3b7d4e 4e12a10 f56bf7c 2d84166 5ce9009 f56bf7c 2d84166 f56bf7c 2d84166 f56bf7c 2d84166 f56bf7c 2d84166 0b6301b 44a2029 0b6301b b441fb6 0b6301b b441fb6 0b6301b b441fb6 0b6301b 1454d37 0b6301b 5ce9009 1454d37 76a4e39 1454d37 76a4e39 1454d37 16ad07f 0b6301b 1454d37 0b6301b 1454d37 0b6301b 1454d37 16ad07f 44a2029 925113b 1454d37 5ce9009 1454d37 925113b 1454d37 925113b 1454d37 925113b 1454d37 925113b 5102079 49c7b41 44a2029 5102079 49c7b41 5102079 5ce9009 5102079 c4b4e0f 2773ed3 5102079 2773ed3 5102079 8f59b9d 2773ed3 5102079 49c7b41 925113b 5102079 2e5b1f6 5ce9009 5102079 2e5b1f6 5102079 2e5b1f6 5102079 2e5b1f6 5102079 b441fb6 8f59b9d 5102079 b441fb6 5102079 b441fb6 8f59b9d 5102079 8f59b9d 5102079 da47433 8f59b9d 2e5b1f6 5102079 2e5b1f6 5102079 49c7b41 5102079 49c7b41 5ce9009 5102079 c4b4e0f 49c7b41 5102079 49c7b41 5102079 8f59b9d 49c7b41 925113b 5102079 b441fb6 8f59b9d 5102079 b441fb6 8f59b9d 5ce9009 8f59b9d 5ce9009 925113b 49c7b41 5102079 2773ed3 925113b 5ce9009 d2d5c74 2032a70 44a2029 d2d5c74 5102079 d2d5c74 5ce9009 5102079 d2d5c74 8f59b9d d2d5c74 5ce9009 5102079 76a4e39 5102079 49c7b41 925113b 5102079 049d943 5102079 049d943 5fc052c 49c7b41 2e5b1f6 16ad07f 5102079 049d943 f925b72 2f69958 2773ed3 2032a70 44a2029 2a75c72 44a2029 2e5b1f6 44a2029 ef8b5e6 49c7b41 44a2029 16ad07f 5102079 44a2029 8f59b9d 6492b16 44a2029 8f59b9d 5102079 8f59b9d 44a2029 8f59b9d 5fc052c 049d943 5fc052c 8f59b9d 2eb0f8f 5102079 8f59b9d 007c39c 5102079 8f59b9d 2d84166 5102079 2d84166 5102079 2d84166 5ce9009 2d84166 8f59b9d 5ce9009 2d84166 5ce9009 2d84166 007c39c 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 2d84166 5ce9009 44a2029 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d f925b72 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 2e5b1f6 8f59b9d 2e5b1f6 8f59b9d 2e5b1f6 8f59b9d 5ce9009 8f59b9d 5ce9009 2e5b1f6 5ce9009 2e5b1f6 5ce9009 2e5b1f6 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 16ad07f 8f59b9d 16ad07f 8f59b9d 5ce9009 16ad07f 8f59b9d 5ce9009 49c7b41 8f59b9d 5ce9009 8f59b9d 49c7b41 8f59b9d 2738430 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 5ce9009 8f59b9d 2773ed3 8f59b9d 5ce9009 049d943 f56bf7c 2773ed3 f925b72 76a4e39 2a75c72 76a4e39 d8185d2 2773ed3 d8185d2 2773ed3 d8185d2 c3e783d d8185d2 c3e783d d8185d2 c3e783d d8185d2 c3e783d d8185d2 76a4e39 a866be3 06ce646 a866be3 06ce646 31ecd77 a866be3 06ce646 d8185d2 2a75c72 c0379f6 7692476 2a75c72 c6753f9 c54bedc c6753f9 ef8b5e6 7692476 2a75c72 d8185d2 c54bedc c6753f9 ef8b5e6 2a75c72 ef8b5e6 c6753f9 3f4d656 5fc052c 49c7b41 2e5b1f6 16ad07f 3f4d656 d8185d2 2773ed3 c6753f9 d8185d2 ef8b5e6 49c7b41 2e5b1f6 16ad07f c6753f9 2f69958 2a75c72 7692476 d8185d2 c54bedc d2d5c74 d8185d2 3e89e72 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 | import gradio as gr
from openai import OpenAI
import os
user_profile = {
"mode": None,
"specific_career": None,
"bg_info": None,
"work_value": None,
"personality_summary": None,
"dream_day": None,
"forward_direction_choice": None,
"recommended_directions": [],
"selected_direction": None,
"recommended_jobs": [],
"final_choice": None
}
base_questions = [
("mode", "Do you have any preferred future plans?\n- if yes, reply'Y'(Backward Mode)\n- if NO,reply'N'(Forward Mode)")
]
# ============================ Forward Mode Questions ============================
forward_additional_questions = [
("bg_info", """To get started, please tell me a bit about your academic background and interests. What's your school, year, major, and core courses? If you have a transcript or resume, that would be even better!"""),
("work_value", """Great! What do you think is the meaning or value of 'work'? What should an ideal job provide for you? (e.g., helping others, high income, free time, personal growth, creative space, etc.)"""),
("personality_summary", "Briefly describe your personality: Are you introverted or extroverted? Do you enjoy challenges? Detail-oriented? Do you dislike repetitive work?"),
("dream_day", "Now describe what your ideal workday looks like: Where are you working? What are you doing? Who are you collaborating with? Is it busy or relaxed? More freedom or more structure?")
]
# ============================ Backward Mode Questions ============================
backward_additional_questions = [
("specific_career", "Please describe the specific career path you want to pursue."),
("bg_info", "Please provide your school, year, major, and any internship or project experience you already have, so I can help you build a clearer path to your goal.")
]
current_q_index = 0
questions = base_questions[:]
in_forward_flow = False
in_backward_flow = False
forward_index = 0
backward_index = 0
forward_done = False
backward_done = False
forward_recommendation_given = False
recommendation_round = 0
forward_deep_dive_done = False
roadmap_offered = False
roadmap_done = False
direction_chosen = False
jobs_recommended = False
job_chosen = False
post_career_detail_asked = False
post_career_detail_done = False
model_default = "gpt-4o"
token_default = 2000
temp_default = 0.7
top_p_default = 0.95
def backward_strategy_plan(specific_career, bg_info):
prompt = f"""
You are a professional career planning advisor,use english.
A student has the target career: {specific_career}
Their current background is: {bg_info}
Please help the student build a clear plan to reach their goal, including:
1. Should they consider changing majors or taking a minor?
2. Are there any courses they should take? What are the key course topics?
3. Recommended certificates/exams (e.g., CFA) and study tips
4. Suggested internship directions (based on their background)
5. How to make use of university resources (career center, clubs, networking, etc.)
6. If their background is mismatched (e.g., mechanical engineering to finance), how to bridge the gap?
Use Markdown formatting in sections, with a minimum of 300 words. The content must align closely with the student's current background and goals.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong: API_TOKEN not set"
client = OpenAI(api_key=api_key)
msgs = [
{"role": "system", "content": "You are an experienced career advisor, good at creating roadmaps based on user background. "},
{"role": "user", "content": prompt}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong path: {str(e)}"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def answer_abc_questions(selected, bg_info, wv, ps, dd):
desired_parts = []
if "a" in selected.lower():
desired_parts.append("A")
if "b" in selected.lower():
desired_parts.append("B")
if "c" in selected.lower():
desired_parts.append("C")
if not desired_parts:
return "OK, you don't need ABC"
prompt_text = f"""
You are a professional career planning advisor. Below is the student's background information. Please provide detailed analysis and suggestions based on the selected module(s): A, B, or C,use english.
Student Profile:
- Academic Background: {bg_info}
- Work Value: {wv}
- Personality: {ps}
- Ideal Workday: {dd}
The student wants insights on the following module(s): {', '.join(desired_parts)}
Please write a separate section for each selected module in order, using Markdown formatting.
(A: Course Selection & Career Entry)
- Analyze the student's current academic background and what capabilities they already have.
- Based on their intended career, recommend what types of courses they should focus on.
- Suggest course names and keywords to guide their course planning.
(B: School Resource Utilization)
- Provide 3 types of suggestions:
1. How to utilize the university's career services.
2. How to get involved with career-related clubs, organizations, and platforms.
3. How to network with alumni in their field and improve networking skills.
(C: Internships & Experience Building)
- Suggest platforms to find internships.
- Recommend internship directions aligned with the student's career goal.
- Provide tips for preparing materials and applying.
- Strategies for gaining experience through networking, internships, or campus jobs.
Only include the modules selected by the student. Do not generate content for unselected modules.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN Not set"
client = OpenAI(api_key=api_key)
msgs = [
{"role": "system", "content": "You are a professional career advisor who provides module-specific (A/B/C) analysis and suggestions."},
{"role": "user", "content": prompt_text}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong ABC: {str(e)}"
def do_selected_career_detail(selected_career, bg_info, wv, ps, dd):
prompt = f"""
You are a professional career planning advisor.
The student has selected the following specific career: {selected_career}
Student Profile:
- Academic Background: {bg_info}
- Work Value: {wv}
- Personality: {ps}
- Ideal Workday: {dd}
Please write a detailed description of this career including at least the following,use english:
1. Average salary (entry-level / mid-level / senior)
2. Work environment (remote/hybrid/in-office, team size, etc.)
3. Promotion difficulty (what qualifications or milestones are needed)
4. Key skills and certifications required
5. Typical work rhythm (fast-paced or routine?)
6. Industry outlook
Please use Markdown formatting in separate sections, with a minimum of 300 words.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN not set"
client = OpenAI(api_key=api_key)
msgs = [
{"role": "system", "content": "You are a professional career advisor who provides in-depth career descriptions."},
{"role": "user", "content": prompt}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong path: {str(e)}"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Time line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def do_time_roadmap():
direction = user_profile.get("final_choice") or user_profile.get("selected_direction") or \
user_profile.get("forward_direction_choice") or user_profile.get("specific_career")
bg_info = user_profile["bg_info"] or "None"
wv = user_profile["work_value"] or "None"
ps = user_profile["personality_summary"] or "None"
dd = user_profile["dream_day"] or "None"
prompt_roadmap = f"""
Student Profile:
- Academic Background: {bg_info}
- Career Direction / Specific Role: {direction}
- Work Values: {wv}
- Personality: {ps}
- Ideal Workday: {dd}
Please create a timeline-style career roadmap based on the student's background and goal,use english.
Use the following structure as a reference:
📍 Summer after Year 2: [What internship to apply for, what activities to participate in, what certifications to pursue]
🎓 Year 3: [Recommended courses, key projects or academic goals]
💼 Summer after Year 3: [Target internships, certifications, personal/professional development plans]
📄 6–12 Months Before Graduation: [Certifications to complete, job/grad school application materials to prepare]
🚀 Post-Graduation: [Target roles, how to apply, next steps]
Please write the roadmap using Markdown formatting and tailor your suggestions specifically to the student's profile.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN NOt set"
client = OpenAI(api_key=api_key)
msgs = [
{"role":"system","content":"You are a professional career advisor who generates timeline-based career roadmaps"},
{"role":"user","content": prompt_roadmap}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong path: {str(e)}"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Recomend jpb ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def recommend_3jobs_for_direction(direction, bg_info, wv, ps, dd):
prompt = f"""
You are a professional career advisor,use english.
The student has selected the following general career direction: {direction}
Student background: {bg_info}
Work values: {wv}
Personality: {ps}
Ideal workday: {dd}
Please recommend 3 specific job roles related to this direction, and provide details for each:
1) Why this job fits the chosen direction
2) Typical responsibilities
3) Required skills and certifications
4) Future career prospects
End your response with this format (do not repeat this format earlier in the message):
Please select your ideal job:
1. [Job Title 1]
2. [Job Title 2]
3. [Job Title 3]
If none of these suit you, enter 'change'.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN not set"
client = OpenAI(api_key=api_key)
msgs = [
{"role": "system", "content": "You are a professional career advisor, recommending 3 specific jobs based on the student's chosen direction."},
{"role": "user", "content": prompt}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
output_text = resp.choices[0].message.content
import re
job_pattern = r'(\d+)\.\s+\[?(.*?)\]?(?:\n|$)'
job_matches = re.findall(job_pattern, output_text)
job_list = [match[1].strip() for match in job_matches]
if len(job_list) < 3:
job_list = [
f"{direction} - JobA",
f"{direction} - JobB",
f"{direction} - JobC"
]
user_profile["recommended_jobs"] = job_list[:3]
global jobs_recommended
jobs_recommended = True
return output_text
except Exception as e:
return f"wrong job: {str(e)}"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ big direction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def recommend_3directions():
bg_info = user_profile["bg_info"] or "None"
wv = user_profile["work_value"] or "None"
ps = user_profile["personality_summary"] or "None"
dd = user_profile["dream_day"] or "None"
rec_prompt = f"""
Based on the following information, write a structured student profile and recommend 3 general career directions, use english.
Address the student as "you" (not he/she).
- Academic Background: {bg_info}
- Work Values: {wv}
- Personality: {ps}
- Ideal Workday: {dd}
Two parts required:
[1. Student Profile]: Briefly summarize their academic background, core values, personality, and career expectations.
[2. Recommend 3 General Directions]: For each direction, write 1–2 paragraphs explaining why it's a good fit for the student.
End with only the following format (do not repeat it earlier):
Please choose your career direction:
1. [Direction Name 1]
2. [Direction Name 2]
3. [Direction Name 3]
If none are suitable, type 'change'.
"""
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN not set"
client = OpenAI(api_key=api_key)
msgs = [
{"role":"system","content":"You are a career advisor who recommends 3 general directions based on the user's profile."},
{"role":"user","content": rec_prompt}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
output_text = resp.choices[0].message.content
import re
dir_pattern = r'(\d+)\.\s+\[?(.*?)\]?(?:\n|$)'
dir_matches = re.findall(dir_pattern, output_text)
dir_list = [match[1].strip() for match in dir_matches]
if len(dir_list) < 3:
dir_list = [
"Direction 1",
"Directionn2",
"Direction 3"
]
user_profile["recommended_directions"] = dir_list[:3]
return output_text
except Exception as e:
return f"Wrong direction: {str(e)}"
def generate_system_prompt():
mode = user_profile["mode"]
sc = user_profile["specific_career"]
bg = user_profile["bg_info"]
wv = user_profile["work_value"]
ps = user_profile["personality_summary"]
dd = user_profile["dream_day"]
fwd = user_profile["forward_direction_choice"]
if mode == "Y":
return f"""
You are a professional career advisor using the Backward Design method to help students achieve their career goals,use english.
Target career: {sc}
Background information: {bg}
Please provide:
1. A brief analysis of the target career
2. Top companies or organizations in this field
3. Required skills and qualifications
4. Career development path
5. Academic/course suggestions, skill development, use of resources, internship planning, resume tips, etc.
Finally, output a career roadmap in Markdown format like this:
📍 Now → 🎓 Learning Suggestions → 💼 Practice Suggestions → 📄 Certification Advice → 🚀 Job Search Suggestions
"""
else:
return f"""
You are a professional career advisor using the Forward Design method to help students explore suitable career paths,use english.
Student background: {bg}
Work values: {wv}
Personality summary: {ps}
Ideal workday: {dd}
Student's selected direction: {fwd}
Please provide:
1. An analysis of the student's strengths, personality traits, and values
2. 3 recommended specific jobs, including daily work content, fit, requirements, and preparation pathway
3. A final career roadmap:
📍 Now → 🎓 Learning Suggestions → 💼 Practice Suggestions → 📄 Certification Advice → 🚀 Job Search Suggestions
"""
def predict(message, history):
global current_q_index, questions
global in_forward_flow, in_backward_flow
global forward_index, backward_index
global forward_done, backward_done
global forward_recommendation_given
global recommendation_round
global forward_deep_dive_done
global roadmap_offered, roadmap_done
global direction_chosen, jobs_recommended, job_chosen
global post_career_detail_asked, post_career_detail_done
if not history:
current_q_index = 0
questions[:] = base_questions
for k in user_profile:
user_profile[k] = None
in_forward_flow = False
in_backward_flow = False
forward_index = 0
backward_index = 0
forward_done = False
backward_done = False
forward_recommendation_given = False
recommendation_round = 0
forward_deep_dive_done = False
roadmap_offered = False
roadmap_done = False
direction_chosen = False
jobs_recommended = False
job_chosen = False
post_career_detail_asked = False
post_career_detail_done = False
if 0 < current_q_index <= len(questions):
key = questions[current_q_index - 1][0]
if key == "mode" and current_q_index == 1:
ans = message.strip()
user_profile["mode"] = ans
questions[:] = []
if "Y" in ans:
in_backward_flow = True
else:
in_forward_flow = True
if current_q_index < len(questions)and not in_forward_flow and not in_backward_flow:
nxt = questions[current_q_index][1]
current_q_index += 1
return nxt
mode = user_profile.get("mode") or ""
if mode == "Y":
if in_backward_flow and not backward_done:
if backward_index > 0 and backward_index <= len(backward_additional_questions):
prev_key = backward_additional_questions[backward_index - 1][0]
user_profile[prev_key] = message.strip()
if backward_index < len(backward_additional_questions):
k, prompt_text = backward_additional_questions[backward_index]
backward_index += 1
return prompt_text
else:
strategy = backward_strategy_plan(
specific_career=user_profile.get("specific_career"),
bg_info=user_profile.get("bg_info")
)
user_profile["final_choice"] = user_profile.get("specific_career")
job_chosen = True
forward_deep_dive_done = True
post_career_detail_asked = True
return strategy + "\n\nI can do further exploration:" \
"\n- A:Major or course & Job direction" \
"\n- B:School Resources" \
"\n- C:Internship & networking " \
"\nEnter A / B / C / AB / BC / AC / ABC" \
"\nif No need'Please NO'。"
elif post_career_detail_asked and not post_career_detail_done:
user_choice = message.strip().lower()
if user_choice in ["Please NO", "no", "n"]:
post_career_detail_done = True
roadmap_offered = True
return "OK, would you like a job path【I need】,or【NO need】。"
else:
abc_text = answer_abc_questions(
selected=user_choice,
bg_info=user_profile.get("bg_info", ""),
wv=user_profile.get("work_value", "None"),
ps=user_profile.get("personality_summary", "None"),
dd=user_profile.get("dream_day", "None")
)
post_career_detail_done = True
roadmap_offered = True
return abc_text + "\n\nDo you need a time path plan?enter【I need】,or 【NO need】。"
elif job_chosen and not roadmap_offered and not roadmap_done:
roadmap_offered = True
return "Need a time path map?【I need】,or【NO need】。"
elif roadmap_offered and not roadmap_done:
ans = message.strip().lower()
if ans in ["I need", "yes", "y"]:
roadmap_done = True
backward_done = True
return do_time_roadmap()
else:
roadmap_done = True
backward_done = True
return "OK, your plan is finished"
if backward_done:
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN not set"
client = OpenAI(api_key=api_key)
sprompt = generate_system_prompt()
msgs = [
{"role": "system", "content": sprompt},
{"role": "user", "content": f"this material: {user_profile}. enter if you need more"}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong: {str(e)}"
else:
if in_forward_flow and not direction_chosen:
if forward_index > 0 and forward_index <= len(forward_additional_questions):
prev_key = forward_additional_questions[forward_index - 1][0]
user_profile[prev_key] = message.strip()
if forward_index < len(forward_additional_questions):
k, prompt_text = forward_additional_questions[forward_index]
forward_index += 1
return prompt_text
elif not forward_recommendation_given:
forward_recommendation_given = True
return recommend_3directions()
else:
choice = message.strip().lower()
if choice in ["1","2","3"]:
idx = int(choice) - 1
if idx < len(user_profile["recommended_directions"]):
sel_dir = user_profile["recommended_directions"][idx]
user_profile["selected_direction"] = sel_dir
direction_chosen = True
return recommend_3jobs_for_direction(
direction=sel_dir,
bg_info=user_profile["bg_info"] or "",
wv=user_profile["work_value"] or "",
ps=user_profile["personality_summary"] or "",
dd=user_profile["dream_day"] or ""
)
else:
return "Enter 1/2/3或'Change'"
elif choice == "Change":
recommendation_round += 1
if recommendation_round > 2:
forward_done = True
return "Change too many times"
else:
return recommend_3directions()
else:
return "enter 1,2,3 or change"
elif direction_chosen and jobs_recommended and not job_chosen:
choice = message.strip().lower()
if choice in ["1","2","3"]:
idx = int(choice) - 1
if idx < len(user_profile["recommended_jobs"]):
final_job = user_profile["recommended_jobs"][idx]
user_profile["final_choice"] = final_job
job_chosen = True
detail_msg = do_selected_career_detail(
selected_career=final_job,
bg_info=user_profile["bg_info"] or "",
wv=user_profile["work_value"] or "",
ps=user_profile["personality_summary"] or "",
dd=user_profile["dream_day"] or ""
)
forward_deep_dive_done = True
post_career_detail_asked = True
return detail_msg + "\n\nI can do futher information for you:" \
"\n- A:major course & job" \
"\n- B:School Resources" \
"\n- C:Internship & networking" \
"\nneed more information A / B / C / AB / BC / AC / ABC" \
"\nNO need,enter'No need'。"
else:
return "Re enter please"
elif choice == "Change":
recommendation_round += 1
if recommendation_round > 2:
forward_done = True
return "too many changes"
else:
sel_dir = user_profile.get("selected_direction") or "No direction"
return recommend_3jobs_for_direction(
direction=sel_dir,
bg_info=user_profile["bg_info"] or "",
wv=user_profile["work_value"] or "",
ps=user_profile["personality_summary"] or "",
dd=user_profile["dream_day"] or ""
)
else:
return "enter 1,2,3 or renture"
elif post_career_detail_asked and not post_career_detail_done:
user_choice = message.strip().lower()
if user_choice in ["NO need", "no", "n"]:
post_career_detail_done = True
roadmap_offered = True
return "OK, do you need a time plan, enter 【I need】,or【NO need】。"
else:
abc_text = answer_abc_questions(
selected=user_choice,
bg_info=user_profile["bg_info"],
wv=user_profile["work_value"],
ps=user_profile["personality_summary"],
dd=user_profile["dream_day"]
)
post_career_detail_done = True
roadmap_offered = True
return abc_text + "\n\n this is your further information, do you need a time plan, enter【I need】, or【NO need】。"
# 已选定具体职业 -> 问是否需要时间轴
elif job_chosen and not roadmap_offered and not roadmap_done:
roadmap_offered = True
return "Need a time path plan enter【I need】,否则回复【NO need】。"
elif roadmap_offered and not roadmap_done:
ans = message.strip().lower()
if ans in ["I need", "yes", "y"]:
roadmap_done = True
forward_done = True
return do_time_roadmap()
else:
roadmap_done = True
forward_done = True
return "OK, plan is finished"
if forward_done:
try:
api_key = os.environ.get("API_TOKEN")
if not api_key:
return "Wrong:API_TOKEN Not set"
client = OpenAI(api_key=api_key)
sprompt = generate_system_prompt()
msgs = [
{"role":"system","content":sprompt},
{"role":"user","content": f"this is material: {user_profile}. enter to find more"}
]
resp = client.chat.completions.create(
model=model_default,
messages=msgs,
max_tokens=token_default,
temperature=temp_default,
top_p=top_p_default,
stream=False
)
return resp.choices[0].message.content
except Exception as e:
return f"Wrong: {str(e)}"
return "Information down"
# ============================ Gradio UI ============================
# Gradio import is already done at the top of the file
css = """
body {
background-color: #1e1e1e;
color: #ffffff;
}
.gradio-container {
font-family: 'Segoe UI', sans-serif;
}
.gr-chatbot {
background-color: transparent !important;
}
.message.user {
background-color: #cce6ff !important;
color: #000000 !important;
border-radius: 10px !important;
padding: 10px;
margin: 6px;
}
.message.bot {
background-color: #99ccff !important;
color: #000000 !important;
border-radius: 10px !important;
padding: 10px;
margin: 6px;
}
.gr-button {
border-radius: 8px;
}
#custom-send {
background-color: #3b82f6 !important;
color: white !important;
border-radius: 999px !important;
padding: 10px 24px !important;
font-weight: bold;
box-shadow: 0 0 10px #3b82f6;
transition: all 0.3s ease-in-out;
}
#custom-send:hover {
background-color: #2563eb !important;
box-shadow: 0 0 12px #3b82f6;
}
textarea, input {
background-color: #e6f0ff !important;
color: #1e3a8a !important;
border: 1px solid #3b82f6 !important;
}
footer {
display: none !important;
}
"""
with gr.Blocks(css=css) as demo:
with gr.Row():
gr.HTML("""
<div style='display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 10px;'>
<img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif'
width='200'
style='border-radius: 12px; box-shadow: 0 0 10px #3b82f6;'>
<div style='text-align: left;'>
<h1 style='color:White; font-size: 36px; margin-bottom: 6px;'>🎓 Explora:AI Career Exploration Assistant</h1>
<p style='font-size: 18px; font-weight:bold; color:#3b82f6; margin-top: 0; margin-left:150px'>
Hi! Let's Make the Dream Come True 💙
</p>
</div>
</div>
""")
chatbot = gr.Chatbot(height=500, show_label=False, show_copy_button=True, type="messages")
msg = gr.Textbox(placeholder="请输入你的回答...")
send = gr.Button("Send 🚀", elem_id="custom-send")
reset = gr.Button("🔄 Restart")
def add_user_message(m, hist):
hist = hist or []
hist.append({"role": "user", "content": m})
return "", hist
def add_bot_response(hist):
user_msg = hist[-1]["content"]
bot_msg = predict(user_msg, hist[:-1])
hist.append({"role": "assistant", "content": bot_msg})
return hist
send.click(add_user_message, [msg, chatbot], [msg, chatbot]) \
.then(add_bot_response, chatbot, chatbot)
msg.submit(add_user_message, [msg, chatbot], [msg, chatbot]) \
.then(add_bot_response, chatbot, chatbot)
def reset_state():
global current_q_index, questions
global in_forward_flow, in_backward_flow
global forward_index, backward_index
global forward_done, backward_done
global forward_recommendation_given
global recommendation_round
global forward_deep_dive_done
global roadmap_offered, roadmap_done
global direction_chosen, jobs_recommended, job_chosen
global post_career_detail_asked, post_career_detail_done
current_q_index = 0
questions[:] = base_questions
for k in user_profile:
user_profile[k] = None
in_forward_flow = False
in_backward_flow = False
forward_index = 0
backward_index = 0
forward_done = False
backward_done = False
forward_recommendation_given = False
recommendation_round = 0
forward_deep_dive_done = False
roadmap_offered = False
roadmap_done = False
direction_chosen = False
jobs_recommended = False
job_chosen = False
post_career_detail_asked = False
post_career_detail_done = False
return []
reset.click(reset_state, outputs=chatbot)
def auto_first():
return [{"role": "assistant", "content": questions[0][1]}]
demo.load(auto_first, outputs=chatbot)
demo.launch()
|