npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

openai-function-schema

v0.2.6

Published

OpenAI LLM function schema from OpenAPI (Swagger) document

Downloads

214

Readme

Deprecated

openai-function-schema has been renamed to @wrtnai/openai-function-schema

OpenAI Function Schema

Wrtn Technologies

GitHub license npm version Downloads Build Status

OpenAI function call schema definition, converter and executor.

@wrtnio/openai-function-schema supports OpenAI function call schema definitions, and converter from Swagger (OpenAPI) documents. About the converter from Swagger (OpenAPI) documents, @wrtnio/openai-function-schema supports every versions of them.

  • Swagger v2.0
  • OpenAPI v3.0
  • OpenApi v3.1

Also, @wrtnio/openai-function-schema provides function call executor from IOpenAiDocument and IOpenAiFunction, so that you can easily execute the remote Restful API operation with OpenAI composed arguments.

Let's learn how to use it by example code of below.

Setup

npm install @wrtnio/openai-function-schema
import {
  IOpenAiDocument,
  IOpenAiFunction,
  OpenAiComposer,
  OpenAiFetcher,
} from "@wrtnio/openai-function-schema";
import fs from "fs";
import typia from "typia";
import { v4 } from "uuid";

import { IBbsArticle } from "../../../api/structures/IBbsArticle";

const main = async (): Promise<void> => {
  // COMPOSE OPENAI FUNCTION CALL SCHEMAS
  const swagger = JSON.parse(
    await fs.promises.readFile("swagger.json", "utf8"),
  );
  const document: IOpenAiDocument = OpenAiComposer.document({ 
    swagger 
  });

  // EXECUTE OPENAI FUNCTION CALL
  const func: IOpenAiFunction = document.functions.find(
    (f) => f.method === "put" && f.path === "/bbs/articles",
  )!;
  const article: IBbsArticle = await OpenAiFetcher.execute({
    document,
    function: func,
    connection: { host: "http://localhost:3000" },
    arguments: [
      // imagine that arguments are composed by OpenAI
      v4(),
      typia.random<IBbsArticle.ICreate>(),
    ],
  });
  typia.assert(article);
};
main().catch(console.error);

Features

About supported features, please read description comments of each component.

I'm preparing documentation and playground website of @wrtnio/openai-function-schema features. Until that, please read below components' description comments. Even though you have to read source code of each component, but description comments of them may satisfy you.

Command Line Interface

########
# LAUNCH CLI
########
# PRIOR TO NODE V20
npm install -g @wrtnio/openai-function-schema
npx wofs

# SINCE NODE V20
npx @wrtnio/openai-function-schema

########
# PROMPT
########
--------------------------------------------------------
 Swagger to OpenAI Function Call Schema Converter
--------------------------------------------------------
? Swagger file path: test/swagger.json
? OpenAI Function Call Schema file path: test/plain.json
? Whether to wrap parameters into an object with keyword or not: No

Convert swagger to OpenAI function schema file by a CLI command.

If you run npx @wrtnio/openai-function-schema (or npx wofs after global setup), the CLI (Command Line Interface) will inquiry those arguments. After you fill all of them, the OpenAI function call schema file of IOpenAiDocument type would be created to the target location.

If you want to specify arguments without prompting, you can fill them like below:

# PRIOR TO NODE V20
npm install -g @wrtnio/openai-function-schema
npx wofs --input swagger.json --output openai.json --keyword false

# SINCE NODE V20
npx @wrtnio/openai-function-schema
  --input swagger.json 
  --output openai.json 
  --keyword false

Here is the list of IOpenAiDocument files generated by CLI command.

Project | Swagger | Positional | Keyworded --------------|---------|--------|----------- BBS | swagger.json | positional.json | keyworded.json Clickhouse | swagger.json | positional.json | keyworded.json Fireblocks | swagger.json | positional.json | keyworded.json Iamport | swagger.json | positional.json | keyworded.json PetStore | swagger.json | positional.json | keyworded.json Shopping Mall | swagger.json | positional.json | keyworded.json Toss Payments | swagger.json | positional.json | keyworded.json Uber | swagger.json | positional.json | keyworded.json

Library API

If you want to utilize @wrtnio/openai-function-schema in the API level, you should start from composing IOpenAiDocument through OpenAiComposer.document() method.

After composing the IOpenAiDocument data, you may provide the nested IOpenAiFunction instances to the OpenAI, and the OpenAI may compose the arguments by its function calling feature. With the OpenAI automatically composed arguments, you can execute the function call by OpenAiFetcher.execute() method.

Here is the example code composing and executing the IOpenAiFunction.

import {
  IOpenAiDocument,
  IOpenAiFunction,
  OpenAiComposer,
  OpenAiFetcher,
} from "@wrtnio/openai-function-schema";
import fs from "fs";
import typia from "typia";
import { v4 } from "uuid";

import { IBbsArticle } from "../../../api/structures/IBbsArticle";

