Skip to content

Reactive Agents

A composable TypeScript framework for building reliable LLM agents on a harness you fully control. The same code runs the full agent loop on a local 4B model or a frontier API, and every step is a typed event you can hook into, inspect, and steer.
39Packages & Apps
8,294Tests
8LLM Providers
8Reasoning Strategies
12Execution Phases

Watch the same agent investigate an incident — call two tools, correlate the data, recommend a fix — and finish the job on a 4B local model just like on Claude. One builder; the only line that changes is the model. That cross-tier reliability is the harness doing its job: tool-call healing, verification, and a single-owner termination oracle.

The same Reactive Agents code completing a tool-using task on a local 4B Ollama model and on Claude — only the provider/model line changes
Terminal window
bun add reactive-agents
echo "ANTHROPIC_API_KEY=sk-ant-..." > .env
import { createAgent } from 'reactive-agents'
const agent = await createAgent({
name: 'researcher',
provider: 'anthropic',
reasoning: {}, // ReAct loop: Think → Act → Observe
tools: {}, // Built-in: web-search, file-read, code-execute
observability: {},
})
const result = await agent.run('Find the top 3 TypeScript testing frameworks')
console.log(result.output)

One declarative config object — the front door you already know from the Vercel AI SDK. Enable exactly what you need as config keys; createAgent and the fluent ReactiveAgents.create().withX() builder are the same API in two syntaxes.

No API key? Use provider: 'ollama' with a pulled model (ollama pull qwen3:4b) and skip the .env line entirely — see Local Models.

rax demo
$
 
 

Stay in the loop

Get notified when new releases ship. Reactive Agents is under active development — new strategies, adapters, and integrations land regularly. No spam. One-click unsubscribe.

Two headline capabilities just landed: typed structured output and durable crash-resume.

Typed Structured Output

Attach any Standard Schema (Zod, Valibot, ArkType, Effect) and read a fully-typed value off the result — no prompt engineering, no manual parsing. Streams field-by-field with streamObject().

.withOutputSchema(schema) → typed result.object

Read the guide →

Durable Execution

Persist runs to disk and resume a crashed or paused run from its last checkpoint — across process boundaries.

.withDurableRuns()agent.resumeRun(runId)

Read the guide →

Why a framework instead of a hand-rolled loop?

Section titled “Why a framework instead of a hand-rolled loop?”

An agent is a loop — LLM → tool → observe → repeat. Hand-rolling it works well for prototypes.

The gap shows up under real workloads. A bare ReAct loop (an LLM in a while with tools) breaks in ways the loop itself can’t see — and everything that isn’t the loop is where the work lives:

  • Tool calls returning malformed JSON, wrong types, or hallucinated tool names
  • Loops that don’t terminate — or terminate too early
  • Context that overflows mid-run; memory that leaks between runs
  • Local models dropping reasoning tags, repeating themselves, or refusing structured output
  • Provider-specific streaming quirks; path resolution; type coercion
  • No clean overrides, hooks, or escape hatches when your edge case shows up

This is harness engineering, and there are three honest paths:

Build it yourself

Workable, but it’s an ongoing maintenance cost — every new provider, model quirk, and edge case missed in v1 is yours to chase. It’s easy to underestimate.

Use a black-box harness

Fast to start, but hard to debug, audit, or override. When something breaks, you’re reading framework internals — without source-level control over the parts that matter to your agent.

Use a transparent harness ← Reactive Agents

Every phase emits typed events. The 12-phase pipeline exposes before/after/on-error hooks; system prompts are readable templates, not buried strings; raw provider clients ship standalone so you can skip the harness entirely. Components like the healing pipeline, context curator, and arbitrator are exported and inspectable today — custom-replacement surfaces land progressively (see stability tiers). No hidden prompts, no proprietary loop.

If you’re going to spend the time anyway, spend it on your agent’s logic — not on rebuilding tool-call recovery, context curation, and termination oracles for the third time this year.

Built-in reliability machinery — on by default, no extra wiring required.

Self-healing tool calls

A 4-stage Healing Pipeline runs before every tool execution: tool-name fuzzy match → parameter-name aliasing → path resolution → type coercion. Malformed calls from smaller models get repaired deterministically instead of failing or burning an LLM reprompt — which is what makes 4B+ Ollama models usable for tool-calling agents.

Compact context on long runs

Three-stage context curation: tool results are compressed and stashed, the curator renders only what the next step needs, and an optional reactive trim kicks in under pressure. Long runs stay inside the context window without you managing it.

Secret-leak detection

Every output is scanned for system-prompt, API-key, credential, and internal-instruction leaks (4 categories) with regex-based detection and false-positive filters — deterministic and fast, no extra LLM call.

Guaranteed termination

All 12 phases route stop decisions through a single-owner termination arbitrator, with a loop detector and iteration cap built in. A CI lint guard prevents new bypass paths. Agents finish cleanly instead of hanging or looping.

Verified tool execution, evidence receipts, and the healing pipeline are what carry the same agent code from a frontier API down to a local 4B model. Same builder chain — just .withProvider(“ollama”).

Type-Safe from End to End

Zero any in framework code. Every agent, tool, memory entry, and LLM call is validated by Effect-TS schemas. Failures are typed tagged errors, not exceptions. 8,294 tests keep every service boundary honest on every PR.

Composable Layer Architecture

13 capability layers, every one opt-in. Each is an independent Effect Layer with explicit dependencies. Memory without guardrails? Reasoning without cost tracking? Just stream tokens? Pick exactly what you need — no hidden coupling, no surprise state, no wasted resources.

Observable Execution Engine

12-phase deterministic lifecycle with before / after / on-error hooks per phase. Every phase emits spans, metrics, and EventBus events. You see what your agent decided, why, in what order, at what cost — no manual instrumentation required.

Reasoning, Honestly Scoped

ReAct is the default — it wins on cost and reliability across every tier. Reflexion, Plan-Execute, Tree-of-Thought, and Code-Action (@experimental) are there for frontier/niche work, not sold as a default win (heavy strategies trade real cost for parity, and we document them that way). Adaptive routes to reactive on local tiers automatically, and strategy-switching kicks in when entropy detects a stuck agent. Register your own.

Reliable on Local Models

The 4-stage Healing Pipeline repairs malformed tool calls deterministically — no LLM reprompt needed — and model-adaptive context tunes prompts and compaction per tier. That’s what makes Ollama 4B+ viable for tool-calling agents. Same code, frontier-to-local.

MCP-Native Tool I/O

Connect any Model Context Protocol server — local (stdio) or remote (streamable-http). The 9,400+ public MCP servers (filesystem, GitHub, Slack, browsers, databases) plug in alongside your custom tools via .withMCP(). The protocol is the integration layer; we don’t reinvent it.

Skills as a Primitive

First-class SKILL.md lifecycle — load, activate, and hand-off built into the kernel, not bolted on. Compatible with the emerging cross-tool skill format used by Claude Code, Codex, and Cursor. Browse the Skills guide →

Verified, Not Vibes

Every run produces an evidence receipt: tool invocations, artifact digests, verifier verdicts, and per-deliverable produced/missing status. The verify phase checks output against tool observations, and the fabrication guard rejects invented measurements — the framework proves what it did instead of asserting it.

Developer Experience

60 seconds to first agent. Progressive disclosure — start with 3 lines, add reasoning, memory, guardrails, and observability as you need them. The builder API reads like a sentence. rax CLI scaffolds, runs, and inspects.

Cortex Local Studio

bunx @reactive-agents/cortex for a full local studio: Beacon (live agent canvas with entropy charts), Thalamus (visual agent builder), Lab (debrief UI), and Living Skills views. One flag away from any agent: .withCortex().

vs. LangChain / LlamaIndex

Python-first, dynamically typed, monolithic. Reactive Agents is TypeScript-native with zero any, fully modular layers, and built-in observability. You see every decision — not just the final output. Side-by-side migration guide included.

vs. Vercel AI SDK

Great for streaming and tool calling, but stops there. Reactive Agents adds the reliability harness — tool-call healing, context curation, termination oracle — plus opt-in 4-tier memory, guardrails, verification, cost routing, and a 12-phase execution engine with full observability. Same TypeScript ergonomics; the parts that break at scale are handled.

vs. AutoGen / CrewAI

Multi-agent-first frameworks. Reactive Agents takes the Cognition-aligned posture: single-threaded writes, sub-agent delegation only when it pays for itself. Type-safe, composable, with the healing pipeline that keeps local-model tool calling viable — and A2A (JSON-RPC + SSE) ready when you actually need fan-out.

vs. Building From Scratch

39 production-ready packages, 8,294 tests, 12-phase engine. Memory, reasoning, tools, A2A, gateway, reactive intelligence, safety, cost, identity, orchestration — all composable, all opt-in. Focus on your agent’s logic, not infrastructure.

