redai
redai is a minimal, provider-agnostic agent runtime you embed in your own Node/TypeScript apps. Configure an Agent (instructions, model, tools, optional schemas, guardrails, handoffs), then call run() or stream().
It is deliberately not a wrapper around LangChain, LlamaIndex, or the OpenAI Agents SDK. The agent loop, tool dispatch, guardrails, handoffs, streaming, and tracing are all hand-written. Provider SDKs are optional peer dependencies, so you install only what you use.
Typed agent loop
A readable, owned agent loop in runner.ts. Tool calling, turn management, and termination conditions with zero framework magic.
Structured output
Zod schemas compile to JSON Schema for providers, then validate, with automatic repair attempts on malformed model output.
Guardrails everywhere
Input, output, and tool-level guardrails intercept bad data before it reaches the model or your systems.
Multi-agent handoffs
Agents delegate to other agents with self-handoff blocks and loop caps to prevent runaway delegation.
Sessions & memory
Multi-turn conversations via in-memory or JSON-file session stores. Your infra, your choice.
Observable by default
Every run returns a Trace with spans and token totals. Streaming events let you watch the loop think.
- 01
No framework under the hood. The loop is owned and readable in runner.ts
- 02
Result types over throws. Expected failures return { ok: false, error } so callers branch with instanceof
- 03
One streaming path. run() is simply a drain of stream(), so features never drift apart
- 04
Provider-agnostic core. Only ModelProvider and ModelMessage exist at the boundary; OpenAI, Anthropic, and Gemini adapters are optional peers
- 05
Safety valves. maxTurns, maxHandoffs, and maxOutputRepairAttempts prevent runaway loops and runaway bills