xsAI v0.4 "AIAIAI" is now available! Read Announcement
xsAI0.5.0-beta.8

Tool Calling

Connect LLMs to external data and systems.

install sizeminified sizeminzipped size
npm i @xsai/tool

Examples

defineTool

Use this when your schema library already supports Standard JSON Schema.

It is synchronous, and it is the recommended option over tool().

import {  } from '@xsai/tool'
import * as  from 'zod'

const  = .({
  : .().('The location to get the weather for'),
}).('Get the weather in a location')

const  = ({
  : 'Get the weather in a location',
  : ({  }) => .({
    ,
    : 42,
  }),
  : 'weather',
  : ,
})

tool

accepts a StandardSchemaV1, automatically infers the type.

tool() converts schema inputs to JSON Schema internally, so it remains async. Use it when your schema library does not already provide StandardJSONSchemaV1.

For convenience, we use valibot as an example.

But this package uses xsschema internally, so it supports any schema library that xsschema supports: e.g. zod, valibot, arktype, etc.

See xsschema for more information.

These below examples require you to install a standard schema to json schema parser (a separate package). As they are not provided by zod or valibot natively.

Read more about them here

import {  } from '@xsai/generate-text'
import {  } from '@xsai/generate-text/shared-chat'
import {  } from '@xsai/tool'
import {  } from 'node:process'
import * as  from 'valibot'

const  = await ({
  : 'Get the weather in a location',
  : ({  }) => .({
    ,
    : 42,
  }),
  : 'weather',
  : .({
    : .(
      .(),
      .('The location to get the weather for'),
    ),
  }),
})

const {  } = await ({
  : .!,
  : 'https://api.openai.com/v1/',
  : [
    {
      : 'You are a helpful assistant.',
      : 'system',
    },
    {
      : 'What is the weather in San Francisco?',
      : 'user',
    },
  ],
  : 'gpt-4o',
  : (2), 
  : [], 
})

rawTool

accepts a JsonSchema, execute params type to be defined manually.

import {  } from '@xsai/generate-text'
import {  } from '@xsai/generate-text/shared-chat'
import {  } from '@xsai/tool'
import {  } from 'node:process'

const  = <{ : string }>({
  : 'Get the weather in a location',
  : ({  }) => .({
    ,
    : 42,
  }),
  : 'weather',
  : {
    : false,
    : {
      : {
        : 'The location to get the weather for',
        : 'string',
      },
    },
    : [
      'location',
    ],
    : 'object',
  },
})

const {  } = await ({
  : .!,
  : 'https://api.openai.com/v1/',
  : [
    {
      : 'You are a helpful assistant.',
      : 'system',
    },
    {
      : 'What is the weather in San Francisco?',
      : 'user',
    },
  ],
  : 'gpt-4o',
  : (2), 
  : [], 
})

You can also use it like this to avoid tool's asynchronous contagion:

import type {  } from '@xsai/tool'

import {  } from '@xsai/tool'
import * as  from 'zod'

const  = .({
  : 
    .()
    .('The location to get the weather for'),
})

const  = <.<typeof >>({
  : 'Get the weather in a location',
  : ({  }) => .({
    ,
    : 42,
  }),
  : 'weather',
  : .() as unknown as ['parameters'],
})

Tool

You can also pass an object directly without installing @xsai/tool.

import type { Tool } from '@xsai/shared-chat'

import {  } from '@xsai/generate-text'
import {  } from '@xsai/generate-text/shared-chat'
import {  } from 'node:process'

const  = {
  : (({  }) => .({
    ,
    : 42,
  })) as Tool['execute'], 
  : {
    : 'Get the weather in a location',
    : 'weather',
    : {
      : false,
      : {
        : {
          : 'The location to get the weather for',
          : 'string',
        },
      },
      : [
        'location',
      ],
      : 'object',
    },
    : true,
  },
  : 'function',
} satisfies Tool

const {  } = await ({
  : .!,
  : 'https://api.openai.com/v1/',
  : [
    {
      : 'You are a helpful assistant.',
      : 'system',
    },
    {
      : 'What is the weather in San Francisco?',
      : 'user',
    },
  ],
  : 'gpt-4o',
  : (2), 
  : [], 
})

Zod example:

import type { Tool } from '@xsai/shared-chat'

import * as  from 'zod'

const  = .({
  : 
    .()
    .('The location to get the weather for'),
})

const  = {
  : () => .({
    : ( as .<typeof >).,
    : 42,
  }),
  : {
    : 'Get the weather in a location',
    : 'weather',
    : .() as unknown as <string, unknown>, 
  },
  : 'function',
} satisfies Tool

overrides

await tool(), rawTool() ultimately returns a Tool object, so you can modify it freely.

import {  } from '@xsai/generate-text'
import {  } from '@xsai/tool'
import {  } from 'node:process'
import * as  from 'valibot'

const  = .({
  : .(
    .(),
    .('The location to get the weather for'),
  ),
})

const  = await ({
  : 'Get the weather in a location',
  : ({  }) => .({
    ,
    : 42,
  }),
  : 'weather',
  ,
})

. = () => .({
  : ( as .<typeof >).,
  : 5500,
})

On this page