Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
markns opened this issue Mar 22, 2025 · 3 comments
Closed
Labels
bug Something isn't working

Comments

@markns
Copy link

markns commented Mar 22, 2025

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
@markns markns added the bug Something isn't working label Mar 22, 2025
@rm-openai
Copy link
Collaborator

Looking into it, thanks!

@rm-openai
Copy link
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
Copy link
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
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants