Gaykar commited on
Commit
fd01f65
·
1 Parent(s): 8e7153b

made chnages in graph and tools

Browse files
Notebooks/CodeForge.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
app/agents/agents.py CHANGED
@@ -2,6 +2,10 @@ from langchain_groq import ChatGroq
2
  from app.schemas.pydanticschema import ResumeExtract,JobDescriptionExtract,SkillGapAnalysis
3
  from app.core.config import settings
4
  from app.tools.tools import roadmap_planner_agent_tools
 
 
 
 
5
  import os
6
 
7
  if "GROQ_API_KEY" not in os.environ:
@@ -49,11 +53,15 @@ gap_analysis_agent=gap_analysis_agent.with_structured_output(
49
  strict=True
50
  )
51
 
52
-
53
-
54
- roadmap_planner_agent=ChatGroq(
55
- model="qwen/qwen3-32b",
56
- temperature=0.2,
 
 
 
 
 
 
57
  )
58
-
59
- roadmap_planner_agent=roadmap_planner_agent.bind_tools(roadmap_planner_agent_tools)
 
2
  from app.schemas.pydanticschema import ResumeExtract,JobDescriptionExtract,SkillGapAnalysis
3
  from app.core.config import settings
4
  from app.tools.tools import roadmap_planner_agent_tools
5
+ from app.prompts.roadmap_planner_agent_prompt import roadmap_planner_agent_prompt
6
+ from typing import Any
7
+ from langchain.agents import create_agent
8
+ from langchain.agents.middleware import ToolCallLimitMiddleware
9
  import os
10
 
11
  if "GROQ_API_KEY" not in os.environ:
 
53
  strict=True
54
  )
55
 
56
+ roadmap_planner_agent = create_agent(
57
+ model="qwen/qwen3-32b",
58
+ tools=roadmap_planner_agent_tools,
59
+ system_prompt=roadmap_planner_agent_prompt,
60
+ middleware=[
61
+ ToolCallLimitMiddleware[Any, None](
62
+ tool_name="search_courses",
63
+ run_limit=4,
64
+ thread_limit=10,
65
+ )
66
+ ],
67
  )
 
 
app/graph.py CHANGED
@@ -1,42 +1,50 @@
1
  from app.state.state import OnboardingState
2
  from app.nodes.graphnodes import *
3
  from langgraph.prebuilt import ToolNode ,tools_condition
 
4
  from langgraph.graph import StateGraph,END,START
5
 
6
  builder = StateGraph(OnboardingState)
7
 
 
8
  # Define Nodes
9
  builder.add_node("input_node", input_node)
10
  builder.add_node("resume_data_extraction", extractResumeDataNode)
11
  builder.add_node("jd_data_extraction", extractJDDataNode)
12
  builder.add_node("skill_gap_analysis", skill_gap_node)
13
- builder.add_node("roadmap_planning_agent", roadmap_planning_node)
14
- builder.add_node("tools", tool_node) # Named 'tools' for tools_condition compatibility
 
 
 
 
 
15
  builder.add_node("finalize_state", finalize_state_node)
16
 
17
- # Define Entry Point and initial Extraction Parallelism
18
- builder.set_entry_point("input_node")
19
  builder.add_edge("input_node", "resume_data_extraction")
20
  builder.add_edge("input_node", "jd_data_extraction")
21
 
22
- # Join Extractions into Gap Analysis
23
  builder.add_edge("resume_data_extraction", "skill_gap_analysis")
24
  builder.add_edge("jd_data_extraction", "skill_gap_analysis")
25
 
26
- # Transition from Analysis to Planning Agent
27
  builder.add_edge("skill_gap_analysis", "roadmap_planning_agent")
28
 
29
- # Agentic ReAct Loop (Planning Agent <-> Tools)
30
  builder.add_conditional_edges(
31
  "roadmap_planning_agent",
32
- tools_condition,
33
  {
34
- "tools": "tools",
35
- "__end__": "finalize_state" # tools_condition returns '__end__' when no tools are called
36
  }
37
  )
38
 
 
39
  builder.add_edge("tools", "roadmap_planning_agent")
40
- builder.add_edge("finalize_state", END)
41
 
 
42
  graph = builder.compile()
 
1
  from app.state.state import OnboardingState
2
  from app.nodes.graphnodes import *
3
  from langgraph.prebuilt import ToolNode ,tools_condition
4
+ from app.agents.agents import roadmap_planner_agent
5
  from langgraph.graph import StateGraph,END,START
6
 
7
  builder = StateGraph(OnboardingState)
8
 
9
+ # Define Nodes
10
  # Define Nodes
11
  builder.add_node("input_node", input_node)
12
  builder.add_node("resume_data_extraction", extractResumeDataNode)
13
  builder.add_node("jd_data_extraction", extractJDDataNode)
14
  builder.add_node("skill_gap_analysis", skill_gap_node)
15
+
16
+ # The ReAct Agent Node
17
+ builder.add_node("roadmap_planning_agent", roadmap_planner_agent)
18
+
19
+ # The Tool Execution Node (Required for the loop)
20
+ builder.add_node("tools", ToolNode(roadmap_planner_agent_tools))
21
+
22
  builder.add_node("finalize_state", finalize_state_node)
