Skip to main content Link Search Menu Expand Document (external link)

Tool.ts overview

The Tool module provides functionality for defining and managing tools that language models can call to augment their capabilities.

This module enables creation of both user-defined and provider-defined tools, with full schema validation, type safety, and handler support. Tools allow AI models to perform actions like searching databases, calling APIs, or executing code within your application context.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Define a simple calculator tool
const Calculator = Tool.make("Calculator", {
  description: "Performs basic arithmetic operations",
  parameters: {
    operation: Schema.Literal("add", "subtract", "multiply", "divide"),
    a: Schema.Number,
    b: Schema.Number
  },
  success: Schema.Number
})

Since v1.0.0


Exports Grouped by Category


Annotations

Destructive (class)

Annotation indicating whether a tool performs destructive operations.

Example

import { Tool } from "@effect/ai"

const safeTool = Tool.make("search_database").annotate(Tool.Destructive, false)

Signature

declare class Destructive

Source

Since v1.0.0

Idempotent (class)

Annotation indicating whether a tool can be called multiple times safely.

Example

import { Tool } from "@effect/ai"

const idempotentTool = Tool.make("get_current_time").annotate(Tool.Idempotent, true)

Signature

declare class Idempotent

Source

Since v1.0.0

OpenWorld (class)

Annotation indicating whether a tool can handle arbitrary external data.

Example

import { Tool } from "@effect/ai"

const restrictedTool = Tool.make("internal_operation").annotate(Tool.OpenWorld, false)

Signature

declare class OpenWorld

Source

Since v1.0.0

Readonly (class)

Annotation indicating whether a tool only reads data without making changes.

Example

import { Tool } from "@effect/ai"

const readOnlyTool = Tool.make("get_user_info").annotate(Tool.Readonly, true)

Signature

declare class Readonly

Source

Since v1.0.0

Title (class)

Annotation for providing a human-readable title for tools.

Example

import { Tool } from "@effect/ai"

const myTool = Tool.make("calculate_tip").annotate(Tool.Title, "Tip Calculator")

Signature

declare class Title

Source

Since v1.0.0

Constructors

fromTaggedRequest

Creates a Tool from a Schema.TaggedRequest.

This utility function converts Effect’s TaggedRequest schemas into Tool definitions, automatically mapping the request parameters, success, and failure schemas.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Define a tagged request for user operations
class GetUser extends Schema.TaggedRequest<GetUser>()("GetUser", {
  success: Schema.Struct({
    id: Schema.Number,
    name: Schema.String,
    email: Schema.String
  }),
  failure: Schema.Struct({
    error: Schema.Literal("UserNotFound", "DatabaseError"),
    message: Schema.String
  }),
  payload: {
    userId: Schema.Number
  }
}) {}

// Convert to a Tool
const getUserTool = Tool.fromTaggedRequest(GetUser)

Signature

declare const fromTaggedRequest: <S extends AnyTaggedRequestSchema>(schema: S) => FromTaggedRequest<S>

Source

Since v1.0.0

make

Creates a user-defined tool with the specified name and configuration.

This is the primary constructor for creating custom tools that AI models can call. The tool definition includes parameter validation, success/failure schemas, and optional service dependencies.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Simple tool with no parameters
const GetCurrentTime = Tool.make("GetCurrentTime", {
  description: "Returns the current timestamp",
  success: Schema.Number
})

Signature

declare const make: <
  const Name extends string,
  Parameters extends Schema.Struct.Fields = {},
  Success extends Schema.Schema.Any = typeof Schema.Void,
  Failure extends Schema.Schema.All = typeof Schema.Never,
  Dependencies extends Array<Context.Tag<any, any>> = []
>(
  name: Name,
  options?: {
    readonly description?: string | undefined
    readonly parameters?: Parameters | undefined
    readonly success?: Success | undefined
    readonly failure?: Failure | undefined
    readonly dependencies?: Dependencies | undefined
  }
) => Tool<
  Name,
  { readonly parameters: Schema.Struct<Parameters>; readonly success: Success; readonly failure: Failure },
  Context.Tag.Identifier<Dependencies[number]>
>

Source

Since v1.0.0

providerDefined

Creates a provider-defined tool which leverages functionality built into a large language model provider (e.g. web search, code execution).

These tools are executed by the large language model provider rather than by your application. However, they can optionally require custom handlers implemented in your application to process provider generated results.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Web search tool provided by OpenAI
const WebSearch = Tool.providerDefined({
  id: "openai.web_search",
  toolkitName: "WebSearch",
  providerName: "web_search",
  args: {
    query: Schema.String
  },
  success: Schema.Struct({
    results: Schema.Array(
      Schema.Struct({
        title: Schema.String,
        url: Schema.String,
        content: Schema.String
      })
    )
  })
})

Signature

declare const providerDefined: <
  const Name extends string,
  Args extends Schema.Struct.Fields = {},
  Parameters extends Schema.Struct.Fields = {},
  Success extends Schema.Schema.Any = typeof Schema.Void,
  Failure extends Schema.Schema.All = typeof Schema.Never,
  RequiresHandler extends boolean = false
>(options: {
  readonly id: `${string}.${string}`
  readonly toolkitName: Name
  readonly providerName: string
  readonly args: Args
  readonly requiresHandler?: RequiresHandler | undefined
  readonly parameters?: Parameters | undefined
  readonly success?: Success | undefined
  readonly failure?: Failure | undefined
}) => (
  args: Schema.Simplify<Schema.Struct.Encoded<Args>>
) => ProviderDefined<
  Name,
  {
    readonly args: Schema.Struct<Args>
    readonly parameters: Schema.Struct<Parameters>
    readonly success: Success
    readonly failure: Failure
  },
  RequiresHandler
>

Source

Since v1.0.0

Guards

isProviderDefined

Type guard to check if a value is a provider-defined tool.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

const UserDefinedTool = Tool.make("Calculator", {
  description: "Performs basic arithmetic operations",
  parameters: {
    operation: Schema.Literal("add", "subtract", "multiply", "divide"),
    a: Schema.Number,
    b: Schema.Number
  },
  success: Schema.Number
})

const ProviderDefinedTool = Tool.providerDefined({
  id: "openai.web_search",
  toolkitName: "WebSearch",
  providerName: "web_search",
  args: {
    query: Schema.String
  },
  success: Schema.Struct({
    results: Schema.Array(
      Schema.Struct({
        title: Schema.String,
        url: Schema.String,
        snippet: Schema.String
      })
    )
  })
})

console.log(Tool.isUserDefined(UserDefinedTool)) // false
console.log(Tool.isUserDefined(ProviderDefinedTool)) // true

Signature

declare const isProviderDefined: (u: unknown) => u is ProviderDefined<string, any>

Source

Since v1.0.0

isUserDefined

Type guard to check if a value is a user-defined tool.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

const UserDefinedTool = Tool.make("Calculator", {
  description: "Performs basic arithmetic operations",
  parameters: {
    operation: Schema.Literal("add", "subtract", "multiply", "divide"),
    a: Schema.Number,
    b: Schema.Number
  },
  success: Schema.Number
})

const ProviderDefinedTool = Tool.providerDefined({
  id: "openai.web_search",
  toolkitName: "WebSearch",
  providerName: "web_search",
  args: {
    query: Schema.String
  },
  success: Schema.Struct({
    results: Schema.Array(
      Schema.Struct({
        title: Schema.String,
        url: Schema.String,
        snippet: Schema.String
      })
    )
  })
})

console.log(Tool.isUserDefined(UserDefinedTool)) // true
console.log(Tool.isUserDefined(ProviderDefinedTool)) // false

Signature

declare const isUserDefined: (u: unknown) => u is Tool<string, any, any>

