Ashmit003's picture
Uploading modified local folder struture
be5f49d
# agent_plan_solve/graph/nodes.py
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState
from agent_plan_solve.graph.state import Plan, PlanState
from agent_plan_solve.utils.llm_config import get_openai_llm
from agent_plan_solve.tools.calculator import calculator_tool
from langchain.agents import load_tools
from typing import Literal
# Load LLM
llm = get_openai_llm()
# Planner prompt
planner_prompt = ChatPromptTemplate.from_messages([
("system",
"For the given task, come up with a step-by-step plan.\n"
"Each step should be self-contained and lead to the final answer.\n"
"Avoid superfluous steps."),
("user", "Prepare a plan to solve the following task:\n{task}\n")
])
planner = planner_prompt | llm.with_structured_output(Plan)
# Toolset
tools = load_tools(
tool_names=["ddg-search", "arxiv", "wikipedia"],
llm=llm
) + [calculator_tool]
# Execution agent prompt
step_prompt = ChatPromptTemplate.from_messages([
("system",
"You're a smart assistant that carefully helps solve complex tasks.\n"
"Use tools to verify facts, compute results, and avoid assumptions."),
("user",
"TASK:\n{task}\n\nPLAN:\n{plan}\n\nSTEP TO EXECUTE:\n{step}\n")
])
class StepState(AgentState):
task: str
plan: str
step: str
execution_agent = create_react_agent(
model=llm,
tools=tools,
state_schema=StepState,
prompt=step_prompt
)
# Final response prompt
final_prompt = PromptTemplate.from_template(
"You're a helpful assistant that has executed a plan.\n"
"Given the results, prepare the final response.\n"
"TASK:\n{task}\n\nPLAN WITH RESULTS:\n{plan}\nFINAL RESPONSE:\n"
)
# Utility functions
def get_current_step(state: PlanState) -> int:
return len(state.get("past_steps", []))
def get_full_plan(state: PlanState) -> str:
full_plan = []
for i, step in enumerate(state["plan"].steps):
full_step = f"# {i+1}. Planned step: {step}\n"
if i < get_current_step(state):
full_step += f"Result: {state['past_steps'][i]}\n"
full_plan.append(full_step)
return "\n".join(full_plan)
# Node functions
async def _build_initial_plan(state: PlanState) -> PlanState:
plan = await planner.ainvoke(state["task"])
return {"plan": plan}
async def _run_step(state: PlanState) -> PlanState:
plan = state["plan"]
current_step = get_current_step(state)
step = await execution_agent.ainvoke({
"plan": get_full_plan(state),
"step": plan.steps[current_step],
"task": state["task"]
})
return {"past_steps": [step["messages"][-1].content]}
async def _get_final_response(state: PlanState) -> PlanState:
final_response = await (final_prompt | llm).ainvoke({
"task": state["task"],
"plan": get_full_plan(state)
})
return {"final_response": final_response}
def _should_continue(state: PlanState) -> Literal["run", "response"]:
return "run" if get_current_step(state) < len(state["plan"].steps) else "response"