Skip to content

Conversation

@IMax153
Copy link
Member

@IMax153 IMax153 commented May 23, 2025

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

Warning

This PR will depend on merge of #4910 to replace AiPlan.

The goal of this PR is to simplify the usage of AiModels in both Effect and Stream programs by leveraging well-known patterns in Effect for requiring and providing services. The ergonomics of AiModel have been substantially improved - an AiModel now returns a plain Layer which can be used to provide services to a program that makes use of large language model interactions.

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 = AiLanguageModel.generateText({
  prompt: "Tell me a dad joke"
}).pipe(
  Effect.flatMap((response) => Console.log(response.text)),
  // Provide the model to use
  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 

Related

  • Related Issue #
  • Closes #

@github-project-automation github-project-automation bot moved this to Discussion Ongoing in PR Backlog May 23, 2025
@changeset-bot
Copy link

changeset-bot bot commented May 23, 2025

🦋 Changeset detected

Latest commit: 5da36c5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@effect/ai-anthropic Major
@effect/ai-openai Major
@effect/ai Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@IMax153 IMax153 requested review from mikearnaldi and tim-smart May 23, 2025 18:23
@IMax153 IMax153 self-assigned this May 23, 2025
@tim-smart tim-smart changed the base branch from main to next-minor May 24, 2025 07:35
@effect-bot effect-bot force-pushed the next-minor branch 2 times, most recently from 2212e0f to 05cd1a9 Compare May 24, 2025 08:02
@effect-bot effect-bot force-pushed the next-minor branch 2 times, most recently from 59ef614 to 7d8c110 Compare May 24, 2025 09:18
@effect-bot effect-bot force-pushed the next-minor branch 2 times, most recently from ffbe642 to 21e4d2e Compare May 27, 2025 02:04
@tim-smart
Copy link
Contributor

/rebase

IMax153 and others added 2 commits May 27, 2025 14:32
Co-authored-by: Tim <hello@timsmart.co>
@github-project-automation github-project-automation bot moved this from Discussion Ongoing to Needs merge in PR Backlog May 27, 2025
@IMax153 IMax153 merged commit d546ac0 into next-minor May 27, 2025
11 checks passed
@IMax153 IMax153 deleted the feat/ai-redesign branch May 27, 2025 15:57
@github-project-automation github-project-automation bot moved this from Needs merge to Done in PR Backlog May 27, 2025
@effect-bot effect-bot mentioned this pull request May 27, 2025
effect-bot pushed a commit that referenced this pull request May 27, 2025
Co-authored-by: Maxim Khramtsov <khraks.mamtsov@gmail.com>
Co-authored-by: Tim <hello@timsmart.co>
Co-authored-by: Vincent François <vincent.francois@inato.com>
Co-authored-by: Chris Wilkinson <chris@prereview.org>
Co-authored-by: Tylor Steinberger <tlsteinberger167@gmail.com>
Co-authored-by: Jason Rudder <indxxxd@gmail.com>
Co-authored-by: Sebastian Lorenz <fubhy@fubhy.com>
effect-bot pushed a commit that referenced this pull request May 27, 2025
Co-authored-by: Maxim Khramtsov <khraks.mamtsov@gmail.com>
Co-authored-by: Tim <hello@timsmart.co>
Co-authored-by: Vincent François <vincent.francois@inato.com>
Co-authored-by: Chris Wilkinson <chris@prereview.org>
Co-authored-by: Tylor Steinberger <tlsteinberger167@gmail.com>
Co-authored-by: Jason Rudder <indxxxd@gmail.com>
Co-authored-by: Sebastian Lorenz <fubhy@fubhy.com>
tim-smart added a commit that referenced this pull request May 27, 2025
Co-authored-by: Maxim Khramtsov <khraks.mamtsov@gmail.com>
Co-authored-by: Tim <hello@timsmart.co>
Co-authored-by: Vincent François <vincent.francois@inato.com>
Co-authored-by: Chris Wilkinson <chris@prereview.org>
Co-authored-by: Tylor Steinberger <tlsteinberger167@gmail.com>
Co-authored-by: Jason Rudder <indxxxd@gmail.com>
Co-authored-by: Sebastian Lorenz <fubhy@fubhy.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

8 participants