---
title: Reactive Agents
description: A TypeScript framework for building LLM agents on Effect-TS — typed, observable, and composable, with the same code running on local and frontier models.
template: splash
hero:
    tagline: '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.'
    image:
        file: ../../assets/logo-dark.svg
    actions:
        - text: Get Started
          link: guides/quickstart/
          icon: right-arrow
          variant: primary
        - text: "⭐ Star on GitHub"
          link: https://github.com/tylerjrbuell/reactive-agents-ts
          icon: external
          variant: secondary
---

import {
    Card,
    CardGrid,
    LinkCard,
    Tabs,
    TabItem,
} from '@astrojs/starlight/components'
import HeroInteraction from '../../components/HeroInteraction.astro'
import EmailSubscribe from '../../components/EmailSubscribe.astro'
import TerminalReplay from '../../components/TerminalReplay.astro'
import FeatureCarousel from '../../components/FeatureCarousel.astro'
import ScrollReveal from '../../components/ScrollReveal.astro'
import metrics from '../../data/metrics.json'
import demoGif from '../../assets/local-vs-frontier.gif'

{/*
  Scroll-reveal scripts (both the inline FOUC-prevention class signal
  AND the bundled IntersectionObserver) live in ScrollReveal.astro so
  MDX doesn't mangle script contents with smart quotes or <p> wrapping.
*/}
{/*
  GitHub star count is fetched client-side and injected into both this
  hero button and the sidebar CTA by HeroStarBadge, rendered globally
  from PageSidebar.astro (Starlight's sidebar override, present on
  every page including this one) — no separate import needed here.
*/}
<ScrollReveal />

{/*
  All numeric stats below are auto-generated at build time by
  scripts/generate-metrics.ts (runs as `prebuild`). Counts are derived
  from filesystem (packages, apps, test files), parsed TypeScript source
  (LifecyclePhase enum), or read from metrics-cache.json (test count
  refreshed by CI). Never hardcode a literal here — edit the script.
*/}

<div class="ra-panel ra-stats-panel">
    <div class="ra-panel-inner ra-stats">
        <div class="ra-stat">
            <span class="ra-stat-value">{metrics.grandTotal}</span>
            <span class="ra-stat-label">Packages & Apps</span>
        </div>
        <div class="ra-stat">
            <span class="ra-stat-value">{metrics.tests.toLocaleString()}</span>
            <span class="ra-stat-label">Tests</span>
        </div>
        <div class="ra-stat">
            <span class="ra-stat-value">{metrics.providers}</span>
            <span class="ra-stat-label">LLM Providers</span>
        </div>
        <div class="ra-stat">
            <span class="ra-stat-value">{metrics.strategies}</span>
            <span class="ra-stat-label">Reasoning Strategies</span>
        </div>
        <div class="ra-stat">
            <span class="ra-stat-value">{metrics.phases}</span>
            <span class="ra-stat-label">Execution Phases</span>
        </div>
    </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner" style="text-align:center">

## Reliable on every model tier

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.

<img
  src={demoGif.src}
  alt="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"
  loading="lazy"
  style="border-radius:12px;max-width:100%;box-shadow:0 10px 50px rgba(124,58,237,0.3)"
/>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Start in 60 Seconds

```bash
bun add reactive-agents
```

```typescript
import { ReactiveAgents } from 'reactive-agents'

const agent = await ReactiveAgents.create()
    .withProvider('anthropic')
    .withReasoning() // ReAct loop: Think → Act → Observe
    .withTools() // Built-in: web-search, file-read, code-execute
    .withObservability()
    .build()

const result = await agent.run('Find the top 3 TypeScript testing frameworks')
console.log(result.output)
```

One package. Composable layers. Enable exactly what you need — skip everything you don't.

<TerminalReplay />

  </div>
</div>

<EmailSubscribe />

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## New in v0.12

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

<div class="ra-v12-cards">
<CardGrid>
    <Card title="Typed Structured Output" icon="seti:typescript">
        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 →](/guides/structured-output/)
    </Card>
    <Card title="Durable Execution" icon="setting">
        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 →](/guides/durable-execution/)
    </Card>
</CardGrid>
</div>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## 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. On our 35-task benchmark, a bare ReAct loop (an LLM in a `while` with tools) reaches **85%**. The same models inside this harness reach **100%**. That difference is everything that isn't the loop itself:

- 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:

