Build TypeScript agents with Effect and Effect AI. Define inputs, outputs, and tools with schemas. Effect Agent runs the loop, executes tools, and validates the result — with typed errors, streaming, and bounded execution.
bun add effect-agent@betaUse an Effect AI provider for model access.
Prefer named namespace imports from package roots, such as import { Agent } from "effect-agent".
Direct module paths use kebab-case, such as effect-agent/agent-runtime; see the
import guide for direct imports and lazy loading.
Public beta: APIs and stored data may change before 1.0. Persistent adapters support a data-preserving beta49/beta50 storage upgrade.
import { Effect, Schema } from "effect";
import { Agent, AgentRuntime } from "effect-agent";
import { Toolkit } from "effect/unstable/ai";
const planner = Agent.make("travel-planner", {
input: Schema.Struct({ city: Schema.String, days: Schema.Int }),
output: Schema.Struct({ itinerary: Schema.Array(Schema.String) }),
instructions: ({ city, days }) => `Plan ${days} days in ${city}. Suggest one activity per day.`,
toolkit: Toolkit.empty,
policy: { maxTurns: 6, maxToolCalls: 10, maxDuration: "2 minutes" },
});
const program = Effect.gen(function* () {
const result = yield* AgentRuntime.run(planner, { city: "Lisbon", days: 2 });
yield* Effect.log(result.output.itinerary); // readonly string[]
});The output is schema-validated. Supply your model and runtime services to run it:
Run this example with OpenAI
Save the code above and the setup below as agent.ts.
import { InMemory } from "effect-agent";
import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai";
import { BunRuntime } from "@effect/platform-bun";
import { Config, Layer } from "effect";
import { FetchHttpClient } from "effect/unstable/http";
const AppLive = Layer.mergeAll(OpenAiLanguageModel.model("gpt-6-astra"), InMemory.layer).pipe(
Layer.provide(OpenAiClient.layerConfig({ apiKey: Config.Redacted("OPENAI_API_KEY") })),
Layer.provide(FetchHttpClient.layer),
);
BunRuntime.runMain(program.pipe(Effect.provide(AppLive)));export OPENAI_API_KEY="your-api-key"
bun agent.tsUse native Effect AI tools with typed parameters, results, and Effect handlers:
import { Tool } from "effect/unstable/ai";
const SearchActivities = Tool.make("search_activities", {
description: "Find activities in a city.",
parameters: Schema.Struct({ city: Schema.String }),
success: Schema.Array(Schema.String),
});
const TravelTools = Toolkit.make(SearchActivities);
const TravelToolsLive = TravelTools.toLayer({
// Sample data; replace with your database or API.
search_activities: ({ city }) =>
Effect.succeed(city === "Lisbon" ? ["Riverside walk", "Food market"] : []),
});Define these before planner, set its toolkit to TravelTools, and add TravelToolsLive
to Layer.mergeAll above.
More about tools, approvals, and MCP →
Use the same agent and services to observe text, tool activity, and lifecycle events:
import { Stream } from "effect";
const streaming = AgentRuntime.stream(planner, { city: "Lisbon", days: 2 }).pipe(
Stream.runForEach((event) => Effect.log(event._tag)),
Effect.provide(AppLive),
);
BunRuntime.runMain(streaming);Use this in place of the earlier BunRuntime.runMain call.
More about streaming and interactive input →
- Travel planner — complete agent, tools, and provider setup.
- Subagents, browser tools, and Code Mode — delegate research, browse pages, and execute code.
- Persistent threads, durable execution, and Effect Workflows — keep history and resume work.
- Cloudflare travel planner and the PR reviewer.
Start with the getting-started guide, or explore the package map and deployment guide.
Framework packages live in packages/*, and runnable examples live in examples/*.
Use Vite+ for repository commands. Bun is the package manager.
vp install
vp run docs:dev
vp run readyvp run ready runs static checks, tests, package builds, and the documentation build with link
validation. Before changing code, read the toolchain guide,
glossary, and contributor instructions.
We took inspiration from Flue and Pi for parts of the agent loop, interaction model, and durability design.