23
 
24
+ # 5. Define Edges and Workflow
25
+ builder.add_edge(START, "input_node")
26
  builder.add_edge("input_node", "resume_data_extraction")
27
  builder.add_edge("input_node", "jd_data_extraction")
28
 
29
+ # Join Parallel Extractions
30
  builder.add_edge("resume_data_extraction", "skill_gap_analysis")
31
  builder.add_edge("jd_data_extraction", "skill_gap_analysis")
32
 
33
+ # Start the Planning Phase
34
  builder.add_edge("skill_gap_analysis", "roadmap_planning_agent")
35
 
36
+ # Agentic ReAct Loop
37
  builder.add_conditional_edges(
38
  "roadmap_planning_agent",
39
+ tools_condition, # Built-in: routes to "tools" if the model calls a tool
40
  {
41
+ "tools": "tools",
42
+ END: "finalize_state" # Routes to finalize if the model gives a final answer
43
  }
44
  )
45
 
46
+ # Loop back to agent after tool execution
47
  builder.add_edge("tools", "roadmap_planning_agent")
 
48
 
49
+ # 6. Compile
50
  graph = builder.compile()
app/nodes/graphnodes.py CHANGED
@@ -124,24 +124,6 @@ def skill_gap_node(state: OnboardingState):
124
  return {"skill_gap_analysis_data": result["parsed"]}
125
 
126
 
127
-
128
-
129
- def roadmap_planning_node(state: OnboardingState):
130
-
131
- """
132
- The agent's 'thinking' node. It looks at the Skill Gaps and
133
- decides which tool to call next.
134
- """
135
- skill_gap_data = state["skill_gap_analysis_data"]
136
-
137
- skill_gap_data= skill_gap_data.model_dump()
138
-
139
- system_prompt = SystemMessage(content=roadmap_planner_agent_prompt)
140
- input_msg = HumanMessage(content=f"<skill_gap_data> {skill_gap_data} </skill_gap_data>")
141
-
142
- response = roadmap_planner_agent.invoke([system_prompt, input_msg] + state["messages"])
143
-
144
- return {"messages": [response]}
145
 
146
 
147
  def finalize_state_node(state: OnboardingState):
 
124
  return {"skill_gap_analysis_data": result["parsed"]}
125
 
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
 
129
  def finalize_state_node(state: OnboardingState):
app/schemas/pydanticschema.py CHANGED
@@ -317,10 +317,12 @@ class SkillGapAnalysis(BaseModel):
317
  )
318
 
319
 
 
 
320
  class RoadmapStep(BaseModel):
321
  course_id: str
322
  title: str
323
- reasoning: str = Field(..., description="Why this specific course was chosen for this user")
324
  is_foundation: bool
325
  sequence_order: int = Field(..., description="The order in which the course should be taken")
326
 
@@ -328,4 +330,12 @@ class LearningRoadmap(BaseModel):
328
  candidate_name: str
329
  target_role: str
330
  roadmap: List[RoadmapStep]
331
- onboarding_summary: str
 
 
 
 
 
 
 
 
 
317
  )
318
 
319
 
320
+
321
+ # Schema for learning_roadmap tool
322
  class RoadmapStep(BaseModel):
323
  course_id: str
324
  title: str
325
+ reasoning: str = Field(..., description="Why this specific course was chosen for this user tell in short 10-15 words strictly")
326
  is_foundation: bool
327
  sequence_order: int = Field(..., description="The order in which the course should be taken")
328
 
 
330
  candidate_name: str
331
  target_role: str
332
  roadmap: List[RoadmapStep]
333
+ onboarding_summary: str
334
+
335
+
336
+
337
+
338
+ # Schema for search_courses tool
339
+
340
+ class SearchCourse(BaseModel):
341
+ query:str=Field(..., description="The skill to find with semantic terms (e.g., 'FastAPI', 'PostgreSQL', 'Docker','Enterprise VMS Strategy','Utilization Management')")
app/tools/tools.py CHANGED
@@ -1,7 +1,7 @@
1
  from langchain_core.tools import tool
2
  from typing import Optional
3
  from app.utils.vectordatabase import retriever
4
- from app.schemas.pydanticschema import LearningRoadmap
5
  import json
6
  from typing import Dict, List,Any
7
  from pathlib import Path
@@ -68,7 +68,7 @@ def submit_final_roadmap(candidate_name, target_role, roadmap, onboarding_summar
68
  return result
69
 
70
 
71
- @tool
72
  def submit_mermaid_visualization(mermaid_code: str):
73
  """
74
  STRICTLY call this tool to save the Mermaid.js visualization of the roadmap.
 
1
  from langchain_core.tools import tool
2
  from typing import Optional
3
  from app.utils.vectordatabase import retriever
4
+ from app.schemas.pydanticschema import LearningRoadmap,SearchCourse
5
  import json
6
  from typing import Dict, List,Any
7
  from pathlib import Path
 
68
  return result
69
 
70
 
71
+ @tool(args_schema=SearchCourse)
72
  def submit_mermaid_visualization(mermaid_code: str):
73
  """
74
  STRICTLY call this tool to save the Mermaid.js visualization of the roadmap.