langgraph-studio
langgraph-studio copied to clipboard
TypeError: Type is not JSON serializable: ModelMetaclass
Hi, I am using tool calling functions with dynamically created Pydantic BaseModel's as type hints. For example:
def configure_workout_plan_template(state: AgentState, config: dict) -> AgentState:
num_weeks = config.get("configurable", {}).get("num_weeks", 4)
logger.debug(f"Dynamically configuring WorkoutPlan template with {num_weeks} weeks")
workout_plan_template = create_workout_plan_template(num_weeks)
def create_workout_plan(request: workout_plan_template) -> dict: # type: ignore[valid-type]
"""Return a generated workout program"""
return request.dict()
tools = (create_workout_plan,)
logger.debug(f"Tools available: {tools}")
state["workout_planner_tools"] = tools
state["workout_plan_template"] = workout_plan_template
return state
def call_model(state: AgentState, config: dict) -> AgentState:
"""Call the model with the messages"""
messages = state["messages"]
default_model_id = config.get("configurable", {}).get("default_model_id", "anthropic.claude-3-haiku-20240307-v1:0")
tool_choice = config.get("configurable", {}).get("planner_tool_choice", "auto")
tools = state["workout_planner_tools"]
model = _get_model(default_model_id, tools, tool_choice)
response = model.invoke([SystemMessage(SYSTEM_PROMPT), *messages])
state["messages"] = [response]
return state
def create_workout_plan_template(num_weeks: int = 2) -> Type[BaseModel]:
"""Create a generic workout plan template"""
class Day(BaseModel):
"""A single day of the workout program"""
description: str = Field(
description="Description of the workout for this day.",
)
duration: int = Field(
ge=0,
description="Duration of the workout in minutes. Every day requires a duration, even rest days (use 0).",
)
class Week(BaseModel):
"""7 days of the workout program (may inlcude rest days)"""
monday: Day
tuesday: Day
wednesday: Day
thursday: Day
friday: Day
saturday: Day
sunday: Day
class WorkoutPlan(BaseModel):
"""Multi-week workout program"""
weeks: list[Week] = Field(description=f"List of {num_weeks} weeks to structure the workout program.")
# Use validator instead of `conlist` to provide a custom error message
@validator("weeks", allow_reuse=True)
def validate_days_length(cls, value) -> Any:
actual_weeks = len(value)
if actual_weeks != num_weeks:
raise ValueError( # noqa: TRY003
f"Invalid number of workout weeks. Expected {num_weeks} weeks, but got {actual_weeks} weeks. "
"Try the tool call again!"
)
return value
return WorkoutPlan
I'm able to run my graph successfully end-to-end using graph.invoke, but when I try to execute it in LangGraph Studio I get this error:
TypeError: Type is not JSON serializable: ModelMetaclass
I'm not sure if there's a more recommended way for me to implement dynamic BaseModel's which LangGraph Studio already supports, or if it's currently not possible to do this?