Source

Since v1.0.0

Models

Handler (interface)

Represents an Tool that has been implemented within the application.

Signature

export interface Handler<Name extends string> {
  readonly _: unique symbol
  readonly name: Name
  readonly context: Context.Context<never>
  readonly handler: (params: any) => Effect.Effect<any, any>
}

Source

Since v1.0.0

HandlerResult (interface)

Represents the result of calling the handler for a particular Tool.

Signature

export interface HandlerResult<Tool extends Any> {
  /**
   * The result of executing the handler for a particular tool.
   */
  readonly result: Success<Tool>
  /**
   * The pre-encoded tool call result of executing the handler for a particular
   * tool as a JSON-serializable value. The encoded result can be incorporated
   * into subsequent requests to the large language model.
   */
  readonly encodedResult: unknown
}

Source

Since v1.0.0

ProviderDefined (interface)

A provider-defined tool is a tool which is built into a large language model provider (e.g. web search, code execution).

These tools are executed by the large language model provider rather than by your application. However, they can optionally require custom handlers implemented in your application to process provider generated results.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Define a web search tool provided by OpenAI
const WebSearch = Tool.providerDefined({
  id: "openai.web_search",
  toolkitName: "WebSearch",
  providerName: "web_search",
  args: {
    query: Schema.String
  },
  success: Schema.Struct({
    results: Schema.Array(
      Schema.Struct({
        title: Schema.String,
        url: Schema.String,
        snippet: Schema.String
      })
    )
  })
})

Signature

export interface ProviderDefined<
  Name extends string,
  Config extends {
    readonly args: AnyStructSchema
    readonly parameters: AnyStructSchema
    readonly success: Schema.Schema.Any
    readonly failure: Schema.Schema.All
  } = {
    readonly args: Schema.Struct<{}>
    readonly parameters: Schema.Struct<{}>
    readonly success: typeof Schema.Void
    readonly failure: typeof Schema.Never
  },
  RequiresHandler extends boolean = false
> extends Tool<
      Name,
      {
        readonly parameters: Config["parameters"]
        success: RequiresHandler extends true ? Config["success"] : Schema.Either<Config["success"], Config["failure"]>
        failure: RequiresHandler extends true ? Config["failure"] : typeof Schema.Never
      }
    >,
    Tool.ProviderDefinedProto {
  /**
   * The arguments passed to the provider-defined tool.
   */
  readonly args: Config["args"]["Encoded"]

  /**
   * A `Schema` representing the arguments provided by the end-user which will
   * be used to configure the behavior of the provider-defined tool.
   */
  readonly argsSchema: Config["args"]

  /**
   * Name of the tool as recognized by the large language model provider.
   */
  readonly providerName: string

  /**
   * If set to `true`, this provider-defined tool will require a user-defined
   * tool call handler to be provided when converting the `Toolkit` containing
   * this tool into a `Layer`.
   */
  readonly requiresHandler: RequiresHandler

  /**
   * Decodes the result received after the provider-defined tool is called.
   */
  decodeResult(args: unknown): Effect.Effect<Config["success"]["Type"], AiError.AiError>
}

Source

Since v1.0.0

Tool (interface)

A user-defined tool that language models can call to perform actions.

Tools represent actionable capabilities that large language models can invoke to extend their functionality beyond text generation. Each tool has a defined schema for parameters, results, and failures.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

// Create a weather lookup tool
const GetWeather = Tool.make("GetWeather", {
  description: "Get current weather for a location",
  parameters: {
    location: Schema.String,
    units: Schema.Literal("celsius", "fahrenheit")
  },
  success: Schema.Struct({
    temperature: Schema.Number,
    condition: Schema.String,
    humidity: Schema.Number
  })
})

Signature

