Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature: ToolSchemaExtractor from jsDoc function (working mvp) #130

Open
websharik opened this issue Aug 7, 2024 · 0 comments
Open

Feature: ToolSchemaExtractor from jsDoc function (working mvp) #130

websharik opened this issue Aug 7, 2024 · 0 comments

Comments

@websharik
Copy link

websharik commented Aug 7, 2024

Only TS supported, only function, no check's (ex empty jsDoc). Todos concept: use function as tool with auto detect and convert to schema from jsDoc for tools list. Then auto call that function on tool prompt, with middleware support (before/after tool call).

jsDocToolsExtractor.ts

import ts from 'typescript'

interface functionTool {
  type: 'function'
  function: {
    name: string
    description: string
    parameters: {
      type: 'object'
      properties: {
        [prop: string]: {
          type: string
          description: string
        }
      }
      required: string[]
    }
  }
}

export const jsDocToolsExtractor = (
  filePath: string,
  allowedNames?: string[]
): functionTool[] => {
  const sourceFile = ts.createProgram([filePath], {}).getSourceFile(filePath)
  let declarations: functionTool[] = []
  if (sourceFile) {
    ts.forEachChild(sourceFile, node => {
      if (ts.isFunctionDeclaration(node)) {
        const functionName = node?.name?.text as string
        //@ts-ignore
        const function_jsDoc = node?.jsDoc?.[0]
        const functionDescription = function_jsDoc.comment
        const functionParams = node.parameters.map((param, index) => {
          let param_jsDoc = function_jsDoc?.tags?.[index]
          const paramName = param.name.getText(sourceFile)
          const paramType = param.type
            ? param.type.getText(sourceFile)
            : 'string'
          const paramDescription = param_jsDoc?.comment
          const paramIsRequired = !param.questionToken

          return {
            name: paramName,
            type: paramType,
            description: paramDescription,
            required: paramIsRequired
          }
        })
        const functionRequiredParams = functionParams
          .filter(param => param.required)
          .map(param => param.name)

        if (!allowedNames || allowedNames.includes(functionName as string))
          declarations.push({
            type: 'function',
            function: {
              name: functionName,
              description: functionDescription,
              parameters: {
                type: 'object',
                properties: functionParams.reduce(
                  (acc: any, { name, type, description }) => {
                    acc[name] = { type, description }
                    return acc
                  },
                  {}
                ),
                required: functionRequiredParams
              }
            }
          })
      }
    })
  }

  return declarations
}

Usage:
tools.ts

/**
 * Tool to decode base64 string.
 * @param str string to be decoded
 * @returns decoded string
 */
export function base64DecodeTool(str: string): string {
  return `Decoded string is: ${atob(str)}`
}

/**
 * Tool to on/off light
 * @param state state of light
 * @returns current state of light
 */
export function toggleLightTool(state: boolean): string {
  return `Light now is ${state ? 'on' : 'off'}`
}

index.ts

const TOOLS_SCHEMA = jsDocToolsExtractor('./tools.ts')

TOOLS_SCHEMA:

[
  {
    "type": "function",
    "function": {
      "name": "base64DecodeTool",
      "description": "Tool to decode base64 string.",
      "parameters": {
        "type": "object",
        "properties": {
          "str": {
            "type": "string",
            "description": "string to be decoded"
          }
        },
        "required": [
          "str"
        ]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "toggleLightTool",
      "description": "Tool to on/off light",
      "parameters": {
        "type": "object",
        "properties": {
          "state": {
            "type": "boolean",
            "description": "state of light"
          }
        },
        "required": [
          "state"
        ]
      }
    }
  }
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant