Skip to content

tuple or namedtuple as a tool parameter type generates invalid schema #302

Closed
@markns

Description

@markns

Describe the bug

Using tuple or namedtuple as a function_tool parameter type

LatLong = namedtuple('LatLong', "lat long")

@function_tool
def get_weather(lat_long: LatLong) -> Weather:

@function_tool
def get_weather(lat_long: tuple[float, float]) -> Weather:

leads to the following error during function schema creation:

Error getting response: Error code: 400 - 
{'error': {'message': "Invalid schema for function 'get_weather': In context=(), 'minItems' is not permitted.", 
'type': 'invalid_request_error', 'param': 'tools[0].parameters', 'code': 'invalid_function_parameters'}}. 

Debug information

  • Agents SDK version: v0.0.6
  • Python version = 3.13

Repro steps

import asyncio
from collections import namedtuple
from pydantic import BaseModel

from agents import Agent, Runner, function_tool

class Weather(BaseModel):
    lat_long: tuple[float, float]
    temperature_range: str
    conditions: str

LatLong = namedtuple('LatLong', "lat long")

@function_tool
def get_weather(lat_long: LatLong) -> Weather:
    return Weather(lat_long=lat_long, temperature_range="14-20C", conditions="Sunny with wind.")

agent = Agent(
    name="Hello world",
    instructions="You are a helpful agent.",
    tools=[get_weather],
)

async def main():
    result = await Runner.run(agent, input="What's the weather in Tokyo?")
    print(result.final_output)
    # The weather in Tokyo is sunny.

await main()

Expected behavior

Using a tuple or namedtuple as type annotation should work.

I've previously used this function to normalize a schema generated by LLMEasyTools, but not sure how to make that work with the agents sdk yet.

def normalize_for_openai(obj: dict):
    if isinstance(obj, dict):
        # Create a new dict to avoid mutating while iterating
        new_obj = {}
        for k, v in obj.items():
            if k in ("minItems", "maxItems"):
                continue
            elif k == "prefixItems":
                # Assumes all prefixItems are the same type
                first_type = v[0].get("type", "number")
                new_obj["items"] = {"type": first_type}
            else:
                new_obj[k] = normalize_for_openai(v)
        return new_obj
    elif isinstance(obj, list):
        return [normalize_for_openai(i) for i in obj]
    else:
        return obj

Activity

rm-openai

rm-openai commented on Mar 22, 2025

@rm-openai
Collaborator

Looking into it, thanks!

rm-openai

rm-openai commented on Mar 23, 2025

@rm-openai
Collaborator

Looks like the OpenAI API doesn't support prefixItems, which was introduced in JSON Schema Draft 2020-12. And Pydantic (which we use under the hood for tool schema generation) turns tuple[float, float] into prefixItems.

I can ask internally if we can fix this. Until then, unfortunately your best bet is to use 2 floats args, an object, a list, or some other type.

rm-openai

rm-openai commented on Mar 24, 2025

@rm-openai
Collaborator

Reported this internally. Hopefully we support this in the API soon. Closing this out - feel free to create a new issue/reopen if needed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @markns@rm-openai

        Issue actions

          tuple or namedtuple as a tool parameter type generates invalid schema · Issue #302 · openai/openai-agents-python