willn9 commited on
Commit
2648ef7
·
verified ·
1 Parent(s): fe61726

Uncollapse

Browse files
Files changed (1) hide show
  1. app.py +97 -64
app.py CHANGED
@@ -2,96 +2,129 @@ import os
2
  import gradio as gr
3
  from openai import OpenAI
4
 
5
- # Initialize OpenAI client
6
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
7
 
8
- # Streaming response function
9
- def respond(
 
 
 
 
 
 
 
 
 
 
 
 
10
  message,
11
- history: list[tuple[str, str]],
12
  system_message,
13
  role,
14
- ad,
15
  education,
16
- experience,
17
  skills,
18
- ask_for_skills_suggestions,
19
  max_tokens,
20
- temperature,
21
  top_p,
22
  ):
23
- # Construct the system message
24
- enhanced_system_message = (
25
- f"{system_message}\n\n"
26
- f"Role, Industry and Type of Organization: {role}\n"
27
- f"Job Ad Responsibilities and Key Requirements: {ad}\n"
28
- f"Education, Training and Certifications: {education}\n"
29
- f"Work Experience: {experience}\n"
30
- f"Skills: {skills}\n"
31
- )
32
-
33
- if ask_for_skills_suggestions:
34
- enhanced_system_message += " The user is also asking for suggestions of skills related to this role."
35
 
36
- # Compose the conversation
37
- messages = [{"role": "system", "content": enhanced_system_message}]
38
- for user_msg, assistant_msg in history:
39
  if user_msg:
40
  messages.append({"role": "user", "content": user_msg})
41
  if assistant_msg:
42
  messages.append({"role": "assistant", "content": assistant_msg})
43
  messages.append({"role": "user", "content": message})
44
 
45
- # Generate and stream response
46
- response_text = ""
 
 
 
 
47
  try:
48
  response = client.chat.completions.create(
49
- model="gpt-4o-mini", # use "gpt-4o-mini" when officially available
50
  messages=messages,
51
- max_tokens=max_tokens,
52
- temperature=temperature,
53
- top_p=top_p,
54
  stream=True,
55
  )
56
  for chunk in response:
57
- if chunk.choices and chunk.choices[0].delta.content:
58
  token = chunk.choices[0].delta.content
59
- response_text += token
60
- yield response_text
 
 
61
  except Exception as e:
62
- yield f"❌ An error occurred: {str(e)}"
63
-
64
- # Gradio interface
65
- demo = gr.ChatInterface(
66
- fn=respond,
67
- additional_inputs=[
68
- gr.Textbox(
69
- 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.",
 
 
 
 
 
 
 
 
 
 
 
 
70
  label="Instructions to Bot",
71
- ),
72
- gr.Textbox(label="Role, Industry and Employer", placeholder="Describe the role, industry and employer you are applying to."),
73
- gr.Textbox(
74
- label="Job Ad Responsibilities and Key Requirements",
75
- placeholder="Describe the Responsibilities and Key Requirements advertised in the job ad",
76
- ),
77
- gr.Textbox(
78
- label="Your Education, certifications, training, etc.",
79
- placeholder="Describe your education, training, certifications and professional designations",
80
- ),
81
- gr.Textbox(
82
- label="Your Work Experience",
83
- placeholder="Describe your work experience, previous responsibilities and key career achievements",
84
- ),
85
- gr.Textbox(label="Skills", placeholder="List your key skills that match this job or ask for suggestions"),
86
- gr.Checkbox(label="Ask for Skills Suggestions", value=False),
87
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
88
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
89
- gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"),
90
- ],
91
- title="Resumize Customize your CV!",
92
- description="This app customizes your resume to best suit a specific role, industry, employer and job ad. Based on your input. Powered by OpenAI GPT-4o, design thinking, and domain expertise. Developed by wn. Disclaimer: AI can make mistakes. Use with caution and at your own risk!",
93
- type="messages", # Required for Gradio ChatInterface streaming
94
- )
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  if __name__ == "__main__":
97
  demo.launch()
 
2
  import gradio as gr
3
  from openai import OpenAI
4
 
5
+ # Initialize OpenAI client (expects OPENAI_API_KEY in env)
6
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
7
 
8
+ def make_system_message(system_message, role, jobad, education, workexp, skills, ask_sugg):
9
+ msg = (
10
+ f"{system_message}\n\n"
11
+ f"Role, Industry and Type of Organization: {role}\n"
12
+ f"Job Ad Responsibilities and Key Requirements: {jobad}\n"
13
+ f"Education, Training and Certifications: {education}\n"
14
+ f"Work Experience: {workexp}\n"
15
+ f"Skills: {skills}\n"
16
+ )
17
+ if ask_sugg:
18
+ msg += " The user is also asking for suggestions of skills related to this role."
19
+ return msg
20
+
21
+ def stream_chat(
22
  message,
23
+ history, # list[list[str, str]] from gr.Chatbot
24
  system_message,
25
  role,
26
+ jobad,
27
  education,
28
+ workexp,
29
  skills,
30
+ ask_sugg,
31
  max_tokens,
32
+ temp,
33
  top_p,
34
  ):
