agents icon indicating copy to clipboard operation
agents copied to clipboard

Pydantic Validation Issues for nullable tool fields

Open chasemcdo opened this issue 2 weeks ago • 2 comments

Bug Description

When an agent tries to call a tool which has a nullable parameter but does not provide a value for said parameter it fails pydantic model validation.

Specifically the tools are defined as per the docs via:

from livekit.agents.llm import function_tool

async def tool_method(context: RunContext, non_nullable: str, nullable: str | None = None) -> Dict[str, Any]:
    # method cost
    return {"success": "ok"}

function_tool(tool_method, name="tool name", description="description")

Expected Behavior

Not get a validation error and use default parameter

Reproduction Steps

1. define tools as per the bug description
2. get agent to call tool without setting the nullable parameter
3. get validation error:

pydantic_core._pydantic_core.ValidationError: 1 validation error for ToolMethodArgs
nullable
  Field required [type=missing, input_value={'non_nullable': 'value'}, input_type=dict]

...
- Sample code snippet, or a GitHub Gist link -

Operating System

MacOS 26.0.1 (25A362)

Models Used

Deepgram Nova 3, Gemini 2.5 Flash, Cartesia Sonic 2

Package Versions

livekit-agents >= 1.2.17

Session/Room/Call IDs

No response

Proposed Solution


Additional Context

This issue is presently blocking an update from LK version 1.2.14 and was originally observed on version 1.2.17 and continues to occur on 1.3.3.

I've taken a glance through the source code and cannot identify any recent changes to this code related to this error, but this does not happen on the current version of 1.2.14 but as of 1.2.17 this happens very consistently.

Screenshots and Recordings

No response

chasemcdo avatar Nov 21 '25 19:11 chasemcdo

Can you share the full traceback or the example? I cannot reproduce it with the following tool call, also tried to remove the nullable var from the arguments manually in llm_node

    @function_tool
    async def get_weather(self, location: str, date: str | None = None) -> str:
        """
        Called when the user asks about the weather.

        Args:
            location: The location to get the weather for
            date: The date to get the weather for, if user does not provide a date, ignore it.
        """
        logger.info(f"Getting weather for {location} for date {date}")
        return f"The weather in {location} is sunny {date or 'today'}."

    async def llm_node(self, chat_ctx: ChatContext, tools: list[FunctionTool], model_settings: ModelSettings):
        async for chunk in Agent.default.llm_node(self, chat_ctx, tools, model_settings):
            if isinstance(chunk, ChatChunk) and chunk.delta and chunk.delta.tool_calls:
                for tool_call in chunk.delta.tool_calls:
                    logger.info(f"Tool call: {tool_call}")
                    if tool_call.name == "get_weather":
                        args = json.loads(tool_call.arguments)
                        args.pop("date", None)
                        tool_call.arguments = json.dumps(args)
                    logger.info(f"Tool call after: {tool_call}")
            yield chunk

longcw avatar Nov 24 '25 08:11 longcw

Hey @longcw here is the complete stacktrace printed by my service (note your code is not using programmatic tool creation as shown in my ticket which could be the reason you are unable to reproduce):

ERROR  livekit.agents   tried to call AI function `TransferCall` with invalid arguments                             {"room_name": "call_yH7uJ3sNu2sa", "external_number": "+1234567890",          
                        Traceback (most recent call last):                                                          "trunk_number": "+1234567890", "function": "TransferCall", "arguments": "{\"phone_number\":
                        File                                                                                      \"1234567890\"}", "speech_id": "speech_00a9d4b2018b", "pid": 43126, "job_id":               
                        "/path/to/livekit-workers/venv/lib/python3.11/site-packages/l "AJ_jKiindanenJA", "room_id": "RM_RaN36KY8tbX5"}                                            
                        ivekit/agents/voice/generation.py", line 490, in _execute_tools_task                                                                                                                    
                            fnc_args, fnc_kwargs = llm_utils.prepare_function_arguments(                                                                                                                        
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                        
                        File                                                                                                                                                                                  
                        "/path/to/livekit-workers/venv/lib/python3.11/site-packages/l                                                                                             
                        ivekit/agents/llm/utils.py", line 383, in prepare_function_arguments                                                                                                                    
                            model = model_type.model_validate(args_dict)  # can raise ValidationError                                                                                                           
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                        
                        File                                                                                                                                                                                  
                        "/path/to/livekit-workers/venv/lib/python3.11/site-packages/p                                                                                             
                        ydantic/main.py", line 716, in model_validate                                                                                                                                           
                            return cls.__pydantic_validator__.validate_python(                                                                                                                                  
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                  
                        pydantic_core._pydantic_core.ValidationError: 1 validation error for TransferCallArgs                                                                                                   
                        dtmf_tones                                                                                                                                                                              
                        Field required [type=missing, input_value={'phone_number': '1234567890'},                                                                                                             
                        input_type=dict]                                                                                                                                                                        
                            For further information visit https://errors.pydantic.dev/2.12/v/missing  

chasemcdo avatar Nov 24 '25 14:11 chasemcdo