<CardGrid>
    <Card title="Build it yourself" icon="warning">
        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.
    </Card>
    <Card title="Use a black-box harness" icon="warning">
        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.
    </Card>
</CardGrid>

<div class="ra-harness-pick">
    <Card title="Use a transparent harness ← Reactive Agents" icon="approve-check">
        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](/reference/stability/)). No hidden prompts, no
        proprietary loop.
    </Card>
</div>

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.

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## What You Get Out of the Box

<p class="ra-lab-meta">
    Built-in capabilities measured on real workloads — no extra wiring required.
</p>

<div class="ra-lab-grid">
    <div class="ra-readout">
        <p class="ra-readout-label">Self-healing tool calls</p>
        <p class="ra-readout-value">
            +80<span class="unit">pp accuracy</span>
        </p>
        <span class="ra-readout-mark">fires on every tool call</span>
        <ul class="ra-readout-rows">
            <li class="ok">
                <span>Recovers from</span>
                <b>86.7%</b>
            </li>
            <li class="ok">
                <span>Cheaper than LLM reprompt</span>
                <b>10×</b>
            </li>
            <li>
                <span>Lifts local models most</span>
                <b>4B+ Ollama</b>
            </li>
        </ul>
    </div>
    <div class="ra-readout">
        <p class="ra-readout-label">Compact context on long runs</p>
        <p class="ra-readout-value">
            38.6<span class="unit">% tokens saved</span>
        </p>
        <span class="ra-readout-mark">runs every iteration</span>
        <ul class="ra-readout-rows">
            <li>
                <span>Context compression</span>
                <b>60.7%</b>
            </li>
            <li class="ok">
                <span>Per-step overhead</span>
                <b>0.16ms</b>
            </li>
            <li>
                <span>Aggressive mode</span>
                <b>44.1%</b>
            </li>
        </ul>
    </div>
    <div class="ra-readout">
        <p class="ra-readout-label">Secret-leak detection</p>
        <p class="ra-readout-value">
            100<span class="unit">% catch rate</span>
        </p>
        <span class="ra-readout-mark">scans every output</span>
        <ul class="ra-readout-rows">
            <li class="ok">
                <span>False positives</span>
                <b>0%</b>
            </li>
            <li class="ok">
                <span>Detection latency</span>
                <b>0.02ms</b>
            </li>
            <li>
                <span>Leak categories</span>
                <b>4 types</b>
            </li>
        </ul>
    </div>
    <div class="ra-readout">
        <p class="ra-readout-label">Guaranteed termination</p>
        <p class="ra-readout-value">
            12<span class="unit">/12 phases</span>
        </p>
        <span class="ra-readout-mark">single-owner termination</span>
        <ul class="ra-readout-rows">
            <li class="ok">
                <span>Stop paths covered</span>
                <b>100%</b>
            </li>
            <li class="ok">
                <span>Loop detector + iter cap</span>
                <b>built-in</b>
            </li>
            <li>
                <span>Enforced by</span>
                <b>CI</b>
            </li>
        </ul>
    </div>
</div>

<div class="ra-bench">
    <div class="ra-bench-label">
        <strong>Frontier Benchmark</strong>
        ra-full · 4 frontier models · Apr 30 2026 (W21)
    </div>
    <div class="ra-bench-bars">
        <div class="ra-bar">
            <span class="ra-bar-name">claude-sonnet-4-6</span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:100%"></span>
            </span>
            <span class="ra-bar-pct">100%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">claude-haiku-4-5</span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:100%"></span>
            </span>
            <span class="ra-bar-pct">100%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">gpt-4o-mini</span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:100%"></span>
            </span>
            <span class="ra-bar-pct">100%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">gemini-2.5-pro</span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:100%"></span>
            </span>
            <span class="ra-bar-pct">100%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">bare LLM (no harness)</span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill bare" style="width:85%"></span>
            </span>
            <span class="ra-bar-pct">85%</span>
        </div>
    </div>
</div>

<div class="ra-bench">
    <div class="ra-bench-label">
        <strong>Local Model Benchmark</strong>
        ra-full · same harness · 35-task suite (Apr 7 2026 baseline)
    </div>
    <div class="ra-bench-bars">
        <div class="ra-bar">
            <span class="ra-bar-name">
                gemma4:e4b<em> (local · 4 GB)</em>
            </span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:94%"></span>
            </span>
            <span class="ra-bar-pct">94%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">
                gemini-2.5-flash<em> (frontier ref)</em>
            </span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:94%"></span>
            </span>
            <span class="ra-bar-pct">94%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">
                cogito:14b<em> (local · 9 GB)</em>
            </span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:91%"></span>
            </span>
            <span class="ra-bar-pct">91%</span>
        </div>
        <div class="ra-bar">
            <span class="ra-bar-name">
                gpt-4o-mini<em> (frontier ref)</em>
            </span>
            <span class="ra-bar-track">
                <span class="ra-bar-fill" style="width:91%"></span>
            </span>
            <span class="ra-bar-pct">91%</span>
        </div>
    </div>
