Skip to content
Effect Days 2026 Get your ticket

@effect/ai

0.37.0

Patch Changes

  • Updated dependencies [fffdee0]:
    • effect@3.22.0
    • @effect/experimental@0.61.0
    • @effect/platform@0.97.0
    • @effect/rpc@0.76.0

0.36.0

Minor Changes

  • #6260 02ae8fb Thanks @IMax153! - Support Tool.EmptyParams as an explicit tool parameters schema.

Patch Changes

0.35.0

Patch Changes

0.34.0

Patch Changes

  • #6094 88a5260 Thanks @IMax153! - Remove superfluous / defensive check from tool call json schema generation

  • #6101 cf74940 Thanks @IMax153! - Prevent schema validation when directly constructing an AiError.HttpRequestError / AiError.HttpResponseError

  • Updated dependencies [fc82e81, 82996bc, 4d97a61, f6b0960, 8798a84]:

    • effect@3.20.0
    • @effect/experimental@0.59.0
    • @effect/platform@0.95.0
    • @effect/rpc@0.74.0

0.33.2

Patch Changes

  • #5944 f21f034 Thanks @IMax153! - Fix Prompt.fromResponseParts when input contains a provider executed tool

0.33.1

Patch Changes

  • #5931 ba9e790 Thanks @IMax153! - Fix the accumulation logic for response parts in the AI Chat module

  • Updated dependencies [65e9e35, ee69cd7, 488d6e8]:

    • @effect/platform@0.94.1
    • effect@3.19.14

0.33.0

Patch Changes

  • Updated dependencies [77eeb86, ff7053f, 287c32c]:
    • effect@3.19.13
    • @effect/platform@0.94.0
    • @effect/experimental@0.58.0
    • @effect/rpc@0.73.0

0.32.1

Patch Changes

  • #5685 fb53370 Thanks @janglad! - Fix Response.Part, AllParts, StreamPart not inferring Schema properly if toolkit is WithHandler

  • Updated dependencies [7d28a90]:

    • effect@3.19.3

0.32.0

Patch Changes

  • Updated dependencies [3c15d5f, 3863fa8, 2a03c76, 24a1685]:
    • effect@3.19.0
    • @effect/rpc@0.72.0
    • @effect/platform@0.93.0
    • @effect/experimental@0.57.0

0.31.1

Patch Changes

  • #5634 a5d0f2b Thanks @IMax153! - Ensure that tool calls are emitted as soon as possible when streaming

0.31.0

