Dhahlan2000 commited on
Commit
3b9b6a5
·
1 Parent(s): 86fa7e0

Initial commit with project setup and basic structure.

Browse files
Files changed (2) hide show
  1. app.py +200 -0
  2. requirements.txt +0 -0
app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import os
4
+ from dotenv import load_dotenv
5
+ from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
6
+ from langchain.schema import AgentAction, AgentFinish, HumanMessage
7
+ from langchain.prompts import BaseChatPromptTemplate
8
+ from langchain.tools import Tool
9
+ from langchain.memory import ConversationBufferWindowMemory
10
+ from transformers import pipeline
11
+ from typing import List, Union
12
+ import re
13
+
14
+ # Load environment variables from .env
15
+ load_dotenv()
16
+
17
+ # Job API keys and endpoints
18
+ JOB_API_KEY = os.getenv("JOB_API_KEY") # Add your job API key here if required
19
+ JOBS_API_URL = "https://jobs.github.com/positions.json" # Example API endpoint (replace with an actual one)
20
+
21
+ # Function to find global job openings
22
+ def find_global_jobs():
23
+ try:
24
+ response = requests.get(JOBS_API_URL)
25
+ if response.status_code == 200:
26
+ jobs = response.json()
27
+ return [
28
+ {
29
+ "title": job["title"],
30
+ "company": job["company"],
31
+ "location": job["location"],
32
+ "url": job["url"]
33
+ } for job in jobs
34
+ ]
35
+ else:
36
+ return {"error": "Unable to fetch job data."}
37
+ except Exception as e:
38
+ return {"error": str(e)}
39
+
40
+ # Function to find remote jobs
41
+ def find_remote_jobs():
42
+ try:
43
+ response = requests.get(f"{JOBS_API_URL}?location=remote")
44
+ if response.status_code == 200:
45
+ jobs = response.json()
46
+ return [
47
+ {
48
+ "title": job["title"],
49
+ "company": job["company"],
50
+ "url": job["url"]
51
+ } for job in jobs
52
+ ]
53
+ else:
54
+ return {"error": "Unable to fetch remote job data."}
55
+ except Exception as e:
56
+ return {"error": str(e)}
57
+
58
+ # Function to find jobs near a location
59
+ def find_jobs_near_location(location):
60
+ try:
61
+ response = requests.get(f"{JOBS_API_URL}?location={location}")
62
+ if response.status_code == 200:
63
+ jobs = response.json()
64
+ return [
65
+ {
66
+ "title": job["title"],
67
+ "company": job["company"],
68
+ "location": job["location"],
69
+ "url": job["url"]
70
+ } for job in jobs
71
+ ]
72
+ else:
73
+ return {"error": "Unable to fetch job data for location."}
74
+ except Exception as e:
75
+ return {"error": str(e)}
76
+
77
+ # Define LangChain tools
78
+ global_jobs_tool = Tool(
79
+ name="Global Job Finder",
80
+ func=find_global_jobs,
81
+ description="Find all job openings around the world."
82
+ )
83
+
84
+ remote_jobs_tool = Tool(
85
+ name="Remote Job Finder",
86
+ func=find_remote_jobs,
87
+ description="Find remote job openings."
88
+ )
89
+
90
+ local_jobs_tool = Tool(
91
+ name="Local Job Finder",
92
+ func=find_jobs_near_location,
93
+ description="Find job openings near a specified location. Input should be a city or region name."
94
+ )
95
+
96
+ # Set up the tools
97
+ tools = [
98
+ global_jobs_tool,
99
+ remote_jobs_tool,
100
+ local_jobs_tool
101
+ ]
102
+
103
+ # Set up a prompt template with history
104
+ template_with_history = """You are JobSearchGPT, an AI assistant specialized in finding job openings. Answer the following questions as best you can. You have access to the following tools:
105
+
106
+ {tools}
107
+
108
+ Use the following format:
109
+
110
+ Question: the input question you must answer
111
+ Thought: you should always think about what to do
112
+ Action: the action to take, should be one of [{tool_names}]
113
+ Action Input: the input to the action
114
+ Observation: the result of the action
115
+ ... (this Thought/Action/Action Input/Observation can repeat N times)
116
+ Thought: I now know the final answer
117
+ Final Answer: the final answer to the original input question
118
+
119
+ Begin! Remember to give detailed, informative answers
120
+
121
+ Previous conversation history:
122
+ {history}
123
+
124
+ New question: {input}
125
+ {agent_scratchpad}"""
126
+
127
+ # Set up the prompt template
128
+ class CustomPromptTemplate(BaseChatPromptTemplate):
129
+ template: str
130
+ tools: List[Tool]
131
+
132
+ def format_messages(self, **kwargs) -> str:
133
+ intermediate_steps = kwargs.pop("intermediate_steps")
134
+ thoughts = ""
135
+ for action, observation in intermediate_steps:
136
+ thoughts += action.log
137
+ thoughts += f"\nObservation: {observation}\nThought: "
138
+
139
+ kwargs["agent_scratchpad"] = thoughts
140
+ kwargs["tools"] = "\n".join([f"{tool.name}: {tool.description}" for tool in self.tools])
141
+ kwargs["tool_names"] = ", ".join([tool.name for tool in self.tools])
142
+ formatted = self.template.format(**kwargs)
143
+ return [HumanMessage(content=formatted)]
144
+
145
+ prompt_with_history = CustomPromptTemplate(
146
+ template=template_with_history,
147
+ tools=tools,
148
+ input_variables=["input", "intermediate_steps", "history"]
149
+ )
150
+
151
+ # Custom output parser
152
+ class CustomOutputParser(AgentOutputParser):
153
+ def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:
154
+ if "Final Answer:" in llm_output:
155
+ return AgentFinish(
156
+ return_values={"output": llm_output.split("Final Answer:")[-1].strip()},
157
+ log=llm_output,
158
+ )
159
+ regex = r"Action: (.*?)[\n]*Action Input:[\s]*(.*)"
160
+ match = re.search(regex, llm_output, re.DOTALL)
161
+ if not match:
162
+ raise ValueError(f"Could not parse LLM output: `{llm_output}`")
163
+ action = match.group(1).strip()
164
+ action_input = match.group(2)
165
+ return AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=llm_output)
166
+
167
+ output_parser = CustomOutputParser()
168
+
169
+ # Initialize HuggingFace pipeline
170
+ pipe = pipeline("text-generation", model="gpt-neo-2.7B") # Replace with a suitable model
171
+
172
+ # LLM chain
173
+ llm_chain = LLMChain(llm=pipe, prompt=prompt_with_history)
174
+ tool_names = [tool.name for tool in tools]
175
+ agent = LLMSingleActionAgent(
176
+ llm_chain=llm_chain,
177
+ output_parser=output_parser,
178
+ stop=["\nObservation:"],
179
+ allowed_tools=tool_names
180
+ )
181
+
182
+ memory = ConversationBufferWindowMemory(k=2)
183
+ agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True, memory=memory)
184
+
185
+ # Streamlit app
186
+ st.title("Job Search Helper Agent")
187
+
188
+ query = st.text_input("Enter your query:")
189
+
190
+ if st.button("Submit"):
191
+ if query:
192
+ st.write("Debug: User Query ->", query)
193
+ with st.spinner("Processing..."):
194
+ try:
195
+ # Run the agent and get the response
196
+ response = agent_executor.run(query) # Correct method is `run()`
197
+ st.success("Response:")
198
+ st.write(response)
199
+ except Exception as e:
200
+ st.error(f"An error occurred: {e}")
requirements.txt ADDED
File without changes