examples/ai-agent-effect/README.md
A stateful AI agent actor built with the Effect SDK for Rivet Actors and Effect AI. The agent persists its conversation history in actor state, so it remembers every turn across calls and restarts.
Running against a real model needs an OpenAI API key:
export OPENAI_API_KEY=sk-...
The test suite needs neither a key nor network access: it runs a real in-process mock LLM server instead.
git clone https://github.com/rivet-dev/rivet.git
cd rivet/examples/ai-agent-effect
npm install
npm run dev
In a separate terminal, run the client against the server:
npm run client
Schema.Array of role/content messages), so the model sees the full history on each call, even after the actor sleeps or restartsLanguageModel.generateText from effect/unstable/ai with the running history as the promptLanguageModel service but never constructs it. The concrete model is provided as an Effect Layer where the actor is composed: a real OpenAI model in dev, a mock model in testsActor.make and implemented with toLayer, returning action handlers from an Effect wake scopeSendMessage declares an EmptyMessageError that arrives on the caller as a real tagged instance, caught with Effect.catchTagThe actor is split into a public contract and a server-only implementation:
src/actors/agent/api.ts): Declares the Agent actor, the Message type, the SendMessage / GetHistory actions, and the EmptyMessageErrorsrc/actors/agent/live.ts): Implements the wake scope, the conversation-history state schema, and the action handlers that call the LLMsrc/model.ts): Composes a Layer<LanguageModel> from OpenAiLanguageModel, OpenAiClient, and FetchHttpClientsrc/main.ts): Provides the model Layer to the actor layer and serves it with Registry.servesrc/client.ts): An Effect client using the typed Agent.client accessortests/agent.test.ts): Runs the actor against a real engine and a real in-process mock LLM server, swapping in a mock model LayerRead more about actions, state, and the Effect quickstart.
MIT