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
- Constructors
- Guards
- Models
- Type Ids
- Utilities
- Utility Types
- Any (interface)
- AnyProviderDefined (interface)
- AnyStructSchema (interface)
- AnyTaggedRequestSchema (interface)
- Failure (type alias)
- FailureEncoded (type alias)
- FromTaggedRequest (interface)
- HandlersFor (type alias)
- Name (type alias)
- Parameters (type alias)
- ParametersEncoded (type alias)
- ParametersSchema (type alias)
- Requirements (type alias)
- RequiresHandler (type alias)
- Success (type alias)
- SuccessEncoded (type alias)
- SuccessSchema (type alias)
- utils
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
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
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
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
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
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>
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]>
>
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
>
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>
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>
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>
}
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
}
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>
}
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>
}
Since v1.0.0
Type Ids
ProviderDefinedTypeId
Unique identifier for provider-defined tools.
Signature
declare const ProviderDefinedTypeId: "~@effect/ai/Tool/ProviderDefined"
Since v1.0.0
ProviderDefinedTypeId (type alias)
Type-level representation of the provider-defined tool identifier.
Signature
type ProviderDefinedTypeId = typeof ProviderDefinedTypeId
Since v1.0.0
TypeId
Unique identifier for user-defined tools.
Signature
declare const TypeId: "~@effect/ai/Tool"
Since v1.0.0
TypeId (type alias)
Type-level representation of the user-defined tool identifier.
Signature
type TypeId = typeof TypeId
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
Since v1.0.0
getDescriptionFromSchemaAst
Signature
declare const getDescriptionFromSchemaAst: (ast: AST.AST) => string | undefined
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
Since v1.0.0
getJsonSchemaFromSchemaAst
Signature
declare const getJsonSchemaFromSchemaAst: (ast: AST.AST) => JsonSchema.JsonSchema7
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
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>
}
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>
}
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
}
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
}
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
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
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"]
}
> {}
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]
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
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
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
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
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
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
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
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
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
Since v1.0.0
utils
Tool (namespace)
Since v1.0.0
Variance (interface)
Signature
export interface Variance<out Requirements> extends Pipeable {
readonly [TypeId]: VarianceStruct<Requirements>
}
Since v1.0.0
VarianceStruct (interface)
Signature
export interface VarianceStruct<out Requirements> {
readonly _Requirements: Covariant<Requirements>
}
Since v1.0.0
ProviderDefinedProto (interface)
Signature
export interface ProviderDefinedProto {
readonly [ProviderDefinedTypeId]: ProviderDefinedTypeId
}
Since v1.0.0