Repository: vercel/ai

Issue #4662: Using openai o*-mini generates an invalid tool's parameters schema.
Created: 2025-02-02T14:22:19Z
Description
When using o1-mini or o3-mini model with function calls, strict: true is added vs gpt-4o that does not have strict flag. This leads to bugs when optional parameters are provided on the schema.
await generateText({
    model: openai("o3-mini"),
    prompt: "What is the weather here?",
    tools: {
      getWeather: tool({
        description: "Get the weather in a location",
        parameters: z.object({
        location: z
          .string()
          .optional()  // Note the optional
//    ...
Same bug happens with .default or .nullable. The root cause seems like when "strict": true is added the schema needs to change its typings as described here:
{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Retrieves current weather for the given location.",
        "strict": true,
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City and country e.g. Bogotá, Colombia"
                },
                "units": {
                    "type": ["string", "null"], // If strict is true, type must change this way. Currently, ai-sdk keeps "string" as type even with strict: true
                    "enum": ["celsius", "fahrenheit"],
                    "description": "Units the temperature will be returned in."
                }
            },
            "required": ["location", "units"],
            "additionalProperties": false
        }
    }
}
As a workaround you can create a OpenAI client that removes strict flag:
const openaiWithWorkaround = createOpenAI({
  fetch: async (url, options) => {
    if (!options?.body) {
      return fetch(url, options);
    }

    // Parse the request body
    const body = JSON.parse(options.body as string);
    
    // Check if there are tools with functions
    if (body.tools?.length > 0) {
      body.tools = body.tools.map((tool: any) => {
        if (tool.type === 'function' && tool.function.strict) {
          // Remove the strict flag if present
          const { strict, ...functionWithoutStrict } = tool.function;
          return {
            ...tool,
            function: functionWithoutStrict
          };
        }
        return tool;
      });
    }

    // Create new options with modified body
    const newOptions = {
      ...options,
      body: JSON.stringify(body)
    };

    console.log(
      `Body ${JSON.stringify(
        JSON.parse((newOptions?.body as string) || "{}"),
        null,
        2
      )}`)

    // Make the actual fetch call
    return fetch(url, newOptions);
  },
});
Surprisingly, when using gpt-4o strict flag is not added vs when o*-mini is used. So I detected this bug when migrating to o3-mini
Code example
Reproduction and workaround here:  https://gist.github.com/double-thinker/f60bde68cd5705a33288f2000eeec53d
AI provider
@ai-sdk/openai 1.1.9
Additional context
No response

Duplicate issue #4681: generateObject throws error with o3-mini when schema has an optional param
Created: 2025-02-03T23:07:27Z
Description
Any optional property in a schema causes the following error:
Error in streaming examples: Error [AI_APICallError]: Invalid schema for response_format 'response': In context=('properties', 'recipe'), 'required' is required to be supplied and to be an array including every key in properties. Missing 'steps'.
The same schema works fine with Flash/Claude/4o. We rely on optional properties pretty heavily.
Code example
const test = await generateObject({
  model: openai("o3-mini"),
  schema: z.object({
    recipe: z.object({
      name: z.string(),
      ingredients: z.array(z.string()),
      steps: z.array(z.string()).optional(),
    }),
  }),
  prompt: 'Generate a lasagna recipe.',
});

AI provider
@ai-sdk/openai 1.1.9
Additional context
No response

Closing comment (2025-02-05T12:08:10Z): Duplicates #4662