const main = async (): Promise<void> => {
  // COMPOSE OPENAI FUNCTION CALL SCHEMAS
  const swagger = JSON.parse(
    await fs.promises.readFile("swagger.json", "utf8"),
  );
  const document: IOpenAiDocument = OpenAiComposer.document({ 
    swagger 
  });

  // EXECUTE OPENAI FUNCTION CALL
  const func: IOpenAiFunction = document.functions.find(
    (f) => f.method === "put" && f.path === "/bbs/articles",
  )!;
  const article: IBbsArticle = await OpenAiFetcher.execute({
    document,
    function: func,
    connection: { host: "http://localhost:3000" },
    arguments: [
      // imagine that arguments are composed by OpenAI
      v4(),
      typia.random<IBbsArticle.ICreate>(),
    ],
  });
  typia.assert(article);
};
main().catch(console.error);

By the way, above example code's target operation function has multiple parameters. You know what? If you configure a function to have only one parameter by wrapping into one object type, OpenAI function calling feature constructs arguments a little bit efficiently than multiple parameters case.

Such only one object typed parameter is called keyword parameter, and @wrtnio/openai-function-schema supports such keyword parameterized function schemas. When composing IOpenAiDocument by OpenAiComposer.document() method, configures option.keyword to be true, then every IOpenAiFunction instances would be keyword parameterized. Also, OpenAiFetcher understands the keyword parameterized function specification, so that performs proper execution by automatic decomposing the arguments.

Here is the example code of keyword parameterizing.

import {
  IOpenAiDocument,
  IOpenAiFunction,
  OpenAiComposer,
  OpenAiFetcher,
} from "@wrtnio/openai-function-schema";
import fs from "fs";
import typia from "typia";
import { v4 } from "uuid";

import { IBbsArticle } from "../../../api/structures/IBbsArticle";

const main = async (): Promise<void> => {
  // COMPOSE OPENAI FUNCTION CALL SCHEMAS
  const swagger = JSON.parse(
    await fs.promises.readFile("swagger.json", "utf8"),
  );
  const document: IOpenAiDocument = OpenAiComposer.document({ 
    swagger,
    options: {
      keyword: true, // keyword parameterizing
    }
  });

  // EXECUTE OPENAI FUNCTION CALL
  const func: IOpenAiFunction = document.functions.find(
    (f) => f.method === "put" && f.path === "/bbs/articles",
  )!;
  const article: IBbsArticle = await OpenAiFetcher.execute({
    document,
    function: func,
    connection: { host: "http://localhost:3000" },
    arguments: [
      // imagine that argument is composed by OpenAI
      {
        id: v4(),
        body: typia.random<IBbsArticle.ICreate>(),
      },
    ],
  });
  typia.assert(article);
};
main().catch(console.error);

At last, there can be some special API operation that some arguments must be composed by user, not by LLM (Large Language Model). For example, if an API operation requires file uploading or secret key identifier, it must be composed by user manually in the frontend application side.

For such case, @wrtnio/openai-function-schema supports special option IOpenAiDocument.IOptions.separate. If you configure the callback function, it would be utilized for determining whether the value must be composed by user or not. When the arguments are composed by both user and LLM sides, you can combine them into one through OpenAiDataComposer.parameters() method, so that you can still execute the function calling with OpenAiFetcher.execute() method.

Here is the example code of such special case:

import {
  IOpenAiDocument,
  IOpenAiFunction,
  IOpenAiSchema,
  OpenAiComposer,
  OpenAiDataCombiner,
  OpenAiFetcher,
  OpenAiTypeChecker,
} from "@wrtnio/openai-function-schema";
import fs from "fs";
import typia from "typia";

import { IMembership } from "../../api/structures/IMembership";

const main = async (): Promise<void> => {
  // COMPOSE OPENAI FUNCTION CALL SCHEMAS
  const swagger = JSON.parse(
    await fs.promises.readFile("swagger.json", "utf8"),
  );
  const document: IOpenAiDocument = OpenAiComposer.document({
    swagger,
    options: {
      keyword: true,
      separate: (schema: IOpenAiSchema) =>
        OpenAiTypeChecker.isString(schema) &&
        (schema["x-wrtn-secret-key"] !== undefined ||
          schema["contentMediaType"] !== undefined),
    },
  });

  // EXECUTE OPENAI FUNCTION CALL
  const func: IOpenAiFunction = document.functions.find(
    (f) => f.method === "patch" && f.path === "/membership/change",
  )!;
  const membership: IMembership = await OpenAiFetcher.execute({
    document,
    function: func,
    connection: { host: "http://localhost:3000" },
    arguments: OpenAiDataCombiner.parameters({
      function: func,
      llm: [
        // imagine that below argument is composed by OpenAI
        {
          body: {
            name: "Wrtn Technologies",
            email: "[email protected]",
            password: "1234",
            age: 20,
            gender: 1,
          },
        },
      ],
      human: [
        // imagine that below argument is composed by human
        {
          query: {
            secret: "something",
          },
          body: {
            secretKey: "something",
            picture: "https://wrtn.io/logo.png",
          },
        },
      ],
    }),
  });
  typia.assert(membership);
};
main().catch(console.error);