From dd32428f4dd23d378419ffa2472064964826108e Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 13:23:23 -0500 Subject: [PATCH 01/15] adding a few baseline tools: prettier, eslint, tsup, changesets + basic actions for publish test etc + porting over some of the work already done in the test repo for review --- .changeset/README.md | 8 ++ .changeset/config.json | 14 +++ .eslintrc.js | 27 +++++ .github/workflows/publish.yml | 61 ++++++++++++ .github/workflows/release-pr.yml | 50 ++++++++++ .github/workflows/test.yml | 25 +++++ .prettierignore | 27 +++++ .prettierrc | 28 ++++++ .tool-versions | 2 + .vscode/settings.json | 77 +++++++++++++++ bun.d.ts | 1 + bun.lockb | Bin 0 -> 216693 bytes examples/extract_user/run.ts | 20 ++-- examples/test.ts | 31 ++++++ package.json | 29 +++++- src/constants/modes.ts | 9 ++ src/index.ts | 4 +- src/instructor.ts | 162 ++++++++++++++++++++++++++++++ src/oai/fns/index.ts | 83 ++++++++++++++++ src/oai/fns/schema.ts | 119 ++++++++++++++++++++++ src/oai/params.ts | 67 +++++++++++++ src/oai/parser.ts | 88 +++++++++++++++++ src/patch.ts | 165 ++++++++++++++----------------- tsconfig.json | 34 ++++--- tsup.config.ts | 13 +++ 25 files changed, 1025 insertions(+), 119 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .eslintrc.js create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/release-pr.yml create mode 100644 .github/workflows/test.yml create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .tool-versions create mode 100644 .vscode/settings.json create mode 100644 bun.d.ts create mode 100755 bun.lockb create mode 100644 examples/test.ts create mode 100644 src/constants/modes.ts create mode 100644 src/instructor.ts create mode 100644 src/oai/fns/index.ts create mode 100644 src/oai/fns/schema.ts create mode 100644 src/oai/params.ts create mode 100644 src/oai/parser.ts create mode 100644 tsup.config.ts diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 00000000..e5b6d8d6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000..15320837 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "jxnl/instructor-js" }], + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "ignore": [], + "privatePackages": { + "version": true, + "tag": false + } +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..380fd968 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,27 @@ +module.exports = { + $schema: "https://json.schemastore.org/eslintrc", + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "prettier"], + extends: ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], + rules: { + "prettier/prettier": "error", + "linebreak-style": "off", + "semi": "off", + "indent": "off", + "@typescript-eslint/semi": "off", + "tailwindcss/no-custom-classname": "off", + "react/react-in-jsx-scope": "off", + "react/prop-types": 0, + "react/no-unknown-property": "off", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_" + } + ] + } +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..ad61c49f --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,61 @@ +name: Publish changesets + +on: + pull_request: + types: + - closed + +concurrency: ${{ github.workflow }}-${{ github.ref }} +permissions: {} #reset +jobs: + publish: + if: github.repository == 'jxnl/instructor-js' && github.event.pull_request.merged == true && (startsWith(github.head_ref, 'changeset-release/main') || startsWith(github.head_ref, '_publish-trigger')) + permissions: + contents: write + pull-requests: write + + name: Publish packages + runs-on: ubuntu-latest + + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8.6.9 + + - name: Setup bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + + - name: Setup Node.js 18 + uses: actions/setup-node@v3 + with: + node-version: 18.16.0 + + - name: Install Dependencies + run: bun i + + - name: Creating .npmrc + run: | + cat << EOF > "$HOME/.npmrc" + //registry.npmjs.org/:_authToken=$NPM_TOKEN + EOF + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish packages & create release + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm publish-packages + createGithubReleases: true + + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml new file mode 100644 index 00000000..28054c3e --- /dev/null +++ b/.github/workflows/release-pr.yml @@ -0,0 +1,50 @@ +name: Create changeset release PR + +on: + push: + branches: + - main + +concurrency: ${{ github.workflow }}-${{ github.ref }} +permissions: {} #reset +env: + CI: true + +jobs: + release: + if: github.repository == 'jxnl/instructor-js' + permissions: + contents: write + pull-requests: write + + name: Changeset Release + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: setup node.js + uses: actions/setup-node@v3 + with: + node-version: 18.16.0 + + - uses: oven-sh/setup-bun@v1 + + - name: Setup npmrc + run: echo "//npm.pkg.github.com/:_authToken=$NPM_TOKEN" > .npmrc + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Install Dependencies + run: bun i + + - name: Create version PR + uses: changesets/action@v1 + with: + version: bun run version-packages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..a4a63227 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: test-wf +on: [push] + +jobs: + + test: + name: run-tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: oven-sh/setup-bun@v1 + + - name: setup node.js + uses: actions/setup-node@v3 + with: + node-version: 18.16.0 + + - name: Install Dependencies + run: bun i + + - run: bun test diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..5f803fb3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,27 @@ +node_modules +.next +build +dist +*.tsbuildinfo +*.gitignore +*.svg +*.lock +*.npmignore +*.sql +*.png +*.jpg +*.jpeg +*.gif +*.ico +*.sh +Dockerfile +Dockerfile.* +.env +.env.* +LICENSE +*.log +.DS_Store +.dockerignore +*.patch +*.toml +*.prisma diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..ce6c89e9 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,28 @@ +{ + "endOfLine": "lf", + "semi": false, + "trailingComma": "none", + "arrowParens": "avoid", + "singleQuote": false, + "tabWidth": 2, + "importOrder": [ + "^(react/(.*)$)|^(react$)", + "^(next/(.*)$)|^(next$)", + "", + "", + "^types$", + "^@/types/(.*)$", + "^@/config/(.*)$", + "^@/constants/(.*)$", + "^@/lib/(.*)$", + "", + "^[./]" + ], + "importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"], + "plugins": [ + "@ianvs/prettier-plugin-sort-imports" + ], + "printWidth": 100, + "proseWrap": "never", + "quoteProps": "consistent" +} diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..cfe83282 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 20.9.0 +bun 1.0.15 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..3a837b2f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,77 @@ +{ + "editor.defaultFormatter": "GitHub.copilot", + "editor.tabSize": 2, + "editor.formatOnSave": false, + "editor.formatOnType": false, + "editor.formatOnPaste": false, + "editor.trimAutoWhitespace": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + }, + "[html]": { + "editor.defaultFormatter": "GitHub.copilot" + }, + "[javascript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.autoIndent": "advanced" + }, + "[yaml]": { + "editor.defaultFormatter": "redhat.vscode-yaml", + "editor.autoIndent": "advanced", + "editor.tabSize": 2, + "editor.formatOnSave": true, + "editor.formatOnType": false, + "editor.formatOnPaste": true, + }, + "eslint.validate": [ + "javascript", + "typescript", + "typescriptreact", + ], + "eslint.debug": true, + "eslint.workingDirectories": [ + // Monorepo directories + { + "pattern": "./apps/*/" + }, + { + "pattern": "./functions/*/" + }, + { + "pattern": "./infra/*/" + }, + { + "pattern": "./packages/*/" + } + ], + "github-actions.workflows.pinned.workflows": [ + ".github/workflows/release.yml" + ], + "typescript.tsdk": "./node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.validate.enable": true, + "editor.quickSuggestions": { + "strings": true + }, + "css.validate": false, + "editor.inlineSuggest.enabled": true, + "[typescriptreact]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + "[typescript]": { + "editor.defaultFormatter": "vscode.typescript-language-features", + }, + "yaml.schemas": { + "openapi:v2": "file:///Users/beast/dev/image-gen/gcp/functions/chat/openapi.yaml", + "https://json.schemastore.org/workflows.json": "file:///Users/beast/dev/image-gen/infra/gcp/workflows/dataset-processing-workflow.yml", + }, + "yaml.format.enable": true, + "yaml.schemaStore.enable": true, + "yaml.validate": true +} diff --git a/bun.d.ts b/bun.d.ts new file mode 100644 index 00000000..22f6a666 --- /dev/null +++ b/bun.d.ts @@ -0,0 +1 @@ +/// diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..6ad5168c4c9ff51f24d258a40652d2b40d730dd0 GIT binary patch literal 216693 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%0D9-SYoG{kDx%jR*?aeitN%5I-Q-d@-%wevW} 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%0A?^=CK}=@01L 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 name === name.toUpperCase(), { - message: "name should have uppercase", - }), + name: z.string().refine(name => name === name.toUpperCase(), { + message: "name should have uppercase" + }) }), - max_retries: 3, + max_retries: 3 }) - .then(console.log); + .then(console.log) diff --git a/examples/test.ts b/examples/test.ts new file mode 100644 index 00000000..a2eaef55 --- /dev/null +++ b/examples/test.ts @@ -0,0 +1,31 @@ +import { Instruct } from "@/instructor" +import OpenAI from "openai" +import { z } from "zod" + +const UserSchema = z.object({ + age: z.number(), + name: z.string().refine(name => name.includes(" "), { + message: "Name must contain a space" + }) +}) + +type User = z.infer + +const oai = new OpenAI({ + apiKey: process.env.OPENAI_API_KEY ?? undefined, + organization: process.env.OPENAI_ORG_ID ?? undefined +}) + +const client = new Instruct({ + client: oai, + mode: "" +}) + +const user: User = await client.chat.completions.create({ + messages: [{ role: "user", content: "Jason Liu is 30 years old" }], + model: "gpt-3.5-turbo", + response_model: UserSchema, + max_retries: 3 +}) + +console.log(user) diff --git a/package.json b/package.json index 49bb134e..48411a27 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,19 @@ { - "name": "instructor", + "name": "instructor-js", "version": "0.0.1", "description": "structured outputs for llms", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "prepublish": "tsc", - "build": "tsc" + "build": "tsup", + "lint": "eslint src/", + "type-check": "tsc --noEmit", + "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", + "changeset": "changeset", + "version-packages": "changeset version", + "publish-packages": "tsup && changeset publish" }, "repository": { "type": "git", @@ -31,7 +37,20 @@ "zod-to-json-schema": "^3.22.3" }, "devDependencies": { + "@changesets/changelog-github": "^0.5.0", + "@changesets/cli": "^2.27.1", + "@ianvs/prettier-plugin-sort-imports": "4.1.0", "@types/node": "^20.10.6", + "@typescript-eslint/eslint-plugin": "6.5.0", + "@typescript-eslint/parser": "6.5.0", + "eslint": "^8.40.0", + "eslint-config-prettier": "9.0.0", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^5.0.0", + "husky": "^8.0.3", + "prettier": "3.0.0", + "tsup": "^8.0.1", "typescript": "^5.3.3" } } diff --git a/src/constants/modes.ts b/src/constants/modes.ts new file mode 100644 index 00000000..b3970b32 --- /dev/null +++ b/src/constants/modes.ts @@ -0,0 +1,9 @@ +export const MODE = { + FUNCTIONS: "FUNCTIONS", + TOOLS: "TOOLS", + JSON: "JSON", + MD_JSON: "MD_JSON", + JSON_SCHEMA: "JSON_SCHEMA" +} + +export type MODE = keyof typeof MODE diff --git a/src/index.ts b/src/index.ts index f6a68516..d872246f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ -export * as instructor from "./patch"; -export * from "./patch"; +export * as instructor from "./patch" +export * from "./patch" diff --git a/src/instructor.ts b/src/instructor.ts new file mode 100644 index 00000000..48ebd35c --- /dev/null +++ b/src/instructor.ts @@ -0,0 +1,162 @@ +import { createSchemaFunction } from "@/oai/fns/schema" +import OpenAI from "openai" +import { ChatCompletion, ChatCompletionCreateParamsNonStreaming } from "openai/resources/index.mjs" +import { ZodObject } from "zod" + +import { MODE } from "@/constants/modes" + +import { + OAIBuildFunctionParams, + OAIBuildMessageBasedParams, + OAIBuildToolFunctionParams +} from "./oai/params" +import { + OAIResponseFnArgsParser, + OAIResponseTextParser, + OAIResponseToolArgsParser +} from "./oai/parser" + +const MODE_TO_PARSER = { + [MODE.FUNCTIONS]: OAIResponseFnArgsParser, + [MODE.TOOLS]: OAIResponseToolArgsParser, + [MODE.JSON]: OAIResponseTextParser, + [MODE.MD_JSON]: OAIResponseTextParser, + [MODE.JSON_SCHEMA]: OAIResponseTextParser +} + +const MODE_TO_PARAMS = { + [MODE.FUNCTIONS]: OAIBuildFunctionParams, + [MODE.TOOLS]: OAIBuildToolFunctionParams, + [MODE.JSON]: OAIBuildMessageBasedParams, + [MODE.MD_JSON]: OAIBuildMessageBasedParams, + [MODE.JSON_SCHEMA]: OAIBuildMessageBasedParams +} + +type PatchedChatCompletionCreateParams = ChatCompletionCreateParamsNonStreaming & { + //eslint-disable-next-line @typescript-eslint/no-explicit-any + response_model?: ZodObject + max_retries?: number +} + +export class Instruct { + private client: OpenAI + private mode: MODE + + /** + * Creates an instance of the `Instruct` class. + * @param {OpenAI} client - The OpenAI client. + * @param {string} mode - The mode of operation. + */ + constructor({ client, mode }: { client: OpenAI; mode: MODE }) { + this.client = client + this.mode = mode + } + + /** + * Handles chat completion with retries. + * @param {PatchedChatCompletionCreateParams} params - The parameters for chat completion. + * @returns {Promise} The response from the chat completion. + */ + private chatCompletion = async ({ + response_model, + max_retries = 3, + ...params + }: PatchedChatCompletionCreateParams) => { + let attempts = 0 + + const functionConfig = this.generateSchemaFunction({ + schema: response_model + }) + + const makeCompletionCall = async () => { + try { + const completion = await this.client.chat.completions.create({ + stream: false, + ...params, + ...functionConfig + }) + + const response = this.parseOAIResponse(completion) + + return response + } catch (error) { + throw error + } + } + + const makeCompletionCallWithRetries = async () => { + try { + return await makeCompletionCall() + } catch (error) { + if (attempts < max_retries) { + attempts++ + return await makeCompletionCallWithRetries() + } else { + throw error + } + } + } + + return await makeCompletionCallWithRetries() + } + + private buildChatCompletionParams = ({ + response_model, + ...params + }: PatchedChatCompletionCreateParams) => { + const { definition } = createSchemaFunction({ schema: response_model }) + + const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params) + + return { + stream: false, //TODO: not sure what streaming support looks like TBH + ...paramsForMode + } + } + + /** + * Parses the OAI response. + * @param {ChatCompletion} response - The response from the chat completion. + * @returns {any} The parsed response. + */ + private parseOAIResponse = (response: ChatCompletion) => { + const parser = MODE_TO_PARSER[this.mode] + + return parser(response) + } + + /** + * Generates a schema function. + * @param {ZodSchema} schema - The schema to generate the function from. + * @returns {Object} The generated function configuration. + */ + private generateSchemaFunction({ schema }) { + const { definition } = createSchemaFunction({ schema }) + + return { + function_call: { + name: definition.name + }, + functions: [ + { + name: definition.name, + description: definition.description, + parameters: { + type: "object", + properties: definition.parameters, + required: definition.required + } + } + ] + } + } + + /** + * Public chat interface. + */ + public chat = { + completions: { + create: this.chatCompletion + } + } +} diff --git a/src/oai/fns/index.ts b/src/oai/fns/index.ts new file mode 100644 index 00000000..e5c9df35 --- /dev/null +++ b/src/oai/fns/index.ts @@ -0,0 +1,83 @@ +import { z } from "zod" +import { zodToJsonSchema } from "zod-to-json-schema" + +export type FunctionPayload = { + name: string + description: string + parameters: object + required: string[] +} + +export type FunctionDefinitionParams

, R extends z.ZodType> = { + paramsSchema: P + jsonSchema?: object + name: string + description: string + execute: (params: z.infer

) => Promise> + required?: string[] +} + +export type FunctionDefinitionInterface = { + run: (params: unknown) => Promise + definition: FunctionPayload +} + +/** + * `createFunctionDefinition` is a function that creates a function definition. It creates a runner function + * that validates its parameters against a provided schema before executing the provided function. + * It also creates a payload that describes the function. + * + * @param {FunctionDefinitionParams} params - The parameters for the function definition. + * @returns {FunctionDefinitionInterface} - The function definition runner function and the function payload. + * + * @example + * + * const paramsSchema = z.object({ + * name: z.string(), + * age: z.number() + * }); + * + * const execute = async (params) => { + * return { message: `Hello, ${params.name}. You are ${params.age} years old.` }; + * }; + * + * const functionDefinition = createFunctionDefinition({ + * paramsSchema, + * name: 'greet', + * description: 'Greets a person.', + * execute + * }); + * + */ +function createFunctionDefinition

, R extends z.ZodType>({ + paramsSchema, + jsonSchema, + name, + description, + execute, + required = [] +}: FunctionDefinitionParams): FunctionDefinitionInterface { + const run = async (params: unknown): Promise => { + try { + const validatedParams = paramsSchema.parse(params) + return await execute(validatedParams) + } catch (error) { + console.error(`Error executing function ${name}:`, error) + throw error + } + } + + const functionDefinition: FunctionDefinitionInterface = { + run, + definition: { + name: name, + description: description, + parameters: jsonSchema ?? zodToJsonSchema(paramsSchema), + required + } + } + + return functionDefinition +} + +export { createFunctionDefinition } diff --git a/src/oai/fns/schema.ts b/src/oai/fns/schema.ts new file mode 100644 index 00000000..632bf5a3 --- /dev/null +++ b/src/oai/fns/schema.ts @@ -0,0 +1,119 @@ +import { createFunctionDefinition } from "@/oai/fns" +import { z, ZodArray, ZodBoolean, ZodNumber, ZodObject, ZodRecord, ZodString } from "zod" + +type AnyZodType = z.ZodTypeAny +type PropertyType = "string" | "boolean" | "number" | "object" | "array" + +const getTypeFromZod = (schema: AnyZodType): PropertyType => { + if (schema instanceof ZodNumber) { + return "number" + } + + if (schema instanceof ZodBoolean) { + return "boolean" + } + + if (schema instanceof ZodString) { + return "string" + } + + if (schema instanceof ZodObject) { + return "object" + } + + if (schema instanceof ZodArray) { + return "array" + } + + if (schema instanceof ZodRecord) { + return "object" + } + + return "string" +} + +const getDescriptionAndType = (schema: AnyZodType) => { + const maybeDescription = ` + ${schema._def?.description ?? ""}\n + rules: ${JSON.stringify(schema._def?.checks ?? []) ?? ""} + ` + + if (schema instanceof ZodObject) { + const properties = {} + + for (const key in schema.shape) { + properties[key] = getDescriptionAndType(schema.shape[key]) + } + + return { + type: getTypeFromZod(schema), + description: maybeDescription, + properties + } + } + + if (schema instanceof ZodArray) { + return { + type: getTypeFromZod(schema), + description: maybeDescription, + items: getDescriptionAndType(schema.element) + } + } + + return { + type: getTypeFromZod(schema), + description: maybeDescription + } +} + +/** + * `createSchemaFunction` creates a schema-based function definition using the `createFunctionDefinition` utility. + * The created function always returns null when executed, and its purpose is mainly to provide a structured + * description of the schema in a specific format. + * + * @param {Object} args - The arguments for the function definition. + * @param {z.ZodObject} args.schema - The zod schema object. + * @returns {FunctionDefinitionInterface} - The function definition. + * + * @example + * + * const schema = z.object({ + * name: z.string(), + * age: z.number() + * }); + * + * const schemaFunctionDefinition = createSchemaFunction({ schema, name: 'mySchema', description: 'returns a person object with name and age' }); + * + */ +export function createSchemaFunction({ + schema +}: { + //eslint-disable-next-line @typescript-eslint/no-explicit-any + schema: z.ZodObject +}) { + const propertiesMapping: { + [index: string]: { type: PropertyType; description: string } + } = {} + + for (const key in schema.shape) { + propertiesMapping[key] = getDescriptionAndType(schema.shape[key]) + } + + const requiredParameters = Object.keys(propertiesMapping) + + const name = "return_json" + const description = `Returns the assistant response as JSON.` + + const execute = async (): Promise => { + return null + } + + return createFunctionDefinition({ + paramsSchema: schema, + jsonSchema: propertiesMapping, + name, + description, + execute, + required: requiredParameters + }) +} diff --git a/src/oai/params.ts b/src/oai/params.ts new file mode 100644 index 00000000..e03e6c89 --- /dev/null +++ b/src/oai/params.ts @@ -0,0 +1,67 @@ +import { FunctionPayload } from "./fns" + +export function OAIBuildFunctionParams(definition: FunctionPayload, params) { + return { + ...params, + function_call: { + name: definition.name + }, + functions: [ + ...(params?.functions ?? []), + { + name: definition.name, + description: definition.description, + parameters: { + type: "object", + properties: definition.parameters, + required: definition.required + } + } + ] + } +} + +export function OAIBuildToolFunctionParams(definition: FunctionPayload, params) { + return { + ...params, + tool_choice: { + type: "function", + function: { name: definition.name } + }, + tools: [ + ...(params?.tools ?? []), + { + type: "function", + function: { + name: definition.name, + description: definition.description, + parameters: { + type: "object", + properties: definition.parameters, + required: definition.required + } + } + } + ] + } +} + +export function OAIBuildMessageBasedParams(definition: FunctionPayload, params) { + return { + ...params, + messages: [ + ...(params?.messages ?? []), + { + role: "SYSTEM", + content: ` + Given a user prompt, you will return fully valid JSON based on the following description and schema. + You will return no other prose. You will take into account the descriptions for each paramater within the schema + and return a valid JSON object that matches the schema and those instructions. + + description: ${definition.description} + paramaters: ${JSON.stringify(definition.parameters)} + ` + } + ] + } +} diff --git a/src/oai/parser.ts b/src/oai/parser.ts new file mode 100644 index 00000000..720ac689 --- /dev/null +++ b/src/oai/parser.ts @@ -0,0 +1,88 @@ +import OpenAI from "openai" +import { Stream } from "openai/streaming" + +/** + * `OAIResponseTextParser` parses a JSON string and extracts the text content. + * + * @param {string} data - The JSON string to parse. + * @returns {string} - The extracted text content. + * + */ +export function OAIResponseTextParser( + data: + | string + | Stream + | OpenAI.Chat.Completions.ChatCompletion +) { + const parsedData = typeof data === "string" ? JSON.parse(data) : data + + const text = + parsedData.choices?.[0].delta?.content ?? parsedData?.choices[0]?.message?.content ?? "" + + return text +} + +/** + * `OAIResponseFnArgsParser` parses a JSON string and extracts the function call arguments. + * + * @param {string} data - The JSON string to parse. + * @returns {Object} - The extracted function call arguments. + * + */ +export function OAIResponseFnArgsParser( + data: + | string + | Stream + | OpenAI.Chat.Completions.ChatCompletion +) { + const parsedData = typeof data === "string" ? JSON.parse(data) : data + + const text = + parsedData.choices?.[0]?.delta?.function_call?.arguments ?? + parsedData.choices?.[0]?.message?.function_call?.arguments ?? + null + + return text +} + +/** + * `OAIResponseToolArgsParser` parses a JSON string and extracts the tool call arguments. + * + * @param {string} data - The JSON string to parse. + * @returns {Object} - The extracted tool call arguments. + * + */ +export function OAIResponseToolArgsParser( + data: + | string + | Stream + | OpenAI.Chat.Completions.ChatCompletion +) { + const parsedData = typeof data === "string" ? JSON.parse(data) : data + + const text = + parsedData.choices?.[0]?.delta?.tool_call?.function?.arguments ?? + parsedData.choices?.[0]?.message?.tool_call?.function?.arguments ?? + null + + return text +} + +/** + * `OAIResponseJSONParser` parses a JSON string and extracts the JSON content. + * + * @param {string} data - The JSON string to parse. + * @returns {Object} - The extracted JSON content. + * + */ +export function OAIResponseJSONStringParser( + data: + | string + | Stream + | OpenAI.Chat.Completions.ChatCompletion +) { + const parsedData = typeof data === "string" ? JSON.parse(data) : data + const text = parsedData.choices?.[0]?.delta?.content ?? parsedData?.choices[0]?.message?.content + + return text +} diff --git a/src/patch.ts b/src/patch.ts index acd60ca7..692c52ad 100644 --- a/src/patch.ts +++ b/src/patch.ts @@ -1,39 +1,32 @@ -import OpenAI from "openai"; -import { ZodSchema } from "zod"; -import { JsonSchema7Type, zodToJsonSchema } from "zod-to-json-schema"; - -import { - ChatCompletion, - ChatCompletionCreateParams, - ChatCompletionMessage, -} from "openai/resources"; - -import assert = require("assert"); +import assert from "assert" +import OpenAI, { ChatCompletion, ChatCompletionCreateParams, ChatCompletionMessage } from "openai" +import { ZodSchema } from "zod" +import { JsonSchema7Type, zodToJsonSchema } from "zod-to-json-schema" export enum MODE { FUNCTIONS, TOOLS, JSON, MD_JSON, - JSON_SCHEMA, + JSON_SCHEMA } export class OpenAISchema { - private responseModel: ReturnType | any; + private responseModel: ReturnType | any constructor(public zod_schema: ZodSchema) { - this.responseModel = zodToJsonSchema(zod_schema); + this.responseModel = zodToJsonSchema(zod_schema) } get definitions() { - return this.responseModel["definitions"]; + return this.responseModel["definitions"] } get properties() { - return this.responseModel["properties"]; + return this.responseModel["properties"] } get schema() { - return this.responseModel; + return this.responseModel } get openaiSchema() { @@ -50,22 +43,22 @@ export class OpenAISchema { curr.startsWith("$") || ["title", "description", "additionalProperties"].includes(curr) ) - return acc; - acc[curr] = this.responseModel[curr]; - return acc; + return acc + acc[curr] = this.responseModel[curr] + return acc }, {} as { - [key: string]: object | JsonSchema7Type; + [key: string]: object | JsonSchema7Type } - ), - }; + ) + } } } type PatchedChatCompletionCreateParams = ChatCompletionCreateParams & { - responseModel?: ZodSchema | OpenAISchema; - maxRetries?: number; -}; + responseModel?: ZodSchema | OpenAISchema + maxRetries?: number +} function handleResponseModel( responseModel: ZodSchema | OpenAISchema, @@ -73,54 +66,52 @@ function handleResponseModel( mode: MODE = MODE.FUNCTIONS ): [OpenAISchema, PatchedChatCompletionCreateParams[], MODE] { if (!(responseModel instanceof OpenAISchema)) { - responseModel = new OpenAISchema(responseModel); + responseModel = new OpenAISchema(responseModel) } if (mode === MODE.FUNCTIONS) { - args[0].functions = [responseModel.openaiSchema]; - args[0].function_call = { name: responseModel.openaiSchema.name }; + args[0].functions = [responseModel.openaiSchema] + args[0].function_call = { name: responseModel.openaiSchema.name } } else if (mode === MODE.TOOLS) { - args[0].tools = [ - { type: "function", function: responseModel.openaiSchema }, - ]; + args[0].tools = [{ type: "function", function: responseModel.openaiSchema }] args[0].tool_choice = { type: "function", - function: { name: responseModel.openaiSchema.name }, - }; + function: { name: responseModel.openaiSchema.name } + } } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { let message: string = `As a genius expert, your task is to understand the content and provide the parsed objects in json that match the following json_schema: \n${JSON.stringify( responseModel.properties - )}`; + )}` if (responseModel["definitions"]) { message += `Here are some more definitions to adhere to: \n${JSON.stringify( responseModel.definitions - )}`; + )}` } if (mode === MODE.JSON) { - args[0].response_format = { type: "json_object" }; + args[0].response_format = { type: "json_object" } } else if (mode == MODE.JSON_SCHEMA) { // ! TODO: include json schema in the response args[0].response_format = { - type: "json_object", + type: "json_object" // This is supported my Anyscale but not OpenAI // schema: responseModel.schema, - }; + } } else if (mode === MODE.MD_JSON) { args[0].messages.push({ role: "assistant", - content: "```json", - }); - args[0].stop = "```"; + content: "```json" + }) + args[0].stop = "```" } if (args[0].messages[0].role != "system") { - args[0].messages.unshift({ role: "system", content: message }); + args[0].messages.unshift({ role: "system", content: message }) } else { - args[0].messages[0].content += `\n${message}`; + args[0].messages[0].content += `\n${message}` } } else { - console.error("unknown mode", mode); + console.error("unknown mode", mode) } - return [responseModel, args, mode]; + return [responseModel, args, mode] } function processResponse( @@ -128,98 +119,90 @@ function processResponse( responseModel: OpenAISchema, mode: MODE = MODE.FUNCTIONS ) { - const message = response.choices[0].message; + const message = response.choices[0].message if (mode === MODE.FUNCTIONS) { assert.equal( message.function_call!.name, responseModel.openaiSchema.name, "Function name does not match" - ); - return responseModel.zod_schema.parse( - JSON.parse(message.function_call!.arguments) - ); + ) + return responseModel.zod_schema.parse(JSON.parse(message.function_call!.arguments)) } else if (mode === MODE.TOOLS) { - const tool_call = message.tool_calls![0]; + const tool_call = message.tool_calls![0] assert.equal( tool_call.function.name, responseModel.openaiSchema.name, "Tool name does not match" - ); - return responseModel.zod_schema.parse( - JSON.parse(tool_call.function.arguments) - ); + ) + return responseModel.zod_schema.parse(JSON.parse(tool_call.function.arguments)) } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { - return responseModel.zod_schema.parse(JSON.parse(message.content!)); + return responseModel.zod_schema.parse(JSON.parse(message.content!)) } else { - console.error("unknown mode", mode); + console.error("unknown mode", mode) } } function dumpMessage(message: ChatCompletionMessage) { const ret: ChatCompletionMessage = { role: message.role, - content: message.content || "", - }; + content: message.content || "" + } if (message.tool_calls) { - ret["content"] += JSON.stringify(message.tool_calls); + ret["content"] += JSON.stringify(message.tool_calls) } if (message.function_call) { - ret["content"] += JSON.stringify(message.function_call); + ret["content"] += JSON.stringify(message.function_call) } - return ret; + return ret } export const patch = ({ client, - mode, + mode }: { - client: OpenAI; - responseModel?: ZodSchema | OpenAISchema; - max_retries?: number; - mode?: MODE; + client: OpenAI + responseModel?: ZodSchema | OpenAISchema + max_retries?: number + mode?: MODE }): OpenAI => { client.chat.completions.create = new Proxy(client.chat.completions.create, { async apply(target, ctx, args: PatchedChatCompletionCreateParams[]) { let retries = 0, max_retries = args[0].maxRetries || 1, response: ChatCompletion | undefined = undefined, - responseModel = args[0].responseModel; - [responseModel, args, mode] = handleResponseModel( - responseModel!, - args, - mode - ); - delete args[0].responseModel; - delete args[0].maxRetries; + responseModel = args[0].responseModel + ;[responseModel, args, mode] = handleResponseModel(responseModel!, args, mode) + delete args[0].responseModel + delete args[0].maxRetries while (retries < max_retries) { try { response = (await target.apply( ctx, args as [PatchedChatCompletionCreateParams] - )) as ChatCompletion; - return processResponse(response, responseModel as OpenAISchema, mode); + )) as ChatCompletion + return processResponse(response, responseModel as OpenAISchema, mode) } catch (error: any) { - console.error(error.errors || error); + console.error(error.errors || error) if (!response) { - break; + break } - args[0].messages.push(dumpMessage(response.choices[0].message)); + args[0].messages.push(dumpMessage(response.choices[0].message)) args[0].messages.push({ role: "user", - content: `Recall the function correctly, fix the errors, exceptions found\n${error}`, - }); + content: `Recall the function correctly, fix the errors, exceptions found\n${error}` + }) if (mode == MODE.MD_JSON) { - args[0].messages.push({ role: "assistant", content: "```json" }); + args[0].messages.push({ role: "assistant", content: "```json" }) } - retries++; + retries++ if (retries > max_retries) { - throw error; + throw error } } finally { - response = undefined; + response = undefined } } - }, - }); - return client; -}; + } + }) + return client +} diff --git a/tsconfig.json b/tsconfig.json index 30ad2f6d..9074fbaf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,26 @@ { "compilerOptions": { - "target": "es6", - "module": "commonjs", - "rootDir": "./src", - "outDir": "./dist", + "strict": false, + "noEmit": true, + "allowJs": true, + "jsx": "preserve", + "module": "esnext", + "target": "ESNext", + "skipLibCheck": true, "esModuleInterop": true, - "strict": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "strictPropertyInitialization": false, - "declaration": true - } -} \ No newline at end of file + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "moduleDetection": "force", + "baseUrl": ".", + "lib": ["ESNext", "dom", "dom.iterable", "esnext"], + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "incremental": true, + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 00000000..701fa7fc --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "tsup" + +export default defineConfig(options => { + return { + splitting: true, + entry: ["src/**/*.{ts,tsx}"], + format: ["esm", "cjs"], + dts: true, + minify: true, + clean: true, + ...options + } +}) From ab3c0ccb98b60bc558b19d0be9258f91597a7d0c Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 13:51:53 -0500 Subject: [PATCH 02/15] remove unused and add test --- .gitignore | 92 +++++++++++++++++++++++++++++++++++++++- bun.lockb | Bin 216693 -> 217400 bytes examples/test.ts | 2 +- package.json | 1 + src/instructor.ts | 53 ++++++----------------- src/oai/fns/index.ts | 9 +--- src/oai/fns/schema.ts | 1 - src/oai/parser.ts | 23 ++++------ tests/functions.test.ts | 43 +++++++++++++++++++ 9 files changed, 157 insertions(+), 67 deletions(-) create mode 100644 tests/functions.test.ts diff --git a/.gitignore b/.gitignore index b3eb616a..b8449cf0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,91 @@ -node_modules/ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +.next/ +out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files .env -dist/ \ No newline at end of file +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel +.turbo + +node_modules +.pnp +.pnp.js + +# testing +coverage + +# next.js +.next/ +out/ +build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# turbo +.turbo + +# vercel +.vercel + +dist + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# vim +*.sw* + +# env +.env*.local +.envrc + + +tsconfig.tsbuildinfo + diff --git a/bun.lockb b/bun.lockb index 6ad5168c4c9ff51f24d258a40652d2b40d730dd0..5c3046b9f219fd2dfa9c08ece1f52289a864d186 100755 GIT binary patch delta 36148 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 delta 34744 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%0Aglm@x5zI5(7XV^H3B{&cnN@u1lBGA;44ZA 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 diff --git a/examples/test.ts b/examples/test.ts index a2eaef55..06ee26ff 100644 --- a/examples/test.ts +++ b/examples/test.ts @@ -18,7 +18,7 @@ const oai = new OpenAI({ const client = new Instruct({ client: oai, - mode: "" + mode: "FUNCTIONS" }) const user: User = await client.chat.completions.create({ diff --git a/package.json b/package.json index 48411a27..777bd4dd 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.1", "@ianvs/prettier-plugin-sort-imports": "4.1.0", + "@types/bun": "^1.0.0", "@types/node": "^20.10.6", "@typescript-eslint/eslint-plugin": "6.5.0", "@typescript-eslint/parser": "6.5.0", diff --git a/src/instructor.ts b/src/instructor.ts index 48ebd35c..413a0b6f 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -12,16 +12,16 @@ import { } from "./oai/params" import { OAIResponseFnArgsParser, - OAIResponseTextParser, + OAIResponseJSONStringParser, OAIResponseToolArgsParser } from "./oai/parser" const MODE_TO_PARSER = { [MODE.FUNCTIONS]: OAIResponseFnArgsParser, [MODE.TOOLS]: OAIResponseToolArgsParser, - [MODE.JSON]: OAIResponseTextParser, - [MODE.MD_JSON]: OAIResponseTextParser, - [MODE.JSON_SCHEMA]: OAIResponseTextParser + [MODE.JSON]: OAIResponseJSONStringParser, + [MODE.MD_JSON]: OAIResponseJSONStringParser, + [MODE.JSON_SCHEMA]: OAIResponseJSONStringParser } const MODE_TO_PARAMS = { @@ -58,24 +58,16 @@ export class Instruct { * @returns {Promise} The response from the chat completion. */ private chatCompletion = async ({ - response_model, max_retries = 3, ...params }: PatchedChatCompletionCreateParams) => { let attempts = 0 - const functionConfig = this.generateSchemaFunction({ - schema: response_model - }) + const completionParams = this.buildChatCompletionParams(params) const makeCompletionCall = async () => { try { - const completion = await this.client.chat.completions.create({ - stream: false, - ...params, - ...functionConfig - }) - + const completion = await this.client.chat.completions.create(completionParams) const response = this.parseOAIResponse(completion) return response @@ -100,10 +92,15 @@ export class Instruct { return await makeCompletionCallWithRetries() } + /** + * Builds the chat completion parameters. + * @param {PatchedChatCompletionCreateParams} params - The parameters for chat completion. + * @returns {ChatCompletionCreateParamsNonStreaming} The chat completion parameters. + */ private buildChatCompletionParams = ({ response_model, ...params - }: PatchedChatCompletionCreateParams) => { + }: PatchedChatCompletionCreateParams): ChatCompletionCreateParamsNonStreaming => { const { definition } = createSchemaFunction({ schema: response_model }) const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params) @@ -125,32 +122,6 @@ export class Instruct { return parser(response) } - /** - * Generates a schema function. - * @param {ZodSchema} schema - The schema to generate the function from. - * @returns {Object} The generated function configuration. - */ - private generateSchemaFunction({ schema }) { - const { definition } = createSchemaFunction({ schema }) - - return { - function_call: { - name: definition.name - }, - functions: [ - { - name: definition.name, - description: definition.description, - parameters: { - type: "object", - properties: definition.parameters, - required: definition.required - } - } - ] - } - } - /** * Public chat interface. */ diff --git a/src/oai/fns/index.ts b/src/oai/fns/index.ts index e5c9df35..df912dc5 100644 --- a/src/oai/fns/index.ts +++ b/src/oai/fns/index.ts @@ -1,5 +1,4 @@ import { z } from "zod" -import { zodToJsonSchema } from "zod-to-json-schema" export type FunctionPayload = { name: string @@ -9,7 +8,6 @@ export type FunctionPayload = { } export type FunctionDefinitionParams

, R extends z.ZodType> = { - paramsSchema: P jsonSchema?: object name: string description: string @@ -42,7 +40,6 @@ export type FunctionDefinitionInterface = { * }; * * const functionDefinition = createFunctionDefinition({ - * paramsSchema, * name: 'greet', * description: 'Greets a person.', * execute @@ -50,7 +47,6 @@ export type FunctionDefinitionInterface = { * */ function createFunctionDefinition

, R extends z.ZodType>({ - paramsSchema, jsonSchema, name, description, @@ -59,8 +55,7 @@ function createFunctionDefinition

, R extends z.ZodT }: FunctionDefinitionParams): FunctionDefinitionInterface { const run = async (params: unknown): Promise => { try { - const validatedParams = paramsSchema.parse(params) - return await execute(validatedParams) + return await execute(params) } catch (error) { console.error(`Error executing function ${name}:`, error) throw error @@ -72,7 +67,7 @@ function createFunctionDefinition

, R extends z.ZodT definition: { name: name, description: description, - parameters: jsonSchema ?? zodToJsonSchema(paramsSchema), + parameters: jsonSchema, required } } diff --git a/src/oai/fns/schema.ts b/src/oai/fns/schema.ts index 632bf5a3..04c97b06 100644 --- a/src/oai/fns/schema.ts +++ b/src/oai/fns/schema.ts @@ -109,7 +109,6 @@ export function createSchemaFunction({ } return createFunctionDefinition({ - paramsSchema: schema, jsonSchema: propertiesMapping, name, description, diff --git a/src/oai/parser.ts b/src/oai/parser.ts index 720ac689..e5a4276d 100644 --- a/src/oai/parser.ts +++ b/src/oai/parser.ts @@ -16,10 +16,9 @@ export function OAIResponseTextParser( ) { const parsedData = typeof data === "string" ? JSON.parse(data) : data - const text = - parsedData.choices?.[0].delta?.content ?? parsedData?.choices[0]?.message?.content ?? "" + const text = parsedData?.choices[0]?.message?.content ?? "{}" - return text + return JSON.parse(text) } /** @@ -37,12 +36,9 @@ export function OAIResponseFnArgsParser( ) { const parsedData = typeof data === "string" ? JSON.parse(data) : data - const text = - parsedData.choices?.[0]?.delta?.function_call?.arguments ?? - parsedData.choices?.[0]?.message?.function_call?.arguments ?? - null + const text = parsedData.choices?.[0]?.message?.function_call?.arguments ?? "{}" - return text + return JSON.parse(text) } /** @@ -60,12 +56,9 @@ export function OAIResponseToolArgsParser( ) { const parsedData = typeof data === "string" ? JSON.parse(data) : data - const text = - parsedData.choices?.[0]?.delta?.tool_call?.function?.arguments ?? - parsedData.choices?.[0]?.message?.tool_call?.function?.arguments ?? - null + const text = parsedData.choices?.[0]?.message?.tool_call?.function?.arguments ?? "{}" - return text + return JSON.parse(text) } /** @@ -82,7 +75,7 @@ export function OAIResponseJSONStringParser( | OpenAI.Chat.Completions.ChatCompletion ) { const parsedData = typeof data === "string" ? JSON.parse(data) : data - const text = parsedData.choices?.[0]?.delta?.content ?? parsedData?.choices[0]?.message?.content + const text = parsedData?.choices[0]?.message?.content ?? "{}" - return text + return JSON.parse(text) } diff --git a/tests/functions.test.ts b/tests/functions.test.ts new file mode 100644 index 00000000..81b293e9 --- /dev/null +++ b/tests/functions.test.ts @@ -0,0 +1,43 @@ +import { Instruct } from "@/instructor" +import { describe, expect, test } from "bun:test" +import OpenAI from "openai" +import { z } from "zod" + +async function extractUser() { + const UserSchema = z.object({ + age: z.number(), + name: z.string().refine(name => name.includes(" "), { + message: "Name must contain a space" + }) + }) + + type User = z.infer + + const oai = new OpenAI({ + apiKey: process.env.OPENAI_API_KEY ?? undefined, + organization: process.env.OPENAI_ORG_ID ?? undefined + }) + + const client = new Instruct({ + client: oai, + mode: "FUNCTIONS" + }) + + const user: User = await client.chat.completions.create({ + messages: [{ role: "user", content: "Jason Liu is 30 years old" }], + model: "gpt-3.5-turbo", + response_model: UserSchema, + max_retries: 3 + }) + + return user +} + +describe("FunctionCall", () => { + test("Should return extracted name and age based on schema", async () => { + const user = await extractUser() + + expect(user.name).toEqual("Jason Liu") + expect(user.age).toEqual(30) + }) +}) From 55a52ec849893cf74bde9d2a16a8debb6caec7ef Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 13:54:22 -0500 Subject: [PATCH 03/15] remove unused --- .eslintrc.js | 4 ---- .vscode/settings.json | 28 +--------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 380fd968..9737c557 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,10 +10,6 @@ module.exports = { "semi": "off", "indent": "off", "@typescript-eslint/semi": "off", - "tailwindcss/no-custom-classname": "off", - "react/react-in-jsx-scope": "off", - "react/prop-types": 0, - "react/no-unknown-property": "off", "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": [ "warn", diff --git a/.vscode/settings.json b/.vscode/settings.json index 3a837b2f..9b64678f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,6 @@ "editor.autoIndent": "advanced" }, "[yaml]": { - "editor.defaultFormatter": "redhat.vscode-yaml", "editor.autoIndent": "advanced", "editor.tabSize": 2, "editor.formatOnSave": true, @@ -32,24 +31,6 @@ "typescriptreact", ], "eslint.debug": true, - "eslint.workingDirectories": [ - // Monorepo directories - { - "pattern": "./apps/*/" - }, - { - "pattern": "./functions/*/" - }, - { - "pattern": "./infra/*/" - }, - { - "pattern": "./packages/*/" - } - ], - "github-actions.workflows.pinned.workflows": [ - ".github/workflows/release.yml" - ], "typescript.tsdk": "./node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, "typescript.validate.enable": true, @@ -66,12 +47,5 @@ }, "[typescript]": { "editor.defaultFormatter": "vscode.typescript-language-features", - }, - "yaml.schemas": { - "openapi:v2": "file:///Users/beast/dev/image-gen/gcp/functions/chat/openapi.yaml", - "https://json.schemastore.org/workflows.json": "file:///Users/beast/dev/image-gen/infra/gcp/workflows/dataset-processing-workflow.yml", - }, - "yaml.format.enable": true, - "yaml.schemaStore.enable": true, - "yaml.validate": true + } } From 10018679a4c6976414670024c4f8578715eff95c Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 14:12:25 -0500 Subject: [PATCH 04/15] replicate the retry with parse error approach from the patch class --- src/instructor.ts | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/instructor.ts b/src/instructor.ts index 413a0b6f..9823b540 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -62,12 +62,32 @@ export class Instruct { ...params }: PatchedChatCompletionCreateParams) => { let attempts = 0 + let validationIssues = [] + let lastMessage = null const completionParams = this.buildChatCompletionParams(params) const makeCompletionCall = async () => { + let resolvedParams = completionParams + try { - const completion = await this.client.chat.completions.create(completionParams) + if (validationIssues.length > 0) { + resolvedParams = { + ...completionParams, + messages: [ + ...completionParams.messages, + ...(lastMessage ? [lastMessage] : []), + { + role: "system", + content: `Your last response had the following validation issues, please try again: ${validationIssues.join( + ", " + )}` + } + ] + } + } + + const completion = await this.client.chat.completions.create(resolvedParams) const response = this.parseOAIResponse(completion) return response @@ -78,7 +98,24 @@ export class Instruct { const makeCompletionCallWithRetries = async () => { try { - return await makeCompletionCall() + const data = await makeCompletionCall() + const validation = params.response_model.safeParse(data) + + if (!validation.success) { + if ("error" in validation) { + lastMessage = { + role: "assistant", + content: JSON.stringify(data) + } + + validationIssues = validation.error.issues.map(issue => issue.message) + throw validation.error + } else { + throw new Error("Validation failed.") + } + } + + return data } catch (error) { if (attempts < max_retries) { attempts++ From 781b51e4923f7af5de673c4f78ef32dff35e49ed Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 14:23:20 -0500 Subject: [PATCH 05/15] update instruct -> instructor + clean up exports --- examples/{test.ts => extract_user/index.ts} | 4 +- examples/extract_user/run.ts | 24 --- package.json | 12 +- src/index.ts | 2 - src/instructor.ts | 4 +- src/patch.ts | 208 -------------------- tests/functions.test.ts | 4 +- 7 files changed, 15 insertions(+), 243 deletions(-) rename examples/{test.ts => extract_user/index.ts} (90%) delete mode 100644 examples/extract_user/run.ts delete mode 100644 src/index.ts delete mode 100644 src/patch.ts diff --git a/examples/test.ts b/examples/extract_user/index.ts similarity index 90% rename from examples/test.ts rename to examples/extract_user/index.ts index 06ee26ff..685ecebe 100644 --- a/examples/test.ts +++ b/examples/extract_user/index.ts @@ -1,4 +1,4 @@ -import { Instruct } from "@/instructor" +import Instructor from "@/instructor" import OpenAI from "openai" import { z } from "zod" @@ -16,7 +16,7 @@ const oai = new OpenAI({ organization: process.env.OPENAI_ORG_ID ?? undefined }) -const client = new Instruct({ +const client = new Instructor({ client: oai, mode: "FUNCTIONS" }) diff --git a/examples/extract_user/run.ts b/examples/extract_user/run.ts deleted file mode 100644 index c1998062..00000000 --- a/examples/extract_user/run.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { instructor } from "@/" -import OpenAI from "openai" -import { z } from "zod" - -const client = instructor.patch({ - client: new OpenAI(), - mode: instructor.MODE.TOOLS -}) - -client.chat.completions - .create({ - messages: [{ role: "user", content: "Jason Liu is 30 years old" }], - model: "gpt-3.5-turbo", - // @ts-ignore TODO fix type issue - response_model: z.object({ - age: z.number(), - // name should be uppercase, or - name: z.string().refine(name => name === name.toUpperCase(), { - message: "name should have uppercase" - }) - }), - max_retries: 3 - }) - .then(console.log) diff --git a/package.json b/package.json index 777bd4dd..ece43206 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,15 @@ "name": "instructor-js", "version": "0.0.1", "description": "structured outputs for llms", - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", + "main": "./dist/instructor.js", + "module": "./dist/instructor.mjs", + "types": "./dist/instructor.d.ts", + "exports": { + ".": { + "import": "./dist/instructor.mjs", + "require": "./dist/instructor.js" + } + }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "tsup", diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index d872246f..00000000 --- a/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as instructor from "./patch" -export * from "./patch" diff --git a/src/instructor.ts b/src/instructor.ts index 9823b540..016ff85d 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -38,12 +38,12 @@ type PatchedChatCompletionCreateParams = ChatCompletionCreateParamsNonStreaming max_retries?: number } -export class Instruct { +export default class Instructor { private client: OpenAI private mode: MODE /** - * Creates an instance of the `Instruct` class. + * Creates an instance of the `Instructor` class. * @param {OpenAI} client - The OpenAI client. * @param {string} mode - The mode of operation. */ diff --git a/src/patch.ts b/src/patch.ts deleted file mode 100644 index 692c52ad..00000000 --- a/src/patch.ts +++ /dev/null @@ -1,208 +0,0 @@ -import assert from "assert" -import OpenAI, { ChatCompletion, ChatCompletionCreateParams, ChatCompletionMessage } from "openai" -import { ZodSchema } from "zod" -import { JsonSchema7Type, zodToJsonSchema } from "zod-to-json-schema" - -export enum MODE { - FUNCTIONS, - TOOLS, - JSON, - MD_JSON, - JSON_SCHEMA -} - -export class OpenAISchema { - private responseModel: ReturnType | any - constructor(public zod_schema: ZodSchema) { - this.responseModel = zodToJsonSchema(zod_schema) - } - - get definitions() { - return this.responseModel["definitions"] - } - - get properties() { - return this.responseModel["properties"] - } - - get schema() { - return this.responseModel - } - - get openaiSchema() { - return { - name: this.responseModel["title"] || "schema", - description: - this.responseModel["description"] || - `Correctly extracted \`${ - this.responseModel["title"] || "schema" - }\` with all the required parameters with correct types`, - parameters: Object.keys(this.responseModel).reduce( - (acc, curr) => { - if ( - curr.startsWith("$") || - ["title", "description", "additionalProperties"].includes(curr) - ) - return acc - acc[curr] = this.responseModel[curr] - return acc - }, - {} as { - [key: string]: object | JsonSchema7Type - } - ) - } - } -} - -type PatchedChatCompletionCreateParams = ChatCompletionCreateParams & { - responseModel?: ZodSchema | OpenAISchema - maxRetries?: number -} - -function handleResponseModel( - responseModel: ZodSchema | OpenAISchema, - args: PatchedChatCompletionCreateParams[], - mode: MODE = MODE.FUNCTIONS -): [OpenAISchema, PatchedChatCompletionCreateParams[], MODE] { - if (!(responseModel instanceof OpenAISchema)) { - responseModel = new OpenAISchema(responseModel) - } - - if (mode === MODE.FUNCTIONS) { - args[0].functions = [responseModel.openaiSchema] - args[0].function_call = { name: responseModel.openaiSchema.name } - } else if (mode === MODE.TOOLS) { - args[0].tools = [{ type: "function", function: responseModel.openaiSchema }] - args[0].tool_choice = { - type: "function", - function: { name: responseModel.openaiSchema.name } - } - } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { - let message: string = `As a genius expert, your task is to understand the content and provide the parsed objects in json that match the following json_schema: \n${JSON.stringify( - responseModel.properties - )}` - if (responseModel["definitions"]) { - message += `Here are some more definitions to adhere to: \n${JSON.stringify( - responseModel.definitions - )}` - } - if (mode === MODE.JSON) { - args[0].response_format = { type: "json_object" } - } else if (mode == MODE.JSON_SCHEMA) { - // ! TODO: include json schema in the response - args[0].response_format = { - type: "json_object" - // This is supported my Anyscale but not OpenAI - // schema: responseModel.schema, - } - } else if (mode === MODE.MD_JSON) { - args[0].messages.push({ - role: "assistant", - content: "```json" - }) - args[0].stop = "```" - } - if (args[0].messages[0].role != "system") { - args[0].messages.unshift({ role: "system", content: message }) - } else { - args[0].messages[0].content += `\n${message}` - } - } else { - console.error("unknown mode", mode) - } - return [responseModel, args, mode] -} - -function processResponse( - response: OpenAI.Chat.Completions.ChatCompletion, - responseModel: OpenAISchema, - mode: MODE = MODE.FUNCTIONS -) { - const message = response.choices[0].message - if (mode === MODE.FUNCTIONS) { - assert.equal( - message.function_call!.name, - responseModel.openaiSchema.name, - "Function name does not match" - ) - return responseModel.zod_schema.parse(JSON.parse(message.function_call!.arguments)) - } else if (mode === MODE.TOOLS) { - const tool_call = message.tool_calls![0] - assert.equal( - tool_call.function.name, - responseModel.openaiSchema.name, - "Tool name does not match" - ) - return responseModel.zod_schema.parse(JSON.parse(tool_call.function.arguments)) - } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { - return responseModel.zod_schema.parse(JSON.parse(message.content!)) - } else { - console.error("unknown mode", mode) - } -} - -function dumpMessage(message: ChatCompletionMessage) { - const ret: ChatCompletionMessage = { - role: message.role, - content: message.content || "" - } - if (message.tool_calls) { - ret["content"] += JSON.stringify(message.tool_calls) - } - if (message.function_call) { - ret["content"] += JSON.stringify(message.function_call) - } - return ret -} - -export const patch = ({ - client, - mode -}: { - client: OpenAI - responseModel?: ZodSchema | OpenAISchema - max_retries?: number - mode?: MODE -}): OpenAI => { - client.chat.completions.create = new Proxy(client.chat.completions.create, { - async apply(target, ctx, args: PatchedChatCompletionCreateParams[]) { - let retries = 0, - max_retries = args[0].maxRetries || 1, - response: ChatCompletion | undefined = undefined, - responseModel = args[0].responseModel - ;[responseModel, args, mode] = handleResponseModel(responseModel!, args, mode) - delete args[0].responseModel - delete args[0].maxRetries - while (retries < max_retries) { - try { - response = (await target.apply( - ctx, - args as [PatchedChatCompletionCreateParams] - )) as ChatCompletion - return processResponse(response, responseModel as OpenAISchema, mode) - } catch (error: any) { - console.error(error.errors || error) - if (!response) { - break - } - args[0].messages.push(dumpMessage(response.choices[0].message)) - args[0].messages.push({ - role: "user", - content: `Recall the function correctly, fix the errors, exceptions found\n${error}` - }) - if (mode == MODE.MD_JSON) { - args[0].messages.push({ role: "assistant", content: "```json" }) - } - retries++ - if (retries > max_retries) { - throw error - } - } finally { - response = undefined - } - } - } - }) - return client -} diff --git a/tests/functions.test.ts b/tests/functions.test.ts index 81b293e9..1c003c55 100644 --- a/tests/functions.test.ts +++ b/tests/functions.test.ts @@ -1,4 +1,4 @@ -import { Instruct } from "@/instructor" +import Instructor from "@/instructor" import { describe, expect, test } from "bun:test" import OpenAI from "openai" import { z } from "zod" @@ -18,7 +18,7 @@ async function extractUser() { organization: process.env.OPENAI_ORG_ID ?? undefined }) - const client = new Instruct({ + const client = new Instructor({ client: oai, mode: "FUNCTIONS" }) From 4eabb44ab10a2aabfd1568563cb659b416156bf0 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 14:32:15 -0500 Subject: [PATCH 06/15] consistent versions --- .github/workflows/publish.yml | 9 ++------- .github/workflows/release-pr.yml | 11 +++++++---- .github/workflows/test.yml | 9 ++++++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ad61c49f..f2be69c8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,20 +23,15 @@ jobs: with: fetch-depth: 0 - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 8.6.9 - - name: Setup bun uses: oven-sh/setup-bun@v1 with: bun-version: latest - - name: Setup Node.js 18 + - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 18.16.0 + node-version: 20.9.0 - name: Install Dependencies run: bun i diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 28054c3e..991fb138 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -26,12 +26,15 @@ jobs: with: fetch-depth: 0 - - name: setup node.js + - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 18.16.0 - - - uses: oven-sh/setup-bun@v1 + node-version: 20.9.0 + + - name: Setup bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest - name: Setup npmrc run: echo "//npm.pkg.github.com/:_authToken=$NPM_TOKEN" > .npmrc diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4a63227..369bd919 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,12 +12,15 @@ jobs: with: fetch-depth: 0 - - uses: oven-sh/setup-bun@v1 + - name: Setup bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest - - name: setup node.js + - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 18.16.0 + node-version: 20.9.0 - name: Install Dependencies run: bun i From 8177a0a4a6859993fb21fc62f9b81c8d3bc72865 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 14:34:11 -0500 Subject: [PATCH 07/15] remove deps --- bun.lockb | Bin 217400 -> 216993 bytes package.json | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bun.lockb b/bun.lockb index 5c3046b9f219fd2dfa9c08ece1f52289a864d186..3db76668c487f6f2940b04be0af4c611621e8f7c 100755 GIT binary patch delta 40411 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 LyR*019e4acZ Date: Tue, 2 Jan 2024 14:36:04 -0500 Subject: [PATCH 08/15] remove deps and set peers + externals --- bun.lockb | Bin 216993 -> 216993 bytes bunfig.toml | 2 ++ package.json | 6 +++--- tsup.config.ts | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 bunfig.toml diff --git a/bun.lockb b/bun.lockb index 3db76668c487f6f2940b04be0af4c611621e8f7c..143ad1ed8b31461b7f5915d97e0c413ef836979c 100755 GIT binary patch delta 42176 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 NW?ITLed8R)835Vz;E@0T delta 42449 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 diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 00000000..dcd8084d --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,2 @@ +[install] +peer = true \ No newline at end of file diff --git a/package.json b/package.json index 72c07cd8..545eb55d 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,9 @@ "url": "https://github.com/jxnl/instructor-js/issues" }, "homepage": "https://github.com/jxnl/instructor-js#readme", - "dependencies": { - "openai": "^4.24.1", - "zod": "^3.22.4" + "peerDependencies": { + "openai": ">=4.24.1", + "zod": ">=3.22.4" }, "devDependencies": { "@changesets/changelog-github": "^0.5.0", diff --git a/tsup.config.ts b/tsup.config.ts index 701fa7fc..cd612b0c 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -8,6 +8,7 @@ export default defineConfig(options => { dts: true, minify: true, clean: true, + external: ["openai", "zod"], ...options } }) From 4d7e2623ec5339ac163d38d91d9d7cc69a3cb09e Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 15:09:57 -0500 Subject: [PATCH 09/15] move back to the zod to json schema package --- bun.lockb | Bin 216993 -> 217400 bytes package.json | 3 ++ src/instructor.ts | 11 ++-- src/oai/fns/index.ts | 78 ---------------------------- src/oai/fns/schema.ts | 118 ------------------------------------------ src/oai/params.ts | 41 +++------------ 6 files changed, 18 insertions(+), 233 deletions(-) delete mode 100644 src/oai/fns/index.ts delete mode 100644 src/oai/fns/schema.ts diff --git a/bun.lockb b/bun.lockb index 143ad1ed8b31461b7f5915d97e0c413ef836979c..8e677c65376f19844e2496f9a0f26225b6ed2cd5 100755 GIT binary patch delta 41317 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 I2Xh=d0P-6>vj6}9 delta 40990 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

h~S&x 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 U!%lA78-8L(?LF4L*vOLq52sF&Q~&?~ diff --git a/package.json b/package.json index 545eb55d..39015436 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,9 @@ "url": "https://github.com/jxnl/instructor-js/issues" }, "homepage": "https://github.com/jxnl/instructor-js#readme", + "dependencies": { + "zod-to-json-schema": "^3.22.3" + }, "peerDependencies": { "openai": ">=4.24.1", "zod": ">=3.22.4" diff --git a/src/instructor.ts b/src/instructor.ts index 016ff85d..e326843a 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -1,7 +1,7 @@ -import { createSchemaFunction } from "@/oai/fns/schema" import OpenAI from "openai" import { ChatCompletion, ChatCompletionCreateParamsNonStreaming } from "openai/resources/index.mjs" import { ZodObject } from "zod" +import zodToJsonSchema from "zod-to-json-schema" import { MODE } from "@/constants/modes" @@ -138,12 +138,17 @@ export default class Instructor { response_model, ...params }: PatchedChatCompletionCreateParams): ChatCompletionCreateParamsNonStreaming => { - const { definition } = createSchemaFunction({ schema: response_model }) + const jsonSchema = zodToJsonSchema(response_model, "response_model") + + const definition = { + name: "response_model", + ...jsonSchema.definitions.response_model + } const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params) return { - stream: false, //TODO: not sure what streaming support looks like TBH + stream: false, ...paramsForMode } } diff --git a/src/oai/fns/index.ts b/src/oai/fns/index.ts deleted file mode 100644 index df912dc5..00000000 --- a/src/oai/fns/index.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { z } from "zod" - -export type FunctionPayload = { - name: string - description: string - parameters: object - required: string[] -} - -export type FunctionDefinitionParams

, R extends z.ZodType> = { - jsonSchema?: object - name: string - description: string - execute: (params: z.infer

) => Promise> - required?: string[] -} - -export type FunctionDefinitionInterface = { - run: (params: unknown) => Promise - definition: FunctionPayload -} - -/** - * `createFunctionDefinition` is a function that creates a function definition. It creates a runner function - * that validates its parameters against a provided schema before executing the provided function. - * It also creates a payload that describes the function. - * - * @param {FunctionDefinitionParams} params - The parameters for the function definition. - * @returns {FunctionDefinitionInterface} - The function definition runner function and the function payload. - * - * @example - * - * const paramsSchema = z.object({ - * name: z.string(), - * age: z.number() - * }); - * - * const execute = async (params) => { - * return { message: `Hello, ${params.name}. You are ${params.age} years old.` }; - * }; - * - * const functionDefinition = createFunctionDefinition({ - * name: 'greet', - * description: 'Greets a person.', - * execute - * }); - * - */ -function createFunctionDefinition

, R extends z.ZodType>({ - jsonSchema, - name, - description, - execute, - required = [] -}: FunctionDefinitionParams): FunctionDefinitionInterface { - const run = async (params: unknown): Promise => { - try { - return await execute(params) - } catch (error) { - console.error(`Error executing function ${name}:`, error) - throw error - } - } - - const functionDefinition: FunctionDefinitionInterface = { - run, - definition: { - name: name, - description: description, - parameters: jsonSchema, - required - } - } - - return functionDefinition -} - -export { createFunctionDefinition } diff --git a/src/oai/fns/schema.ts b/src/oai/fns/schema.ts deleted file mode 100644 index 04c97b06..00000000 --- a/src/oai/fns/schema.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { createFunctionDefinition } from "@/oai/fns" -import { z, ZodArray, ZodBoolean, ZodNumber, ZodObject, ZodRecord, ZodString } from "zod" - -type AnyZodType = z.ZodTypeAny -type PropertyType = "string" | "boolean" | "number" | "object" | "array" - -const getTypeFromZod = (schema: AnyZodType): PropertyType => { - if (schema instanceof ZodNumber) { - return "number" - } - - if (schema instanceof ZodBoolean) { - return "boolean" - } - - if (schema instanceof ZodString) { - return "string" - } - - if (schema instanceof ZodObject) { - return "object" - } - - if (schema instanceof ZodArray) { - return "array" - } - - if (schema instanceof ZodRecord) { - return "object" - } - - return "string" -} - -const getDescriptionAndType = (schema: AnyZodType) => { - const maybeDescription = ` - ${schema._def?.description ?? ""}\n - rules: ${JSON.stringify(schema._def?.checks ?? []) ?? ""} - ` - - if (schema instanceof ZodObject) { - const properties = {} - - for (const key in schema.shape) { - properties[key] = getDescriptionAndType(schema.shape[key]) - } - - return { - type: getTypeFromZod(schema), - description: maybeDescription, - properties - } - } - - if (schema instanceof ZodArray) { - return { - type: getTypeFromZod(schema), - description: maybeDescription, - items: getDescriptionAndType(schema.element) - } - } - - return { - type: getTypeFromZod(schema), - description: maybeDescription - } -} - -/** - * `createSchemaFunction` creates a schema-based function definition using the `createFunctionDefinition` utility. - * The created function always returns null when executed, and its purpose is mainly to provide a structured - * description of the schema in a specific format. - * - * @param {Object} args - The arguments for the function definition. - * @param {z.ZodObject} args.schema - The zod schema object. - * @returns {FunctionDefinitionInterface} - The function definition. - * - * @example - * - * const schema = z.object({ - * name: z.string(), - * age: z.number() - * }); - * - * const schemaFunctionDefinition = createSchemaFunction({ schema, name: 'mySchema', description: 'returns a person object with name and age' }); - * - */ -export function createSchemaFunction({ - schema -}: { - //eslint-disable-next-line @typescript-eslint/no-explicit-any - schema: z.ZodObject -}) { - const propertiesMapping: { - [index: string]: { type: PropertyType; description: string } - } = {} - - for (const key in schema.shape) { - propertiesMapping[key] = getDescriptionAndType(schema.shape[key]) - } - - const requiredParameters = Object.keys(propertiesMapping) - - const name = "return_json" - const description = `Returns the assistant response as JSON.` - - const execute = async (): Promise => { - return null - } - - return createFunctionDefinition({ - jsonSchema: propertiesMapping, - name, - description, - execute, - required: requiredParameters - }) -} diff --git a/src/oai/params.ts b/src/oai/params.ts index e03e6c89..6788b148 100644 --- a/src/oai/params.ts +++ b/src/oai/params.ts @@ -1,52 +1,25 @@ -import { FunctionPayload } from "./fns" - -export function OAIBuildFunctionParams(definition: FunctionPayload, params) { +export function OAIBuildFunctionParams(definition, params) { return { ...params, function_call: { name: definition.name }, - functions: [ - ...(params?.functions ?? []), - { - name: definition.name, - description: definition.description, - parameters: { - type: "object", - properties: definition.parameters, - required: definition.required - } - } - ] + functions: [...(params?.functions ?? []), definition] } } -export function OAIBuildToolFunctionParams(definition: FunctionPayload, params) { +export function OAIBuildToolFunctionParams(definition, params) { return { ...params, tool_choice: { type: "function", function: { name: definition.name } }, - tools: [ - ...(params?.tools ?? []), - { - type: "function", - function: { - name: definition.name, - description: definition.description, - parameters: { - type: "object", - properties: definition.parameters, - required: definition.required - } - } - } - ] + tools: [...(params?.tools ?? []), definition] } } -export function OAIBuildMessageBasedParams(definition: FunctionPayload, params) { +export function OAIBuildMessageBasedParams(definition, params) { return { ...params, messages: [ @@ -58,8 +31,8 @@ export function OAIBuildMessageBasedParams(definition: FunctionPayload, params) You will return no other prose. You will take into account the descriptions for each paramater within the schema and return a valid JSON object that matches the schema and those instructions. - description: ${definition.description} - paramaters: ${JSON.stringify(definition.parameters)} + description: ${definition?.description} + json schema: ${JSON.stringify(definition)} ` } ] From 10178fd737986481e5827fb88c6a3f31352ecd9e Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 15:23:33 -0500 Subject: [PATCH 10/15] mode specific configs --- src/instructor.ts | 2 +- src/oai/params.ts | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/instructor.ts b/src/instructor.ts index e326843a..e02f10d5 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -145,7 +145,7 @@ export default class Instructor { ...jsonSchema.definitions.response_model } - const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params) + const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params, this.mode) return { stream: false, diff --git a/src/oai/params.ts b/src/oai/params.ts index 6788b148..ae1795ca 100644 --- a/src/oai/params.ts +++ b/src/oai/params.ts @@ -1,3 +1,5 @@ +import { MODE } from "@/constants/modes" + export function OAIBuildFunctionParams(definition, params) { return { ...params, @@ -19,9 +21,21 @@ export function OAIBuildToolFunctionParams(definition, params) { } } -export function OAIBuildMessageBasedParams(definition, params) { +export function OAIBuildMessageBasedParams(definition, params, mode) { + const MODE_SPECIFIC_CONFIGS = { + [MODE.JSON]: { + response_format: { type: "json_object" } + }, + [MODE.JSON_SCHEMA]: { + response_format: { type: "json_object", schema: definition } + } + } + + const modeConfig = MODE_SPECIFIC_CONFIGS[mode] ?? {} + return { ...params, + ...modeConfig, messages: [ ...(params?.messages ?? []), { From 161fb8baa4a37f4c5bc3bba3e9d5cb3faf94e81b Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 15:37:37 -0500 Subject: [PATCH 11/15] remove all the non tool updates + fix some type errors with patch --- examples/extract_user/index.ts | 4 +- package-lock.json | 333 --------------------------------- src/instructor.ts | 329 +++++++++++++++++--------------- src/oai/params.ts | 54 ------ src/oai/parser.ts | 81 -------- tests/functions.test.ts | 4 +- 6 files changed, 184 insertions(+), 621 deletions(-) delete mode 100644 package-lock.json delete mode 100644 src/oai/params.ts delete mode 100644 src/oai/parser.ts diff --git a/examples/extract_user/index.ts b/examples/extract_user/index.ts index 685ecebe..710df601 100644 --- a/examples/extract_user/index.ts +++ b/examples/extract_user/index.ts @@ -16,14 +16,16 @@ const oai = new OpenAI({ organization: process.env.OPENAI_ORG_ID ?? undefined }) -const client = new Instructor({ +const client = Instructor({ client: oai, mode: "FUNCTIONS" }) +//@ts-expect-error these types wont work since were using a proxy and just returning the OAI instance type const user: User = await client.chat.completions.create({ messages: [{ role: "user", content: "Jason Liu is 30 years old" }], model: "gpt-3.5-turbo", + //@ts-expect-error same as above response_model: UserSchema, max_retries: 3 }) diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 1a756cc3..00000000 --- a/package-lock.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "name": "instructor", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "instructor", - "version": "0.0.1", - "license": "MIT", - "dependencies": { - "openai": "^4.24.1", - "zod": "^3.22.4", - "zod-to-json-schema": "^3.22.3" - }, - "devDependencies": { - "@types/node": "^20.10.6", - "typescript": "^5.3.3" - } - }, - "node_modules/@types/node": { - "version": "20.10.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", - "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.10.tgz", - "integrity": "sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "engines": { - "node": "*" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "engines": { - "node": "*" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/digest-fetch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", - "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", - "dependencies": { - "base-64": "^0.1.0", - "md5": "^2.3.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" - }, - "node_modules/formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "dependencies": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "engines": { - "node": ">= 12.20" - } - }, - "node_modules/formdata-node/node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/openai": { - "version": "4.24.1", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.24.1.tgz", - "integrity": "sha512-ezm/O3eiZMnyBqirUnWm9N6INJU1WhNtz+nK/Zj/2oyKvRz9pgpViDxa5wYOtyGYXPn1sIKBV0I/S4BDhtydqw==", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "digest-fetch": "^1.3.0", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "web-streams-polyfill": "^3.2.1" - }, - "bin": { - "openai": "bin/cli" - } - }, - "node_modules/openai/node_modules/@types/node": { - "version": "18.19.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.4.tgz", - "integrity": "sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.3.tgz", - "integrity": "sha512-9isG8SqRe07p+Aio2ruBZmLm2Q6Sq4EqmXOiNpDxp+7f0LV6Q/LX65fs5Nn+FV/CzfF3NLBoksXbS2jNYIfpKw==", - "peerDependencies": { - "zod": "^3.22.4" - } - } - } -} diff --git a/src/instructor.ts b/src/instructor.ts index e02f10d5..5fe3e214 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -1,175 +1,202 @@ +import assert from "assert" import OpenAI from "openai" -import { ChatCompletion, ChatCompletionCreateParamsNonStreaming } from "openai/resources/index.mjs" -import { ZodObject } from "zod" -import zodToJsonSchema from "zod-to-json-schema" +import { + ChatCompletion, + ChatCompletionCreateParams, + ChatCompletionMessage +} from "openai/resources/index.mjs" +import { ZodSchema } from "zod" +import { JsonSchema7Type, zodToJsonSchema } from "zod-to-json-schema" import { MODE } from "@/constants/modes" -import { - OAIBuildFunctionParams, - OAIBuildMessageBasedParams, - OAIBuildToolFunctionParams -} from "./oai/params" -import { - OAIResponseFnArgsParser, - OAIResponseJSONStringParser, - OAIResponseToolArgsParser -} from "./oai/parser" +export class OpenAISchema { + private response_model: ReturnType + constructor(public zod_schema: ZodSchema) { + this.response_model = zodToJsonSchema(zod_schema) + } -const MODE_TO_PARSER = { - [MODE.FUNCTIONS]: OAIResponseFnArgsParser, - [MODE.TOOLS]: OAIResponseToolArgsParser, - [MODE.JSON]: OAIResponseJSONStringParser, - [MODE.MD_JSON]: OAIResponseJSONStringParser, - [MODE.JSON_SCHEMA]: OAIResponseJSONStringParser -} + get definitions() { + return this.response_model["definitions"] + } -const MODE_TO_PARAMS = { - [MODE.FUNCTIONS]: OAIBuildFunctionParams, - [MODE.TOOLS]: OAIBuildToolFunctionParams, - [MODE.JSON]: OAIBuildMessageBasedParams, - [MODE.MD_JSON]: OAIBuildMessageBasedParams, - [MODE.JSON_SCHEMA]: OAIBuildMessageBasedParams + get properties() { + return this.response_model["properties"] + } + + get openai_schema() { + return { + name: this.response_model["title"] || "schema", + description: + this.response_model["description"] || + `Correctly extracted \`${ + this.response_model["title"] || "schema" + }\` with all the required parameters with correct types`, + parameters: Object.keys(this.response_model).reduce( + (acc, curr) => { + if ( + curr.startsWith("$") || + ["title", "description", "additionalProperties"].includes(curr) + ) + return acc + acc[curr] = this.response_model[curr] + return acc + }, + {} as { + [key: string]: object | JsonSchema7Type + } + ) + } + } } -type PatchedChatCompletionCreateParams = ChatCompletionCreateParamsNonStreaming & { - //eslint-disable-next-line @typescript-eslint/no-explicit-any - response_model?: ZodObject +type PatchedChatCompletionCreateParams = ChatCompletionCreateParams & { + response_model?: ZodSchema | OpenAISchema max_retries?: number } -export default class Instructor { - private client: OpenAI - private mode: MODE - - /** - * Creates an instance of the `Instructor` class. - * @param {OpenAI} client - The OpenAI client. - * @param {string} mode - The mode of operation. - */ - constructor({ client, mode }: { client: OpenAI; mode: MODE }) { - this.client = client - this.mode = mode +function handleResponseModel( + response_model: ZodSchema | OpenAISchema, + args: PatchedChatCompletionCreateParams[], + mode: MODE = "FUNCTIONS" +): [OpenAISchema, PatchedChatCompletionCreateParams[], MODE] { + if (!(response_model instanceof OpenAISchema)) { + response_model = new OpenAISchema(response_model) } - /** - * Handles chat completion with retries. - * @param {PatchedChatCompletionCreateParams} params - The parameters for chat completion. - * @returns {Promise} The response from the chat completion. - */ - private chatCompletion = async ({ - max_retries = 3, - ...params - }: PatchedChatCompletionCreateParams) => { - let attempts = 0 - let validationIssues = [] - let lastMessage = null - - const completionParams = this.buildChatCompletionParams(params) - - const makeCompletionCall = async () => { - let resolvedParams = completionParams - - try { - if (validationIssues.length > 0) { - resolvedParams = { - ...completionParams, - messages: [ - ...completionParams.messages, - ...(lastMessage ? [lastMessage] : []), - { - role: "system", - content: `Your last response had the following validation issues, please try again: ${validationIssues.join( - ", " - )}` - } - ] - } - } - - const completion = await this.client.chat.completions.create(resolvedParams) - const response = this.parseOAIResponse(completion) - - return response - } catch (error) { - throw error - } + if (mode === MODE.FUNCTIONS) { + args[0].functions = [response_model.openai_schema] + args[0].function_call = { name: response_model.openai_schema.name } + } else if (mode === MODE.TOOLS) { + args[0].tools = [{ type: "function", function: response_model.openai_schema }] + args[0].tool_choice = { + type: "function", + function: { name: response_model.openai_schema.name } } - - const makeCompletionCallWithRetries = async () => { - try { - const data = await makeCompletionCall() - const validation = params.response_model.safeParse(data) - - if (!validation.success) { - if ("error" in validation) { - lastMessage = { - role: "assistant", - content: JSON.stringify(data) - } - - validationIssues = validation.error.issues.map(issue => issue.message) - throw validation.error - } else { - throw new Error("Validation failed.") - } - } - - return data - } catch (error) { - if (attempts < max_retries) { - attempts++ - return await makeCompletionCallWithRetries() - } else { - throw error - } - } + } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { + let message: string = `As a genius expert, your task is to understand the content and provide the parsed objects in json that match the following json_schema: \n${JSON.stringify( + response_model.properties + )}` + if (response_model["definitions"]) { + message += `Here are some more definitions to adhere to: \n${JSON.stringify( + response_model.definitions + )}` } - - return await makeCompletionCallWithRetries() - } - - /** - * Builds the chat completion parameters. - * @param {PatchedChatCompletionCreateParams} params - The parameters for chat completion. - * @returns {ChatCompletionCreateParamsNonStreaming} The chat completion parameters. - */ - private buildChatCompletionParams = ({ - response_model, - ...params - }: PatchedChatCompletionCreateParams): ChatCompletionCreateParamsNonStreaming => { - const jsonSchema = zodToJsonSchema(response_model, "response_model") - - const definition = { - name: "response_model", - ...jsonSchema.definitions.response_model + if (mode === MODE.JSON) { + args[0].response_format = { type: "json_object" } + } else if (mode == MODE.JSON_SCHEMA) { + args[0].response_format = { type: "json_object" } + } else if (mode === MODE.MD_JSON) { + args[0].messages.push({ + role: "assistant", + content: "```json" + }) + args[0].stop = "```" } - - const paramsForMode = MODE_TO_PARAMS[this.mode](definition, params, this.mode) - - return { - stream: false, - ...paramsForMode + if (args[0].messages[0].role != "system") { + args[0].messages.unshift({ role: "system", content: message }) + } else { + args[0].messages[0].content += `\n${message}` } + } else { + console.error("unknown mode", mode) } + return [response_model, args, mode] +} - /** - * Parses the OAI response. - * @param {ChatCompletion} response - The response from the chat completion. - * @returns {any} The parsed response. - */ - private parseOAIResponse = (response: ChatCompletion) => { - const parser = MODE_TO_PARSER[this.mode] +function processResponse( + response: OpenAI.Chat.Completions.ChatCompletion, + response_model: OpenAISchema, + mode: MODE = "FUNCTIONS" +) { + const message = response.choices[0].message + if (mode === MODE.FUNCTIONS) { + assert.equal( + message.function_call!.name, + response_model.openai_schema.name, + "Function name does not match" + ) + return response_model.zod_schema.parse(JSON.parse(message.function_call!.arguments)) + } else if (mode === MODE.TOOLS) { + const tool_call = message.tool_calls![0] + assert.equal( + tool_call.function.name, + response_model.openai_schema.name, + "Tool name does not match" + ) + return response_model.zod_schema.parse(JSON.parse(tool_call.function.arguments)) + } else if ([MODE.JSON, MODE.MD_JSON, MODE.JSON_SCHEMA].includes(mode)) { + return response_model.zod_schema.parse(JSON.parse(message.content!)) + } else { + console.error("unknown mode", mode) + } +} - return parser(response) +function dumpMessage(message: ChatCompletionMessage) { + const ret: ChatCompletionMessage = { + role: message.role, + content: message.content || "" + } + if (message.tool_calls) { + ret["content"] += JSON.stringify(message.tool_calls) + } + if (message.function_call) { + ret["content"] += JSON.stringify(message.function_call) } + return ret +} - /** - * Public chat interface. - */ - public chat = { - completions: { - create: this.chatCompletion +const patch = ({ + client, + mode +}: { + client: OpenAI + response_model?: ZodSchema | OpenAISchema + max_retries?: number + mode?: MODE +}): OpenAI => { + client.chat.completions.create = new Proxy(client.chat.completions.create, { + async apply(target, ctx, args: PatchedChatCompletionCreateParams[]) { + const max_retries = args[0].max_retries || 1 + let retries = 0, + response: ChatCompletion | undefined = undefined, + response_model = args[0].response_model + ;[response_model, args, mode] = handleResponseModel(response_model!, args, mode) + + delete args[0].response_model + delete args[0].max_retries + + while (retries < max_retries) { + try { + response = (await target.apply( + ctx, + args as [PatchedChatCompletionCreateParams] + )) as ChatCompletion + return processResponse(response, response_model as OpenAISchema, mode) + } catch (error) { + console.error(error.errors || error) + if (!response) { + break + } + args[0].messages.push(dumpMessage(response.choices[0].message)) + args[0].messages.push({ + role: "user", + content: `Recall the function correctly, fix the errors, exceptions found\n${error}` + }) + if (mode == MODE.MD_JSON) { + args[0].messages.push({ role: "assistant", content: "```json" }) + } + retries++ + if (retries > max_retries) { + throw error + } + } finally { + response = undefined + } + } } - } + }) + return client } + +export default patch diff --git a/src/oai/params.ts b/src/oai/params.ts deleted file mode 100644 index ae1795ca..00000000 --- a/src/oai/params.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { MODE } from "@/constants/modes" - -export function OAIBuildFunctionParams(definition, params) { - return { - ...params, - function_call: { - name: definition.name - }, - functions: [...(params?.functions ?? []), definition] - } -} - -export function OAIBuildToolFunctionParams(definition, params) { - return { - ...params, - tool_choice: { - type: "function", - function: { name: definition.name } - }, - tools: [...(params?.tools ?? []), definition] - } -} - -export function OAIBuildMessageBasedParams(definition, params, mode) { - const MODE_SPECIFIC_CONFIGS = { - [MODE.JSON]: { - response_format: { type: "json_object" } - }, - [MODE.JSON_SCHEMA]: { - response_format: { type: "json_object", schema: definition } - } - } - - const modeConfig = MODE_SPECIFIC_CONFIGS[mode] ?? {} - - return { - ...params, - ...modeConfig, - messages: [ - ...(params?.messages ?? []), - { - role: "SYSTEM", - content: ` - Given a user prompt, you will return fully valid JSON based on the following description and schema. - You will return no other prose. You will take into account the descriptions for each paramater within the schema - and return a valid JSON object that matches the schema and those instructions. - - description: ${definition?.description} - json schema: ${JSON.stringify(definition)} - ` - } - ] - } -} diff --git a/src/oai/parser.ts b/src/oai/parser.ts deleted file mode 100644 index e5a4276d..00000000 --- a/src/oai/parser.ts +++ /dev/null @@ -1,81 +0,0 @@ -import OpenAI from "openai" -import { Stream } from "openai/streaming" - -/** - * `OAIResponseTextParser` parses a JSON string and extracts the text content. - * - * @param {string} data - The JSON string to parse. - * @returns {string} - The extracted text content. - * - */ -export function OAIResponseTextParser( - data: - | string - | Stream - | OpenAI.Chat.Completions.ChatCompletion -) { - const parsedData = typeof data === "string" ? JSON.parse(data) : data - - const text = parsedData?.choices[0]?.message?.content ?? "{}" - - return JSON.parse(text) -} - -/** - * `OAIResponseFnArgsParser` parses a JSON string and extracts the function call arguments. - * - * @param {string} data - The JSON string to parse. - * @returns {Object} - The extracted function call arguments. - * - */ -export function OAIResponseFnArgsParser( - data: - | string - | Stream - | OpenAI.Chat.Completions.ChatCompletion -) { - const parsedData = typeof data === "string" ? JSON.parse(data) : data - - const text = parsedData.choices?.[0]?.message?.function_call?.arguments ?? "{}" - - return JSON.parse(text) -} - -/** - * `OAIResponseToolArgsParser` parses a JSON string and extracts the tool call arguments. - * - * @param {string} data - The JSON string to parse. - * @returns {Object} - The extracted tool call arguments. - * - */ -export function OAIResponseToolArgsParser( - data: - | string - | Stream - | OpenAI.Chat.Completions.ChatCompletion -) { - const parsedData = typeof data === "string" ? JSON.parse(data) : data - - const text = parsedData.choices?.[0]?.message?.tool_call?.function?.arguments ?? "{}" - - return JSON.parse(text) -} - -/** - * `OAIResponseJSONParser` parses a JSON string and extracts the JSON content. - * - * @param {string} data - The JSON string to parse. - * @returns {Object} - The extracted JSON content. - * - */ -export function OAIResponseJSONStringParser( - data: - | string - | Stream - | OpenAI.Chat.Completions.ChatCompletion -) { - const parsedData = typeof data === "string" ? JSON.parse(data) : data - const text = parsedData?.choices[0]?.message?.content ?? "{}" - - return JSON.parse(text) -} diff --git a/tests/functions.test.ts b/tests/functions.test.ts index 1c003c55..fa7044b9 100644 --- a/tests/functions.test.ts +++ b/tests/functions.test.ts @@ -18,14 +18,16 @@ async function extractUser() { organization: process.env.OPENAI_ORG_ID ?? undefined }) - const client = new Instructor({ + const client = Instructor({ client: oai, mode: "FUNCTIONS" }) + //@ts-expect-error these types wont work since were using a proxy and just returning the OAI instance type const user: User = await client.chat.completions.create({ messages: [{ role: "user", content: "Jason Liu is 30 years old" }], model: "gpt-3.5-turbo", + //@ts-expect-error same as above response_model: UserSchema, max_retries: 3 }) From 5ae08a220487fe3fcb4c0db906e38a33940cc70b Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 15:45:14 -0500 Subject: [PATCH 12/15] lint and test --- .github/workflows/publish.yml | 2 +- .github/workflows/test.yml | 3 +++ bun.lockb | Bin 217400 -> 219721 bytes package.json | 4 ++-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f2be69c8..99787459 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -48,7 +48,7 @@ jobs: id: changesets uses: changesets/action@v1 with: - publish: pnpm publish-packages + publish: bun publish-packages createGithubReleases: true env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 369bd919..dfae7b82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,4 +25,7 @@ jobs: - name: Install Dependencies run: bun i + - run: bun run type-check + - run: bun run lint + - run: bun test diff --git a/bun.lockb b/bun.lockb index 8e677c65376f19844e2496f9a0f26225b6ed2cd5..f15e43b9afccbdf7f405e1d8902627c86e5d408e 100755 GIT binary patch delta 19606 zcmeI4d0bRw-^R}z9A#7lcR;{>7ZMZ(w+Yb{6;#YUHx!Uz7f=C(0atL>qu!w6k{c*y znub8LZ6@Ges9SP*KZPscT81R{;VCmJ^flm(&rN!eYRCOJjO-g5wLPpQ}z3{ z`?5W1db!0ZN>fECI2WrZp0GDzTfuhKw$yCv*axo}ybR=`T?Oj}`)9d~^z9S$(!vrI z#SQ5LVC%uw2KR-XigIefj!IIL+OXr{*Mz+U-vZkmeoIAps^G7uDzn7(#ySTbuPfkp7vOP1)q4dhu``0x`Q5qrPCRh#xs*OpGiH&OupZ%#1+W@u( zY;D-4$ma*^2Fro{7!@>x?TE&4Ja*<86=h6C-;~MudcK^%P;^mIqT$z7swoBG`PvJ$ z+k{t#&wrShg%o!Dp(emlpHsmYiCL( z1_H-~`TDq~*t1ix@RVry>|O*c)AxjBaT{gxwLERVTZs2lMSAo?U`EeOuun#}YQC^YZ)AgFEvQZ#$K)k?p&4uV@3BO@)tKQ7z6LeJM5`8j8=!sjFpSm~StN5N49xO$$20>f7?D3fJmWb!-Y5>c8DKY8( zX_FI`>XJLw=pE3xBT@Nbv7RttdP+>HzdbfS6V1-bh}pSTFPO_X-kuznjqzlGSt;qx z>DeXpf~LW8q(Vyc^ivXIGGgPhl(^Js)9o2?87auek(*-ox2MLZDWl}va;-P83u0y&XGy?M{~2{GSdCgM>KWo z20fn{@hty)l*^7>C{q*%7n0XTy@Fg=_M{vMm{8fI7uXmXnc*_H5A0eQ{{n0?_~T%? z5#+&o!P;Q`U=ME5^OwVN4K0A>euT1|<;13CxyPkqvAb;5cYtTMYTZ@8f!pA+9ck%t zsWEmma=U&$XTY)?!*9Jq?^p~t2WA9pZP=99VCM|2->D6(>o>4JFjvGY<@!We;d7j# zEA(t_WcEAoIUM1;^y*XWDRKU>la(&;+5PIfpW9zIwWfBWNi)|}zi*D7zu2nVbIpA2 zkF-QE7FE{O>bC5td1P5?$0^G2-@u_QUENlI_WNJ-0_cR_Q%hL9qJ)8(wCioHmI8P^ z;hD9VR#wYP@VdgQp~XCDwcLS+OF%(&ZA*aF(gCX{1YR|IZj<1RWZc8Xu^rF<5w(oM z<)*)0&Ty+`BfKXcdSAhN;-MFUIT`=Z)8LITJhvP0`q6u|Ml~u?^PXW-ixRc5Gi+|B z6BT9XZ_;?!Ev6*xGLlS5(!6KdEZdS41(S&GqZ{gnN!mI<-(*}&0MWO$R`p`C=ACUb z$D}Aqq*fNtL*0|2t;@El4N|qsFv+Q!caBZ%nWl}+v6+k0Fo2qGb`SM1VHQu*yl2@gN2V!CUsPw-wqQU^*o#8pxj2Wp8$5Oa?F+S9 zis9Luan1d$mN(#qJL8%Uv|221XH%j)h-v>RC})GJ;$cLn5&JQV>7F>u%xxCsBRKM{TQ8w^}WY3iSrmHX&EEvl|DZZtfOlitgxWgNz%wbgtDUXWI1@98=px3)-x+3$z(h8N+i3f)zopRbKw zY*TN}*Ve&wT%cWEY%|9%U|+_Mz)T{fj~iCI`2%=1XV3f=KI{v|dMZ4&7aJHxsT3Y( z3m#f{4PLm@W3QVR>E)r97U z=b8ToJQiKud7`A@KB5OaMZ0ddT6V!>Ph6a!n|Z!+Rk=TM)5Czm|7 zCXW?*(Tc{cX)wIu&XnBJuELuH4?~Ixn}8dyVNQ>YII~i_yvAnnTxFbPT!Rzf>2ttQ zDu>73V(m_|s#jKNm)F|V7MkWQY?eGtUr_o=J_nDZi}i_$YOK~v!Hx*8KRlMApRcpv z^@XQ8^+coxCq@Kkfo!)r1nJmk9z?{Q}hF%ed?buCv8 zS5z89;LcIEJO__`Q@Fk?-^e(9emde7kL|#`V#&-B+Sv6r^K*dCrK#Q)+U4~&OL&Q1 z0`?P>Fb7_UULGdw5Ioj}DZ=h@2Oj4erQ>u9DAl~nY?fHu{tW=k9N5yk1d;AR0?$xz!R6Pu7Le-X=XP2aL>D@bp$S zABP=vgPu~~Q>Mb>dPOPyLS5nL2{~oA-~}PdIZ0+e+(z28s{?yj#v!B+AyaLD$0^ZI zhHKK(H-JtX6=g8u(7OPuc^lVj-HriUd3p#WrcUO>#-;Ne=E+{5xdLYzM=bzJy7%8iBEd`PJ4 zLx)p18(v>$-P|tTf@gz=^AGK^ROq9pPw!-SyylplJ6L6fHg>noau1Lzz&TfHab~&OC+#t!D5fmF0JVVNNZ|CoEW^z)@(2+MSHV0k=h$>+-Wc`}}s}4;hK$uPhtz3DU9QpGy0gLuUL8mOZ--TMPCsETewp zzyG6Umizd}iXKS&v$Vf35(h0C7+(Zz*{z$!R&jk4Ya^ zUjqcp5D3eHf@Fe6Em5%Kv}{l}>C@8hC4E|!W0O8Dgf(YsV zk!92%8UI(751 zq<>w;(=z`F>Hm>s{F{hpl2Z%_N-GO%xr|((bZnS-sm|woS?Zx$FGYk6rOpl*(wo`Tcg%e81w~fyC zO<%tDROHq-3#MFLJ>+Y*!}Xsw-N89yQhs*-8M{bt?j-W4)^vM%jeFJ>ANqyeD#`4* zzumRYO?Q^viELfGqsC+PixxJ|nqKJo>@}NL^{ChDPfWD`u%u&~0j)Cc-@V>-d~$v);eZ*z237$3~8Q zx6#!fP7S)=Xzp9fUs||(L62%v|NF*)?#pU6zjq7GF`C!s(dHEn_q*5PYS$k=T3vc? z__-~sZzN5$`6Tu<&n#66lg4~^w$w5Iq~q;)uYy)@wb;4gcKO&V8=7@mI;Z27l6MDN z8~TiSt*Y1Krn9E7C-N_UJ+4{zfXnL#1m8Me=RcpucmCwAt>mo(2POr?em66xcg*>P zAHHRZe#y7=w0(NR`+IWRe*Md|ufH$v)*;sShsK^Fs<+8Aa%4NlNA=z}47yT*FOnBFbhOWQr1{Hh@C}4+w?`Q*VHTJ|?%wfQ7dr?w-0o@01pt z{e{oi=O%|gdv@N2gb^<C|Ja9PubjCsY-wo!x8^svbfz+~ z<*^z4d-@G{q~d5{2}iM>eNj(JxM@(-laG$~yx=Qi?e9IG?|#wur;{E_70|0IlOcC8803rqgltlo38Dr7OckXA0Llje zJRq=(0RsU>M*{2_2#_T15x7PHj2{G$A}ZMaLj-P-0BK@OBtXJofFlIcge3~Va|l36 z6hNjpOmKq0cQC+oVIK^TJrv*+!A#*b1fX3sK;9659C4E1B7y%39wXDj08AD;5G_ixfnAFAYlx^5rUP% zG8({hEI`U=08JbwI6>e$24Ib_j{(Sj3g8rh5ME;e+KmIq8w*e>P7+)s@P7(my~ueA zplCe6Rf00nejGsP1c0UE05*wB1UCqJjR)8wipK+#Oa!=1uvK)M01z<=plkxbc5##7 zEg$q)Y*LP8=pULEsw;a8TG|0kY!(P7zcIuQ-5qQvveg01k_j1Q!YX z;{je2Iq?8R2>@3Kj)?YC0YdEnOQ!-H6_*HZ5cEm_cvTc90F)#G+$K0Cy4e9Dk^su= z0LR5mg1ZD!i2!ei(nNsrWPk?*C&hpyfYB)cdy)X&688vPQvt>&1Dp~S$pD84+)@C} zh%qSu326XF2+j#hDu8D?KuRjWf5c&e69m3#0Oy504Iq0Oz$t=vg;zR2y9|K5bbw3Z zB*8@j|7ig4iJWNwMVSCs39gFv833VK0829fu8B(oHwb!V0$dlxnE)lz0d5m~B)Vk* zM9csv%L4dB+$6Y55H%g(Gf_GnpnN941A?1kzzl%V*#LWH0DLa)5xC|6jGqZ`TU5*h zI7Hx<4e+HHlMRrN3vh(sD`Ck2@SFvZk^}IKI81PYz&97*J7LcS$es;wir@#~H4C6! z9zfnKfP3O3!9@c9*#JL@oY??H`2bf59*FjN0HF?mrFj6qh)V=F2zuq42B{`hEXp^H z6eR^9w@F-7(cJ+OQ3z7zKqj-e=|HBt1W^S5HAHCvK=~Yi2Lu)|pb%j6T!1}=0JX$D z0@rx}JQo0@%mb(|4ilUp@SP9PP}t`K zWG@6bMbKDyEdXd&1dz7?z)PGYxJcl?5TJ?3SqM;63~-geSF|qz2weoQvvv8liCRg*gg?MXJ1Xg03>Ac?LQT6R!Q#)1NxT?x;zv;B9ez?Bs zivy;{sc86jHACC+RT*BBJSN;*sy#&{{yF$=8ILb;hryc+zTL++u6TSY8Q)o}?IenF z2aK?15w+U{fUHO*a1cX)mRhWWPvO56lMU zY&I;%q(0P4rmF_aybYi;5aJz*8IbV}p{o#&8Zu!cgzGaBhpS|b5pE!vMKVvY?kpKc zP073v?kia>$-Kc>CXd=qhPNx5z-j74m>HSS2mW+9`gJ7p1sgA!I~aq0&?L#~$#g8M zjbv;*+t3VZFBuz8)*R|!yj|H45P$q|p7XH-XQ(j%^R$Hc5T*{SH!S}6nP=r)25|Vm zvcT5RWyyRcYXi1SGCx=b+d>@?;M6#pA;8S-C7Ls*9*h{jOl63@| z2yrA^f#FZ-1hGsWZDcxsglD5i9No4$bMWz~k_gD*<%z~NJO)h$>-bClHrLkKfmD|^6rv74xbI@(L=H@g!zn(Bi>UoM{fx^ zygZ-ThH!|_l2{SXXR9bKI zB^%Bju!SsSl!PM?W3<|J}u(AeihIj zXfL!5;$y2h5VzzUh}-ZaC?CZZK*JFp0gZ%)LebDLhz~$pL)?zrLhbl`jQem0s3X(~ z@`nPTpHWal*hWxeh@)E@_B`wbh}-QYh+FJpXbHrvbvd*GS_Q3v1XKbQLB-G_C7u@m;`|pgEXpKG@?^z$x^Rw-Dkp z$x%=gG#DBJ@j+<>Gyob1@ri72h`Z%uP-mzG#9gs7%Bb#wk5|=z;|f`z8-O<y= zj4RMp=zZuK^Z_&*+79i2c0wDWO;y_;Q{7GD`Mm5rv;b-f%|%=|Y#%5XvO;|PTo0-V zeU12Upzk1lV&G$lr!CL41qknkDxp2lGoo&w+NWVNWa|&{{qpWm59nE84^%rkdLihB zlauEwA2CivE*r$Vj!^J!5Z{YC4*x9T-+=Z((;z+~o&a%c<}(aldP|`!h}VfQh&x+2 z#Eq*X#H%E)2lr4O?$*RlfoeksFLib(5lVt4Ly=Gz6a;mJ+#p_X+##coTPW~4R1Q@@ zyomUtaPA4-uraWcA@2Ep$j9B$u%Ym|bz`gcQ|cp77cw&5M#3+l@1b3yB1moGbss^> zD1*Bwch(=p)gZO0g;6Tp`@-Bswbner%MgxM5!`Xwcr{`){5trz04*C0jf93*6?RcI zSG=mJ+f!|8=DTo1MX#P}(-DIZT!$P(V56YHP$aY%jGXMGvM5ME|^SxrZHK4df^2jLme zbchXLWkv_G5N2aCVKbmFQU7leum{=DOo%;Tr5p)XNX>)hLbIV<=t~qf3w91v2o*qi zkORtxn9gV@U$@l6l)FL}s5+$bbg2RHex5H99zfL)z6X03`X1torD*6D#1Xg+eGYvB zeF$BLUWSf9WzcgFFPEII-Ow&*A#@gO8|+qSCFBj?u?&GCXeq>2FM$?AyxUv^TP(v& z>;)}{zXA$@o`$wSjAJ>gpiR(fXdPsfRf=#4#4-i!T1bP|aQ>NiJ+vQ@8(`UkjSv&F z;LQj(g*ALuQ~{MkJE85+4yY1JLb_*RpMmy3ymj6SyC2#|!GDoH>;c$=Cd@w_8=NZW zdFXTahhYyvFF?GBcnOw0`T)8Ly$4-}Em+LYe1lh&^PUZy_=+USo0o zAlc8b51{)H&O|@L`AI@f10tM-s5ldt@C)b{h*QB8&F#|!xj?M!(R8eojHek- zu}9A)mcz6>lGcFLU|w*B@#FwSrneK2Q_L6Jq+tkT>K7HHY}hwHeeD@`GAJ zOVFX#uq>-B)CuYUwS(G2yad-A9fAKi0xHFVaP_O^YI00gTxJ$dW#H^mZen~T*!X&xY6=Mmvr}~<@iuSYAsj{TBziJhG(mGHdkn2V7W$hdMrmJe2 z&@~`90QAp$Z+sPcW!14`_7;Ifzm7|LVaose&7U+|O+a%`&Q?3N?46*0BQ-8F+0Jji z9v)sWYp+N7T@RBnR{O-YS*n-bFE6|ojY0Rq`;Pvz)h>T9s9qu?SM@eh%VZd@!A-ix zJKqQ^INdO!_qJ~nZ=lD47(MjZIry?nuaFubc+;UE^Q95HpHbbva*j+_j+yb5@Dn$? zR!)ER{ac8^1O@~KDPf5sGEepVzpWg7`k&2H10JpmeM!mnr4OnaX#I5+Vbp^2)s8k} zY>Y3XThe;I{@>_zFRG^e;DDfzfUb)1we(rHrk*OQ_jwD|COEAF2T&2@GYZwys(*^;H%ATfF}}WkqkNJ3g$vcwQ5x152gYb>`5bka z`f--HKL?}qyU_|UzMbE7_R^BCXYYSsZwz~Ce4l?z?zSV}HGKaWBc_YeZMw*xixK|g z<}&Y}4+NIM+sJDygX&D(fBM>aYF~BCbkT2~+Wjv^@sBba({23Rz=TV80tRpPE`B(w z!Nv~~q~&W*T-w>;lo9iAy8mL?89#n-;GW;*6$Kj)dFW^A!_hT5!kKZ)7Mtf|@fg2P z@cHhz?Hm8S>3L(|g7J$7;+^?we2DQ&23=N7$$hnKbDnDYF&kG)>=nju9emy+Cgx<& zU<>jF26PPw=^WTLN2D*nz~QOIq6Ii*Hsy$y;WsdzY^0T(anCP`6dtCE9P!@;YIn8s zY;mU)Ic&2<*g{N~@xAV#A6BpJ`$4%sS-esHWtJ*NfD6 zH5(6Siq&=M!aVV2u^Jho<>A%>gLv#>m|E5JJ3ON^_6XxQ751)f6*0Wou2^Rb_A%Tm z=ZVNgD64wDIIsw1h3AW*i&0l}zDQiGMyiwZ#i7OO0d-Y@NL>QHzCaW$Q47>-1)}Cs zOoN`jVK?mc`tM5M_b9GLzhS@aJ3&^0n41O8M-l~|*UOK7dUSWwUmNywfmp&~Y8HxD zV0|X%>(`cEQ_sfEUYOVlDFZ_T0t14SQH7$;GBn^?K~=kD>QGaN@p}>1KJ8?0bm5+c zq+PI7@Z!(-MG60($}j!UDKZB!T>}C`5EVUNJhL2yOqefDELU%+PZf#%E6~dZ#cNl> z#1)IdE3vn{ut@l=QsaG$-%?2Lw&|T&tv0;C*68b^`Vz5u71osTvkV8%efHq>NjE~A zDVzgq{BXnQs+`ZiuK&ejh`~n2ArD+4zCd0d<2NLJdUAr-rS}(c>j}c015%7yB3ft| zmB~xQNZ61+8DQi1hpM46&p*` z13t!2Y}|i$p!&q{)3~j}IqsZty{vd2c+7d$kP-dJ5hX8Jm^d4Mfpq)muy| z#=nv4&~YRB_uI?X4dNAUH%7Lv*Qp5)ovih0S0m?N>|iplYHTwX%0#^lI2ZqXJMr2m zCT+m#H-2HGGWhu8$JRXm3%bMM#XK9owXy&8kA1vv9ULu(0*{1bPyTj$oD;!)+~?2t zZ@EkV{ms_s>tD1&?(4=r{@X!{G{)E{NSxlN4*nZsEld4vX`W)^Cd{z`jkz|iJqxxt zpP?1JFsj3itOwoeImgm@A8o7#Bd0NgWv|+PNQKHT2&uCOnPxV*H}Xe{bBv@84{1?ySXmi8Frl zWKz9_t)E$yJCAqSR-UIy#&%JOygtv!7Owby`{oyXUFOJo@$k^GU3`EP0j+oF_mvp~ z4}a0=qW^CFPMwR<_=S}*<)6RNcgx%8UC0j6W~-X&vwo-EtI`i6KU@>?cCd4U2*f>^ z@=CdQb}Pm(x$EkLtWa6rnOysA9d=9^ja>p z#hltMje)Dy)pjW`JsR&OhSYIsMuGwzqDC#0da;p96A|X_Qk|u_iRCQdlUgn>{yqY= bj}Twhaq&R*weBuo$a1?@we)al*!zC~#M|;E delta 18541 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 Date: Tue, 2 Jan 2024 15:48:23 -0500 Subject: [PATCH 13/15] set env for test action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dfae7b82..c931ebf5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: test: name: run-tests runs-on: ubuntu-latest - + environment: OPENAI steps: - uses: actions/checkout@v3 with: From 81dc18be5465126b112106d6e6d73a9a56b08925 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 16:08:16 -0500 Subject: [PATCH 14/15] try pulling env explicitly --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c931ebf5..c8ad6f48 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,9 @@ jobs: name: run-tests runs-on: ubuntu-latest environment: OPENAI + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + steps: - uses: actions/checkout@v3 with: From fa1228ea050441f6ddad7c5870379971ef1a831d Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 2 Jan 2024 16:14:37 -0500 Subject: [PATCH 15/15] merge --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a7427cf0..7b10ff1f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "import": "./dist/instructor.mjs", "require": "./dist/instructor.js" } + }, "publishConfig": { "access": "public" },