|
|
import os |
|
|
import gradio as gr |
|
|
from openai import OpenAI |
|
|
|
|
|
|
|
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) |
|
|
|
|
|
def make_system_message(system_message, role, jobad, education, workexp, skills, ask_sugg): |
|
|
msg = ( |
|
|
f"{system_message}\n\n" |
|
|
f"Role, Industry and Type of Organization: {role}\n" |
|
|
f"Job Ad Responsibilities and Key Requirements: {jobad}\n" |
|
|
f"Education, Training and Certifications: {education}\n" |
|
|
f"Work Experience: {workexp}\n" |
|
|
f"Skills: {skills}\n" |
|
|
) |
|
|
if ask_sugg: |
|
|
msg += " The user is also asking for suggestions of skills related to this role." |
|
|
return msg |
|
|
|
|
|
def stream_chat( |
|
|
message, |
|
|
history, |
|
|
system_message, |
|
|
role, |
|
|
jobad, |
|
|
education, |
|
|
workexp, |
|
|
skills, |
|
|
ask_sugg, |
|
|
max_tokens, |
|
|
temp, |
|
|
top_p, |
|
|
): |
|
|
""" |
|
|
Streaming generator that yields the progressively updated chat history. |
|
|
""" |
|
|
|
|
|
sys_msg = make_system_message(system_message, role, jobad, education, workexp, skills, ask_sugg) |
|
|
|
|
|
messages = [{"role": "system", "content": sys_msg}] |
|
|
for user_msg, assistant_msg in (history or []): |
|
|
if user_msg: |
|
|
messages.append({"role": "user", "content": user_msg}) |
|
|
if assistant_msg: |
|
|
messages.append({"role": "assistant", "content": assistant_msg}) |
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
|
|
|
running_reply = "" |
|
|
|
|
|
running_history = (history or []) + [[message, ""]] |
|
|
yield running_history |
|
|
|
|
|
try: |
|
|
response = client.chat.completions.create( |
|
|
model="gpt-4o-mini", |
|
|
messages=messages, |
|
|
max_tokens=int(max_tokens), |
|
|
temperature=float(temp), |
|
|
top_p=float(top_p), |
|
|
stream=True, |
|
|
) |
|
|
for chunk in response: |
|
|
if chunk.choices and chunk.choices[0].delta and chunk.choices[0].delta.content: |
|
|
token = chunk.choices[0].delta.content |
|
|
running_reply += token |
|
|
running_history[-1][1] = running_reply |
|
|
|
|
|
yield running_history |
|
|
except Exception as e: |
|
|
running_history[-1][1] = f"❌ An error occurred: {str(e)}" |
|
|
yield running_history |
|
|
|
|
|
|
|
|
with gr.Blocks(title="Resumize – Customize your CV!") as demo: |
|
|
gr.Markdown(""" |
|
|
# Resumize – Customize your CV! |
|
|
This app customizes your resume to best suit a specific role, industry, employer and job ad. |
|
|
Powered by OpenAI GPT-4o and domain expertise. |
|
|
""") |
|
|
|
|
|
chatbot = gr.Chatbot(height=400) |
|
|
|
|
|
with gr.Column(): |
|
|
instructions = gr.Textbox( |
|
|
value=( |
|
|
"You are a friendly Chatbot, a career coach and a talented copywriter. " |
|
|
"You are trying to help a user customize their resume according to a specific role, employer organization and job Ad " |
|
|
"- based on user input. Include tips if some items are missing." |
|
|
), |
|
|
label="Instructions to Bot", |
|
|
lines=4, |
|
|
) |
|
|
role = gr.Textbox(label="Role, Industry and Employer", placeholder="Describe the role, industry and employer you are applying to.") |
|
|
jobad = gr.Textbox(label="Job Ad Responsibilities and Key Requirements", placeholder="Paste/describe the job ad responsibilities and key requirements", lines=4) |
|
|
education = gr.Textbox(label="Your Education, Certifications, Training, etc.", placeholder="Degrees, diplomas, certifications, courses", lines=3) |
|
|
workexp = gr.Textbox(label="Your Work Experience", placeholder="Roles, responsibilities, achievements", lines=4) |
|
|
skills = gr.Textbox(label="Skills", placeholder="List your key skills that match this job or ask for suggestions") |
|
|
ask_sugg = gr.Checkbox(label="Ask for Skills Suggestions", value=False) |
|
|
|
|
|
with gr.Row(): |
|
|
max_tokens = gr.Slider(minimum=1, maximum=4096, value=512, step=1, label="Max new tokens") |
|
|
temp = gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature") |
|
|
top_p = gr.Slider(minimum=0.0, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus)") |
|
|
|
|
|
msg = gr.Textbox(label="Type your message here...", placeholder="e.g., Draft a tailored resume summary") |
|
|
with gr.Row(): |
|
|
send = gr.Button("Send", variant="primary") |
|
|
clear = gr.Button("Clear") |
|
|
|
|
|
|
|
|
inputs = [msg, chatbot, instructions, role, jobad, education, workexp, skills, ask_sugg, max_tokens, temp, top_p] |
|
|
outputs = [chatbot] |
|
|
|
|
|
msg.submit(stream_chat, inputs, outputs) |
|
|
send.click(stream_chat, inputs, outputs) |
|
|
|
|
|
|
|
|
def do_clear(): |
|
|
return [], "", "", "", "", "", "", False, 512, 0.7, 0.95 |
|
|
|
|
|
clear.click( |
|
|
do_clear, |
|
|
inputs=[], |
|
|
outputs=[chatbot, msg, instructions, role, jobad, education, workexp, skills, ask_sugg, max_tokens, temp, top_p], |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|