effect-agentsv4 · beta

integrations · flue

Flue + Effect

The smallest Flue agent whose body is an Effect program.

integrations/flue/agent.ts

// integrations/flue — the smallest Flue agent whose body is an Effect program.
//
// Flue handles the webhook trigger and the response shape. The agent itself
// runs inside `Effect.gen` and is executed with a single `Effect.runPromise`.
// That one line is the only seam between the two systems.
//
// Mirrors flue-snippets/examples/effect-hello.
//   https://github.com/acoyfellow/flue-snippets/tree/main/examples/effect-hello

import type { FlueContext } from "@flue/sdk/client"
import { Effect } from "effect"

interface Env {
  AI: { run: (model: string, args: unknown) => Promise<{ response: string }> }
}

export const triggers = { webhook: true }

// The agent — pure Effect. Inputs are plain values; output is a string.
const greet = (name: string, ai: Env["AI"]) =>
  Effect.gen(function* () {
    const out = yield* Effect.tryPromise({
      try: () =>
        ai.run("@cf/moonshotai/kimi-k2.6", {
          prompt: `Greet ${name} in one short, friendly sentence. No preamble.`
        }),
      catch: (e) => new Error(`Workers AI call failed: ${String(e)}`)
    })
    return out.response.trim()
  }).pipe(Effect.timeout("30 seconds"))

export default async function ({ payload, env }: FlueContext & { env: Env }) {
  const name = typeof payload.name === "string" ? payload.name : "world"
  const greeting = await Effect.runPromise(greet(name, env.AI))
  return { greeting }
}

The smallest Flue agent whose body is an Effect program.

Flue handles the webhook trigger and the response shape. The agent itself is an Effect.Effect<string, Error> executed with one Effect.runPromise(...) call. That single line is the only seam between the two systems.

The seam

const greeting = await Effect.runPromise(greet(name, env.AI))

Everything above that line is Flue. Everything below it is Effect.

Composition

What Flue gives you What Effect gives you
HTTP boundary webhook trigger, JSON response shape —
Agent body — Effect.gen, typed errors, Effect.timeout, retries, structured concurrency
Scaling up adding more triggers, durable runs, observability adding more combinators (Effect.retry, Effect.forEach({ concurrency }), structured output, MCP)

If you want to see what real Effect agents look like — concurrency, retry, streaming, approval flows, typed errors, MCP — see the five agents in this repo.

Live in the Flue repo

This file is also shipped as a runnable example in flue-snippets/examples/effect-hello, where it deploys via the host repo's Alchemy harness and runs an end-to-end probe against a real Cloudflare Worker.

# from acoyfellow/flue-snippets
bash examples/effect-hello/run-e2e.sh