35
+ """
36
+ Streaming generator that yields the progressively updated chat history.
37
+ """
38
+ # 1) Build system + conversation messages
39
+ sys_msg = make_system_message(system_message, role, jobad, education, workexp, skills, ask_sugg)
 
 
 
 
 
 
 
40
 
41
+ messages = [{"role": "system", "content": sys_msg}]
42
+ for user_msg, assistant_msg in (history or []):
 
43
  if user_msg:
44
  messages.append({"role": "user", "content": user_msg})
45
  if assistant_msg:
46
  messages.append({"role": "assistant", "content": assistant_msg})
47
  messages.append({"role": "user", "content": message})
48
 
49
+ # 2) Start streaming back to the Chatbot
50
+ running_reply = ""
51
+ # Optimistically show the assistant "typing"
52
+ running_history = (history or []) + [[message, ""]]
53
+ yield running_history
54
+
55
  try:
56
  response = client.chat.completions.create(
57
+ model="gpt-4o-mini", # adjust if needed
58
  messages=messages,
59
+ max_tokens=int(max_tokens),
60
+ temperature=float(temp),
61
+ top_p=float(top_p),
62
  stream=True,
63
  )
64
  for chunk in response:
65
+ if chunk.choices and chunk.choices[0].delta and chunk.choices[0].delta.content:
66
  token = chunk.choices[0].delta.content
67
+ running_reply += token
68
+ running_history[-1][1] = running_reply
69
+ # Yield the whole history each time so the UI updates
70
+ yield running_history
71
  except Exception as e:
72
+ running_history[-1][1] = f"❌ An error occurred: {str(e)}"
73
+ yield running_history
74
+
75
+
76
+ with gr.Blocks(title="Resumize – Customize your CV!") as demo:
77
+ gr.Markdown("""
78
+ # Resumize – Customize your CV!
79
+ This app customizes your resume to best suit a specific role, industry, employer and job ad.
80
+ Powered by OpenAI GPT-4o and domain expertise.
81
+ """)
82
+
83
+ chatbot = gr.Chatbot(height=400)
84
+
85
+ with gr.Column():
86
+ instructions = gr.Textbox(
87
+ value=(
88
+ "You are a friendly Chatbot, a career coach and a talented copywriter. "
89
+ "You are trying to help a user customize their resume according to a specific role, employer organization and job Ad "
90
+ "- based on user input. Include tips if some items are missing."
91
+ ),
92
  label="Instructions to Bot",
93
+ lines=4,
94
+ )
95
+ role = gr.Textbox(label="Role, Industry and Employer", placeholder="Describe the role, industry and employer you are applying to.")
96
+ jobad = gr.Textbox(label="Job Ad Responsibilities and Key Requirements", placeholder="Paste/describe the job ad responsibilities and key requirements", lines=4)
97
+ education = gr.Textbox(label="Your Education, Certifications, Training, etc.", placeholder="Degrees, diplomas, certifications, courses", lines=3)
98
+ workexp = gr.Textbox(label="Your Work Experience", placeholder="Roles, responsibilities, achievements", lines=4)
99
+ skills = gr.Textbox(label="Skills", placeholder="List your key skills that match this job or ask for suggestions")
100
+ ask_sugg = gr.Checkbox(label="Ask for Skills Suggestions", value=False)
101
+
102
+ with gr.Row():
103
+ max_tokens = gr.Slider(minimum=1, maximum=4096, value=512, step=1, label="Max new tokens")
104
+ temp = gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature")
105
+ top_p = gr.Slider(minimum=0.0, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus)")
106
+
107
+ msg = gr.Textbox(label="Type your message here...", placeholder="e.g., Draft a tailored resume summary")
108
+ with gr.Row():
109
+ send = gr.Button("Send", variant="primary")
110
+ clear = gr.Button("Clear")
111
+
112
+ # Wire up sending (submit or button) → stream_chat → chatbot
113
+ inputs = [msg, chatbot, instructions, role, jobad, education, workexp, skills, ask_sugg, max_tokens, temp, top_p]
114
+ outputs = [chatbot]
115
+
116
+ msg.submit(stream_chat, inputs, outputs)
117
+ send.click(stream_chat, inputs, outputs)
118
+
119
+ # Clear everything
120
+ def do_clear():
121
+ return [], "", "", "", "", "", "", False, 512, 0.7, 0.95
122
+
123
+ clear.click(
124
+ do_clear,
125
+ inputs=[],
126
+ outputs=[chatbot, msg, instructions, role, jobad, education, workexp, skills, ask_sugg, max_tokens, temp, top_p],
127
+ )
128
 
129
  if __name__ == "__main__":
130
  demo.launch()