export interface Tool<
  Name extends string,
  Config extends {
    readonly parameters: AnyStructSchema
    readonly success: Schema.Schema.Any
    readonly failure: Schema.Schema.All
  } = {
    readonly parameters: Schema.Struct<{}>
    readonly success: typeof Schema.Void
    readonly failure: typeof Schema.Never
  },
  Requirements = never
> extends Tool.Variance<Requirements> {
  /**
   * The tool identifier which is used to uniquely identify the tool. */
  readonly id: string

  /**
   * The name of the tool.
   */
  readonly name: Name

  /**
   * The optional description of the tool.
   */
  readonly description?: string | undefined

  /**
   * A `Schema` representing the parameters that a tool must be called with.
   */
  readonly parametersSchema: Config["parameters"]

  /**
   * A `Schema` representing the value that a tool must return when called if
   * the tool call is successful.
   */
  readonly successSchema: Config["success"]

  /**
   * A `Schema` representing the value that a tool must return when called if
   * it fails.
   */
  readonly failureSchema: Config["failure"]

  /**
   * A `Context` object containing tool annotations which can store metadata
   * about the tool.
   */
  readonly annotations: Context.Context<never>

  /**
   * Adds a _request-level_ dependency which must be provided before the tool
   * call handler can be executed.
   *
   * This can be useful when you want to enforce that a particular dependency
   * **MUST** be provided to each request to the large language model provider
   * instead of being provided when creating the tool call handler layer.
   */
  addDependency<Identifier, Service>(
    tag: Context.Tag<Identifier, Service>
  ): Tool<Name, Config, Identifier | Requirements>

  /**
   * Set the schema to use to validate the result of a tool call when successful.
   */
  setParameters<ParametersSchema extends Schema.Struct<any> | Schema.Struct.Fields>(
    schema: ParametersSchema
  ): Tool<
    Name,
    {
      readonly parameters: ParametersSchema extends Schema.Struct<infer _>
        ? ParametersSchema
        : ParametersSchema extends Schema.Struct.Fields
          ? Schema.Struct<ParametersSchema>
          : never
      readonly success: Config["success"]
      readonly failure: Config["failure"]
    },
    Requirements
  >

  /**
   * Set the schema to use to validate the result of a tool call when successful.
   */
  setSuccess<SuccessSchema extends Schema.Schema.Any>(
    schema: SuccessSchema
  ): Tool<
    Name,
    {
      readonly parameters: Config["parameters"]
      readonly success: SuccessSchema
      readonly failure: Config["failure"]
    },
    Requirements
  >

  /**
   * Set the schema to use to validate the result of a tool call when it fails.
   */
  setFailure<FailureSchema extends Schema.Schema.Any>(
    schema: FailureSchema
  ): Tool<
    Name,
    {
      readonly parameters: Config["parameters"]
      readonly success: Config["success"]
      readonly failure: FailureSchema
    },
    Requirements
  >

  /**
   * Add an annotation to the tool.
   */
  annotate<I, S>(tag: Context.Tag<I, S>, value: S): Tool<Name, Config, Requirements>

  /**
   * Add many annotations to the tool.
   */
  annotateContext<I>(context: Context.Context<I>): Tool<Name, Config, Requirements>
}

Source

Since v1.0.0

Type Ids

ProviderDefinedTypeId

Unique identifier for provider-defined tools.

Signature

declare const ProviderDefinedTypeId: "~@effect/ai/Tool/ProviderDefined"

Source

Since v1.0.0

ProviderDefinedTypeId (type alias)

Type-level representation of the provider-defined tool identifier.

Signature

type ProviderDefinedTypeId = typeof ProviderDefinedTypeId

Source

Since v1.0.0

TypeId

Unique identifier for user-defined tools.

Signature

declare const TypeId: "~@effect/ai/Tool"

Source

Since v1.0.0

TypeId (type alias)

Type-level representation of the user-defined tool identifier.

Signature

type TypeId = typeof TypeId

Source

Since v1.0.0

Utilities

getDescription

Extracts the description from a tool’s metadata.

