---
title: What's New
description: Latest features and changes to Reactive Agents across recent releases
sidebar:
  order: 2
---

import { Aside } from '@astrojs/starlight/components';
import metrics from '../../../data/metrics.json';

<Aside type="tip" title="Subscribe">
Get release highlights as an RSS feed: [`/rss.xml`](/rss.xml). Drop into NetNewsWire, Inoreader, or any feed reader.
</Aside>

A quick-scan guide to what has landed in each major release. Start here when returning after time away — each bullet links to the relevant documentation.

---

## v0.13.5 — Groq, xAI & the Agentic UI Kit (July 2026)

<Aside type="tip" title="Released on npm">
Shipped July 2026 — all {metrics.packagesTotal} packages are published. Install or upgrade with `bunx create-reactive-agent` or pin `reactive-agents@0.13.5`.
</Aside>

Two new providers, a headless UI-controller package that unifies the React, Svelte, and Vue bindings, a durable request-for-input rail in Cortex, and honest error surfacing.

### Groq and xAI providers

Both wire through a shared `makeOpenAICompatProvider` factory, so they inherit the full OpenAI-compatible stack — streaming, native function calling, structured output — with no bespoke adapter.

```typescript
ReactiveAgents.create().withProvider("groq").withModel("llama-3.3-70b-versatile").build();
ReactiveAgents.create().withProvider("xai").withModel("grok-4").build();
```

Both are live-verified end to end (plain completion + native tool-call round-trips). Logprobs and embeddings are capability-gated (neither provider exposes them); structured output on Groq is model-dependent (`json_schema` strict on `gpt-oss` and some models, `json_object` elsewhere), with the parse-retry loop covering the gap. The selectable-provider count is now **{metrics.providers}**. See [LLM Providers](/features/llm-providers/).

### Agentic UI Kit — `@reactive-agents/ui-core`

A new framework-agnostic headless package holds the shared controllers behind every UI binding: a progressive UI-tree reconciler, a task-inbox fetch controller, and interaction + approval POST controllers. React, Svelte, and Vue now delegate to these instead of each re-implementing the wire protocol.

- **React** — rewired onto `ui-core` with a core `useRun` hook and the full v1 family surface: Interact (`AgentPrompt`/`ChoiceCard`), Inbox (`useTaskInbox`/`TaskInbox`), Observe (`useRunCost`/`useRunSteps`, `CostMeter`/`StepTimeline`), Render (`AgentSurface` registry + UI-tree schema), plus `useResumableRun` and an `AgentDevtools` overlay with `testing`/`styles` subpaths.
- **Svelte** and **Vue** — rewired onto the same controllers (`createRun`, `createInteractions`, `createResumableRun`, run cost/steps), with `requestInit`/header pass-through restored on structured streams.

### Cortex `request_user_input` rail

Cortex gains a durable request-for-input rail — runner methods plus a `.withInteraction(...)` surface, an interaction-watcher, and a real pause → register → respond → resume flow. The Cortex UI renders a live Interact panel and streaming structured previews.

### Honest run errors

Reasoning failures now propagate the real error string to `result.error` end to end. Previously the kernel captured the message in `state.error`, but `normalizeReasoningResult` dropped it during its whitelist rebuild, so callers only saw a generic `"Reasoning failed"`. A bad model id now surfaces `"…404 The model … does not exist"` on `result.error`.

---

## v0.13.0 — Receipts & first-touch (July 2026)

<Aside type="tip" title="Released on npm">
Shipped July 2026 — all 35 packages are published. Install or upgrade with `bunx create-reactive-agent` or pin `reactive-agents@0.13.0`.
</Aside>

The v0.13 line is about **receipts and first-touch**: native reasoning on every provider, cost-aware routing, an overhauled first-ten-minutes developer experience, honest abstention as a first-class terminal, a new efficiency-first Blueprint strategy, two token-waste guards, and a broad correctness sweep across providers and the kernel.

### Native thinking on every provider

