Gaykar commited on
Commit
9002aed
·
1 Parent(s): 586b608

removed jd agent

Browse files
Files changed (4) hide show
  1. app/graph.py +17 -13
  2. app/nodes/graphnodes.py +24 -28
  3. app/test.py +0 -2
  4. graph.png +0 -0
app/graph.py CHANGED
@@ -5,35 +5,28 @@ from langgraph.graph import StateGraph,END,START
5
  from langgraph.types import RetryPolicy
6
 
7
 
8
- node_retry = RetryPolicy(
9
- max_attempts=3,
10
- initial_interval=1.5,
11
- retry_on=[ConnectionError]
12
- )
13
 
14
  builder = StateGraph(OnboardingState)
15
 
16
  # Define Nodes
17
  builder.add_node("input_node", input_node)
18
  builder.add_node("resume_data_extraction", extractResumeDataNode)
19
- builder.add_node("jd_data_extraction", extractJDDataNode ,retry_policy=node_retry)
20
  builder.add_node("skill_gap_analysis", skill_gap_node)
21
 
22
  # The ReAct Agent Node
23
  builder.add_node("roadmap_planning_agent", roadmap_planning_node)
24
-
25
  # The Tool Execution Node (Required for the loop)
26
  builder.add_node("tools", ToolNode(roadmap_planner_agent_tools))
27
-
28
  # 5. Define Edges and Workflow
29
  builder.add_edge(START, "input_node")
30
  builder.add_edge("input_node", "resume_data_extraction")
31
- builder.add_edge("input_node", "jd_data_extraction")
32
-
33
  # Join Parallel Extractions
34
  builder.add_edge("resume_data_extraction", "skill_gap_analysis")
35
- builder.add_edge("jd_data_extraction", "skill_gap_analysis")
36
-
37
  # Start the Planning Phase
38
  builder.add_edge("skill_gap_analysis", "roadmap_planning_agent")
39
 