// Token-by-token streaming via AsyncGenerator
for await (const event of agent.runStream("Write a haiku about TypeScript")) {
if (event._tag === "TextDelta") process.stdout.write(event.text);
if (event._tag === "IterationProgress") console.log(`Step ${event.iteration}/${event.maxIterations}`);
if (event._tag === "StreamCompleted") console.log("\nDone!");
}
// One-liner SSE endpoint
Bun.serve({ fetch: (req) => AgentStream.toSSE(agent.runStream("Hello")) });

Fluent Builder API

Chain capabilities like a sentence — readable and naturally discoverable

🔌

8 LLM Providers

Anthropic, OpenAI, Gemini, Groq, xAI, Ollama, LiteLLM (40+ models) — one unified interface

🧠

5 Reasoning Strategies

ReAct, Reflexion, Plan-Execute, Tree-of-Thought, Adaptive

🔧

Built-in Tool Suite

web-search, file-read, code-execute, http-get, calculator

💾

4-Tier Memory

Working, Semantic, Episodic, Procedural — all composable layers

🌐

Web Framework Hooks

React, Vue & Svelte — useAgentStream, useAgent, createAgentStream out of the box

🔒

Effect-TS Type Safety

RuntimeErrors union, typed hooks, zero runtime surprises

builder api
const agent = await ReactiveAgents
  .create()
  .withProvider("anthropic")
  .withReasoning()      // ReAct
  .withTools()           // Built-ins
  .withMemory({
    tier: "enhanced"
  })
  .withObservability()
  .build();

const result = await
  agent.run(task);
// .output .metadata .debrief
🧠

5 Entropy Sources

Token, structural, semantic, behavioral, context pressure — real-time reasoning quality

Early Stop

Detect convergence and stop early — save tokens and time automatically

🔄

Strategy Switching

Auto-switch reasoning strategy when entropy shows the agent is stuck

📊

Trajectory Analysis

Track entropy over time: converging, flat, diverging, oscillating

🎯

Per-Model Calibration

Conformal thresholds adapt to each model's characteristics over time

📈

Local Learning

Thompson Sampling bandit learns optimal strategies per task category

reactive intelligence
.withReactiveIntelligence({
  controller: {
    earlyStop: true,
    contextCompression: true,
    strategySwitch: true,
  },
})

// Dashboard output:
🧠 Reasoning Signal
├─ Grade: B  Signal: converging 
├─ Trace: ████▓▒░ 0.650.25
└─ Tip: Enable earlyStop
📊

12-Phase Execution Engine

bootstrap → guardrail → think → act → observe → complete

🔔

EventBus Auto-Wiring

Zero manual instrumentation — MetricsCollector subscribes automatically

Live Log Streaming

Real-time phase events at 4 verbosity levels: minimal → debug

🔍

Distributed Tracing

OpenTelemetry spans with correlation IDs across every phase

💡

Smart Alerts

Bottleneck detection, budget warnings, optimization suggestions

📈

Cost Metrics

Token count and USD estimate tracked and reported per run

dashboard output
┌──────────────────────────────┐
 ✅ Execution Summary         
├──────────────────────────────┤
 Duration: 13.9s  Steps: 7    
 Tokens:  1,963  Cost: ~$0.003
└──────────────────────────────┘

📊 Execution Timeline
├─ [bootstrap]   100ms 
├─ [guardrail]    50ms 
├─ [think]    10,001ms ⚠️ 7 iter
├─ [act]       1,000ms  2 tools
└─ [complete]     28ms 
🛡️

Prompt Injection Detection

Blocks injection attacks with configurable threshold scoring

🔏

PII & Toxicity Scrubbing

Auto-detects sensitive data and toxic content before LLM ingestion

Kill Switch

Pause, resume, or terminate any running agent with zero state corruption

📋

Behavioral Contracts

Tool deny lists, iteration caps, and output pattern enforcement

💰

Budget Enforcement

Per-request, daily, monthly cost caps — auto-halts before overspend

Approval Gates

Human-in-the-loop confirmation for high-risk tool execution

safety config
.withGuardrails({
  injectionThreshold: 0.8,
  piiThreshold:       0.9,
  toxicityThreshold:  0.7,
})
.withKillSwitch()
.withBehavioralContracts({
  toolDenyList: ["shell-execute"],
  maxIterations: 20,
})
.withCostTracking({
  budget: { perRequest: 0.10 },
})
🌊

Token Streaming

AsyncGenerator with TextDelta, IterationProgress, and SSE adapter

