krinya's picture
feat: Add configurable recursion limit for LangGraph agent
67e3a24
Raw
History Blame Contribute Delete
2.56 kB
import os
from typing import Literal, Optional
from langchain_core.messages import BaseMessage
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import tools_condition
from langgraph.checkpoint.base import BaseCheckpointSaver
from pydantic import BaseModel, Field
from dotenv import load_dotenv
from .agent_node import agent_node
from .tools_node import tool_node
load_dotenv()
class AgentConfig(BaseModel):
"""Configuration for the agent graph with validation."""
model_name: str = Field(default_factory=lambda: os.getenv("MODEL_NAME", "gpt-5-mini"), description="LLM model to use")
model_provider: str = Field(default_factory=lambda: os.getenv("MODEL_PROVIDER", "openai"), description="Model provider")
enable_checkpointing: bool = Field(default=True, description="Enable state persistence")
max_iterations: int = Field(default=10, description="Maximum agent iterations")
recursion_limit: int = Field(default_factory=lambda: int(os.getenv("LANGRAPH_RECURSION_LIMIT", "100")), description="Maximum recursion limit for LangGraph")
def create_agent_graph(
checkpointer: Optional[BaseCheckpointSaver] = None,
config: Optional[AgentConfig] = None
):
"""
Create the ReAct agent using LangGraph's built-in components with typed state.
Args:
checkpointer: Optional checkpointer for state persistence
config: Optional agent configuration
Returns:
Compiled LangGraph with built-in state management
"""
if config is None:
config = AgentConfig()
# Initialize StateGraph with built-in MessagesState (typed)
workflow = StateGraph(MessagesState)
# Add nodes using built-in components with validation
workflow.add_node("agent", agent_node)
workflow.add_node("tools", tool_node)
# Add edges using built-in routing patterns
workflow.add_edge(START, "agent")
# Use built-in tools_condition with proper typing
workflow.add_conditional_edges(
"agent",
tools_condition, # Built-in condition with proper message type checking
{
"tools": "tools",
END: END,
}
)
# Tools return to agent for continued reasoning (ReAct pattern)
workflow.add_edge("tools", "agent")
# Compile with built-in error handling and validation
compile_config = {}
if checkpointer and config.enable_checkpointing:
compile_config["checkpointer"] = checkpointer
return workflow.compile(**compile_config)