From 069163aa6883058db600d97c195eba89d33f3646 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:01:44 -0500 Subject: [PATCH 01/24] feat: integrate job recommendation functionality into API response --- be_repo/app.py | 12 +++- be_repo/modules/job_recommendation_system.py | 67 +++++++------------- be_repo/modules/retrieval_engine.py | 26 ++++---- be_repo/modules/view.py | 8 +-- be_repo/requirements.txt | 5 ++ 5 files changed, 54 insertions(+), 64 deletions(-) diff --git a/be_repo/app.py b/be_repo/app.py index 3ecaf01fa..9626d2bc5 100644 --- a/be_repo/app.py +++ b/be_repo/app.py @@ -9,6 +9,7 @@ from configs.database import get_resume_database, get_user_database from graphs.qa_graph import create_graph from modules.evaluator import evaluate_resume, evaluate_resume_with_jd +from modules.job_recommendation_system import job_recommend from modules.langgraph_qa import get_answer_from_langgraph from modules.upload import upload_parse_resume @@ -218,10 +219,17 @@ def job_suggestion(): if not user_id: return jsonify({"error": "No user ID provided."}), 400 + # Load resume from database + resume = resume_collection.find_one({"user_id": user_id}) + if not resume: + return jsonify({"error": "No resume found for this user."}), 404 + # Get answer using LangGraph - response = 'Example response' + resume_text = resume.get('resume_text', '') + if not resume_text: + return jsonify({"error": "Resume text is empty."}), 400 - return jsonify({"response": response}), 200 + return jsonify({"response": job_recommend(resume_text, user_id)}), 200 if __name__ == '__main__': diff --git a/be_repo/modules/job_recommendation_system.py b/be_repo/modules/job_recommendation_system.py index 95e4b609b..ff8cd84e6 100644 --- a/be_repo/modules/job_recommendation_system.py +++ b/be_repo/modules/job_recommendation_system.py @@ -1,31 +1,28 @@ # job_recommendation_system.py -from neo4j_model import Neo4jModel -from resume_processor import ResumeProcessor -from retrieval_engine import RetrievalEngine -from recommendation_generator import RecommendationGenerator -from view import CLIView -import sys +import logging -def main(): - - - # Redirect standard output to a file - sys.stdout = open('output.log', 'w') - - # Your code here - print("Lots of output") +from .neo4j_model import Neo4jModel +from .recommendation_generator import RecommendationGenerator +from .resume_processor import ResumeProcessor +from .retrieval_engine import RetrievalEngine +from .view import CLIView +def job_recommend(resume_text, user_id): # Setup Logging - import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) - + + # Get Resume Input from User + if not resume_text.strip(): + logger.error(f'No resume text provided, user_id: {user_id}.') + return 'Error: No resume text provided.' + # Neo4j Connection Details NEO4J_URI = "neo4j+ssc://7bf5a48e.databases.neo4j.io" # Replace with your Neo4j URI - NEO4J_USERNAME = "neo4j" # Replace with your Neo4j username - NEO4J_PASSWORD = "oxsK7V5_86emZlYQlvCfQHfVWS95wXz29OhtU8GAdFc" # Replace with your Neo4j password + NEO4J_USERNAME = "neo4j" # Replace with your Neo4j username + NEO4J_PASSWORD = "oxsK7V5_86emZlYQlvCfQHfVWS95wXz29OhtU8GAdFc" # Replace with your Neo4j password # Initialize Model neo4j_model = Neo4jModel( @@ -33,43 +30,27 @@ def main(): username=NEO4J_USERNAME, password=NEO4J_PASSWORD ) - + # Initialize Controller Components resume_processor = ResumeProcessor() retrieval_engine = RetrievalEngine(resume_processor, neo4j_model) recommendation_generator = RecommendationGenerator() - + # Initialize View view = CLIView() - - # Get Resume Input from User - resume_text = view.get_resume_input() - - if not resume_text.strip(): - logger.error("No resume text provided.") - print("Error: No resume text provided.") - return - + # Perform Mixed Retrieval for 'JD' Node Label node_label = "JD" # Adjust as needed; could be dynamic based on user input or other criteria similar_docs, graph_results = retrieval_engine.perform_mixed_retrieval(resume_text, node_label=node_label) - + if not similar_docs and not graph_results: - print("No job recommendations found based on your resume.") - return - + return 'No job recommendations found based on your resume.' + # Generate Recommendations try: recommendations = recommendation_generator.generate_recommendations(similar_docs, graph_results) except Exception as e: - print("Error: Failed to generate job recommendations.") - return - - # Display Recommendations - view.display_recommendations(recommendations) + return 'Error: Failed to generate job recommendations.' - # Close the file - sys.stdout.close() - -if __name__ == "__main__": - main() + # Display Recommendations + return view.display_recommendations(recommendations) diff --git a/be_repo/modules/retrieval_engine.py b/be_repo/modules/retrieval_engine.py index 02fac70e3..1ed8eb389 100644 --- a/be_repo/modules/retrieval_engine.py +++ b/be_repo/modules/retrieval_engine.py @@ -1,12 +1,10 @@ # retrieval_engine.py -from langchain_neo4j import GraphCypherQAChain -from langchain_openai import ChatOpenAI -from langchain.chains.retrieval import create_retrieval_chain from langchain.chains.combine_documents import create_stuff_documents_chain -from configs.openai_key import get_openai_api_key # New import +from langchain.chains.retrieval import create_retrieval_chain from langchain.prompts import PromptTemplate + class RetrievalEngine: def __init__(self, resume_processor, neo4j_model): """ @@ -21,7 +19,7 @@ def __init__(self, resume_processor, neo4j_model): # Initialize Language Model (already initialized in Neo4jModel) self.llm = self.neo4j_model.llm - + # Initialize GraphCypherQAChain (already initialized in Neo4jModel) self.graph_chain = self.neo4j_model.get_graph_chain() @@ -53,12 +51,12 @@ def __init__(self, resume_processor, neo4j_model): {context} \"\"\" """, - input_variables=["input"] + input_variables=["input"] ) - # Create a documents chain + # Create a documents chain self.combine_docs_chain = create_stuff_documents_chain(self.llm, prompt=prompt) - + # Initialize Retrieval Chain # Default node_label is 'JD'; can be adjusted as needed self.retrieval_chain = create_retrieval_chain( @@ -79,13 +77,13 @@ def perform_mixed_retrieval(self, resume_text, node_label="JD"): """ # Process resume into a Document doc = self.resume_processor.process_resume(resume_text) - + if not doc: return [], {} - + # Store the Document in the appropriate vector store self.neo4j_model.store_documents([doc], node_label=node_label) - + # Access the schema property correctly schema = self.neo4j_model.graph.get_schema @@ -94,8 +92,6 @@ def perform_mixed_retrieval(self, resume_text, node_label="JD"): similar_docs = similar_docs_result.get("output", []) print("similar_docs_result:", similar_docs_result) print("Keys in similar_docs_result:", similar_docs_result.keys()) - - for doc in similar_docs: print("Document Metadata:", doc.metadata) @@ -105,5 +101,5 @@ def perform_mixed_retrieval(self, resume_text, node_label="JD"): # After graph query print("Graph Response:") print(graph_response) - - return similar_docs, graph_response \ No newline at end of file + + return similar_docs, graph_response diff --git a/be_repo/modules/view.py b/be_repo/modules/view.py index b7af1eaa1..f6bd1264b 100644 --- a/be_repo/modules/view.py +++ b/be_repo/modules/view.py @@ -28,8 +28,8 @@ def display_recommendations(self, recommendations): Display job recommendations to the user. """ if not recommendations: - print("No job recommendations found based on your resume.") - return - print("\nRecommended Jobs for You:") + return 'No job recommendations found based on your resume.' + res = '\nRecommended Jobs for You:\n' for idx, job in enumerate(recommendations, start=1): - print(f"{idx}. {job}") + res += f'{idx}. {job}\n' + return res diff --git a/be_repo/requirements.txt b/be_repo/requirements.txt index fb0c6b758..ca6ef227e 100644 --- a/be_repo/requirements.txt +++ b/be_repo/requirements.txt @@ -15,4 +15,9 @@ langchain==0.3.7 langsmith==0.1.143 langchain_community==0.3.7 langchain-openai==0.2.8 +langchain_neo4j==0.1.1 +neo4j==5.27.0 +protobuf==3.20.2 +pytest==8.3.3 +chromedriver_autoinstaller==0.6.4 pyvirtualdisplay \ No newline at end of file From 5d389f2a9d02647ffb71a9ea14b646aabf935ce8 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:27:40 -0500 Subject: [PATCH 02/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index 2ed45dfc3..db60936bc 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -66,6 +66,6 @@ jobs: uses: actions-js/push@master with: branch: | - ${{ github.ref_name == 'main' && 'dev/backend' || github.ref_name.startsWith('be/') && github.ref_name || 'dev/backend' }} + ${{ github.ref_name == 'main' && 'dev/backend' || (startsWith(github.ref_name, 'be/') && github.ref_name) || 'dev/backend' }} message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From 49518a77b4205fcf1c4c8b9ebc6b8b092848394f Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:30:55 -0500 Subject: [PATCH 03/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index db60936bc..cf4627bf5 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -66,6 +66,6 @@ jobs: uses: actions-js/push@master with: branch: | - ${{ github.ref_name == 'main' && 'dev/backend' || (startsWith(github.ref_name, 'be/') && github.ref_name) || 'dev/backend' }} + ${{ github.event.pull_request.base.ref || 'dev/backend' }} message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From 54c499665dd25423e3f9a57a74dff6945f73994d Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:35:04 -0500 Subject: [PATCH 04/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index cf4627bf5..0857219b7 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -65,7 +65,5 @@ jobs: - name: Commit & Push changes to Readme uses: actions-js/push@master with: - branch: | - ${{ github.event.pull_request.base.ref || 'dev/backend' }} message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From cc68e16162866a92c89bbfe23112858f87741348 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:37:35 -0500 Subject: [PATCH 05/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index 0857219b7..488318eb7 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -65,5 +65,6 @@ jobs: - name: Commit & Push changes to Readme uses: actions-js/push@master with: + branch: ${{ github.ref_name }} message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From e3211abc3a1befb3bfe6cd847db014c738dfa7da Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:41:04 -0500 Subject: [PATCH 06/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index 488318eb7..f7a92dadd 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -62,6 +62,10 @@ jobs: run: | sed -i '//,//c\\n\${{ steps.coverageComment.outputs.coverageHtml }}\n' ../README.md + - name: Debug current branch + run: | + echo "Current branch: ${{ github.ref_name }}" + - name: Commit & Push changes to Readme uses: actions-js/push@master with: From e843f68d949dbf1254733ff2a09ef0e158d6df59 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:43:34 -0500 Subject: [PATCH 07/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index f7a92dadd..41016b0e5 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -64,11 +64,11 @@ jobs: - name: Debug current branch run: | - echo "Current branch: ${{ github.ref_name }}" + echo "Current branch: ${{ github.head_ref || github.ref_name }}" - name: Commit & Push changes to Readme - uses: actions-js/push@master + uses: ad-m/github-push-action@master with: - branch: ${{ github.ref_name }} + branch: github.head_ref || github.ref_name message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From 8900e38dbec4b2109e4e8fd9ed95647439d92cfe Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:45:09 -0500 Subject: [PATCH 08/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index 41016b0e5..ce5e1ba11 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -64,11 +64,11 @@ jobs: - name: Debug current branch run: | - echo "Current branch: ${{ github.head_ref || github.ref_name }}" + echo "Current branch: ${{ github.ref }}" - name: Commit & Push changes to Readme uses: ad-m/github-push-action@master with: - branch: github.head_ref || github.ref_name + branch: github.ref message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From 90b5f0a3f7e6349da659fd001a678fb184c6a531 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:52:31 -0500 Subject: [PATCH 09/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index ce5e1ba11..652587e25 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -64,11 +64,11 @@ jobs: - name: Debug current branch run: | - echo "Current branch: ${{ github.ref }}" + echo "Current branch: ${{ github.head_ref || github.ref_name }} " - name: Commit & Push changes to Readme uses: ad-m/github-push-action@master with: - branch: github.ref + branch: ${{ github.head_ref || github.ref_name }} message: Update coverage on Readme github_token: ${{ secrets.GITHUB_TOKEN }} From 343c7a33993b3a76c03504424c4896335a83869b Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 01:53:04 -0500 Subject: [PATCH 10/24] doc: modify ci_be --- .github/workflows/ci_be.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_be.yml b/.github/workflows/ci_be.yml index 652587e25..89e8cb2b1 100644 --- a/.github/workflows/ci_be.yml +++ b/.github/workflows/ci_be.yml @@ -64,7 +64,8 @@ jobs: - name: Debug current branch run: | - echo "Current branch: ${{ github.head_ref || github.ref_name }} " + echo "head ref: ${{ github.head_ref }} " + echo "ref name: ${{ github.ref_name }} " - name: Commit & Push changes to Readme uses: ad-m/github-push-action@master From 77077752cd90cd33d5f24e5d2baa40e07654bde2 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 13:51:09 -0500 Subject: [PATCH 11/24] fix: 1. system cannot retrieve user resume 2. backend dependency conflict --- be_repo/app.py | 21 +++++++++++++++++++-- be_repo/modules/langgraph_qa.py | 33 +++++++++++++++------------------ be_repo/requirements.txt | 22 ++++++++++++---------- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/be_repo/app.py b/be_repo/app.py index 9626d2bc5..1fd78d629 100644 --- a/be_repo/app.py +++ b/be_repo/app.py @@ -160,9 +160,17 @@ def ask_question(): return jsonify({"error": "No user ID provided."}), 400 if not question: return jsonify({"error": "No question provided."}), 400 + # Load resume from database + resume = resume_collection.find_one({"user_id": user_id}) + if not resume: + return jsonify({"error": "No resume found for this user."}), 404 + + resume_text = resume.get('resume_text', '') + if not resume_text: + return jsonify({"error": "Resume text is empty."}), 400 # Get answer using LangGraph - response = get_answer_from_langgraph(qa_graph, resume_collection, user_state_collection, user_id, question) + response = get_answer_from_langgraph(qa_graph, resume_text, user_state_collection, user_id, question) return jsonify({"response": response}), 200 @@ -203,8 +211,17 @@ def interview_question_suggestion(): if not user_id: return jsonify({"error": "No user ID provided."}), 400 + # Load resume from database + resume = resume_collection.find_one({"user_id": user_id}) + if not resume: + return jsonify({"error": "No resume found for this user."}), 404 + + resume_text = resume.get('resume_text', '') + if not resume_text: + return jsonify({"error": "Resume text is empty."}), 400 + # Get answer using LangGraph - response = get_answer_from_langgraph(qa_graph, resume_collection, user_state_collection, user_id, prompt) + response = get_answer_from_langgraph(qa_graph, resume_text, user_state_collection, user_id, prompt) return jsonify({"response": response}), 200 diff --git a/be_repo/modules/langgraph_qa.py b/be_repo/modules/langgraph_qa.py index b2d16f1ae..591de0828 100644 --- a/be_repo/modules/langgraph_qa.py +++ b/be_repo/modules/langgraph_qa.py @@ -1,27 +1,24 @@ -def get_answer_from_langgraph(qa_graph, resume_collection, user_state_collection, user_id, question): - resume = resume_collection.find_one({"user_id": user_id}) +def get_answer_from_langgraph(qa_graph, resume_text, user_state_collection, user_id, question): user_state = user_state_collection.find_one({"user_id": user_id}) - resume_text = resume.get('resume_text', '') - state = user_state.get('state', '') thread_id = user_state.get('thread_id', '') config = {"configurable": {"thread_id": user_id + thread_id}} # If state is 0, send resume to LLM first - if state == '0': - events = qa_graph.stream( - {"messages": [("user", resume_text)]}, config, stream_mode="values" - ) - # Update state to 1 - new_state = { - "user_id": user_id, - "state": '1', - "thread_id": thread_id - } - user_state_collection.replace_one({"user_id": user_id}, new_state, upsert=True) - for event in events: - if event["messages"][-1].type == "ai": - print('User ask for the first time!') + # if state == '0': + events = qa_graph.stream( + {"messages": [("user", resume_text)]}, config, stream_mode="values" + ) + # Update state to 1 + new_state = { + "user_id": user_id, + "state": '1', + "thread_id": thread_id + } + user_state_collection.replace_one({"user_id": user_id}, new_state, upsert=True) + for event in events: + if event["messages"][-1].type == "ai": + print('User ask for the first time!') # Then send the question events = qa_graph.stream( {"messages": [("user", question)]}, config, stream_mode="values" diff --git a/be_repo/requirements.txt b/be_repo/requirements.txt index ca6ef227e..a7ac69383 100644 --- a/be_repo/requirements.txt +++ b/be_repo/requirements.txt @@ -1,7 +1,8 @@ Flask==3.0.3 +click>=8.1.0 Flask_Cors==5.0.0 openai==1.54.4 -pandas==2.2.3 +pandas==1.5.3 pymongo==4.10.1 PyPDF2==3.0.1 qdrant_client==1.12.0 @@ -11,13 +12,14 @@ google-auth==2.36.0 google-auth-oauthlib==1.2.1 chromedriver-autoinstaller==0.6.4 langgraph==0.2.48 -langchain==0.3.7 -langsmith==0.1.143 -langchain_community==0.3.7 -langchain-openai==0.2.8 -langchain_neo4j==0.1.1 -neo4j==5.27.0 +langchain +langsmith +langchain_community +langchain-openai +langchain-neo4j +neo4j>=5.0.0,<6.0.0 protobuf==3.20.2 -pytest==8.3.3 -chromedriver_autoinstaller==0.6.4 -pyvirtualdisplay \ No newline at end of file +pytest>=7.0.0 +pyvirtualdisplay>=3.0 +grpcio-tools==1.48.2 +tiktoken>=0.7.0 \ No newline at end of file From 4bb8bede7ed29fe87a07925be310e1541958e4a8 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 14:51:47 -0500 Subject: [PATCH 12/24] fix: automatically retrieve URI --- be_repo/modules/retrieval_engine.py | 3 ++- fe_repo/src/functions/api.ts | 2 +- fe_repo/src/pages/ChatBox.tsx | 5 ++++- fe_repo/src/vite-env.d.ts | 2 ++ fe_repo/vite.config.ts | 27 ++++++++++++++++----------- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/be_repo/modules/retrieval_engine.py b/be_repo/modules/retrieval_engine.py index 1ed8eb389..0cb62aac2 100644 --- a/be_repo/modules/retrieval_engine.py +++ b/be_repo/modules/retrieval_engine.py @@ -96,7 +96,8 @@ def perform_mixed_retrieval(self, resume_text, node_label="JD"): for doc in similar_docs: print("Document Metadata:", doc.metadata) - query = f"Based on the following resume, recommend relevant job positions: {resume_text}" + query = (f"Based on the following resume, recommend relevant job positions based on skills and experience, " + f"while ignoring the location: {resume_text}") graph_response = self.graph_chain.invoke({"query": query, "schema": schema}) # After graph query print("Graph Response:") diff --git a/fe_repo/src/functions/api.ts b/fe_repo/src/functions/api.ts index f9156d9bd..4c2392a55 100644 --- a/fe_repo/src/functions/api.ts +++ b/fe_repo/src/functions/api.ts @@ -1,7 +1,7 @@ import {v4 as uuidv4} from 'uuid'; import axios from "axios"; -const uri = 'http://34.23.225.150:5000' +const uri = __CURRENT_URI__ + ':5000' export type AnalzyeResponse = { analysis: { diff --git a/fe_repo/src/pages/ChatBox.tsx b/fe_repo/src/pages/ChatBox.tsx index 1010dce3a..b0c3c7aec 100644 --- a/fe_repo/src/pages/ChatBox.tsx +++ b/fe_repo/src/pages/ChatBox.tsx @@ -91,7 +91,10 @@ export const ChatBox = ({onSendMessage, onAnalyze, onSuggest, onSuggestJob}: ICh style={{display: 'none'}} onChange={async (event) => { const files = event.target.files; - if (!files || files.length === 0) return; + if (!files || files.length === 0) { + console.log("No file selected"); + return; + } const file = files[0]; if (file) { await uploadFile(file); diff --git a/fe_repo/src/vite-env.d.ts b/fe_repo/src/vite-env.d.ts index 11f02fe2a..9e338340b 100644 --- a/fe_repo/src/vite-env.d.ts +++ b/fe_repo/src/vite-env.d.ts @@ -1 +1,3 @@ /// + +declare const __CURRENT_URI__: string; \ No newline at end of file diff --git a/fe_repo/vite.config.ts b/fe_repo/vite.config.ts index 3a0780315..0e5d90193 100644 --- a/fe_repo/vite.config.ts +++ b/fe_repo/vite.config.ts @@ -1,15 +1,20 @@ -import { defineConfig } from 'vite' +import {defineConfig} from 'vite' import react from '@vitejs/plugin-react-swc' // https://vitejs.dev/config/ -export default defineConfig({ - server: { - port: 3001, - open: true, - }, - preview: { - port: 8081, - open: false, - }, - plugins: [react()], +export default defineConfig(({command}) => { + return { + server: { + port: 3001, + open: true, + }, + preview: { + port: 8081, + open: false, + }, + plugins: [react()], + define: { + __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://cvcoach.site' : 'http://localhost') + } + }; }) From bc4c760e8832194a475acae1bc3ef0c7c63a2e34 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:01:08 -0500 Subject: [PATCH 13/24] fix: automatically retrieve URI --- fe_repo/src/functions/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/fe_repo/src/functions/api.ts b/fe_repo/src/functions/api.ts index 4c2392a55..0936281da 100644 --- a/fe_repo/src/functions/api.ts +++ b/fe_repo/src/functions/api.ts @@ -1,5 +1,6 @@ import {v4 as uuidv4} from 'uuid'; import axios from "axios"; +import __CURRENT_URI__ from '../../vite.config.ts'; const uri = __CURRENT_URI__ + ':5000' From 44c40dbb3b13070754386c9029803ce6bd8e9ce8 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:05:57 -0500 Subject: [PATCH 14/24] fix: automatically retrieve URI --- be_repo/modules/job_recommendation_system.py | 3 +-- fe_repo/src/functions/api.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/be_repo/modules/job_recommendation_system.py b/be_repo/modules/job_recommendation_system.py index ff8cd84e6..0bd08f7cb 100644 --- a/be_repo/modules/job_recommendation_system.py +++ b/be_repo/modules/job_recommendation_system.py @@ -40,8 +40,7 @@ def job_recommend(resume_text, user_id): view = CLIView() # Perform Mixed Retrieval for 'JD' Node Label - node_label = "JD" # Adjust as needed; could be dynamic based on user input or other criteria - similar_docs, graph_results = retrieval_engine.perform_mixed_retrieval(resume_text, node_label=node_label) + similar_docs, graph_results = retrieval_engine.perform_mixed_retrieval(resume_text, node_label='JTitle') if not similar_docs and not graph_results: return 'No job recommendations found based on your resume.' diff --git a/fe_repo/src/functions/api.ts b/fe_repo/src/functions/api.ts index 0936281da..4c2392a55 100644 --- a/fe_repo/src/functions/api.ts +++ b/fe_repo/src/functions/api.ts @@ -1,6 +1,5 @@ import {v4 as uuidv4} from 'uuid'; import axios from "axios"; -import __CURRENT_URI__ from '../../vite.config.ts'; const uri = __CURRENT_URI__ + ':5000' From 211f63d46f78ef796d19d9ea837baed014dc5bb3 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:08:24 -0500 Subject: [PATCH 15/24] fix: automatically retrieve URI --- fe_repo/src/functions/api.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fe_repo/src/functions/api.test.ts b/fe_repo/src/functions/api.test.ts index bd0f8ec06..c0dfb1701 100644 --- a/fe_repo/src/functions/api.test.ts +++ b/fe_repo/src/functions/api.test.ts @@ -1,5 +1,7 @@ import {expect, test} from 'vitest'; -import {analyze, getHasResume, getUserId, login, sendMessage, suggest, uploadFile, suggestJob} from "./api.ts"; +import {analyze, getHasResume, getUserId, login, sendMessage, suggest, suggestJob, uploadFile} from "./api.ts"; + +global.__CURRENT_URI__ = 'http://localhost'; test('sendMessage', () => { expect(sendMessage("I'm adam")).toBeDefined(); From 48312d38485044de1be63b0750d5b92c0e899216 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:11:16 -0500 Subject: [PATCH 16/24] fix: automatically retrieve URI --- fe_repo/src/functions/api.test.ts | 2 -- fe_repo/vitest.config.ts | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fe_repo/src/functions/api.test.ts b/fe_repo/src/functions/api.test.ts index c0dfb1701..177b43048 100644 --- a/fe_repo/src/functions/api.test.ts +++ b/fe_repo/src/functions/api.test.ts @@ -1,8 +1,6 @@ import {expect, test} from 'vitest'; import {analyze, getHasResume, getUserId, login, sendMessage, suggest, suggestJob, uploadFile} from "./api.ts"; -global.__CURRENT_URI__ = 'http://localhost'; - test('sendMessage', () => { expect(sendMessage("I'm adam")).toBeDefined(); }); diff --git a/fe_repo/vitest.config.ts b/fe_repo/vitest.config.ts index 09243618c..4d659e4ac 100644 --- a/fe_repo/vitest.config.ts +++ b/fe_repo/vitest.config.ts @@ -1,5 +1,5 @@ // vitest.config.ts -import { defineConfig } from 'vitest/config' +import {defineConfig} from 'vitest/config' export default defineConfig({ test: { @@ -8,4 +8,7 @@ export default defineConfig({ exclude: ['**/*/index.ts', '**/*/*.d.ts', '**/*/*.test.ts', '**/*/*.tsx'] }, }, + define: { + __CURRENT_URI__: JSON.stringify('http://localhost') + } }) From ef3285073e29c5836aba2586ed79057423dab98c Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:17:27 -0500 Subject: [PATCH 17/24] fix: automatically retrieve URI --- be_repo/requirements.txt | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/be_repo/requirements.txt b/be_repo/requirements.txt index a7ac69383..28a3a8aa6 100644 --- a/be_repo/requirements.txt +++ b/be_repo/requirements.txt @@ -1,25 +1,19 @@ -Flask==3.0.3 -click>=8.1.0 +chromedriver_autoinstaller==0.6.4 +Flask==3.1.0 Flask_Cors==5.0.0 -openai==1.54.4 +langchain==0.3.9 +langchain_community==0.3.8 +langchain_neo4j==0.1.1 +langchain_openai==0.2.10 +langgraph==0.2.53 +neo4j==5.27.0 +openai==1.55.3 pandas==1.5.3 +protobuf==3.20.2 pymongo==4.10.1 PyPDF2==3.0.1 -qdrant_client==1.12.0 +pytest==8.3.4 +PyVirtualDisplay==3.0 +qdrant_client==1.12.1 +selenium==4.27.1 tqdm==4.66.2 -selenium==4.26.1 -google-auth==2.36.0 -google-auth-oauthlib==1.2.1 -chromedriver-autoinstaller==0.6.4 -langgraph==0.2.48 -langchain -langsmith -langchain_community -langchain-openai -langchain-neo4j -neo4j>=5.0.0,<6.0.0 -protobuf==3.20.2 -pytest>=7.0.0 -pyvirtualdisplay>=3.0 -grpcio-tools==1.48.2 -tiktoken>=0.7.0 \ No newline at end of file From 85fdf363a67405c7214533b5671706748d2a8ee7 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:19:40 -0500 Subject: [PATCH 18/24] fix: automatically retrieve URI --- be_repo/requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/be_repo/requirements.txt b/be_repo/requirements.txt index 28a3a8aa6..bcd39f4fd 100644 --- a/be_repo/requirements.txt +++ b/be_repo/requirements.txt @@ -17,3 +17,6 @@ PyVirtualDisplay==3.0 qdrant_client==1.12.1 selenium==4.27.1 tqdm==4.66.2 +google-auth>=2.0.0 +google-auth-oauthlib>=0.4.0 +google-auth-httplib2>=0.1.0 From 11f977d2b5aeb643f1f70b5309790bb052e60d89 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:25:48 -0500 Subject: [PATCH 19/24] fix: increase wait time --- be_repo/tests/test_e2e.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/be_repo/tests/test_e2e.py b/be_repo/tests/test_e2e.py index be899adff..01cfae170 100644 --- a/be_repo/tests/test_e2e.py +++ b/be_repo/tests/test_e2e.py @@ -42,7 +42,7 @@ def driver(): @pytest.fixture def wait(driver): - return WebDriverWait(driver, 30) + return WebDriverWait(driver, 50) def upload_resume(driver, wait): From 7f307e237d5abe94d93e57996e444fbb360fcfed Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:32:35 -0500 Subject: [PATCH 20/24] fix: increase wait time --- fe_repo/src/functions/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/fe_repo/src/functions/api.ts b/fe_repo/src/functions/api.ts index 4c2392a55..d029af915 100644 --- a/fe_repo/src/functions/api.ts +++ b/fe_repo/src/functions/api.ts @@ -148,6 +148,7 @@ export async function login(credential: string): Promise { { headers: { 'Content-Type': 'multipart/form-data' } }) .then(resp => { alert("Login successful"); + setHasResume(false); return resp.data.user_id; }) .catch(error => { From 51d87dd9b7ddff6ce0e59dbf6591ab9536aa6e36 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:43:15 -0500 Subject: [PATCH 21/24] fix: increase wait time --- fe_repo/vitest.config.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fe_repo/vitest.config.ts b/fe_repo/vitest.config.ts index 4d659e4ac..d464c6a16 100644 --- a/fe_repo/vitest.config.ts +++ b/fe_repo/vitest.config.ts @@ -1,14 +1,16 @@ // vitest.config.ts import {defineConfig} from 'vitest/config' -export default defineConfig({ - test: { - coverage: { - include: ['src'], - exclude: ['**/*/index.ts', '**/*/*.d.ts', '**/*/*.test.ts', '**/*/*.tsx'] +export default defineConfig(({command}) => { + return { + test: { + coverage: { + include: ['src'], + exclude: ['**/*/index.ts', '**/*/*.d.ts', '**/*/*.test.ts', '**/*/*.tsx'] + }, + }, + define: { + __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://cvcoach.site' : 'http://localhost') }, - }, - define: { - __CURRENT_URI__: JSON.stringify('http://localhost') } }) From e5e33aa129741cfd4e0d579d05b20d9d7887021f Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:50:33 -0500 Subject: [PATCH 22/24] fix: increase wait time --- fe_repo/vite.config.ts | 2 +- fe_repo/vitest.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fe_repo/vite.config.ts b/fe_repo/vite.config.ts index 0e5d90193..b263e5e25 100644 --- a/fe_repo/vite.config.ts +++ b/fe_repo/vite.config.ts @@ -14,7 +14,7 @@ export default defineConfig(({command}) => { }, plugins: [react()], define: { - __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://cvcoach.site' : 'http://localhost') + __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://34.23.225.150' : 'http://localhost') } }; }) diff --git a/fe_repo/vitest.config.ts b/fe_repo/vitest.config.ts index d464c6a16..f62314082 100644 --- a/fe_repo/vitest.config.ts +++ b/fe_repo/vitest.config.ts @@ -10,7 +10,7 @@ export default defineConfig(({command}) => { }, }, define: { - __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://cvcoach.site' : 'http://localhost') + __CURRENT_URI__: JSON.stringify(command == 'serve' ? 'http://34.23.225.150' : 'http://localhost') }, } }) From 82e4a06b003042472e88a26dbccaa4a4cdc8286d Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 15:58:57 -0500 Subject: [PATCH 23/24] fix: increase wait time --- be_repo/modules/job_recommendation_system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/be_repo/modules/job_recommendation_system.py b/be_repo/modules/job_recommendation_system.py index 0bd08f7cb..ee84e71b4 100644 --- a/be_repo/modules/job_recommendation_system.py +++ b/be_repo/modules/job_recommendation_system.py @@ -39,7 +39,7 @@ def job_recommend(resume_text, user_id): # Initialize View view = CLIView() - # Perform Mixed Retrieval for 'JD' Node Label + # Perform Mixed Retrieval similar_docs, graph_results = retrieval_engine.perform_mixed_retrieval(resume_text, node_label='JTitle') if not similar_docs and not graph_results: From aa625d406c38c3e277d6ff5bab04e5c3cc521763 Mon Sep 17 00:00:00 2001 From: Linchen Xu <592789211@qq.com> Date: Sun, 1 Dec 2024 17:35:51 -0500 Subject: [PATCH 24/24] fix: increase wait time --- fe_repo/src/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fe_repo/src/App.tsx b/fe_repo/src/App.tsx index bccec274f..277305d25 100644 --- a/fe_repo/src/App.tsx +++ b/fe_repo/src/App.tsx @@ -108,7 +108,7 @@ function App() { }; // show loading message setMessages((messages) => [...messages, { - text: 'Suggest jobs', + text: 'Suggested jobs', isUser: true }, sendingMessage]); // show loading message @@ -118,7 +118,7 @@ function App() { } else { sendingMessage.text = ( <> -
Suggested questions:
{response.response}
+
Suggested jobs:
{response.response}
); }