Returns the tool’s description if explicitly set, otherwise attempts to extract it from the parameter schema’s AST annotations.

Example

import { Tool } from "@effect/ai"

const myTool = Tool.make("example", {
  description: "This is an example tool"
})

const description = Tool.getDescription(myTool)
console.log(description) // "This is an example tool"

Signature

declare const getDescription: <
  Name extends string,
  Config extends {
    readonly parameters: AnyStructSchema
    readonly success: Schema.Schema.Any
    readonly failure: Schema.Schema.All
  }
>(
  tool: Tool<Name, Config>
) => string | undefined

Source

Since v1.0.0

getDescriptionFromSchemaAst

Signature

declare const getDescriptionFromSchemaAst: (ast: AST.AST) => string | undefined

Source

Since v1.0.0

getJsonSchema

Generates a JSON Schema for a tool.

This function creates a JSON Schema representation that can be used by large language models to indicate the structure and type of the parameters that a given tool call should receive.

Example

import { Tool } from "@effect/ai"
import { Schema } from "effect"

const weatherTool = Tool.make("get_weather", {
  parameters: {
    location: Schema.String,
    units: Schema.optional(Schema.Literal("celsius", "fahrenheit"))
  }
})

const jsonSchema = Tool.getJsonSchema(weatherTool)
console.log(jsonSchema)
// {
//   type: "object",
//   properties: {
//     location: { type: "string" },
//     units: { type: "string", enum: ["celsius", "fahrenheit"] }
//   },
//   required: ["location"]
// }

Signature

declare const getJsonSchema: <
  Name extends string,
  Config extends {
    readonly parameters: AnyStructSchema
    readonly success: Schema.Schema.Any
    readonly failure: Schema.Schema.All
  }
>(
  tool: Tool<Name, Config>
) => JsonSchema.JsonSchema7

Source

Since v1.0.0

getJsonSchemaFromSchemaAst

Signature

declare const getJsonSchemaFromSchemaAst: (ast: AST.AST) => JsonSchema.JsonSchema7

Source

Since v1.0.0

unsafeSecureJsonParse

Unsafe: This function will throw an error if an insecure property is found in the parsed JSON or if the provided JSON text is not parseable.

Signature

declare const unsafeSecureJsonParse: (text: string) => unknown

Source

Since v1.0.0

Utility Types

Any (interface)

A type which represents any Tool.

Signature

export interface Any extends Pipeable {
  readonly [TypeId]: {
    readonly _Requirements: Covariant<any>
  }
  readonly id: string
  readonly name: string
  readonly description?: string | undefined
  readonly parametersSchema: AnyStructSchema
  readonly successSchema: Schema.Schema.Any
  readonly failureSchema: Schema.Schema.All
  readonly annotations: Context.Context<never>
}

Source

Since v1.0.0

AnyProviderDefined (interface)

A type which represents any provider-defined Tool.

Signature

export interface AnyProviderDefined extends Any {
  readonly args: any
  readonly argsSchema: AnyStructSchema
  readonly requiresHandler: boolean
  readonly providerName: string
  readonly decodeResult: (result: unknown) => Effect.Effect<any, AiError.AiError>
}

Source

Since v1.0.0

AnyStructSchema (interface)

Signature

export interface AnyStructSchema extends Pipeable {
  readonly [Schema.TypeId]: any
  readonly make: any
  readonly Type: any
  readonly Encoded: any
  readonly Context: any
  readonly ast: AST.AST
  readonly fields: Schema.Struct.Fields
  readonly annotations: any
}

Source

Since v1.0.0

AnyTaggedRequestSchema (interface)

Signature

export interface AnyTaggedRequestSchema extends AnyStructSchema {
  readonly _tag: string
  readonly success: Schema.Schema.Any
  readonly failure: Schema.Schema.All
}

Source

Since v1.0.0

Failure (type alias)

A utility type to extract the type of the tool call result when it fails.