</div>

<p class="ra-bench-note">
    Local models tied with frontier on the same 35-task harness. The Healing
    Pipeline closes the gap that bare prompting can't: tool-call recovery for
    4B+ Ollama lifts accuracy by <b>+80pp</b> on FC-heavy tasks (6.7% → 86.7%).
    Same agent code, same builder chain — just{' '}
    <code>.withProvider("ollama")</code>.
</p>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Why Reactive Agents?

<CardGrid stagger>
    <Card title="Type-Safe from End to End" icon="seti:typescript">
        **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. **{metrics.tests.toLocaleString()} tests** keep
        every service boundary honest on every PR.
    </Card>
    <Card title="Composable Layer Architecture" icon="puzzle">
        **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.
    </Card>
    <Card title="Observable Execution Engine" icon="magnifier">
        **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.
    </Card>
    <Card title="Reasoning, Honestly Scoped" icon="star">
        **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.
    </Card>
    <Card title="Reliable on Local Models" icon="setting">
        **+80pp accuracy** on Ollama 4B+ vs. naive prompting. The 4-stage
        Healing Pipeline recovers from **86.7% of tool-call errors** — 90%
        cheaper than LLM reprompt. Model-adaptive context tunes prompts and
        compaction per tier. Same code, frontier-to-local.
    </Card>
    <Card title="MCP-Native Tool I/O" icon="puzzle">
        **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.
    </Card>
    <Card title="Skills as a Primitive" icon="open-book">
        **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 &rarr;](/guides/agent-skills/)
    </Card>
    <Card title="Frontier-Verified" icon="approve-check">
        **100% pass on `ra-full`** across `claude-sonnet-4-6`,
        `claude-haiku-4-5`, `gpt-4o-mini`, and `gemini-2.5-pro` (Apr 30 2026).
        Bare LLM only achieves 85% on the same harness — a measurable lift from
        the framework, not the model.
    </Card>
    <Card title="Developer Experience" icon="rocket">
        **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.
    </Card>
    <Card title="Cortex Local Studio" icon="laptop">
        **`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()`.
    </Card>
</CardGrid>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## How It's Different

<CardGrid>
    <Card title="vs. LangChain / LlamaIndex" icon="document">
        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.
    </Card>
    <Card title="vs. Vercel AI SDK" icon="document">
        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.
    </Card>
    <Card title="vs. AutoGen / CrewAI" icon="document">
        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 lifts local-model accuracy by +80pp** —
        and A2A (JSON-RPC + SSE) ready when you actually need fan-out.
    </Card>
    <Card title="vs. Building From Scratch" icon="document">
        **{metrics.grandTotal} production-ready packages, {metrics.tests.toLocaleString()} tests, {metrics.phases}-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.
    </Card>
</CardGrid>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Common Patterns

<Tabs>
  <TabItem label="Streaming">
```typescript
// 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")) });

````
  </TabItem>
  <TabItem label="Chat Sessions">
```typescript
// Multi-turn conversation with memory
const session = agent.session();

await session.chat("What's the capital of France?");
// → "Paris is the capital of France."

await session.chat("What's the population?");
// → "Paris has approximately 2.1 million residents..."
// (remembers context from previous turn)
````

  </TabItem>
  <TabItem label="Persistent Gateway">
```typescript
// Autonomous agent that runs 24/7
const agent = await ReactiveAgents.create()
  .withProvider("anthropic")
  .withReasoning()
  .withTools()
  .withGateway({
    heartbeat: { intervalMs: 3_600_000, policy: "adaptive" },
    crons: [{ schedule: "0 9 * * MON", instruction: "Weekly report" }],
    webhooks: [{ path: "/github", adapter: "github" }],
    policies: { dailyTokenBudget: 50_000 },
  })
  .build();

agent.start(); // Runs forever, Ctrl+C to stop

```
  </TabItem>
</Tabs>

  </div>
</div>

<FeatureCarousel />

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Next steps