Minor Changes

  • #5621 4c3bdfb Thanks @IMax153! - Remove Either / EitherEncoded from tool call results.

    Specifically, the encoding of tool call results as an Either / EitherEncoded has been removed and is replaced by encoding the tool call success / failure directly into the result property.

    To allow type-safe discrimination between a tool call result which was a success vs. one that was a failure, an isFailure property has also been added to the "tool-result" part. If isFailure is true, then the tool call handler result was an error.

    import * as AnthropicClient from "@effect/ai-anthropic/AnthropicClient"
    import * as AnthropicLanguageModel from "@effect/ai-anthropic/AnthropicLanguageModel"
    import * as LanguageModel from "@effect/ai/LanguageModel"
    import * as Tool from "@effect/ai/Tool"
    import * as Toolkit from "@effect/ai/Toolkit"
    import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"
    import { Config, Effect, Layer, Schema, Stream } from "effect"
    const Claude = AnthropicLanguageModel.model("claude-4-sonnet-20250514")
    const MyTool = Tool.make("MyTool", {
    description: "An example of a tool with success and failure types",
    failureMode: "return", // Return errors in the response
    parameters: { bar: Schema.Number },
    success: Schema.Number,
    failure: Schema.Struct({ reason: Schema.Literal("reason-1", "reason-2") })
    })
    const MyToolkit = Toolkit.make(MyTool)
    const MyToolkitLayer = MyToolkit.toLayer({
    MyTool: () => Effect.succeed(42)
    })
    const program = LanguageModel.streamText({
    prompt: "Tell me about the meaning of life",
    toolkit: MyToolkit
    }).pipe(
    Stream.runForEach((part) => {
    if (part.type === "tool-result" && part.name === "MyTool") {
    // The `isFailure` property can be used to discriminate whether the result
    // of a tool call is a success or a failure
    if (part.isFailure) {
    part.result
    // ^? { readonly reason: "reason-1" | "reason-2"; }
    } else {
    part.result
    // ^? number
    }
    }
    return Effect.void
    }),
    Effect.provide(Claude)
    )
    const Anthropic = AnthropicClient.layerConfig({
    apiKey: Config.redacted("ANTHROPIC_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    program.pipe(Effect.provide([Anthropic, MyToolkitLayer]), Effect.runPromise)

0.30.0

Minor Changes

  • #5614 c63e658 Thanks @IMax153! - Previously, tool call handler errors were always raised as an expected error in the Effect E channel at the point of execution of the tool call handler (i.e. when a generate* method is invoked on a LanguageModel).

    With this PR, the end user now has control over whether tool call handler errors should be raised as an Effect error, or returned by the SDK to allow, for example, sending that error information to another application.

    Tool Call Specification

    The Tool.make and Tool.providerDefined constructors now take an extra optional parameter called failureMode, which can be set to either "error" or "return".

    import { Tool } from "@effect/ai"
    import { Schema } from "effect"
    const MyTool = Tool.make("MyTool", {
    description: "My special tool",
    failureMode: "return" // "error" (default) or "return"
    parameters: {
    myParam: Schema.String
    },
    success: Schema.Struct({
    mySuccess: Schema.String
    }),
    failure: Schema.Struct({
    myFailure: Schema.String
    })
    })

    The semantics of failureMode are as follows:

    • If set to "error" (the default), errors that occur during tool call handler execution will be returned in the error channel of the calling effect
    • If set to "return", errors that occur during tool call handler execution will be captured and returned as part of the tool call result

    Response - Tool Result Parts

    The result field of a "tool-result" part of a large language model provider response is now represented as an Either.

    • If the result is a Left, the result will be the failure specified in the tool call specification
    • If the result is a Right, the result will be the success specified in the tool call specification

    This is only relevant if the end user sets failureMode to "return". If set to "error" (the default), then the result property will always be a Right with the successful result of the tool call handler.

    Similarly the encodedResult field of a "tool-result" part will be represented as an EitherEncoded, where:

    • { _tag: "Left", left: <failure> } represents a tool call handler failure
    • { _tag: "Right", right: <success> } represents a tool call handler success

    Prompt - Tool Result Parts

    The result field of a "tool-result" part of a prompt will now only accept an EitherEncoded as specified above.

Patch Changes

  • Updated dependencies [6ae2f5d]:
    • effect@3.18.4

0.29.1

Patch Changes

  • #5587 d628c15 Thanks @IMax153! - Ensure response schema includes toolkit tools even when tool call resolution is disabled

0.29.0

Minor Changes

  • #5302 f8b93ac Thanks @timurrakhimzhan! - Added “oneOf” property for generateText and streamText “toolChoice” to be able to pick a subset of tools, which are going to be passed to LLM

Patch Changes

  • Updated dependencies [1c6ab74, 70fe803, c296e32, a098ddf]:
    • effect@3.18.0
    • @effect/platform@0.92.0
    • @effect/experimental@0.56.0
    • @effect/rpc@0.71.0

0.28.4

Patch Changes

  • #5570 bc83015 Thanks @IMax153! - Redact headers where possible in AiError

  • #5570 bc83015 Thanks @IMax153! - Fix return type of Response.AllParts

  • #5568 6c2d586 Thanks @IMax153! - Support expiration of persisted chats via time to live

0.28.3

Patch Changes

  • #5566 ab57b7a Thanks @IMax153! - Support generation of persistence identifiers for ai chat

  • #5540 5b13482 Thanks @IMax153! - ensure decoded response metadata is always set

  • #5566 ab57b7a Thanks @IMax153! - fix prompt construction from response parts

0.28.2

Patch Changes

  • #5554 800ab2e Thanks @IMax153! - Accept Prompt.RawInput in Prompt.merge

  • #5554 800ab2e Thanks @IMax153! - Add Prompt.setSystem, Prompt.prependSystem, and Prompt.appendSystem methods

  • #5554 800ab2e Thanks @IMax153! - Improve the information available to the user following a model response error

  • #5554 800ab2e Thanks @IMax153! - Allow raw user and assistant prompt messages to accept plain strings

  • #5554 800ab2e Thanks @IMax153! - Make Prompt pipeable

  • #5554 800ab2e Thanks @IMax153! - Fix leakage of provider-defined tool handler requirements

0.28.1

Patch Changes

  • #5555 aacd472 Thanks @IMax153! - Add support for persisting a Chat via Persistence

0.28.0

Patch Changes

  • Updated dependencies [d4d86a8]:
    • @effect/platform@0.91.0
    • @effect/rpc@0.70.0
    • @effect/experimental@0.55.0

0.27.1

Patch Changes

  • #5521 fa49bc8 Thanks @IMax153! - Fix provider metadata and parse tool call parameters safely

0.27.0

Minor Changes

  • #5469 42b914a Thanks @IMax153! - Refactor the Effect AI SDK and associated provider packages

    This pull request contains a complete refactor of the base Effect AI SDK package as well as the associated provider integration packages to improve flexibility and enhance ergonomics. Major changes are outlined below.

    Modules

    All modules in the base Effect AI SDK have had the leading Ai prefix dropped from their name (except for the AiError module).

    For example, the AiLanguageModel module is now the LanguageModel module.

    In addition, the AiInput module has been renamed to the Prompt module.

    Prompts

    The Prompt module has been completely redesigned with flexibility in mind.

    The Prompt module now supports building a prompt using either the constructors exposed from the Prompt module, or using raw prompt content parts / messages, which should be familiar to those coming from other AI SDKs.

    In addition, the system option has been removed from all LanguageModel methods and must now be provided as part of the prompt.

    Prompt Constructors

    import { LanguageModel, Prompt } from "@effect/ai"
    const textPart = Prompt.makePart("text", {
    text: "What is machine learning?"
    })
    const userMessage = Prompt.makeMessage("user", {
    content: [textPart]
    })
    const systemMessage = Prompt.makeMessage("system", {
    content: "You are an expert in machine learning"
    })
    const program = LanguageModel.generateText({
    prompt: Prompt.fromMessages([systemMessage, userMessage])
    })

    Raw Prompt Input

    import { LanguageModel } from "@effect/ai"
    const program = LanguageModel.generateText({
    prompt: [
    { role: "system", content: "You are an expert in machine learning" },
    {
    role: "user",
    content: [{ type: "text", text: "What is machine learning?" }]
    }
    ]
    })

    NOTE: Providing a plain string as a prompt is still supported, and will be converted internally into a user message with a single text content part.

    Provider-Specific Options

    To support specification of provider-specific options when interacting with large language model providers, support has been added for adding provider-specific options to the parts of a Prompt.

    import { LanguageModel } from "@effect/ai"
    import { AnthropicLanguageModel } from "@effect/ai-anthropic"
    const Claude = AnthropicLanguageModel.model("claude-sonnet-4-20250514")
    const program = LanguageModel.generateText({
    prompt: [
    {
    role: "user",
    content: [{ type: "text", text: "What is machine learning?" }],
    options: {
    anthropic: { cacheControl: { type: "ephemeral", ttl: "1h" } }
    }
    }
    ]
    }).pipe(Effect.provide(Claude))

    Responses

    The Response module has also been completely redesigned to support a wider variety of response parts, particularly when streaming.

    Streaming Responses

    When streaming text via the LanguageModel.streamText method, you will now receive a stream of content parts instead of a stream of responses, which should make it much simpler to filter down the stream to the parts you are interested in.

    In addition, additional content parts will be present in the stream to allow you to track, for example, when a text content part starts / ends.

    Tool Calls / Tool Call Results

    The decoded parts of a Response (as returned by the methods of LanguageModel) are now fully type-safe on tool calls / tool call results. Filtering the content parts of a response to tool calls will narrow the type of the tool call params based on the tool name. Similarly, filtering the response to tool call results will narrow the type of the tool call result based on the tool name.

    import { LanguageModel, Tool, Toolkit } from "@effect/ai"
    import { Effect, Schema } from "effect"
    const DadJokeTool = Tool.make("DadJokeTool", {
    parameters: { topic: Schema.String },
    success: Schema.Struct({ joke: Schema.String })
    })
    const FooTool = Tool.make("FooTool", {
    parameters: { foo: Schema.Number },
    success: Schema.Struct({ bar: Schema.Boolean })
    })
    const MyToolkit = Toolkit.make(DadJokeTool, FooTool)
    const program = Effect.gen(function* () {
    const response = yield* LanguageModel.generateText({
    prompt: "Tell me a dad joke",
    toolkit: MyToolkit
    })
    for (const toolCall of response.toolCalls) {
    if (toolCall.name === "DadJokeTool") {
    // ^? "DadJokeTool" | "FooTool"
    toolCall.params
    // ^? { readonly topic: string }
    }
    }
    for (const toolResult of response.toolResults) {
    if (toolResult.name === "DadJokeTool") {
    // ^? "DadJokeTool" | "FooTool"
    toolResult.result
    // ^? { readonly joke: string }
    }
    }
    })

    Provider Metadata

    As with provider-specific options, provider-specific metadata is now returned as part of the response from the large language model provider.

    import { LanguageModel } from "@effect/ai"
    import { AnthropicLanguageModel } from "@effect/ai-anthropic"
    import { Effect } from "effect"
    const Claude = AnthropicLanguageModel.model("claude-4-sonnet-20250514")
    const program = Effect.gen(function* () {
    const response = yield* LanguageModel.generateText({
    prompt: "What is the meaning of life?"
    })
    for (const part of response.content) {
    // When metadata **is not** defined for a content part, accessing the
    // provider's key on the part's metadata will return an untyped record
    if (part.type === "text") {
    const metadata = part.metadata.anthropic
    // ^? { readonly [x: string]: unknown } | undefined
    }
    // When metadata **is** defined for a content part, accessing the
    // provider's key on the part's metadata will return typed metadata
    if (part.type === "reasoning") {
    const metadata = part.metadata.anthropic
    // ^? AnthropicReasoningInfo | undefined
    }
    }
    }).pipe(Effect.provide(Claude))

    Tool Calls

    The Tool module has been enhanced to support provider-defined tools (e.g. web search, computer use, etc.). Large language model providers which support calling their own tools now have a separate module present in their provider integration packages which contain definitions for their tools.

    These provider-defined tools can be included alongside user-defined tools in existing Toolkits. Provider-defined tools that require a user-space handler will be raise a type error in the associated Toolkit layer if no such handler is defined.

    import { LanguageModel, Tool, Toolkit } from "@effect/ai"
    import { AnthropicTool } from "@effect/ai-anthropic"
    import { Schema } from "effect"
    const DadJokeTool = Tool.make("DadJokeTool", {
    parameters: { topic: Schema.String },
    success: Schema.Struct({ joke: Schema.String })
    })
    const MyToolkit = Toolkit.make(
    DadJokeTool,
    AnthropicTool.WebSearch_20250305({ max_uses: 1 })
    )
    const program = LanguageModel.generateText({
    prompt: "Search the web for a dad joke",
    toolkit: MyToolkit
    })

    AiError

    The AiError type has been refactored into a union of different error types which can be raised by the Effect AI SDK. The goal of defining separate error types is to allow providing the end-user with more granular information about the error that occurred.

    For now, the following errors have been defined. More error types may be added over time based upon necessity / use case.

    type AiError =
    | HttpRequestError,
    | HttpResponseError,
    | MalformedInput,
    | MalformedOutput,
    | UnknownError

0.26.1

Patch Changes

  • #5453 d6887d5 Thanks @tim-smart! - wait for client to initialize before sending notifications

  • Updated dependencies [d6887d5]:

    • @effect/rpc@0.69.2

0.26.0

Patch Changes

  • Updated dependencies [3e163b2]:
    • @effect/rpc@0.69.0
    • @effect/experimental@0.54.6

0.25.2

Patch Changes

  • #5361 292a7c5 Thanks @IMax153! - Add AiEmbeddingModel.embedMany

0.25.1

Patch Changes

  • #5351 fd86f93 Thanks @richburdon! - fixes bug where stream currently ignores disableToolCallResolution flag

  • Updated dependencies [a949539]:

    • effect@3.17.7
    • @effect/experimental@0.54.4

0.25.0

Patch Changes

  • Updated dependencies [5a0f4f1, e9cbd26]:
    • effect@3.17.1
    • @effect/rpc@0.68.0
    • @effect/experimental@0.54.0

0.24.0

Patch Changes

  • Updated dependencies [7813640]:
    • @effect/platform@0.90.0
    • @effect/experimental@0.54.0
    • @effect/rpc@0.67.0

0.23.0

Patch Changes

0.22.2

Patch Changes

  • #5240 e43b1fd Thanks @tim-smart! - expose the AiChat history Ref

0.22.1

Patch Changes

  • Updated dependencies [f5dfabf, 17a5ea8, d25f22b]:
    • effect@3.16.14
    • @effect/platform@0.88.1
    • @effect/experimental@0.52.1
    • @effect/rpc@0.65.1

0.22.0

Patch Changes

  • Updated dependencies [27206d7, dbabf5e]:
    • @effect/platform@0.88.0
    • @effect/experimental@0.52.0
    • @effect/rpc@0.65.0

0.21.17

Patch Changes

  • Updated dependencies [c1c05a8, 5b7cd92, 81fe4a2]:
    • effect@3.16.13
    • @effect/rpc@0.64.14
    • @effect/experimental@0.51.14
    • @effect/platform@0.87.13

0.21.16

Patch Changes

  • Updated dependencies [32ba77a, d5e25b2]:
    • @effect/platform@0.87.12
    • @effect/experimental@0.51.13
    • @effect/rpc@0.64.13

0.21.15

Patch Changes

  • Updated dependencies [79a1947, 001392b, 7bfb099]:
    • @effect/rpc@0.64.12
    • @effect/platform@0.87.11
    • @effect/experimental@0.51.12

0.21.14

Patch Changes

  • Updated dependencies [678318d, 678318d]:
    • @effect/platform@0.87.10
    • @effect/experimental@0.51.11
    • @effect/rpc@0.64.11

0.21.13

Patch Changes

  • Updated dependencies [54514a2]:
    • @effect/platform@0.87.9
    • @effect/experimental@0.51.10
    • @effect/rpc@0.64.10

0.21.12

Patch Changes

  • Updated dependencies [4ce4f82]:
    • @effect/platform@0.87.8
    • @effect/experimental@0.51.9
    • @effect/rpc@0.64.9

0.21.11

Patch Changes

  • #5029 d92d12a Thanks @IMax153! - Add support for generating tool call identifiers when none are returned by the LLM provider

  • #5165 25ca0cf Thanks @IMax153! - Ensure that tool call parts are properly merged when combining AiResponses

  • #5029 d92d12a Thanks @IMax153! - Cleanup AiLanguageModel construction and finish basic support for gemini

0.21.10

Patch Changes

  • Updated dependencies [a9b617f, 7e26e86]:
    • @effect/platform@0.87.7
    • @effect/experimental@0.51.8
    • @effect/rpc@0.64.8

0.21.9

Patch Changes

  • #5154 030ac21 Thanks @IMax153! - Support disabling tool call resolution to give users more control over resolver execution

  • #5133 aaae9b1 Thanks @IMax153! - Support extracting tool call results from AiResponse.WithToolCallResults

  • Updated dependencies [905da99]:

    • effect@3.16.12
    • @effect/experimental@0.51.7
    • @effect/platform@0.87.6
    • @effect/rpc@0.64.7

0.21.8

Patch Changes

  • Updated dependencies [96c1292]:
    • @effect/experimental@0.51.6

0.21.7

Patch Changes

  • Updated dependencies [2fd8676]:
    • @effect/platform@0.87.5
    • @effect/experimental@0.51.5
    • @effect/rpc@0.64.6

0.21.6

Patch Changes

  • Updated dependencies [e82a4fd]:
    • @effect/platform@0.87.4
    • @effect/experimental@0.51.4
    • @effect/rpc@0.64.5

0.21.5

Patch Changes

  • Updated dependencies [1b6e396]:
    • @effect/platform@0.87.3
    • @effect/experimental@0.51.3
    • @effect/rpc@0.64.4

0.21.4

Patch Changes

  • Updated dependencies [4fea68c, b927954, 99590a6, 6c3e24c]:
    • @effect/platform@0.87.2
    • effect@3.16.11
    • @effect/experimental@0.51.2
    • @effect/rpc@0.64.3

0.21.3

Patch Changes

  • Updated dependencies [faad30e]:
    • effect@3.16.10
    • @effect/experimental@0.51.1
    • @effect/platform@0.87.1
    • @effect/rpc@0.64.2

0.21.2

Patch Changes

  • Updated dependencies [112a93a]:
    • @effect/rpc@0.64.1
    • @effect/experimental@0.51.0

0.21.1

Patch Changes

  • #5088 f667373 Thanks @tim-smart! - expose system option in AiChat constructors

  • Updated dependencies []:

    • @effect/experimental@0.51.0

0.21.0

Patch Changes

  • Updated dependencies [b5bac9a]:
    • @effect/rpc@0.64.0
    • @effect/platform@0.87.0
    • @effect/experimental@0.51.0

0.20.0

Patch Changes

  • Updated dependencies [5137c70, c23d25c, 5137c70, 5137c70]:
    • effect@3.16.9
    • @effect/platform@0.86.0
    • @effect/experimental@0.50.0
    • @effect/rpc@0.63.0

0.19.4

Patch Changes

  • #5056 a8d99b2 Thanks @tim-smart! - add support for mcp 2025-06-18

  • Updated dependencies [a8d99b2]:

    • @effect/rpc@0.62.4
    • @effect/experimental@0.49.2

0.19.3

Patch Changes

  • Updated dependencies [914a191]:
    • @effect/platform@0.85.2
    • @effect/experimental@0.49.2
    • @effect/rpc@0.62.3

0.19.2

Patch Changes

  • Updated dependencies [ddfd1e4]:
    • @effect/rpc@0.62.2
    • @effect/experimental@0.49.1

0.19.1

Patch Changes

  • Updated dependencies [8cb98d5, db2dd3c]:
    • effect@3.16.8
    • @effect/experimental@0.49.1
    • @effect/platform@0.85.1
    • @effect/rpc@0.62.1

0.19.0

Patch Changes

  • Updated dependencies [93687dd, 93687dd, 93687dd]:
    • @effect/platform@0.85.0
    • @effect/experimental@0.49.0
    • @effect/rpc@0.62.0

0.18.16

Patch Changes

  • #5040 daed158 Thanks @tim-smart! - allow undefined mcp payloads

0.18.15

Patch Changes

  • #5038 c315989 Thanks @tim-smart! - remove McpServer requirement from McpServer.resource

0.18.14

Patch Changes

  • #5036 cbac1ac Thanks @tim-smart! - add .of helpers to RpcGroup, Entity and AiToolkit

  • #5037 dd4d380 Thanks @tim-smart! - eliminate McpServer requirement from resource layers

  • Updated dependencies [1bb0d8a, cbac1ac]:

    • effect@3.16.7
    • @effect/rpc@0.61.15
    • @effect/experimental@0.48.12
    • @effect/platform@0.84.11

0.18.13

Patch Changes

  • #4961 aa3a819 Thanks @IMax153! - add McpServer module

    The McpServer module provides a way to implement a MCP server using Effect.

    Here’s an example of how to use the McpServer module to create a simple MCP server with a resource template and a test prompt:

    import { McpSchema, McpServer } from "@effect/ai"
    import { NodeRuntime, NodeSink, NodeStream } from "@effect/platform-node"
    import { Effect, Layer, Logger, Schema } from "effect"
    const idParam = McpSchema.param("id", Schema.NumberFromString)
    // Define a resource template for a README file
    const ReadmeTemplate = McpServer.resource`file://readme/${idParam}`({
    name: "README Template",
    // You can add auto-completion for the ID parameter
    completion: {
    id: (_) => Effect.succeed([1, 2, 3, 4, 5])
    },
    content: Effect.fn(function* (_uri, id) {
    return `# MCP Server Demo - ID: ${id}`
    })
    })
    // Define a test prompt with parameters
    const TestPrompt = McpServer.prompt({
    name: "Test Prompt",
    description: "A test prompt to demonstrate MCP server capabilities",
    parameters: Schema.Struct({
    flightNumber: Schema.String
    }),
    completion: {
    flightNumber: () => Effect.succeed(["FL123", "FL456", "FL789"])
    },
    content: ({ flightNumber }) =>
    Effect.succeed(
    `Get the booking details for flight number: ${flightNumber}`
    )
    })
    // Merge all the resources and prompts into a single server layer
    const ServerLayer = Layer.mergeAll(ReadmeTemplate, TestPrompt).pipe(
    // Provide the MCP server implementation
    Layer.provide(
    McpServer.layerStdio({
    name: "Demo Server",
    version: "1.0.0",
    stdin: NodeStream.stdin,
    stdout: NodeSink.stdout
    })
    ),
    // add a stderr logger
    Layer.provide(Logger.add(Logger.prettyLogger({ stderr: true })))
    )
    Layer.launch(ServerLayer).pipe(NodeRuntime.runMain)
  • Updated dependencies [a5f7595, a02470c, bf369b2, f891d45]:

    • effect@3.16.6
    • @effect/platform@0.84.10
    • @effect/experimental@0.48.11
    • @effect/rpc@0.61.14

0.18.12

Patch Changes

  • Updated dependencies [bf418ef]:
    • effect@3.16.5
    • @effect/experimental@0.48.10
    • @effect/platform@0.84.9

0.18.11

Patch Changes

  • #5011 2dc5f93 Thanks @IMax153! - disallow excess options in AiLanguageModel.generateText / AiLanguageModel.streamText

  • Updated dependencies []:

    • @effect/experimental@0.48.9

0.18.10

Patch Changes

  • Updated dependencies [8b9db77]:
    • @effect/platform@0.84.8
    • @effect/experimental@0.48.9

0.18.9

Patch Changes

  • Updated dependencies [74ab9a0, 770008e]:
    • effect@3.16.4
    • @effect/experimental@0.48.8
    • @effect/platform@0.84.7

0.18.8

Patch Changes

  • Updated dependencies [a2d57c9]:
    • @effect/experimental@0.48.7

0.18.7

Patch Changes

  • Updated dependencies [ceea77a]:
    • @effect/platform@0.84.6
    • @effect/experimental@0.48.6

0.18.6

Patch Changes

  • #4968 85f54ed Thanks @IMax153! - fix the type of AiToolkit.Any

  • Updated dependencies [ec52c6a]:

    • @effect/platform@0.84.5
    • @effect/experimental@0.48.5

0.18.5

Patch Changes

  • #4959 4ddb28d Thanks @tim-smart! - improve @effect/ai llm schema compatibility

0.18.4

Patch Changes

  • Updated dependencies [87722fc, 36217ee]:
    • effect@3.16.3
    • @effect/experimental@0.48.4
    • @effect/platform@0.84.4

0.18.3

Patch Changes

  • #4947 52c88c4 Thanks @tim-smart! - fix AiToolkit handlers type extraction

  • Updated dependencies [ab7684f]:

    • @effect/platform@0.84.3
    • @effect/experimental@0.48.3

0.18.2

Patch Changes

  • Updated dependencies [0ddf148]:
    • effect@3.16.2
    • @effect/experimental@0.48.2
    • @effect/platform@0.84.2

0.18.1

Patch Changes

  • Updated dependencies [71174d0, d615e6e]:
    • @effect/platform@0.84.1
    • effect@3.16.1
    • @effect/experimental@0.48.1

0.18.0

Minor Changes

  • #4891 0552674 Thanks @IMax153! - Make AiModel a plain Layer and remove AiPlan in favor of ExecutionPlan

    This release substantially simplifies and improves the ergonomics of using AiModel for various providers. With these changes, an AiModel now returns a plain Layer which can be used to provide services to a program that interacts with large language models.

    Before

    import { AiLanguageModel } from "@effect/ai"
    import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai"
    import { NodeHttpClient } from "@effect/platform-node"
    import { Config, Console, Effect, Layer } from "effect"
    // Produces an `AiModel<AiLanguageModel, OpenAiClient>`
    const Gpt4o = OpenAiLanguageModel.model("gpt-4o")
    // Generate a dad joke
    const getDadJoke = AiLanguageModel.generateText({
    prompt: "Tell me a dad joke"
    })
    const program = Effect.gen(function* () {
    // Build the `AiModel` into a `Provider`
    const gpt4o = yield* Gpt4o
    // Use the built `AiModel` to run the program
    const response = yield* gpt4o.use(getDadJoke)
    // Log the response
    yield* Console.log(response.text)
    })
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    program.pipe(Effect.provide(OpenAi), Effect.runPromise)

    After

    import { AiLanguageModel } from "@effect/ai"
    import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai"
    import { NodeHttpClient } from "@effect/platform-node"
    import { Config, Console, Effect, Layer } from "effect"
    // Produces a `Layer<AiLanguageModel, never, OpenAiClient>`
    const Gpt4o = OpenAiLanguageModel.model("gpt-4o")
    const program = Effect.gen(function*() {
    // Generate a dad joke
    const response = yield* AiLanguageModel.generateText({
    prompt: "Tell me a dad joke"
    })
    // Log the response
    yield* Console.log(response.text)
    ).pipe(Effect.provide(Gpt4o))
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    program.pipe(
    Effect.provide(OpenAi),
    Effect.runPromise
    )

    In addition, AiModel can be yield*’ed to produce a layer with no requirements.

    This shifts the requirements of building the layer into the calling effect, which is particularly useful for creating AI-powered services.

    import { AiLanguageModel } from "@effect/ai"
    import { OpenAiLanguageModel } from "@effect/ai-openai"
    import { Effect } from "effect"
    class DadJokes extends Effect.Service<DadJokes>()("DadJokes", {
    effect: Effect.gen(function* () {
    // Yielding the model will return a layer with no requirements
    //
    // ┌─── Layer<AiLanguageModel>
    // ▼
    const model = yield* OpenAiLanguageModel.model("gpt-4o")
    const getDadJoke = AiLanguageModel.generateText({
    prompt: "Generate a dad joke"
    }).pipe(Effect.provide(model))
    return { getDadJoke } as const
    })
    }) {}
    // The requirements are lifted into the service constructor
    //
    // ┌─── Layer<DadJokes, never, OpenAiClient>
    // ▼
    DadJokes.Default

Patch Changes

0.17.0

Patch Changes

  • Updated dependencies [5522520, cc5bb2b]:
    • @effect/platform@0.83.0
    • effect@3.15.5
    • @effect/experimental@0.47.0

0.16.9

Patch Changes

  • Updated dependencies [0617b9d]:
    • @effect/platform@0.82.8
    • @effect/experimental@0.46.8

0.16.8

Patch Changes

0.16.7

Patch Changes

  • Updated dependencies [618903b]:
    • @effect/platform@0.82.6
    • @effect/experimental@0.46.6

0.16.6

Patch Changes

  • Updated dependencies [7764a07, 4577f54, 30a0d9c]:
    • @effect/platform@0.82.5
    • effect@3.15.3
    • @effect/experimental@0.46.5

0.16.5

Patch Changes

  • Updated dependencies [d45e8a8, d13b68e]:
    • @effect/platform@0.82.4
    • @effect/experimental@0.46.4

0.16.4

Patch Changes

  • Updated dependencies [b8722b8, a328f4b]:
    • effect@3.15.2
    • @effect/platform@0.82.3
    • @effect/experimental@0.46.3

0.16.3

Patch Changes

  • Updated dependencies [739a3d4]:
    • @effect/platform@0.82.2
    • @effect/experimental@0.46.2

0.16.2

Patch Changes

  • Updated dependencies [787ce70, 1269641, 1269641]:
    • effect@3.15.1
    • @effect/experimental@0.46.1
    • @effect/platform@0.82.1

0.16.1

Patch Changes

  • #4866 cb3c30f Thanks @tim-smart! - preserve tool call results in AiResponse.merge

  • Updated dependencies []:

    • @effect/experimental@0.46.0

0.16.0

Patch Changes

0.15.0

Minor Changes

  • #4766 a4d42c5 Thanks @IMax153! - This release includes a complete refactor of the internals of the base @effect/ai library, with a focus on flexibility for the end user and incorporation of more information from model providers.

    Notable Changes

    AiLanguageModel and AiEmbeddingModel

    The Completions service from @effect/ai has been renamed to AiLanguageModel, and the Embeddings service has similarly been renamed to AiEmbeddingModel. In addition, Completions.create and Completions.toolkit have been unified into AiLanguageModel.generateText. Similarly, Completions.stream and Completions.toolkitStream have been unified into AiLanguageModel.streamText.

    Structured Outputs

    Completions.structured has been renamed to AiLanguageModel.generateObject, and this method now returns a specialized AiResponse.WithStructuredOutput type, which contains a value property with the result of the structured output call. This enhancement prevents the end user from having to unnecessarily unwrap an Option.

    AiModel and AiPlan

    The .provide method on a built AiModel / AiPlan has been renamed to .use to improve clarity given that a user is using the services provided by the model / plan to run a particular piece of code.

    In addition, the AiPlan.fromModel constructor has been simplified into AiPlan.make, which allows you to create an initial AiPlan with multiple steps incorporated.

    For example:

    import { AiPlan } from "@effect/ai"
    import { OpenAiLanguageModel } from "@effect/ai-openai"
    import { AnthropicLanguageModel } from "@effect/ai-anthropic"
    import { Effect } from "effect"
    const main = Effect.gen(function* () {
    const plan = yield* AiPlan.make(
    {
    model: OpenAiLanguageModel.model("gpt-4"),
    attempts: 1
    },
    {
    model: AnthropicLanguageModel.model("claude-3-7-sonnet-latest"),
    attempts: 1
    },
    {
    model: AnthropicLanguageModel.model("claude-3-5-sonnet-latest"),
    attempts: 1
    }
    )
    yield* plan.use(program)
    })

    AiInput and AiResponse

    The AiInput and AiResponse types have been refactored to allow inclusion of more information and metadata from model providers where possible, such as reasoning output and prompt cache token utilization.

    In addition, for an AiResponse you can now access metadata that is specific to a given provider. For example, when using OpenAi to generate audio, you can check the input and output audio tokens used:

    import { OpenAiLanguageModel } from "@effect/ai-openai"
    import { Effect, Option } from "effect"
    const getDadJoke = OpenAiLanguageModel.generateText({
    prompt: "Generate a hilarious dad joke"
    })
    Effect.gen(function* () {
    const model = yield* OpenAiLanguageModel.model("gpt-4o")
    const response = yield* model.use(getDadJoke)
    const metadata = response.getProviderMetadata(
    OpenAiLanguageModel.ProviderMetadata
    )
    if (Option.isSome(metadata)) {
    console.log(metadata.value)
    }
    })

    AiTool and AiToolkit

    The AiToolkit has been completely refactored to simplify creating a collection of tools and using those tools in requests to model providers. A new AiTool data type has also been introduced to simplify defining tools for a toolkit. AiToolkit.implement has been renamed to AiToolkit.toLayer for clarity, and defining handlers is now very similar to the way handlers are defined in the @effect/rpc library.

    A complete example of an AiToolkit implementation and usage can be found below:

    import { AiLanguageModel, AiTool, AiToolkit } from "@effect/ai"
    import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai"
    import {
    FetchHttpClient,
    HttpClient,
    HttpClientRequest,
    HttpClientResponse
    } from "@effect/platform"
    import { NodeHttpClient, NodeRuntime } from "@effect/platform-node"
    import { Array, Config, Console, Effect, Layer, Schema } from "effect"
    // =============================================================================
    // Domain Models
    // =============================================================================
    const DadJoke = Schema.Struct({
    id: Schema.String,
    joke: Schema.String
    })
    const SearchResponse = Schema.Struct({
    current_page: Schema.Int,
    limit: Schema.Int,
    next_page: Schema.Int,
    previous_page: Schema.Int,
    search_term: Schema.String,
    results: Schema.Array(DadJoke),
    status: Schema.Int,
    total_jokes: Schema.Int,
    total_pages: Schema.Int
    })
    // =============================================================================
    // Service Definitions
    // =============================================================================
    export class ICanHazDadJoke extends Effect.Service<ICanHazDadJoke>()(
    "ICanHazDadJoke",
    {
    dependencies: [FetchHttpClient.layer],
    effect: Effect.gen(function* () {
    const httpClient = (yield* HttpClient.HttpClient).pipe(
    HttpClient.mapRequest(
    HttpClientRequest.prependUrl("https://icanhazdadjoke.com")
    )
    )
    const httpClientOk = HttpClient.filterStatusOk(httpClient)
    const search = Effect.fn("ICanHazDadJoke.search")(function (
    term: string
    ) {
    return httpClientOk
    .get("/search", {
    acceptJson: true,
    urlParams: { term }
    })
    .pipe(
    Effect.flatMap(HttpClientResponse.schemaBodyJson(SearchResponse)),
    Effect.orDie
    )
    })
    return {
    search
    } as const
    })
    }
    ) {}
    // =============================================================================
    // Toolkit Definition
    // =============================================================================
    export class DadJokeTools extends AiToolkit.make(
    AiTool.make("GetDadJoke", {
    description:
    "Fetch a dad joke based on a search term from the ICanHazDadJoke API",
    success: DadJoke,
    parameters: Schema.Struct({
    searchTerm: Schema.String
    })
    })
    ) {}
    // =============================================================================
    // Toolkit Handlers
    // =============================================================================
    export const DadJokeToolHandlers = DadJokeTools.toLayer(
    Effect.gen(function* () {
    const icanhazdadjoke = yield* ICanHazDadJoke
    return {
    GetDadJoke: (params) =>
    icanhazdadjoke.search(params.searchTerm).pipe(
    Effect.flatMap((response) => Array.head(response.results)),
    Effect.orDie
    )
    }
    })
    ).pipe(Layer.provide(ICanHazDadJoke.Default))
    // =============================================================================
    // Toolkit Usage
    // =============================================================================
    const makeDadJoke = Effect.gen(function* () {
    const languageModel = yield* AiLanguageModel.AiLanguageModel
    const toolkit = yield* DadJokeTools
    const response = yield* languageModel.generateText({
    prompt: "Come up with a dad joke about pirates",
    toolkit
    })
    return yield* languageModel.generateText({
    prompt: response
    })
    })
    const program = Effect.gen(function* () {
    const model = yield* OpenAiLanguageModel.model("gpt-4o")
    const result = yield* model.provide(makeDadJoke)
    yield* Console.log(result.text)
    })
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    program.pipe(
    Effect.provide([OpenAi, DadJokeToolHandlers]),
    Effect.tapErrorCause(Effect.logError),
    NodeRuntime.runMain
    )

Patch Changes

  • Updated dependencies []:
    • @effect/experimental@0.45.1

0.14.1

Patch Changes

  • Updated dependencies [24a9ebb]:
    • effect@3.14.22
    • @effect/experimental@0.45.1
    • @effect/platform@0.81.1

0.14.0

Patch Changes

  • Updated dependencies [672920f]:
    • @effect/platform@0.81.0
    • @effect/experimental@0.45.0

0.13.21

Patch Changes

  • Updated dependencies [2f3b7d4]:
    • effect@3.14.21
    • @effect/experimental@0.44.21
    • @effect/platform@0.80.21

0.13.20

Patch Changes

  • Updated dependencies [17e2f30]:
    • effect@3.14.20
    • @effect/experimental@0.44.20
    • @effect/platform@0.80.20

0.13.19

Patch Changes

  • Updated dependencies [056a910, e25e7bb, 3273d57]:
    • effect@3.14.19
    • @effect/platform@0.80.19
    • @effect/experimental@0.44.19

0.13.18

Patch Changes

  • Updated dependencies [b1164d4]:
    • effect@3.14.18
    • @effect/experimental@0.44.18
    • @effect/platform@0.80.18

0.13.17

Patch Changes

  • Updated dependencies [0b54681, 41a59d5]:
    • effect@3.14.17
    • @effect/experimental@0.44.17
    • @effect/platform@0.80.17

0.13.16

Patch Changes

  • Updated dependencies [ee14444, f1c8583]:
    • effect@3.14.16
    • @effect/platform@0.80.16
    • @effect/experimental@0.44.16

0.13.15

Patch Changes

  • Updated dependencies [239cc99, 8b6c947, c50a63b]:
    • effect@3.14.15
    • @effect/experimental@0.44.15
    • @effect/platform@0.80.15

0.13.14

Patch Changes

  • Updated dependencies [6ed8d15]:
    • effect@3.14.14
    • @effect/experimental@0.44.14
    • @effect/platform@0.80.14

0.13.13

Patch Changes

  • Updated dependencies [ee77788, 5fce6ba, 570e45f]:
    • effect@3.14.13
    • @effect/experimental@0.44.13
    • @effect/platform@0.80.13

0.13.12

Patch Changes

  • Updated dependencies [c2ad9ee, 9c68654]:
    • effect@3.14.12
    • @effect/experimental@0.44.12
    • @effect/platform@0.80.12

0.13.11

Patch Changes

  • Updated dependencies [e536127]:
    • effect@3.14.11
    • @effect/experimental@0.44.11
    • @effect/platform@0.80.11

0.13.10

Patch Changes

  • Updated dependencies [bc7efa3]:
    • effect@3.14.10
    • @effect/experimental@0.44.10
    • @effect/platform@0.80.10

0.13.9

Patch Changes

  • Updated dependencies [d78249f]:
    • effect@3.14.9
    • @effect/experimental@0.44.9
    • @effect/platform@0.80.9

0.13.8

Patch Changes

  • Updated dependencies [b3a2d32]:
    • effect@3.14.8
    • @effect/experimental@0.44.8
    • @effect/platform@0.80.8

0.13.7

Patch Changes

  • Updated dependencies [b542a4b]:
    • effect@3.14.7
    • @effect/experimental@0.44.7
    • @effect/platform@0.80.7

0.13.6

Patch Changes

  • Updated dependencies [47618c1, 6077882]:
    • effect@3.14.6
    • @effect/experimental@0.44.6
    • @effect/platform@0.80.6

0.13.5

Patch Changes

  • Updated dependencies [40dbfef, 85fba81, 5a5ebdd]:
    • effect@3.14.5
    • @effect/platform@0.80.5
    • @effect/experimental@0.44.5

0.13.4

Patch Changes

  • Updated dependencies [e4ba2c6]:
    • effect@3.14.4
    • @effect/experimental@0.44.4
    • @effect/platform@0.80.4

0.13.3

Patch Changes

  • Updated dependencies [37aa8e1, 34f03d6]:
    • effect@3.14.3
    • @effect/experimental@0.44.3
    • @effect/platform@0.80.3

0.13.2

Patch Changes

  • Updated dependencies [f87991b, f87991b, 0a3e3e1]:
    • effect@3.14.2
    • @effect/experimental@0.44.2
    • @effect/platform@0.80.2

0.13.1

Patch Changes

  • Updated dependencies [4a274fe]:
    • effect@3.14.1
    • @effect/experimental@0.44.1
    • @effect/platform@0.80.1

0.13.0

Patch Changes

0.12.4

Patch Changes

0.12.3

Patch Changes

  • Updated dependencies [0c4803f, 6f65ac4]:
    • effect@3.13.12
    • @effect/experimental@0.43.3
    • @effect/platform@0.79.3

0.12.2

Patch Changes

0.12.1

Patch Changes

  • Updated dependencies [527c964]:
    • effect@3.13.10
    • @effect/experimental@0.43.1
    • @effect/platform@0.79.1

0.12.0

Patch Changes

  • Updated dependencies [88fe129, d630249, 2976e52]:
    • @effect/platform@0.79.0
    • effect@3.13.9
    • @effect/experimental@0.43.0

0.11.1

Patch Changes

  • Updated dependencies [c65d336, 22d2ebb]:
    • effect@3.13.8
    • @effect/experimental@0.42.1
    • @effect/platform@0.78.1

0.11.0

Patch Changes

  • Updated dependencies [c5bcf53]:
    • @effect/platform@0.78.0
    • @effect/experimental@0.42.0

0.10.7

Patch Changes

0.10.6

Patch Changes

  • Updated dependencies [3154ce4]:
    • effect@3.13.6
    • @effect/experimental@0.41.6
    • @effect/platform@0.77.6

0.10.5

Patch Changes

  • #4549 3d6d323 Thanks @IMax153! - Fix AiPlan builder to return correct shape

  • #4537 975c20e Thanks @IMax153! - Allow defects to pass through predicates in AiPlan

  • Updated dependencies [367bb35, 6cf11c3, a0acec8]:

    • effect@3.13.5
    • @effect/experimental@0.41.5
    • @effect/platform@0.77.5

0.10.4

Patch Changes

  • Updated dependencies [e0746f9, 17d9e89]:
    • @effect/platform@0.77.4
    • effect@3.13.4
    • @effect/experimental@0.41.4

0.10.3

Patch Changes

  • #4504 a67a8a1 Thanks @IMax153! - Introduce AiModel and AiPlan for describing retry / fallback logic between models and providers

    For example, the following program builds an AiPlan which will attempt to use OpenAi’s chat completions API, and if after three attempts the operation is still failing, the plan will fallback to utilizing Anthropic’s messages API to resolve the request.

    import { AiPlan, Completions } from "@effect/ai"
    import { AnthropicClient, AnthropicCompletions } from "@effect/ai-anthropic"
    import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
    import { NodeHttpClient, NodeRuntime } from "@effect/platform-node"
    import { Config, Console, Effect, Layer } from "effect"
    // Create Anthropic client
    const Anthropic = AnthropicClient.layerConfig({
    apiKey: Config.redacted("ANTHROPIC_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    // Create OpenAi client
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    // Create a plan of request execution
    const Plan = AiPlan.fromModel(OpenAiCompletions.model("gpt-4o-mini"), {
    attempts: 3
    }).pipe(
    AiPlan.withFallback({
    model: AnthropicCompletions.model("claude-3-5-haiku-latest")
    })
    )
    const program = Effect.gen(function* () {
    // Build the plan of execution
    const plan = yield* Plan
    // Create a program which uses the services provided by the plan
    const getDadJoke = Effect.gen(function* () {
    const completions = yield* Completions.Completions
    const response = yield* completions.create("Tell me a dad joke")
    yield* Console.log(response.text)
    })
    // Provide the plan to whichever programs need it
    yield* plan.provide(getDadJoke)
    })
    program.pipe(Effect.provide([Anthropic, OpenAi]), NodeRuntime.runMain)
  • Updated dependencies [cc5588d, 623c8cd, 00b4eb1, f2aee98, fb798eb, 2251b15, 2e15c1e, a4979db, b74255a, d7f6a5c, 9dd8979, 477b488, 10932cb, 9f6c784, 2c639ec, 886aaa8]:

    • effect@3.13.3
    • @effect/experimental@0.41.3
    • @effect/platform@0.77.3

0.10.2

Patch Changes

  • Updated dependencies [31be72a, 3e7ce97, 31be72a]:
    • effect@3.13.2
    • @effect/platform@0.77.2
    • @effect/experimental@0.41.2

0.10.1

Patch Changes

  • #4446 9375c28 Thanks @IMax153! - Add Anthropic AI provider integration

  • Updated dependencies [b56a211]:

    • effect@3.13.1
    • @effect/experimental@0.41.1
    • @effect/platform@0.77.1

0.10.0

Patch Changes

0.9.1

Patch Changes

0.9.0

Patch Changes

0.8.4

Patch Changes

0.8.3

Patch Changes

  • Updated dependencies [1b4a4e9]:
    • effect@3.12.9
    • @effect/experimental@0.39.3
    • @effect/platform@0.75.3

0.8.2

Patch Changes

  • #4378 f5e3b1b Thanks @IMax153! - Support non-identified schemas in AiChat.structured and Completions.structured.

    Instead of requiring a Schema with either an identifier or _tag property for AI APIs that allow for returning structured outputs, you can now optionally pass a correlationId to AiChat.structured and Completions.structured when you want to either use a simple schema or inline the schema.

    Example:

    import { Completions } from "@effect/ai"
    import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
    import { NodeHttpClient } from "@effect/platform-node"
    import { Config, Effect, Layer, Schema, String } from "effect"
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    const Gpt4oCompletions = OpenAiCompletions.layer({
    model: "gpt-4o"
    }).pipe(Layer.provide(OpenAi))
    const program = Effect.gen(function* () {
    const completions = yield* Completions.Completions
    const CalendarEvent = Schema.Struct({
    name: Schema.String,
    date: Schema.DateFromString,
    participants: Schema.Array(Schema.String)
    })
    yield* completions.structured({
    correlationId: "CalendarEvent",
    schema: CalendarEvent,
    input: String.stripMargin(`
    |Extract event information from the following prose:
    |
    |Alice and Bob are going to a science fair on Friday.
    `)
    })
    })
    program.pipe(Effect.provide(Gpt4oCompletions), Effect.runPromise)
  • #4388 fcf3b7c Thanks @IMax153! - Rename correlationId to toolCallId

  • #4389 f089470 Thanks @IMax153! - Add support for GenAI telemetry annotations.

  • #4368 a0c85e6 Thanks @IMax153! - Support creation of embeddings from the AI integration packages.

    For example, the following program will create an OpenAI Embeddings service that will aggregate all embedding requests received within a 500 millisecond window into a single batch.

    import { Embeddings } from "@effect/ai"
    import { OpenAiClient, OpenAiEmbeddings } from "@effect/ai-openai"
    import { NodeHttpClient } from "@effect/platform-node"
    import { Config, Effect, Layer } from "effect"
    // Create the OpenAI client
    const OpenAi = OpenAiClient.layerConfig({
    apiKey: Config.redacted("OPENAI_API_KEY")
    }).pipe(Layer.provide(NodeHttpClient.layerUndici))
    // Create an embeddings service for the `text-embedding-3-large` model
    const TextEmbeddingsLarge = OpenAiEmbeddings.layerDataLoader({
    model: "text-embedding-3-large",
    window: "500 millis",
    maxBatchSize: 2048
    }).pipe(Layer.provide(OpenAi))
    // Use the generic `Embeddings` service interface in your program
    const program = Effect.gen(function* () {
    const embeddings = yield* Embeddings.Embeddings
    const result = yield* embeddings.embed("The input to embed")
    })
    // Provide the specific implementation to use
    program.pipe(Effect.provide(TextEmbeddingsLarge), Effect.runPromise)
  • Updated dependencies [59b3cfb, 766113c, bb05fb8, 712277f, f269122, 8f6006a, c45b559, 430c846, 7b03057, a9c94c8, 107e6f0, c9175ae, 65c11b9, e386d2f, 9172efb]:

    • @effect/platform@0.75.2
    • effect@3.12.8
    • @effect/experimental@0.39.2

0.8.1

Patch Changes

  • Updated dependencies [8dff1d1]:
    • effect@3.12.7
    • @effect/platform@0.75.1

0.8.0

Minor Changes

  • #4306 5e43ce5 Thanks @tim-smart! - eliminate Scope by default in some layer apis

Patch Changes

0.7.0

Patch Changes

0.6.1

Patch Changes

0.6.0

Patch Changes

0.5.2

Patch Changes

0.5.1

Patch Changes

0.5.0

Patch Changes

0.4.8

Patch Changes

0.4.7

Patch Changes

0.4.6

Patch Changes

0.4.5

Patch Changes

0.4.4

Patch Changes

0.4.3

Patch Changes

  • #4139 1237ae8 Thanks @tim-smart! - fix json schema output for Ai completions

0.4.2

Patch Changes

0.4.1

Patch Changes

  • Updated dependencies [1d3df5b]:
    • @effect/platform@0.71.1

0.4.0

Patch Changes

0.3.7

Patch Changes

0.3.6

Patch Changes

  • Updated dependencies [9a5b8e3]:
    • @effect/platform@0.70.6

0.3.5

Patch Changes

0.3.4

Patch Changes

0.3.3

Patch Changes

  • #4071 da3a607 Thanks @tim-smart! - use openai response_format for structured completions

  • Updated dependencies [7044730]:

    • @effect/platform@0.70.3

0.3.2

Patch Changes

0.3.1

Patch Changes

  • Updated dependencies [dd8a2d8, a71bfef]:
    • effect@3.11.1
    • @effect/platform@0.70.1

0.3.0

Patch Changes

0.2.32

Patch Changes

  • Updated dependencies [3069614, 09a5e52]:
    • effect@3.10.20
    • @effect/platform@0.69.32

0.2.31

Patch Changes

  • Updated dependencies [e6d4a37]:
    • @effect/platform@0.69.31

0.2.30

Patch Changes

  • Updated dependencies [270f199]:
    • @effect/platform@0.69.30

0.2.29

Patch Changes

  • Updated dependencies [24cc35e]:
    • @effect/platform@0.69.29

0.2.28

Patch Changes

0.2.27

Patch Changes

  • Updated dependencies [af409cf, beaccae]:
    • effect@3.10.18
    • @effect/platform@0.69.27

0.2.26

Patch Changes

  • Updated dependencies [c963886, 42c4ce6]:
    • @effect/platform@0.69.26
    • effect@3.10.17

0.2.25

Patch Changes

0.2.24

Patch Changes

  • Updated dependencies [3cc6514]:
    • @effect/platform@0.69.24

0.2.23

Patch Changes

  • Updated dependencies [3aff4d3]:
    • @effect/platform@0.69.23

0.2.22

Patch Changes

  • Updated dependencies [8398b32, 72e55b7]:
    • effect@3.10.15
    • @effect/platform@0.69.22

0.2.21

Patch Changes

  • Updated dependencies [f983946, 2d8a750]:
    • effect@3.10.14
    • @effect/platform@0.69.21

0.2.20

Patch Changes

  • #3916 72b0272 Thanks @tim-smart! - use effect/JSONSchema for effect/ai & allow http client transforms

  • Updated dependencies [995bbdf]:

    • effect@3.10.13
    • @effect/platform@0.69.20

0.2.19

Patch Changes

  • Updated dependencies [eb8c52d]:
    • @effect/platform@0.69.19

0.2.18

Patch Changes

0.2.17

Patch Changes

0.2.16

Patch Changes

0.2.15

Patch Changes

  • Updated dependencies [8a30e1d]:
    • @effect/platform@0.69.15

0.2.14

Patch Changes

0.2.13

Patch Changes

0.2.12

Patch Changes

  • Updated dependencies [33f5b9f, 50f0281]:
    • effect@3.10.7
    • @effect/platform@0.69.12

0.2.11

Patch Changes

  • Updated dependencies [ce1c21f, 81ddd45]:
    • effect@3.10.6
    • @effect/platform@0.69.11

0.2.10

Patch Changes

  • Updated dependencies [3a6d757, 59d813a]:
    • effect@3.10.5
    • @effect/platform@0.69.10

0.2.9

Patch Changes

  • Updated dependencies [2367708]:
    • @effect/platform@0.69.9
    • effect@3.10.4

0.2.8

Patch Changes

  • Updated dependencies [522f7c5]:
    • @effect/platform@0.69.8

0.2.7

Patch Changes

0.2.6

Patch Changes

0.2.5

Patch Changes

  • Updated dependencies [9604d6b]:
    • effect@3.10.1
    • @effect/platform@0.69.5

0.2.4

Patch Changes

  • Updated dependencies [c86b1d7]:
    • @effect/platform@0.69.4

0.2.3

Patch Changes

0.2.2

Patch Changes

  • Updated dependencies [e7afc47]:
    • @effect/platform@0.69.2

0.2.1

Patch Changes

0.2.0

Patch Changes

0.1.4

Patch Changes

  • Updated dependencies [382556f, 97cb014]:
    • @effect/schema@0.75.5
    • @effect/platform@0.68.6

0.1.3

Patch Changes

  • Updated dependencies [2036402]:
    • @effect/platform@0.68.5

0.1.2

Patch Changes

  • Updated dependencies [1b1ef29]:
    • @effect/platform@0.68.4

0.1.1

Patch Changes

  • Updated dependencies [61a99b2, 8c33087]:
    • effect@3.9.2
    • @effect/platform@0.68.3
    • @effect/schema@0.75.4

0.1.0

Minor Changes

  • #3631 bd160a4 Thanks @tim-smart! - add @effect/ai packages

    Experimental modules for working with LLMs, currently only from OpenAI.

Patch Changes

  • Updated dependencies [360ec14]:
    • @effect/schema@0.75.3
    • @effect/platform@0.68.2