`.withThinking(...)` turns on native reasoning across Anthropic, OpenAI, Gemini, and local models from one builder switch — pass `true` or `{ effort, budgetTokens }`. It is **off by default everywhere**: `undefined` never auto-enables (this also flips Gemini's former thinks-by-default behavior off). Budgets are bounded and reserved _on top_ of the answer budget, so hidden reasoning can never starve the visible answer.

```typescript
ReactiveAgents.create()
  .withProvider("anthropic").withModel("claude-sonnet-4-6")
  .withThinking({ effort: "medium" })
  .build();
```

See [Builder API](/reference/builder-api/).

### Cost-aware model routing

`.withModelRouting()` (opt-in, off by default) routes each run to the **cheapest _capable_ model** of your configured provider, picked by task complexity — on both the inline and reasoning paths. It stays within the provider's tiers (a `cheap → mid → expensive` ladder mapped to that provider's models, so it's provider-agnostic), is **capability-gated** (never drops below a model whose context window fits the prompt), and is **advisory** (degrades to your configured model on any error — it can only make a run cheaper, never break it). See [Cost-Aware Model Routing](/features/cost-tracking/#cost-aware-model-routing).

```typescript
ReactiveAgents.create()
  .withProvider("anthropic").withModel("claude-sonnet-4-6")
  .withModelRouting()   // simple tasks drop to the haiku tier
  .build();
```

### First-touch developer experience

The first ten minutes are re-paved:

- **Typed tool authoring** — `defineTool({ name, description, input, handler })` takes a Standard Schema input (Zod, Effect, Valibot) and gives the plain-async handler **inferred argument types** — no `Record<string, unknown>` or `as never` casts. It also validates its own options and rejects wrong field names (e.g. `parameters`/`execute`) with a message naming the correct field instead of crashing. See [Tools](/guides/tools/).
- **`ReactiveAgents.quick()`** — a two-line agent that resolves provider, model, and iteration defaults from the environment: `const agent = await ReactiveAgents.quick(); await agent.run("…")`. See [Quickstart](/guides/quickstart/).
- **Fail-fast `build()`** — `.withStrictValidation()` catches a missing API key or unknown model at build time with a typed error and fix instructions, instead of a raw 401/404 on the first call.
- **Per-LLM-call timeout** — `.withLlmTimeout(ms)` configures the local/Ollama per-call timeout (previously hardcoded at 120s); timeout errors name the model, elapsed time, and a cold-load/GPU-contention hint, and the in-flight local request is aborted server-side. See [Local Models](/guides/local-models/).

### Honest abstention — a run that cannot succeed says so

When a task is structurally impossible (a required tool is unavailable, or synthesis is repeatedly ungrounded), the run terminates with `terminatedBy: "abstained"` and a typed `result.abstention { reason, missing }` instead of fabricating an answer. This is harness-forced, not model-initiated. See [Structured Output](/guides/structured-output/).

### Blueprint strategy — plan once, execute in parallel

For static, decomposable tasks the whole plan is knowable up front. **Blueprint** (the 7th reasoning strategy) generates a plan, verifies it, executes independent steps in parallel **with no per-step LLM call**, then solves. Adaptive routing sends static-decomposable tasks to Blueprint automatically. See [Choosing Strategies](/guides/choosing-strategies/).

### Two token-waste guards

- **`.withStallPolicy(...)`** — when the model ignores required-tool nudges and makes no progress across consecutive iterations, the harness escalates and delivers accumulated artifacts (or fails) instead of looping to the full nudge cap — bounding wasted tokens on stuck runs while leaving progressing runs untouched.
- **`.withFabricationGuard(mode)`** — an always-on verifier check (default `"block"`) that rejects empirical performance numbers (benchmark timings, %-speedups) absent from the tool-observation corpus. High-precision — only perf measurements are policed. Soften to `"warn"`/`"off"` or via the `RA_FABRICATION_GUARD` env var.

See [Builder API](/reference/builder-api/).

### Evaluation gate CLI

`rax eval gate` runs the project lift rule over a benchmark report (`default-on | opt-in | reject`); `--ledger` appends a weakness→hypothesis→verdict chain and `rax eval ledger` reads it. Benchmark runs capture a per-run `RunDiagnosis` (honesty label, failure modes) when a trace dir is set. See [Eval](/features/eval/).

### Correctness sweep

Highlights from a broad provider + kernel fix pass:

- **gpt-5.x non-thinking calls work** — the OpenAI adapter now picks the token-limit field by capability (`max_completion_tokens` for gpt-5.x/o-series, `max_tokens` for the gpt-4o family), fixing a 400 on default gpt-5.x calls.
- **Thinking request shapes verified live** — Anthropic uses the adaptive shape on current-generation models and legacy `budget_tokens` on older ones; `temperature` is dropped when thinking is on (both Anthropic and OpenAI reject it otherwise).
- **`withRetryPolicy` retries the real path** — it previously wrapped only `complete()`; the reactive kernel runs through `stream()` / `completeStructured()`, so transient failures were never retried. All three call sites are now retried.
- **`withMinIterations(N)` enforces the full floor** — previously a lone `if` forced a single extra pass regardless of `N`; it now loops to the configured minimum.
- **Cross-provider tool-call arguments are never dropped** — string-encoded JSON args (some Ollama models) are now coerced instead of silently reset to `{}`.
- **Readable provider errors** — a model typo produces one clean error line with a suggestion instead of duplicated raw JSON and an internal stack.
- **Configured-off phases stay off** — `runGuardedPhase` now honors `phase.skip`, so disabled phases don't run via direct callers.
- **Context & structured-output correctness** — string-safe JSON repair, mid-thread user instructions kept over budget, boundary-matched + nested field provenance, duplicate-tool-name warnings, and a gated (O(N²)-removed) streaming reparse.

The `withVerificationStep({ mode: "loop" })` option (documented but unimplemented) was removed; `"reflect"` is the only supported mode.

See the [full 0.13.0 changelog](https://github.com/tylerjrbuell/reactive-agents-ts/blob/main/CHANGELOG.md) for the complete list.

---

## v0.12.0 — Durable & Honest (June 2026)

<Aside type="tip" title="Released on npm">
Shipped June 2026 — all packages are published. Install or upgrade with `bunx create-reactive-agent` or pin `reactive-agents@0.12.0`.
</Aside>

The v0.12 line makes runs **survive crashes**, makes outputs **typed and grounded**, and makes "which capabilities are on" **explicit and honest**. Headline capabilities: typed structured output, durable execution, and `HarnessProfile` composition — plus a developer-experience pass that removes Effect from the common builder surface.

### Typed Structured Output

Turn any agent into a typed extractor. Attach a schema at build time and read a fully-typed value off the result — no prompt engineering, no manual JSON parsing.

```ts
import { z } from "zod";

const Invoice = z.object({ total: z.number(), currency: z.string() });

const agent = await ReactiveAgents.create()
  .withModel({ provider: "anthropic", model: "claude-sonnet-4-6" })
  .withOutputSchema(Invoice)   // builder-only
  .build();

const result = await agent.run("Extract the invoice: total $4,200 USD");
result.object;       // { total: 4200, currency: "USD" } — typed as { total: number; currency: string }
result.objectError;  // populated instead (lenient) if the model's output didn't validate
```

- **Any Standard Schema** — Zod, Valibot, ArkType, and Effect Schema all work through one adapter; JSON Schema is derived per-vendor so the model is never blind to the shape.
- **Streaming** — `agent.streamObject(task)` yields `{ object: DeepPartial<T> }` as fields fill in.
- **Grounded mode** — `.withOutputSchema(schema, { mode: "grounded" })` runs extraction inside the loop with provenance, confidence, and abstention instead of guessing.
- **Top-level arrays, lenient-degrade** — array schemas and partial outputs are handled gracefully; parse failures surface on `result.objectError` rather than throwing (configurable via `{ onParseFail: "throw" }`).

Verified live across Anthropic, OpenAI, Gemini, and local Ollama (qwen3.5, gemma4). See [Typed Structured Output](/guides/structured-output/).

### Durable Execution — crash-resume

Opt a run into a durable store and resume it from its last checkpoint after a crash, restart, or graceful pause.

```ts
const agent = await ReactiveAgents.create()
  .withModel({ provider: "anthropic", model: "claude-sonnet-4-6" })
  .withDurableRuns()
  .build();

const runs = await agent.listRuns({ status: "running" });   // discover interrupted runs
const result = await agent.resumeRun(runs[0].runId);        // continue from last checkpoint
```

Run state is persisted on a content-addressed config hash (system prompt + provider), so a resumed run reattaches to the correct configuration. Verified cross-process with a hard-kill end-to-end test. See [Durable Execution](/guides/durable-execution/).

### Durable human-in-the-loop — approval gates that survive process death

Name the tool calls that require sign-off. A gated call **pauses** the run — on
**both** `run()` and `runStream()` — persists `awaiting-approval` plus the pending
action, and returns `pendingApproval` so the process can exit. A human approves or
denies from **any** process; the run resumes from its checkpoint to completion.

```ts
const agent = await ReactiveAgents.create()
  .withModel({ provider: "anthropic", model: "claude-sonnet-4-6" })
  .withDurableRuns()
  .withApprovalPolicy({ tools: ["shell-execution", "file-write"], mode: "detach" })
  .build();

// 1. A gated call pauses and returns status: "awaiting-approval".
const result = await agent.run("clean up the temp files");
if (result.status === "awaiting-approval") {
  console.log("awaiting approval:", result.pendingApproval.toolName);
}

// 2. Later, from ANY process — decide on whatever is waiting:
for (const p of await agent.listPendingApprovals()) {
  await agent.approveRun(p.runId);          // resume + execute the call
  // or: await agent.denyRun(p.runId, "not allowed");  // resume, skip the call
}
```

Need same-process convenience? Pass `onApproval` and one `run()` call drives the
whole pause → decide → resume loop:

```ts
const result = await agent.run("clean up the temp files", {
  onApproval: ({ toolName, args }) => toolName !== "shell-execution",
});
```

Built on the same durable RunStore as crash-resume — the decision and the paused
checkpoint live in SQLite, so approve/deny works across process and machine
boundaries. See [Durable Human-in-the-Loop](/guides/durable-hitl/).

### Developer experience — Effect-free where it counts

- **Plain-function hooks** — `.withHook()` handlers now accept ordinary sync/async functions; the Effect form still works. No `Effect.gen` required to tap the lifecycle. See [Lifecycle Hooks](/guides/hooks/).
- **Faster `run()`** — the post-answer debrief LLM call was moved off the critical path (forked, non-blocking), cutting end-to-end `run()` latency ~46%. Rich debrief is awaited lazily via `result.debriefRich()`.

### Opt-in evidence grounding

`.withGrounding({ mode })` makes numeric grounding explicit (default **off**), eliminating false "failed at evidence-grounded" warnings on correct figures. Blocking mode does a bounded retry then degrades — it never hard-fails a correct answer. See [Verification](/features/verification/).

### HarnessProfile presets — one-line capability composition

`HarnessProfile` replaces the leaky `.withLeanHarness()` with three named, explicit presets applied via `.withProfile()`:

```ts
import { ReactiveAgents, HarnessProfile } from 'reactive-agents'

const agent = await ReactiveAgents.create()
  .withProvider('anthropic')
  .withProfile(HarnessProfile.balanced())   // canonical entry
  .build()
```

| Preset | Composes |
|--------|----------|
| `HarnessProfile.lean()` | **Disables everything**: memory plus the three registry-default capabilities (reactive intelligence, verifier, strategy switching) + skill persistence. The model is the entire harness — for latency/cost-sensitive paths and benchmark ablations. Fixes the historical `.withLeanHarness()` leak that left reactive intelligence on. |
| `HarnessProfile.balanced()` | The full production stack: reactive intelligence + verifier + strategy switching (registry defaults) **plus memory, enabled explicitly** (memory is off in a bare builder as of v0.12). |
| `HarnessProfile.intelligent()` | Balanced **+ skill persistence** for cross-session compounding learning. |

Presets compose with individual builder methods — later calls win, so `.withProfile(HarnessProfile.balanced()).withoutMemory()` drops memory back off. See [Choosing a Stack](/guides/choosing-a-stack/) and [Builder API](/reference/builder-api/).

### New builder methods

- **`.withBudget({ tokenLimit?, costLimit? })`** — hard cumulative token/cost ceiling enforced inside the loop (a killswitch, distinct from `.withCostTracking()` accounting). See [Builder API](/reference/builder-api/).
- **`.withContract(taskContract)`** — declare a [`TaskContract`](/reference/builder-api/): required + forbidden tools, fixtures, a minimum model floor, and a success oracle. Required tools become an execute-time gate; forbidden tools are excluded from the tool schema. Enforced at `build()`.
- **`.withLearning({ tier?, dbPath? })`** — enable the cross-run learning store (experience + skill learning).
- **`.withSkillPersistence(enabled?)`** — persist learned `SkillRecord`s across process restarts (also enabled by `HarnessProfile.intelligent()`).

### Capability-source honesty gate

When an agent builds for a `(provider, model)` whose capability profile resolves to a silent **`fallback`** source (no probe, cache, or static-table entry → an assumed 2048-token context), `build()` now surfaces it: a **loud warning by default**, or a hard **error under `.withStrictValidation()`**. This catches the misconfigured-context class of failures at build time for every user instead of silently running on a wrong budget. See [Troubleshooting](/guides/troubleshooting/).

### Behavior changes

- **Memory is now OFF by default** (reversing the v0.11 GH #122 default-on). A bare `.create()….build()` is **stateless** — no surprise `~/.reactive-agents/<agentId>/` SQLite writes, predictable in CI. Opt in with one line: `.withMemory()`, `.withLearning()`, or `HarnessProfile.balanced()` / `.intelligent()` (all enable it explicitly). **Migration:** add `.withMemory()` to any v0.11 agent that relied on implicit cross-session memory.
- **`.withLeanHarness()` is superseded** by `HarnessProfile.lean()`, which additionally disables reactive intelligence (the old method did not). Existing chains keep working.

No breaking API removals — existing `ReactiveAgents.create().with*()` chains continue to compile and run; only the memory default changed (see migration note above).

---

## v0.11.x — Production tooling + full observability (May 2026)

The focus: developer tooling that makes agents production-observable and repeatable, plus the first `create-reactive-agent` scaffolder, cross-runtime support, and three new capabilities (`code-action` strategy, skill persistence, interactive playground).

### New packages

- **`@reactive-agents/observe`** — Zero-config OpenTelemetry tracing. Set `OTEL_EXPORTER_OTLP_ENDPOINT` and every run emits a workflow → LLM → tool span hierarchy, OpenInference-compliant, to any OTLP backend (Jaeger, Grafana Tempo, Langfuse, Arize Phoenix). See [OpenTelemetry Tracing](/features/observe/).
- **`@reactive-agents/replay`** — Deterministic trace replay. Record any run to a snapshot file and re-run it with a different model or prompt without calling the LLM again. Enables regression testing and prompt A/B comparisons. See [Snapshot & Replay](/features/snapshot-replay/).
- **`@reactive-agents/runtime-shim`** — Cross-runtime support. The framework now runs on Node.js 22.5+ in addition to Bun. Provides unified `Database`, `spawn`, `serve`, `glob`, `writeFile`, `readFile`, and `hash` primitives that delegate to the available runtime. FTS5 is optional — falls back to LIKE-based search on Node's built-in SQLite. Unblocks Stackblitz WebContainers (Node-only) and Vercel/Netlify deployments.

### New tooling

- **`create-reactive-agent` CLI** — `bunx create-reactive-agent my-app` scaffolds a runnable agent project in seconds. Supports `--template minimal|standard|tool-use|multi-agent|gateway`, `--provider`, `--model`, `--pm bun|npm|yarn|pnpm`. See [create-reactive-agent](/features/create-reactive-agent/).

### Interactive Playground

Three live Stackblitz scenarios, zero install. Runs fully in-browser via WebContainers — no local runtime required. Default provider is Google Gemini (free tier).

| Scenario | What it shows |
|----------|--------------|
| **Hello Agent** | Simple Q&A — minimal builder, one-step response |
| **Tool Integration** | Built-in `code-execute` + `scratchpad` tools working together |
| **Strategy Demo** | `reactive` vs `plan-execute-reflect` side-by-side on the same task |

See [Playground](/guides/playground/).

### `code-action` strategy (`@experimental`)

A 7th reasoning strategy in which the LLM generates a TypeScript IIFE that runs inside a Worker-thread sandbox. Tools are exposed as normal async functions and called via `postMessage` round-trips — no JSON schema juggling in the prompt. Best suited for multi-tool orchestration tasks where expressing control flow in code is cleaner than iterative tool calls.

Enable with `defaultStrategy: "code-action"`. `ToolService` is optional; the strategy also handles pure computation tasks. See [code-action](/features/code-action/).

### Skill persistence

Learned `SkillRecord` objects now survive process restarts. The skill system uses a dual-store: the existing in-memory session store for fast within-run access, plus a new SQLite-backed `SkillStore` that persists across runs. On cold start, skills are resolved from the persistent store before any LLM call. `skillFragmentToSkillRecord()` is exported from `reactive-agents` for manual skill construction.

### New runtime controls

- **`RunHandle`** — `runStream()` now returns a `RunHandle` with four controls and a status property:
  - `.pause()` — suspends the loop at the next safe checkpoint
  - `.resume()` — resumes a paused run
  - `.stop()` — graceful shutdown: finishes the current step, then runs output synthesis
  - `.terminate()` — immediate abort, skips synthesis
  - `.status` — `"running" | "paused" | "stopped" | "terminated" | "completed"`
  - `.result` — `Promise` that resolves when the run reaches a terminal state

  See [Compose API](/reference/compose-api/).

- **Killswitches** — Six factory functions from `@reactive-agents/compose` that wire stopping conditions into the agent loop. Pass them to `.compose()` or `.withHarness()`:

  ```ts
  import { maxIterations, budgetLimit, timeoutAfter, watchdog, requireApprovalFor } from "@reactive-agents/compose";
  ```

  | Factory | Stops when… |
  |---------|-------------|
  | `maxIterations(n)` | Loop count reaches `n` |
  | `budgetLimit({ maxTokens?, maxCostUSD? })` | Token or cost ceiling hit |
  | `timeoutAfter(duration)` | Wall-clock duration exceeded |
  | `watchdog({ timeout })` | No progress within `timeout` |
  | `requireApprovalFor(toolName, approver)` | Named tool needs human approval |

  See [Compose API](/reference/compose-api/).

- **Compose API** (`@stable`) — `.compose(fn)` (alias: `.withHarness(fn)`) attaches a harness transform that intercepts tagged chokepoints (`prompt.system`, `nudge.loop-detected`, `message.tool-result`, etc.) via `h.on()`, `h.tap()`, `h.before()`, `h.after()`, and `h.onError()`. Existing builder methods `.withSystemPrompt()`, `.withErrorHandler()`, and `.withHook()` now desugar through the harness. See [Compose API](/reference/compose-api/) and [Harness Tags](/reference/harness-tags/).

### Strategy switching on by default

`enableStrategySwitching` now defaults to `true`. The reactive intelligence dispatcher will switch strategies automatically when entropy signals a stuck loop — no explicit opt-in required.

### Decision tracing

Agents can capture the model's stated *why* for every tool call. Tool-call rationale on the reactive/adaptive paths is **opt-in** (audit feature, not performance — pure token/latency cost):

- **`auditRationale` opt-in** — `.withReasoning({ auditRationale: true })` (or env `RA_RATIONALE_AUDIT=1`). When on, the kernel coaxes one `<rationale call="N">{"why":"…","confidence":0-1}</rationale>` block per tool call. Off by default.
- **Native function-calling capture** — `parseRationaleBlocks()` reads side-channel blocks from `thought` + `thinking` content and attaches each rationale to the matching `ToolCallSpec` by position. The parser tolerates fenced/prose-wrapped JSON, over-length `why`, and repeated `call="N"` attributes, so capture is reliable on small local models.
- **plan-execute-reflect enforcement (always on)** — `LLMPlanStepSchema` carries a `rationale: { why, confidence? }` field, MANDATORY for every `tool_call` step (independent of `auditRationale`). Failures after retry emit a `plan_rationale_missing` metric — no synthetic fallback invented.
- **`AgentDebrief.rationale[]`** — Unified milestone-decision log: tool selections, curator decisions, strategy switches, reactive interventions, and terminations. All render in `debrief.markdown` under `## Decision Rationale`.

See [Decision Tracing](/concepts/decision-tracing/) for the full pipeline and [Debrief & Chat](/features/debrief-chat/) for the result shape.

### Context-window override (`numCtx`)

Pin the exact context window the provider receives instead of relying on the model's assumed maximum:

- **`.withModel({ model, numCtx })`** — `numCtx` maps to Ollama's `num_ctx`; cloud providers without a context-window knob ignore it. Now a first-class `AgentConfig` field, so it round-trips through `toConfig()` / `fromJSON()` and the config-driven path. See [Builder API](/reference/builder-api/) and [Local Models](/guides/local-models/).
- **Cortex Studio** — exposed as a **Context length (`numCtx`)** field in the Lab Builder's Inference section, and used as the authoritative denominator for the context-usage gauge.

### Cortex rich-trace debugger

The Cortex Run View's Trace Panel adds a **Timeline** view: a fine-grained, filterable, chronological event stream (LLM exchanges with prompt-cache %, tool calls, strategy switches, verifier verdicts, guards) grouped by iteration, reusing the same `TraceEvent` model as `rax diagnose`. The classic per-iteration **Frames** view remains a click away. See [Cortex](/features/cortex/).

---

## v0.10.x — Local models match frontier (May 2026)

The biggest release since v0.9 — `0.10.0` through `0.10.6`, shipped over four weeks. The headline: **local Ollama models now hit 91–94% on the same task suite as paid frontier APIs**, thanks to a closed-loop healing pipeline and adaptive tool-calling. Read the full [v0.10.0 changelog](https://github.com/tylerjrbuell/reactive-agents-ts/blob/main/CHANGELOG.md) for engineering detail.

### What you gain

#### Local models that actually work

- **Healing Pipeline** — 4-stage closed-loop recovery on every tool call (tool-name fuzzy match → parameter-name aliasing → path resolution → type coercion). **86.7% recovery rate, +80pp accuracy, 90% cheaper than LLM reprompt.** Ships on by default — see [LLM Providers](/features/llm-providers/) and [Resilience](/features/resilience/).
- **Adaptive tool calling** — Each model gets fingerprinted on first run; native FC capable models route through the JSON path, weaker ones through a 3-tier text-parse cascade (XML → JSON → pseudo-code). The framework learns each model's dialect after 5 runs and stops asking it to do things it can't.
- **Calibration system** — Per-model observations (parallel-call capability, classifier reliability, tool-call dialect) adapt empirically. Auto-enabled when `.withReasoning()` is on.
- **Frontier benchmark: 100% on `ra-full`** verified across `claude-sonnet-4-6`, `claude-haiku-4-5`, `gpt-4o-mini`, `gemini-2.5-pro`. Bare LLM only reaches 85% on the same suite.
- **Local benchmark: 91–94% on `ra-full`** for `gemma4:e4b` (4 GB) and `cogito:14b` (9 GB) — tied with `gemini-2.5-flash` and `gpt-4o-mini` on the same 35-task suite.

#### Long agent runs stay cheap

- **Three-stage context curation** — Tool results get compressed and stashed → curator renders only what's needed → optional reactive trim. **60.7% context reduction, 38.6% token savings, 0.16 ms overhead per step.** See [Intelligent Context Synthesis](/features/intelligent-context-synthesis/).
- **Reactive Intelligence dispatcher** — 6 corrective interventions fire automatically when an agent shows entropy signs (early-stop, temperature adjust, strategy switch, context compress, tool inject, skill activate). Suppression gates prevent runaway dispatch. See [Reactive Intelligence](/features/reactive-intelligence/).

#### Production safety hardened

- **`@reactive-agents/diagnose`** — Standalone npm package detects system-prompt, API-key, credential, and internal-instruction leaks in any output. **100% true positive, 0% false positive, 0.02 ms latency.** 25 regex patterns + 4 FP filters.
- **Single-owner termination** — All 12 phases route stop decisions through one arbitrator. CI lint guard prevents future bypass paths. Agents always finish cleanly, never get stuck.

#### Better runtime + tooling

- **`@reactive-agents/cortex`** — Cortex Studio is now installable from npm: `bunx @reactive-agents/cortex` or `rax cortex` launches the live agent canvas, debrief UI, and visual builder. See [Cortex](/features/cortex/).
- **Gateway chat mode** — Per-sender SQLite session history, episodic context injection, daily compaction. Set `channels.mode: 'chat'` for conversational webhooks; keep `'task'` for one-shot triggers. See [Gateway](/features/gateway/) and [Messaging Channels](/guides/messaging-channels/).
- **Composable kernel architecture** — Internal `kernel/` reorganized by capability (`act/` · `attend/` · `comprehend/` · `decide/` · `reason/` · `reflect/` · `sense/` · `verify/` + `loop/` + `state/`). Doesn't change the public API; makes contributing to the framework easier. See [Composable Kernel](/concepts/composable-kernel/).
- **{metrics.tests.toLocaleString()} tests** across {metrics.testFiles} files — verified by `bun test` on every PR.

### Patch releases

| Version | Highlights |
|---------|-----------|
| `0.10.0` | Phase 1 release — healing pipeline, calibration, diagnose, cortex npm |
| `0.10.1–0.10.2` | Documentation polish, version drift fixes across 28 packages |
| `0.10.3` | Coordinated package alignment, npm publish drift CI guard |
| `0.10.4` | Coordinated changeset release (single source of truth) |
| `0.10.5–0.10.6` | Static-asset serving in Cortex server, README + cookbook freshness |

### Breaking changes

None. All existing `ReactiveAgents.create().with*()` builder chains keep working unchanged. New calibration fields are forward-compatible — existing `~/.reactive-agents/observations/` files decode cleanly.

---

## v0.9.x — MCP Production Hardening + Pre-v0.10 Polish

- **MCP client rewritten on `@modelcontextprotocol/sdk`** — smart auto-detection between stdio and HTTP-only containers, two-phase docker lifecycle — see [Orchestration](/features/orchestration/)
- **Composable kernel architecture (initial)** — `react-kernel.ts` reduced from ~1,700 to ~197 lines via `makeKernel({ phases })` factory — see [Composable Kernel](/concepts/composable-kernel/)
- **Permanently-failed required tools fix** — tools that always error no longer cause loop-until-maxIterations — see [Harness Control Flow](/features/harness-control-flow/)
- **Cortex MCP CRUD + JSON import** — import Cursor/Claude-style MCP configs directly into Cortex — see [Cortex](/features/cortex/)
- **StatusRenderer TUI** — live terminal display with collapsible think panel (`t` key toggles), `mode: 'stream' | 'status'`
- **3 new terminal tools** — `git-cli`, `gh-cli`, and `gws-cli` are now built-in
- **Web-search provider Serper.dev** — third web-search backend alongside Tavily
- **`crypto-price` built-in tool** — CoinGecko price lookup, no API key required
- **Observability on by default** — minimal verbosity is now enabled out of the box
- **Sub-agent `maxIterations` fully honored** — the silent cap of 3 has been removed

---

## v0.9.0 — MCP Production Hardening

- **MCP client rewritten on `@modelcontextprotocol/sdk`** — smart auto-detection between stdio and HTTP-only containers, two-phase docker lifecycle — see [Orchestration](/features/orchestration)
- **Composable kernel architecture** — `react-kernel.ts` reduced from ~1,700 to ~197 lines via `makeKernel({ phases })` factory; phases are now individually swappable — see [Composable Kernel](/concepts/composable-kernel)
- **Permanently-failed required tools fix** — tools that always error no longer cause loop-until-maxIterations; framework detects and stops early — see [Harness Control Flow](/features/harness-control-flow)
- **Cortex MCP CRUD + JSON import** — import Cursor/Claude-style MCP configs directly into Cortex — see [Cortex](/features/cortex)
- **`effect` moved to `peerDependencies`** — add `effect` explicitly if you import from it directly — see [Installation](/guides/installation)

---

## v0.8.5 — Native FC Hardening + Web Framework Adapters

- **React, Vue, and Svelte adapters** — `useAgentStream()` and `useAgent()` hooks/composables/stores for all three frameworks, consuming SSE endpoints — see [Web Integration](/guides/web-integration) and [Streaming](/features/streaming)
- **7-hook provider adapter system** — `taskFraming`, `toolGuidance`, `errorRecovery`, `synthesisPrompt`, `qualityCheck`, `continuationHint`, `systemPromptPatch` fully wired — see [Reactive Intelligence](/features/reactive-intelligence)
- **Dynamic stopping (3-layer)** — novelty signal (Jaccard overlap), budget exhaustion phase transition, and per-tool call cap (`maxCallsPerTool`) — see [Harness Control Flow](/features/harness-control-flow)
- **Full prompt observability** — `logModelIO: true` logs the complete FC conversation thread with no truncation — see [Observability](/features/observability)
- **Actionable failure messages** — loop detection, required-tools, and stall detection all emit `Fix:` suggestions with specific builder options — see [Troubleshooting](/guides/troubleshooting)

---

## v0.8.0 — Reactive Intelligence Layer

- **Entropy-aware intelligence pipeline** — 5-source composite entropy sensor, trajectory classifier, and reactive controller that takes corrective action automatically — see [Reactive Intelligence](/features/reactive-intelligence)
- **Thompson Sampling strategy learner** — SQLite-backed bandit learns which reasoning strategy wins per task category across runs — see [Reactive Intelligence](/features/reactive-intelligence)
- **Builder hardening** — `withStrictValidation()`, `withTimeout()`, `withRetryPolicy()`, `withFallbacks()`, `withHealthCheck()`, and `withErrorHandler()` — see [Builder API](/reference/builder-api)
- **Automatic strategy switching** — when entropy analysis detects a stuck loop, the agent switches reasoning strategy without user intervention — see [Choosing Strategies](/guides/choosing-strategies)
- **Observability dashboard upgrade** — chalk/boxen terminal UI with entropy grade (A–F), sparklines, and entropy-informed alerts — see [Observability](/features/observability)

---

## v0.5.0 — A2A Protocol + Observability Foundation

- **Full A2A (Agent-to-Agent) protocol** — JSON-RPC 2.0 server, streaming SSE, client, discovery, and capability matching based on Google's A2A spec — see [A2A Protocol](/features/a2a-protocol)
- **Agent-as-tool pattern** — wrap any local or remote A2A agent as a callable tool with `createAgentTool()` / `createRemoteAgentTool()` — see [Sub-agents](/guides/sub-agents)
- **Live observability streaming** — `withObservability({ live: true, verbosity })` writes structured phase logs to stdout as each step fires — see [Observability](/features/observability)
- **`rax serve`** — expose any agent as an A2A-compliant HTTP server with a single CLI command — see [CLI](/reference/cli)
- **EventBus reasoning events** — all strategies publish `ReasoningStepCompleted`; subscribe with `agent.on()` for custom monitoring — see [Observability](/features/observability)