Pick the path that matches where you are.

<CardGrid>
    <LinkCard
        title="Build something fast"
        description="Zero to working agent in 5 minutes — copy-paste ready"
        href="guides/quickstart/"
    />
    <LinkCard
        title="Browse 30+ examples"
        description="Runnable across 11 categories: tools, memory, multi-agent, gateway, streaming, more"
        href="guides/examples/"
    />
    <LinkCard
        title="One-page API cheatsheet"
        description="Every important builder method, runtime call, and event tag — on one page"
        href="reference/cheatsheet/"
    />
    <LinkCard
        title="Should I use this? (FAQ)"
        description="Production readiness, honest caveats, comparisons vs LangChain / AI SDK / AutoGen, what's not done yet."
        href="guides/faq/"
    />
    <LinkCard
        title="Migrating from LangChain"
        description="Side-by-side mapping of LangChain concepts to Reactive Agents"
        href="guides/migrating-from-langchain/"
    />
    <LinkCard
        title="Choosing your stack"
        description="Pick provider · model tier · memory · reasoning strategy in 2 minutes"
        href="guides/choosing-a-stack/"
    />
    <LinkCard
        title="Deploy to production"
        description="Observability, cost controls, guardrails, and the full checklist"
        href="guides/production-checklist/"
    />
</CardGrid>

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Compose API

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](/reference/compose-api) · [Tag Catalog](/reference/harness-tags) · [9 Recipes](/cookbook/composition-recipes)

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## 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](/features/snapshot-replay) · [rax CLI](/reference/cli)

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Scaffold a Project in Seconds

```bash
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](/features/create-reactive-agent)

  </div>
</div>

<div class="ra-section-card ra-panel">
  <div class="ra-panel-inner">

## Architecture at a Glance

<p class="ra-flow-legend">12-phase lifecycle · phases marked <span>↻ </span>run inside the loop body</p>

<div class="ra-flow-grid">
  <div class="ra-phase">
    <span class="ra-phase-num">01</span>
    <div class="ra-phase-body"><p class="ra-phase-name">bootstrap</p><p class="ra-phase-desc">Load context, semantic + episodic memory</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">02</span>
    <div class="ra-phase-body"><p class="ra-phase-name">guardrail</p><p class="ra-phase-desc">Block injection, PII, toxicity pre-LLM</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">03</span>
    <div class="ra-phase-body"><p class="ra-phase-name">cost-route</p><p class="ra-phase-desc">Pick cheapest capable model tier</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">04</span>
    <div class="ra-phase-body"><p class="ra-phase-name">strategy-select</p><p class="ra-phase-desc">ReAct · Reflexion · Plan-Execute · ToT</p></div>
  </div>
  <div class="ra-phase" data-loop="1">
    <span class="ra-phase-num">05</span>
    <div class="ra-phase-body"><p class="ra-phase-name">think</p><p class="ra-phase-desc">LLM reasoning step (one of N iterations)</p></div>
  </div>
  <div class="ra-phase" data-loop="1">
    <span class="ra-phase-num">06</span>
    <div class="ra-phase-body"><p class="ra-phase-name">act</p><p class="ra-phase-desc">Tool execution + healing pipeline</p></div>
  </div>
  <div class="ra-phase" data-loop="1">
    <span class="ra-phase-num">07</span>
    <div class="ra-phase-body"><p class="ra-phase-name">observe</p><p class="ra-phase-desc">Append tool results, curate context</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">08</span>
    <div class="ra-phase-body"><p class="ra-phase-name">verify</p><p class="ra-phase-desc">Entropy, fact decomposition, NLI check</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">09</span>
    <div class="ra-phase-body"><p class="ra-phase-name">memory-flush</p><p class="ra-phase-desc">Persist session, episodic, procedural</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">10</span>
    <div class="ra-phase-body"><p class="ra-phase-name">cost-track</p><p class="ra-phase-desc">Record spend, enforce budget</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">11</span>
    <div class="ra-phase-body"><p class="ra-phase-name">audit</p><p class="ra-phase-desc">Emit audit events for compliance</p></div>
  </div>
  <div class="ra-phase">
    <span class="ra-phase-num">12</span>
    <div class="ra-phase-body"><p class="ra-phase-name">complete</p><p class="ra-phase-desc">Build AgentResult with full metadata</p></div>
  </div>
</div>

[See full installation guide &rarr;](guides/installation/)

  </div>
</div>

<HeroInteraction />
