index.ts overview
The AiError
module provides comprehensive error handling for AI operations.
This module defines a hierarchy of error types that can occur when working with AI services, including HTTP request/response errors, input/output validation errors, and general runtime errors. All errors follow Effect’s structured error patterns and provide detailed context for debugging.
Error Types
- HttpRequestError: Errors occurring during HTTP request processing
- HttpResponseError: Errors occurring during HTTP response processing
- MalformedInput: Errors when input data doesn’t match expected format
- MalformedOutput: Errors when output data can’t be parsed or validated
- UnknownError: Catch-all for unexpected runtime errors
Example
import { AiError } from "@effect/ai"
import { Effect, Match } from "effect"
const handleAiError = Match.type<AiError.AiError>().pipe(
Match.tag("HttpRequestError", (err) => Effect.logError(`Request failed: ${err.message}`)),
Match.tag("HttpResponseError", (err) => Effect.logError(`Response error (${err.response.status}): ${err.message}`)),
Match.tag("MalformedInput", (err) => Effect.logError(`Invalid input: ${err.message}`)),
Match.tag("MalformedOutput", (err) => Effect.logError(`Invalid output: ${err.message}`)),
Match.orElse((err) => Effect.logError(`Unknown error: ${err.message}`))
)
Example
import { AiError } from "@effect/ai"
import { Effect, Option } from "effect"
const aiOperation = Effect.gen(function* () {
// Some AI operation that might fail
return yield* new AiError.HttpRequestError({
module: "OpenAI",
method: "completion",
reason: "Transport",
request: {
method: "POST",
url: "https://api.openai.com/v1/completions",
urlParams: [],
hash: Option.none(),
headers: { "Content-Type": "application/json" }
}
})
})
const program = aiOperation.pipe(
Effect.catchTag("HttpRequestError", (error) => {
console.log("Request failed:", error.message)
return Effect.succeed("fallback response")
})
)
Since v1.0.0
Exports Grouped by Category
- utils
- AiError (namespace export)
- Chat (namespace export)
- EmbeddingModel (namespace export)
- IdGenerator (namespace export)
- LanguageModel (namespace export)
- McpSchema (namespace export)
- McpServer (namespace export)
- Model (namespace export)
- Prompt (namespace export)
- Response (namespace export)
- Telemetry (namespace export)
- Tokenizer (namespace export)
- Tool (namespace export)
- Toolkit (namespace export)
utils
AiError (namespace export)
Re-exports all named exports from the “./AiError.js” module as AiError
.
Example
import { AiError } from "@effect/ai"
import { Effect, Match } from "effect"
const handleAiError = Match.type<AiError.AiError>().pipe(
Match.tag("HttpRequestError", (err) => Effect.logError(`Request failed: ${err.message}`)),
Match.tag("HttpResponseError", (err) => Effect.logError(`Response error (${err.response.status}): ${err.message}`)),
Match.tag("MalformedInput", (err) => Effect.logError(`Invalid input: ${err.message}`)),
Match.tag("MalformedOutput", (err) => Effect.logError(`Invalid output: ${err.message}`)),
Match.orElse((err) => Effect.logError(`Unknown error: ${err.message}`))
)
Example
import { AiError } from "@effect/ai"
import { Effect, Option } from "effect"
const aiOperation = Effect.gen(function* () {
// Some AI operation that might fail
return yield* new AiError.HttpRequestError({
module: "OpenAI",
method: "completion",
reason: "Transport",
request: {
method: "POST",
url: "https://api.openai.com/v1/completions",
urlParams: [],
hash: Option.none(),
headers: { "Content-Type": "application/json" }
}
})
})
const program = aiOperation.pipe(
Effect.catchTag("HttpRequestError", (error) => {
console.log("Request failed:", error.message)
return Effect.succeed("fallback response")
})
)
Signature
export * as AiError from "./AiError.js"
Since v1.0.0
Chat (namespace export)
Re-exports all named exports from the “./Chat.js” module as Chat
.
Example
import { Chat, LanguageModel } from "@effect/ai"
import { Effect, Layer } from "effect"
// Create a new chat session
const program = Effect.gen(function* () {
const chat = yield* Chat.empty
// Send a message and get response
const response = yield* chat.generateText({
prompt: "Hello! What can you help me with?"
})
console.log(response.content)
return response
})
Example
import { Chat, LanguageModel } from "@effect/ai"
import { Effect, Stream } from "effect"
// Streaming chat with tool support
const streamingChat = Effect.gen(function* () {
const chat = yield* Chat.empty
yield* chat
.streamText({
prompt: "Generate a creative story"
})
.pipe(Stream.runForEach((part) => Effect.sync(() => console.log(part))))
})
Signature
export * as Chat from "./Chat.js"
Since v1.0.0
EmbeddingModel (namespace export)
Re-exports all named exports from the “./EmbeddingModel.js” module as EmbeddingModel
.
Example
import { EmbeddingModel } from "@effect/ai"
import { Effect } from "effect"
// Basic embedding usage
const program = Effect.gen(function* () {
const embedding = yield* EmbeddingModel.EmbeddingModel
const vector = yield* embedding.embed("Hello world!")
console.log(vector) // [0.123, -0.456, 0.789, ...]
return vector
})
Example
import { EmbeddingModel } from "@effect/ai"
import { Effect, Duration } from "effect"
declare const generateVectorFor: (text: string) => Array<number>
// Create embedding service with batching and caching
const embeddingService = EmbeddingModel.make({
embedMany: (texts) =>
Effect.succeed(
texts.map((text, index) => ({
index,
embeddings: generateVectorFor(text)
}))
),
maxBatchSize: 50,
cache: {
capacity: 1000,
timeToLive: Duration.minutes(30)
}
})
Signature
export * as EmbeddingModel from "./EmbeddingModel.js"
Since v1.0.0
IdGenerator (namespace export)
Re-exports all named exports from the “./IdGenerator.js” module as IdGenerator
.
Example
import { IdGenerator } from "@effect/ai"
import { Effect, Layer } from "effect"
// Using the default ID generator
const program = Effect.gen(function* () {
const idGen = yield* IdGenerator.IdGenerator
const toolCallId = yield* idGen.generateId()
console.log(toolCallId) // "id_A7xK9mP2qR5tY8uV"
return toolCallId
}).pipe(Effect.provide(Layer.succeed(IdGenerator.IdGenerator, IdGenerator.defaultIdGenerator)))
Example
import { IdGenerator } from "@effect/ai"
import { Effect, Layer } from "effect"
// Creating a custom ID generator for AI tool calls
const customLayer = IdGenerator.layer({
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
prefix: "tool_call",
separator: "-",
size: 12
})
const program = Effect.gen(function* () {
const idGen = yield* IdGenerator.IdGenerator
const id = yield* idGen.generateId()
console.log(id) // "tool_call-A7XK9MP2QR5T"
return id
}).pipe(Effect.provide(customLayer))
Signature
export * as IdGenerator from "./IdGenerator.js"
Since v1.0.0
LanguageModel (namespace export)
Re-exports all named exports from the “./LanguageModel.js” module as LanguageModel
.
Example
import { LanguageModel } from "@effect/ai"
import { Effect } from "effect"
// Basic text generation
const program = Effect.gen(function* () {
const response = yield* LanguageModel.generateText({
prompt: "Explain quantum computing"
})
console.log(response.text)
return response
})
Example
import { LanguageModel } from "@effect/ai"
import { Effect, Schema } from "effect"
// Structured output generation
const ContactSchema = Schema.Struct({
name: Schema.String,
email: Schema.String
})
const extractContact = Effect.gen(function* () {
const response = yield* LanguageModel.generateObject({
prompt: "Extract contact: John Doe, john@example.com",
schema: ContactSchema
})
return response.value
})
Signature
export * as LanguageModel from "./LanguageModel.js"
Since v1.0.0
McpSchema (namespace export)
Re-exports all named exports from the “./McpSchema.js” module as McpSchema
.
Signature
export * as McpSchema from "./McpSchema.js"
Since v1.0.0
McpServer (namespace export)
Re-exports all named exports from the “./McpServer.js” module as McpServer
.
Signature
export * as McpServer from "./McpServer.js"
Since v1.0.0
Model (namespace export)
Re-exports all named exports from the “./Model.js” module as Model
.
Example
import { Model, LanguageModel } from "@effect/ai"
import { Effect, Layer } from "effect"
declare const myAnthropicLayer: Layer.Layer<LanguageModel.LanguageModel>
const anthropicModel = Model.make("anthropic", myAnthropicLayer)
const program = Effect.gen(function* () {
const response = yield* LanguageModel.generateText({
prompt: "Hello, world!"
})
return response.text
}).pipe(Effect.provide(anthropicModel))
Signature
export * as Model from "./Model.js"
Since v1.0.0
Prompt (namespace export)
Re-exports all named exports from the “./Prompt.js” module as Prompt
.
Example
import { Prompt } from "@effect/ai"
// Create a structured conversation
const conversation = Prompt.make([
{
role: "system",
content: "You are a helpful assistant specialized in mathematics."
},
{
role: "user",
content: [
{
type: "text",
text: "What is the derivative of x²?"
}
]
},
{
role: "assistant",
content: [
{
type: "text",
text: "The derivative of x² is 2x."
}
]
}
])
Example
import { Prompt } from "@effect/ai"
// Merge multiple prompts
const systemPrompt = Prompt.make([
{
role: "system",
content: "You are a coding assistant."
}
])
const userPrompt = Prompt.make("Help me write a function")
const combined = Prompt.merge(systemPrompt, userPrompt)
Signature
export * as Prompt from "./Prompt.js"
Since v1.0.0
Response (namespace export)
Re-exports all named exports from the “./Response.js” module as Response
.
Example
import { Response } from "@effect/ai"
// Create a simple text response part
const textResponse = Response.makePart("text", {
text: "The weather is sunny today!"
})
// Create a tool call response part
const toolCallResponse = Response.makePart("tool-call", {
id: "call_123",
name: "get_weather",
params: { city: "San Francisco" },
providerExecuted: false
})
Signature
export * as Response from "./Response.js"
Since v1.0.0
Telemetry (namespace export)
Re-exports all named exports from the “./Telemetry.js” module as Telemetry
.
Example
import { Telemetry } from "@effect/ai"
import { Effect } from "effect"
// Add telemetry attributes to a span
const addTelemetry = Effect.gen(function* () {
const span = yield* Effect.currentSpan
Telemetry.addGenAIAnnotations(span, {
system: "openai",
operation: { name: "chat" },
request: {
model: "gpt-4",
temperature: 0.7,
maxTokens: 1000
},
usage: {
inputTokens: 100,
outputTokens: 50
}
})
})
Signature
export * as Telemetry from "./Telemetry.js"
Since v1.0.0
Tokenizer (namespace export)
Re-exports all named exports from the “./Tokenizer.js” module as Tokenizer
.
Example
import { Tokenizer, Prompt } from "@effect/ai"
import { Effect } from "effect"
const tokenizeText = Effect.gen(function* () {
const tokenizer = yield* Tokenizer.Tokenizer
const tokens = yield* tokenizer.tokenize("Hello, world!")
console.log(`Token count: ${tokens.length}`)
return tokens
})
Example
import { Tokenizer, Prompt } from "@effect/ai"
import { Effect } from "effect"
// Truncate a prompt to fit within token limits
const truncatePrompt = Effect.gen(function* () {
const tokenizer = yield* Tokenizer.Tokenizer
const longPrompt = "This is a very long prompt..."
const truncated = yield* tokenizer.truncate(longPrompt, 100)
return truncated
})
Signature
export * as Tokenizer from "./Tokenizer.js"
Since v1.0.0
Tool (namespace export)
Re-exports all named exports from the “./Tool.js” module as Tool
.
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
})
Signature
export * as Tool from "./Tool.js"
Since v1.0.0
Toolkit (namespace export)
Re-exports all named exports from the “./Toolkit.js” module as Toolkit
.
Example
import { Toolkit, Tool } from "@effect/ai"
import { Effect, Schema } from "effect"
// Create individual tools
const GetCurrentTime = Tool.make("GetCurrentTime", {
description: "Get the current timestamp",
success: Schema.Number
})
const GetWeather = Tool.make("GetWeather", {
description: "Get weather for a location",
parameters: { location: Schema.String },
success: Schema.Struct({
temperature: Schema.Number,
condition: Schema.String
})
})
// Create a toolkit with multiple tools
const MyToolkit = Toolkit.make(GetCurrentTime, GetWeather)
const MyToolkitLayer = MyToolkit.toLayer({
GetCurrentTime: () => Effect.succeed(Date.now()),
GetWeather: ({ location }) =>
Effect.succeed({
temperature: 72,
condition: "sunny"
})
})
Signature
export * as Toolkit from "./Toolkit.js"
Since v1.0.0