Chat
The Chat module provides a stateful conversation interface for AI language
models.
This module enables persistent chat sessions that maintain conversation history, support tool calling, and offer both streaming and non-streaming text generation. It integrates seamlessly with the Effect AI ecosystem, providing type-safe conversational AI capabilities.
Example
import { Chat, LanguageModel } from "@effect/ai"import { Effect, Layer } from "effect"
// Create a new chat sessionconst 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 supportconst 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)) ))})Constructors
Creates a new Chat service with empty conversation history.
This is the most common way to start a fresh chat session without any initial context or system prompts.
Signature
declare const empty: Effect.Effect<Service>Example
import { Chat } from "@effect/ai"import { Effect } from "effect"
const freshChat = Effect.gen(function* () { const chat = yield* Chat.empty
const response = yield* chat.generateText({ prompt: "Hello! Can you introduce yourself?" })
console.log(response.content)
return chat})fromExport
Creates a Chat service from previously exported chat data.
Restores a chat session from structured data that was previously exported
using the export method. Useful for persisting and restoring conversation
state.
Signature
declare function fromExport(data: unknown): Effect<Service, ParseError, LanguageModel>Example
import { Chat } from "@effect/ai"import { Effect } from "effect"
declare const loadFromDatabase: (sessionId: string) => Effect.Effect<unknown>
const restoreChat = Effect.gen(function* () { // Assume we have previously exported data const savedData = yield* loadFromDatabase("chat-session-123")
const restoredChat = yield* Chat.fromExport(savedData)
// Continue the conversation from where it left off const response = yield* restoredChat.generateText({ prompt: "Let's continue our discussion" })}).pipe( Effect.catchTag("ParseError", (error) => { console.log("Failed to restore chat:", error.message) return Effect.void }))Creates a Chat service from previously exported JSON chat data.
Restores a chat session from JSON string that was previously exported
using the exportJson method. This is the most convenient way to
persist and restore chat sessions to/from storage systems.
Signature
declare function fromJson(data: string): Effect<Service, ParseError, LanguageModel>Example
import { Chat } from "@effect/ai"import { Effect } from "effect"
const restoreFromJson = Effect.gen(function* () { // Load JSON from localStorage or file system const jsonData = localStorage.getItem("my-chat-backup") if (!jsonData) return yield* Chat.empty
const restoredChat = yield* Chat.fromJson(jsonData)
// Chat history is now restored const response = yield* restoredChat.generateText({ prompt: "What were we talking about?" })
return response}).pipe( Effect.catchTag("ParseError", (error) => { console.log("Invalid JSON format:", error.message) return Chat.empty // Fallback to empty chat }))fromPrompt
Creates a new Chat service from an initial prompt.
This is the primary constructor for creating chat instances. It initializes a new conversation with the provided prompt as the starting context.
Signature
declare const fromPrompt: (...args: [prompt: RawInput]) => Effect<Service, never, never>Example
import { Chat, Prompt } from "@effect/ai"import { Effect } from "effect"
const chatWithSystemPrompt = Effect.gen(function* () { const chat = yield* Chat.fromPrompt([{ role: "system", content: "You are a helpful assistant specialized in mathematics." }])
const response = yield* chat.generateText({ prompt: "What is 2+2?" })
return response.content})Example
import { Chat, Prompt } from "@effect/ai"import { Effect } from "effect"
// Initialize with conversation historyconst existingChat = Effect.gen(function* () { const chat = yield* Chat.fromPrompt([ { role: "user", content: [{ type: "text", text: "What's the weather like?" }] }, { role: "assistant", content: [{ type: "text", text: "I don't have access to weather data." }] }, { role: "user", content: [{ type: "text", text: "Can you help me with coding?" }] } ])
const response = yield* chat.generateText({ prompt: "I need help with TypeScript" })
return response})layerPersisted
Creates a Layer new chat persistence service.
The provided store identifier will be used to indicate which "store" the backing persistence should load chats from.
Signature
declare function layerPersisted(options: { readonly storeId: string;}): Layer<Persistence, never, BackingPersistence>makePersisted
Creates a new chat persistence service.
The provided store identifier will be used to indicate which "store" the backing persistence should load chats from.
Signature
declare const makePersisted: (...args: [options: { readonly storeId: string;}]) => Effect<any, unknown, unknown>Context
The Chat service tag for dependency injection.
This tag provides access to chat functionality throughout your application, enabling persistent conversational AI interactions with full context management.
Signature
declare class Chat extends any { constructor();}Example
import { Chat } from "@effect/ai"import * as Effect from "effect/Effect"
const useChat = Effect.gen(function* () { const chat = yield* Chat.Chat const response = yield* chat.generateText({ prompt: "Explain quantum computing in simple terms" }) return response.content})Persistence
The context tag for chat persistence.
Signature
declare class Persistence extends any { constructor();}Errors
ChatNotFoundError
An error that occurs when attempting to retrieve a persisted Chat that
does not exist in the backing persistence store.
Signature
declare class ChatNotFoundError extends { readonly _tag: "ChatNotFoundError"; readonly chatId: string;} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "ChatNotFoundError"; readonly chatId: string; }, options?: MakeOptions]);}Models
Represents a Chat that is backed by persistence.
When calling a text generation method (e.g. generateText), the previous
chat history as well as the relevent response parts will be saved to the
backing persistence store.
Signature
interface Persisted extends Service { readonly id: string; readonly save: Effect<void, any>;}Persistence
Represents the interface that the Chat service provides.
Signature
interface Service { readonly export: Effect<unknown, AiError>; readonly exportJson: Effect<string, MalformedOutput>; readonly generateObject: <A, I extends Record<string, unknown>, R, Options extends NoExcessProperties<GenerateObjectOptions<any, A, I, R>, Options>, Tools extends Record<string, Any> = {}>(options: Options & GenerateObjectOptions<Tools, A, I, R>) => Effect<GenerateObjectResponse<Tools, A>, ExtractError<Options>, LanguageModel | R | ExtractContext<Options>>; readonly generateText: <Options extends NoExcessProperties<GenerateTextOptions<any>, Options>, Tools extends Record<string, Any> = {}>(options: Options & GenerateTextOptions<Tools>) => Effect<GenerateTextResponse<Tools>, ExtractError<Options>, LanguageModel | ExtractContext<Options>>; readonly history: Ref<Prompt>; readonly streamText: <Options extends NoExcessProperties<GenerateTextOptions<any>, Options>, Tools extends Record<string, Any> = {}>(options: Options & GenerateTextOptions<Tools>) => Stream<StreamPart<Tools>, ExtractError<Options>, LanguageModel | ExtractContext<Options>>;}