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