Satyam0077 commited on
Commit
84008c2
·
verified ·
1 Parent(s): a3fc58f

Upload 7 files

Browse files
Files changed (7) hide show
  1. agent.py +28 -0
  2. app.py +13 -0
  3. chat_ui.py +139 -0
  4. gibberish.py +12 -0
  5. info_extract.py +29 -0
  6. requirements.txt +0 -0
  7. settings.py +0 -0
agent.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # chatbot/agent.py
2
+
3
+ import os
4
+ import google.generativeai as genai
5
+ from dotenv import load_dotenv
6
+
7
+ # Load environment variables from .env
8
+ load_dotenv()
9
+
10
+ # Configure Gemini API
11
+ genai.configure(api_key=os.getenv("AGENT_API_KEY"))
12
+
13
+ # Initialize Gemini model
14
+ model = genai.GenerativeModel("models/gemini-1.5-flash-latest")
15
+
16
+ def generate_response(conversation):
17
+ """
18
+ Generate a response from Gemini.
19
+ conversation: list of (role, message) tuples.
20
+ Only 'user' role is supported.
21
+ """
22
+ # Convert conversation to Gemini-compatible format
23
+ messages = [{"role": "user", "parts": msg} for role, msg in conversation if role == "user"]
24
+
25
+ # Call Gemini directly (no system/model roles, no start_chat)
26
+ response = model.generate_content(messages)
27
+
28
+ return response.text.strip()
app.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ import streamlit as st
4
+ from ui.chat_ui import render_chat_interface # <── fixed import
5
+
6
+ def main():
7
+ """
8
+ Entry point for TalentScout Hiring Assistant.
9
+ """
10
+ render_chat_interface()
11
+
12
+ if __name__ == "__main__":
13
+ main()
chat_ui.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ui/chat_ui.py
2
+
3
+ import os
4
+ import json
5
+ import streamlit as st
6
+ from chatbot.agent import generate_response
7
+ from prompts.base_prompts import (
8
+ greeting_prompt,
9
+ info_collection_prompt,
10
+ tech_stack_prompt,
11
+ dynamic_generation_prompt,
12
+ exit_keywords,
13
+ exit_message,
14
+ )
15
+
16
+ # Save candidate info to JSON
17
+ def save_candidate_data(candidate):
18
+ os.makedirs("data", exist_ok=True)
19
+ file_path = os.path.join("data", "candidates.json")
20
+
21
+ try:
22
+ with open(file_path, "r") as f:
23
+ data = json.load(f)
24
+ except:
25
+ data = []
26
+
27
+ data.append(candidate)
28
+
29
+ with open(file_path, "w") as f:
30
+ json.dump(data, f, indent=2)
31
+
32
+
33
+ def render_chat_interface():
34
+ st.set_page_config(page_title="TalentScout Hiring Assistant", layout="centered")
35
+
36
+ st.markdown(
37
+ "<h2 style='text-align: center;'>🤖 TalentScout Hiring Assistant</h2>",
38
+ unsafe_allow_html=True,
39
+ )
40
+
41
+ # Initialize states
42
+ if "conversation" not in st.session_state:
43
+ st.session_state.conversation = []
44
+ if "ended" not in st.session_state:
45
+ st.session_state.ended = False
46
+ if "started" not in st.session_state:
47
+ st.session_state.started = False
48
+ if "user_info" not in st.session_state:
49
+ st.session_state.user_info = {}
50
+ if "tech_stack_collected" not in st.session_state:
51
+ st.session_state.tech_stack_collected = False
52
+
53
+ # Greeting
54
+ if not st.session_state.started:
55
+ st.markdown(
56
+ f"<div class='chat-bubble bot'><strong>Assistant:</strong><br>{greeting_prompt}</div>",
57
+ unsafe_allow_html=True,
58
+ )
59
+ if st.button("Begin"):
60
+ st.session_state.started = True
61
+ st.rerun()
62
+ return
63
+
64
+ # Collect user info
65
+ if not st.session_state.user_info:
66
+ st.markdown(info_collection_prompt, unsafe_allow_html=True)
67
+
68
+ with st.form("candidate_info"):
69
+ full_name = st.text_input("Full Name")
70
+ email = st.text_input("Email Address")
71
+ phone = st.text_input("Phone Number")
72
+ years_exp = st.text_input("Years of Experience")
73
+ location = st.text_input("Current Location")
74
+ desired_pos = st.text_input("Desired Position")
75
+ submitted = st.form_submit_button("Save & Continue")
76
+
77
+ if submitted:
78
+ st.session_state.user_info = {
79
+ "Full Name": full_name,
80
+ "Email": email,
81
+ "Phone": phone,
82
+ "Experience": years_exp,
83
+ "Location": location,
84
+ "Desired Position": desired_pos,
85
+ }
86
+ save_candidate_data(st.session_state.user_info)
87
+ st.rerun()
88
+ return
89
+
90
+ # Collect tech stack
91
+ if not st.session_state.tech_stack_collected:
92
+ st.markdown(tech_stack_prompt, unsafe_allow_html=True)
93
+ tech_stack = st.text_input("Tech Stack (comma separated)")
94
+
95
+ if st.button("Submit Tech Stack"):
96
+ st.session_state.user_info["Tech Stack"] = tech_stack
97
+ st.session_state.tech_stack_collected = True
98
+
99
+ bot_msg = (
100
+ f"Thanks, {st.session_state.user_info['Full Name']}! "
101
+ f"Based on your tech stack, here are some questions:"
102
+ )
103
+ st.session_state.conversation.append(("bot", bot_msg))
104
+
105
+ # ✅ Fixed: no system role, just user prompt
106
+ prompt = dynamic_generation_prompt(tech_stack)
107
+ questions = generate_response([("user", prompt)])
108
+
109
+ st.session_state.conversation.append(("bot", questions))
110
+ st.rerun()
111
+ return
112
+
113
+ # Main conversation loop
114
+ if not st.session_state.ended:
115
+ for role, msg in st.session_state.conversation:
116
+ role_class = "bot" if role == "bot" else "user"
117
+ label = "Assistant" if role == "bot" else "You"
118
+ st.markdown(
119
+ f"<div class='chat-bubble {role_class}'><strong>{label}:</strong><br>{msg}</div>",
120
+ unsafe_allow_html=True,
121
+ )
122
+
123
+ with st.form("chat_form", clear_on_submit=True):
124
+ user_input = st.text_input("Your reply", placeholder="Type here...")
125
+ send = st.form_submit_button("Send")
126
+
127
+ if send and user_input.strip():
128
+ st.session_state.conversation.append(("user", user_input.strip()))
129
+
130
+ if any(exit_word in user_input.lower() for exit_word in exit_keywords):
131
+ st.session_state.conversation.append(("bot", exit_message))
132
+ st.session_state.ended = True
133
+ else:
134
+ bot_reply = generate_response([("user", user_input.strip())])
135
+ st.session_state.conversation.append(("bot", bot_reply))
136
+
137
+ st.rerun()
138
+ else:
139
+ st.success("✅ Session ended. Refresh the page to start again.")
gibberish.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # utils/gibberish.py
2
+
3
+ def is_gibberish(text: str) -> bool:
4
+ """
5
+ Detects whether a candidate's input text is likely to be gibberish.
6
+ A simple heuristic: if less than 50% of characters are alphabetic.
7
+ """
8
+ if not text:
9
+ return True
10
+ letters = sum(c.isalpha() for c in text)
11
+ ratio = letters / max(len(text), 1)
12
+ return ratio < 0.5
info_extract.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # utils/info_extract.py
2
+
3
+ def extract_user_info(text: str):
4
+ """
5
+ Extract candidate details if provided in a single text input string.
6
+ Example input: "Full Name: John Doe, Email Address: john@example.com"
7
+ Returns a dictionary with expected fields.
8
+ """
9
+ fields = [
10
+ "Full Name",
11
+ "Email Address",
12
+ "Phone Number",
13
+ "Years of Experience",
14
+ "Desired Position"
15
+ ]
16
+
17
+ info = {field: "" for field in fields}
18
+ parts = text.split(",")
19
+
20
+ for part in parts:
21
+ if ":" in part:
22
+ key, val = part.split(":", 1)
23
+ key = key.strip()
24
+ val = val.strip()
25
+ for field in fields:
26
+ if field.lower() == key.lower():
27
+ info[field] = val
28
+ break
29
+ return info
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
settings.py ADDED
File without changes