🤖

Persistent Gateway

24/7 agent harness with crons, webhooks, adaptive heartbeats

🔗

A2A Protocol

Agent-to-agent JSON-RPC 2.0 with SSE streaming and Agent Cards

🧪

Hallucination Detection

Semantic entropy + fact decomposition verification layer

💬

Chat Sessions

Multi-turn conversation with adaptive routing and persistent memory

🔁

Error Recovery

Retry policies, global error handler, clean FiberFailure unwrapping

streaming
for await (const e of
  agent.runStream(task, {
    signal: ctrl.signal,
  })) {
  if (e._tag === "TextDelta")
    write(e.text);
  if (e._tag === "IterationProgress")
    log(e.iteration, e.maxIterations);
}
⚛️

React Hooks

useAgentStream + useAgent — token streaming and one-shot calls from any React component

💚

Vue Composables

useAgentStream + useAgent with reactive refs — drop into any Vue 3 component

🧡

Svelte Stores

createAgentStream writable store — reactive $agent.text, $agent.status out of the box

🌊

One-Line SSE Endpoint

AgentStream.toSSE() returns a standard Response — works with Next.js App Router, SvelteKit, Nuxt, Bun

60s to First Agent

One install, three lines, full observability dashboard — then layer in capabilities as you need them

🛠️

rax CLI + 3,472 Tests

Scaffold, run, inspect — 25 modular packages, battle-tested across 409 test files

rax cli
# scaffold a new project
$ rax init my-agent \
    --template standard

# run with cloud provider
$ rax run "Analyze codebase" \
    --provider anthropic

# run local — zero API cost
$ rax run "Summarize logs" \
    --provider ollama \
    --model qwen3:14b
🔭

Beacon Agent Grid

Live grid of all connected agents with real-time cognitive state and entropy status

📈

Entropy Signal Charts

D3-powered entropy trajectory: watch reasoning quality converge, plateau, or diverge in real time

🧵

Step-by-Step Trace Panel

Full Thought → Action → Observation breakdown per iteration, live-streamed or replayed from SQLite

📋

Debrief Summaries

Structured post-run cards: task, plan, outcome, sources, confidence score, and agent self-critique

💬

Interactive Chat

Multi-turn conversational sessions tied to agent runs — same context, persistent history

🔬

Lab: Visual Builder

Configure and launch agents without code — skills browser, tool workshop, gateway agent manager

cortex studio
# Terminal 1: start studio (from repo)
$ bun cortex
UI → http://localhost:5173

# Terminal 2: connect agent
$ rax run "Analyze codebase" \
    --provider anthropic \
    --cortex

// or in code:
.withCortex()  // one line
// URL: CORTEX_URL env → localhost:4321

Pick the path that matches where you are.

Shape any agent signal — system prompts, tool results, nudges, lifecycle events — with the declarative .compose() API. One line enables full OpenTelemetry export. Six prebuilt killswitches ship in the box.

Compose API Reference · Tag Catalog · 9 Recipes

Flight Recorder — Snapshot, Replay & Diagnose

Section titled “Flight Recorder — Snapshot, Replay & Diagnose”

Every run is a recording. Re-run any recorded trace deterministically with prompt or model overrides — tool results held constant — so you can prove what your agent did and why, then bisect a regression against the exact same inputs. rax-diagnose reads the structured trace and root-causes failures from data, not log-spelunking. Local-first and RA-native: the receipts live with you, not in a vendor’s funnel.

Snapshot & Replay · rax CLI

Terminal window
npm create reactive-agent my-agent
# or bun create reactive-agent my-agent

Interactive prompts guide you through template (minimal, with-tools, streaming), provider (anthropic, openai, google, groq, xai, ollama), and package manager. Pass --yes for zero-prompt CI scaffolding.

create-reactive-agent

12-phase lifecycle · phases marked run inside the loop body

01

bootstrap

Load context, semantic + episodic memory

02

guardrail

Block injection, PII, toxicity pre-LLM

03

cost-route

Pick cheapest capable model tier

04

strategy-select

ReAct · Reflexion · Plan-Execute · ToT

05

think

LLM reasoning step (one of N iterations)

06

act

Tool execution + healing pipeline

07

observe

Append tool results, curate context

08

verify

Entropy, fact decomposition, NLI check

09

memory-flush

Persist session, episodic, procedural

10

cost-track

Record spend, enforce budget

11

audit

Emit audit events for compliance

12

complete

Build AgentResult with full metadata

See full installation guide →