Signature

type Failure<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? Schema.Schema.Type<_Config["failure"]> : never

Source

Since v1.0.0

FailureEncoded (type alias)

A utility type to extract the encoded type of the tool call result when it fails.

Signature

type FailureEncoded<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? Schema.Schema.Encoded<_Config["failure"]> : never

Source

Since v1.0.0

FromTaggedRequest (interface)

A utility type to convert a Schema.TaggedRequest into an Tool.

Signature

export interface FromTaggedRequest<S extends AnyTaggedRequestSchema>
  extends Tool<
    S["_tag"],
    {
      readonly parameters: S
      readonly success: S["success"]
      readonly failure: S["failure"]
    }
  > {}

Source

Since v1.0.0

HandlersFor (type alias)

A utility type to create a union of Handler types for all tools in a record.

Signature

type HandlersFor<Tools> = {
  [Name in keyof Tools]: RequiresHandler<Tools[Name]> extends true ? Handler<Tools[Name]["name"]> : never
}[keyof Tools]

Source

Since v1.0.0

Name (type alias)

A utility type to extract the Name type from an Tool.

Signature

type Name<T> = T extends Tool<infer _Name, infer _Config, infer _Requirements> ? _Name : never

Source

Since v1.0.0

Parameters (type alias)

A utility type to extract the type of the tool call parameters.

Signature

type Parameters<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements>
    ? Schema.Struct.Type<_Config["parameters"]["fields"]>
    : never

Source

Since v1.0.0

ParametersEncoded (type alias)

A utility type to extract the encoded type of the tool call parameters.

Signature

type ParametersEncoded<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? Schema.Schema.Encoded<_Config["parameters"]> : never

Source

Since v1.0.0

ParametersSchema (type alias)

A utility type to extract the schema for the parameters which an Tool must be called with.

Signature

type ParametersSchema<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? _Config["parameters"] : never

Source

Since v1.0.0

Requirements (type alias)

A utility type to extract the requirements of an Tool.

Signature

type Requirements<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements>
    ? _Config["parameters"]["Context"] | _Config["success"]["Context"] | _Config["failure"]["Context"] | _Requirements
    : never

Source

Since v1.0.0

RequiresHandler (type alias)

A utility type to determine if the specified tool requires a user-defined handler to be implemented.

Signature

type RequiresHandler<Tool> =
  Tool extends ProviderDefined<infer _Name, infer _Config, infer _RequiresHandler> ? _RequiresHandler : true

Source

Since v1.0.0

Success (type alias)

A utility type to extract the type of the tool call result when it succeeds.

Signature

type Success<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? Schema.Schema.Type<_Config["success"]> : never

Source

Since v1.0.0

SuccessEncoded (type alias)

A utility type to extract the encoded type of the tool call result when it succeeds.

Signature

type SuccessEncoded<T> =
  T extends Tool<infer _Name, infer _Config, infer _Requirements> ? Schema.Schema.Encoded<_Config["success"]> : never

Source

Since v1.0.0

SuccessSchema (type alias)

A utility type to extract the schema for the return type of a tool call when the tool call succeeds.

Signature

type SuccessSchema<T> = T extends Tool<infer _Name, infer _Config, infer _Requirements> ? _Config["success"] : never

Source

Since v1.0.0

utils

Tool (namespace)

Source

Since v1.0.0

Variance (interface)

Signature

export interface Variance<out Requirements> extends Pipeable {
  readonly [TypeId]: VarianceStruct<Requirements>
}

Source

Since v1.0.0

VarianceStruct (interface)

Signature

export interface VarianceStruct<out Requirements> {
  readonly _Requirements: Covariant<Requirements>
}

Source

Since v1.0.0

ProviderDefinedProto (interface)

Signature

export interface ProviderDefinedProto {
  readonly [ProviderDefinedTypeId]: ProviderDefinedTypeId
}

Source

Since v1.0.0