Skip to content
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

zodFunction helper rejects default() and min() Zod methods in validation schemas for function calling #1119

Open
1 task done
aleksa-codes opened this issue Oct 4, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@aleksa-codes
Copy link

aleksa-codes commented Oct 4, 2024

Confirm this is a Node library issue and not an underlying OpenAI API issue

  • This is an issue with the Node library

Describe the bug

When using the zodFunction helper found here, Zod schemas containing default() and min() methods are rejected with errors like 'default' is not permitted and 'minLength' is not permitted. These methods work fine when using the example zodFunction utility provided here, but not with the exported helper function. default() for enums seems to work in both cases, but not for other types of values.

To Reproduce

  1. Working Example:
import { z, ZodSchema } from 'zod';
import { JSONSchema } from 'openai/lib/jsonschema';
import { zodToJsonSchema } from 'zod-to-json-schema';
import { RunnableToolFunctionWithParse } from 'openai/lib/RunnableFunction';

export const TimeParams = z.object({
  timeZone: z.string().describe('Time zone of the location').default('Europe/Belgrade'),
});
type TimeParams = z.input<typeof TimeParams>;

const getCurrentTime = async (params: TimeParams) => {
  try {
    const response = await fetch(`https://worldtimeapi.org/api/timezone/${params.timeZone}`);

    const data = await response.json();
    const importantTimeData = {
      abbreviation: data.abbreviation,
      datetime: new Date(data.datetime).toLocaleString('en-US', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
        hour: 'numeric',
        minute: 'numeric',
        timeZone: data.timezone,
        timeZoneName: 'short',
      }),
      timezone: data.timezone,
    };

    return {
      current_time: importantTimeData,
    };
  } catch (error) {
    return {
      error: getErrorMessage(error, 'Failed to fetch the current time'),
    };
  }
};

function zodFunction<T extends object>({
  function: fn,
  schema,
  description = '',
  name,
}: {
  function: (args: T) => Promise<object>;
  schema: ZodSchema<T>;
  description?: string;
  name?: string;
}): RunnableToolFunctionWithParse<T> {
  return {
    type: 'function',
    function: {
      function: fn,
      name: name ?? fn.name,
      description: description,
      parameters: zodToJsonSchema(schema) as JSONSchema,
      parse(input: string): T {
        const obj = JSON.parse(input);
        return schema.parse(obj);
      },
    },
  };
}

export const chatCompletionsTools = [
  zodFunction({
    function: getCurrentTime,
    name: 'getCurrentTime',
    schema: TimeParams,
    description: 'Get the current time in a given location',
  }),
];
  1. Non-Working Example (Using the Official zodFunction Helper):
import { z } from 'zod';
import { zodFunction } from 'openai/helpers/zod';

export const TimeParams = z.object({
  timeZone: z.string().describe('Time zone of the location').default('Europe/Belgrade'),
});
type TimeParams = z.input<typeof TimeParams>;

const getCurrentTime = async (params: TimeParams) => {
  try {
    const response = await fetch(`https://worldtimeapi.org/api/timezone/${params.timeZone}`);

    const data = await response.json();
    const importantTimeData = {
      abbreviation: data.abbreviation,
      datetime: new Date(data.datetime).toLocaleString('en-US', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
        hour: 'numeric',
        minute: 'numeric',
        timeZone: data.timezone,
        timeZoneName: 'short',
      }),
      timezone: data.timezone,
    };

    return {
      current_time: importantTimeData,
    };
  } catch (error) {
    return {
      error: getErrorMessage(error, 'Failed to fetch the current time'),
    };
  }
};

export const chatCompletionsTools = [
  zodFunction({
    function: getCurrentTime,
    name: 'getCurrentTime',
    parameters: TimeParams, 
    description: 'Get the current time in a given location',
  }),
];
  1. Both examples were tested with:
openai.beta.chat.completions.runTools()

Code snippets

No response

OS

Windows 11

Node version

v20.16.0

Library version

4.67.1

@aleksa-codes aleksa-codes added the bug Something isn't working label Oct 4, 2024
@aleksa-codes aleksa-codes changed the title zodFunction helper rejects .default() and .min() zod methods for validation tool call schemas zodFunction Helper Fails to Support .default() and .min() Zod Methods in Validation Schemas for Tool Calls Oct 4, 2024
@aleksa-codes aleksa-codes changed the title zodFunction Helper Fails to Support .default() and .min() Zod Methods in Validation Schemas for Tool Calls zodFunction helper rejects default() and min() Zod methods in validation schemas for function calling Oct 11, 2024
@OB42
Copy link

OB42 commented Oct 16, 2024

same issue here :(

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