@@ -51,4 +44,15 @@ builder.add_conditional_edges(
51
  builder.add_edge("tools", "roadmap_planning_agent")
52
 
53
  # 6. Compile
54
- graph = builder.compile()
 
 
 
 
 
 
 
 
 
 
 
 
5
  from langgraph.types import RetryPolicy
6
 
7
 
8
+ # node_retry = RetryPolicy(
9
+ # max_attempts=3,
10
+ # initial_interval=1.5,
11
+ # retry_on=[ConnectionError]
12
+ # )
13
 
14
  builder = StateGraph(OnboardingState)
15
 
16
  # Define Nodes
17
  builder.add_node("input_node", input_node)
18
  builder.add_node("resume_data_extraction", extractResumeDataNode)
 
19
  builder.add_node("skill_gap_analysis", skill_gap_node)
20
 
21
  # The ReAct Agent Node
22
  builder.add_node("roadmap_planning_agent", roadmap_planning_node)
 
23
  # The Tool Execution Node (Required for the loop)
24
  builder.add_node("tools", ToolNode(roadmap_planner_agent_tools))
 
25
  # 5. Define Edges and Workflow
26
  builder.add_edge(START, "input_node")
27
  builder.add_edge("input_node", "resume_data_extraction")
 
 
28
  # Join Parallel Extractions
29
  builder.add_edge("resume_data_extraction", "skill_gap_analysis")
 
 
30
  # Start the Planning Phase
31
  builder.add_edge("skill_gap_analysis", "roadmap_planning_agent")
32
 
 
44
  builder.add_edge("tools", "roadmap_planning_agent")
45
 
46
  # 6. Compile
47
+ graph = builder.compile()
48
+
49
+
50
+ try:
51
+ # This creates a PNG and saves it to your project folder
52
+ graph_png = graph.get_graph().draw_mermaid_png()
53
+ with open("graph.png", "wb") as f:
54
+ f.write(graph_png)
55
+ print("--- Graph image saved as 'graph.png' ---")
56
+ except Exception as e:
57
+ # This happens if you don't have the 'pypydot' or 'graphviz' dependencies
58
+ print(f"Could not generate graph image: {e}")
app/nodes/graphnodes.py CHANGED
@@ -55,50 +55,46 @@ def extractResumeDataNode(state: OnboardingState):
55
  return {"resume_data": result["parsed"]}
56
 
57
 
58
- def extractJDDataNode(state: OnboardingState):
59
- """Extract structured job description data using JD agent."""
60
- jd_text = state.get("job_description", "")
61
 
62
- if not jd_text or len(jd_text.strip()) < 5:
63
- logger.warning("job_description text is missing from state")
64
- return {"JobDescriptionExtract_data": JobDescriptionExtract()}
65
 
66
- logger.info(f"Extracting JD from {len(jd_text)} characters")
67
 
68
- messages = [
69
- SystemMessage(content=jd_agent_prompt),
70
- HumanMessage(content=f"<job_description>{jd_text}</job_description>")
71
- ]
72
 
73
- try:
74
- result = jd_agent.invoke(messages)
75
- parsed_data = result.get("parsed") if isinstance(result, dict) else result
76
 
77
- if parsed_data.job_title is None and parsed_data.tools_technologies is None:
78
- logger.warning("JD extraction returned empty schema")
79
- else:
80
- logger.info(f"Successfully extracted job title: {parsed_data.job_title}")
81
 
82
- return {"JobDescriptionExtract_data": parsed_data}
83
 
84
- except Exception as e:
85
- logger.error(f"JD extraction failed: {str(e)}")
86
- return {"JobDescriptionExtract_data": JobDescriptionExtract()}
87
 
88
 
89
  def skill_gap_node(state: OnboardingState):
90
  """Analyze skill gaps between resume and job description."""
91
  resume_data = state["resume_data"]
92
  candidate_name = state.get("candidate_name", "Candidate")
93
-
94
  # Convert Pydantic models to lean dicts (exclude None values)
95
  lean_resume_dict = resume_data.model_dump(exclude_none=True)
96
- lean_jd_dict = state["JobDescriptionExtract_data"].model_dump(exclude_none=True)
97
-
98
  # Serialize to JSON
99
  lean_resume_json = json.dumps(lean_resume_dict, indent=2)
100
- lean_jd_json = json.dumps(lean_jd_dict, indent=2)
101
-
102
  # Clean prompt with proper formatting
103
  prompt_text = f"""Analyze the skill gaps for the following candidate:
104
 
@@ -108,7 +104,7 @@ Resume:
108
  {lean_resume_json}
109
 
110
  Job Description:
111
- {lean_jd_json}
112
 
113
  Please provide a detailed skill gap analysis."""
114
 
 
55
  return {"resume_data": result["parsed"]}
56
 
57
 
58
+ # def extractJDDataNode(state: OnboardingState):
59
+ # """Extract structured job description data using JD agent."""
60
+ # jd_text = state.get("job_description", "")
61
 
62
+ # if not jd_text or len(jd_text.strip()) < 5:
63
+ # logger.warning("job_description text is missing from state")
64
+ # return {"JobDescriptionExtract_data": JobDescriptionExtract()}
65
 
66
+ # logger.info(f"Extracting JD from {len(jd_text)} characters")
67
 
68
+ # messages = [
69
+ # SystemMessage(content=jd_agent_prompt),
70
+ # HumanMessage(content=f"<job_description>{jd_text}</job_description>")
71
+ # ]
72
 
73
+ # try:
74
+ # result = jd_agent.invoke(messages)
75
+ # parsed_data = result.get("parsed") if isinstance(result, dict) else result
76
 
77
+ # if parsed_data.job_title is None and parsed_data.tools_technologies is None:
78
+ # logger.warning("JD extraction returned empty schema")
79
+ # else:
80
+ # logger.info(f"Successfully extracted job title: {parsed_data.job_title}")
81
 
82
+ # return {"JobDescriptionExtract_data": parsed_data}
83
 
84
+ # except Exception as e:
85
+ # logger.error(f"JD extraction failed: {str(e)}")
86
+ # return {"JobDescriptionExtract_data": JobDescriptionExtract()}
87
 
88
 
89
  def skill_gap_node(state: OnboardingState):
90
  """Analyze skill gaps between resume and job description."""
91
  resume_data = state["resume_data"]
92
  candidate_name = state.get("candidate_name", "Candidate")
 
93
  # Convert Pydantic models to lean dicts (exclude None values)
94
  lean_resume_dict = resume_data.model_dump(exclude_none=True)
95
+ jd_text = state.get("job_description", "")
 
96
  # Serialize to JSON
97
  lean_resume_json = json.dumps(lean_resume_dict, indent=2)
 
 
98
  # Clean prompt with proper formatting
99
  prompt_text = f"""Analyze the skill gaps for the following candidate:
100
 
 
104
  {lean_resume_json}
105
 
106
  Job Description:
107
+ {jd_text}
108
 
109
  Please provide a detailed skill gap analysis."""
110
 
app/test.py CHANGED
@@ -47,9 +47,7 @@ config = {"configurable": {"thread_id": THREAD_ID}}
47
 
48
  # print(final_result['resume_data'])
49
 
50
- # print()
51
 
52
- # print(final_result['JobDescriptionExtract_data'])
53
 
54
  # print()
55
 
 
47
 
48
  # print(final_result['resume_data'])
49
 
 
50
 
 
51
 
52
  # print()
53
 
graph.png ADDED