## v0.10.0 — 2026-04-30

### Highlights

v0.10.0 ships the **Adaptive Tool Calling System** — a four-layer closed-loop pipeline that makes local models (Ollama, local LLMs) dramatically more reliable by normalizing how they express tool intent before execution. It adds a full **Reactive Intelligence dispatcher** with 6 intervention handlers, a production-grade **Calibration system** with community profiles and a local observations store, and **Benchmark Suite v2** with 5 competitor runners and a CI drift gate. Cortex Studio received its largest-ever update with Beacon, Mission Control, Lab, and living skills.

The release closes with the **`refactor/overhaul` audit** — a 19-wave Stage 5 sweep that rationalised termination, cleaned up dead intent, made the framework's ports explicit, and replaced cosmetic claims with honest deferrals where evidence didn't justify the work. 28 packages total.

### Breaking Changes

None. All existing `ReactiveAgents.create().with*()` builder chains continue to work unchanged. New fields on `ModelCalibrationSchema` (`toolCallDialect`, `knownToolAliases`, `knownParamAliases`) default to `"none"` / empty on decode — existing calibration files are forward-compatible.

### New Features

#### Adaptive Tool Calling System (`@reactive-agents/tools`, `@reactive-agents/reactive-intelligence`, `@reactive-agents/llm-provider`)

- **`ToolCallingDriver` interface** — `NativeFCDriver` (thin passthrough for FC-capable models) + `TextParseDriver` (3-tier cascading parse pipeline for models that struggle with native FC)
- **`HealingPipeline`** — 4-stage normalizer that fires on every tool call regardless of driver: `ToolNameHealer` (alias map + edit-distance fuzzy match), `ParamNameHealer` (per-tool alias map + edit-distance), `PathResolver` (relative path → sandbox CWD, `~/` expansion), `TypeCoercer` (string→number/boolean coercion)
- **FC Calibration probe** — 5-dimension battery (tool name accuracy, param accuracy, type compliance, required param completeness, multi-tool selection) produces `fcCapabilityScore` 0–1; routes model to `NativeFCDriver` (≥0.80) or `TextParseDriver` (<0.80)
- **`ToolCallObservation` schema** — records per-call: attempted vs resolved names/params, which healing stages fired, parse tier used, success/error
- **Alias accumulation with frequency gate** — aliases confirmed ≥3 times are promoted to `CalibrationStore`; prevents noise from one-off hallucinations
- **`ExperienceSummary` materialization** — `toolGuidance` hook now reads concrete patterns ("for `file-read`, use `path` not `input` — confirmed 12 times") instead of generic reminders
- **`StallDetector`** — detects content-level stalls via Jaccard similarity + tier-adaptive iteration window; escalates: nudge → early-stop
- **`HarnessHarmDetector`** — circuit-breaks RI interventions when the harness is net-negative; re-evaluates after 10 clean runs

#### Reactive Intelligence Dispatcher

- **6 intervention handlers** fully wired: `early-stop`, `temp-adjust`, `switch-strategy`, `context-compress`, `tool-inject`, `skill-activate`
- **`tool-failure-streak` evaluator** — detects repeated tool call failures; dispatches redirect + nudge
- **Escalating redirect handler** — soft nudge on first fire, hard redirect on second; tracks nudge effectiveness
- AUC validation confirms entropy discriminates failure scenarios

#### Calibration System

- Community profile HTTP client with 24h TTL cache
- Atomic observations store — rolling 50-run window per model
- Three-tier resolver (shipped prior → community → local observations)
- `classifierReliability` derived from false-positive rate; `"low"` skips classifier LLM call
- `toolCallDialect`, `knownToolAliases`, `knownParamAliases` added to `ModelCalibrationSchema`

#### Benchmark Suite v2 (`@reactive-agents/benchmarks`)

- 10 real-world tasks with fixture generators
- 9-variant ablation (`ABLATION_VARIANTS`)
- 5 competitor runners — LangChain, Vercel AI SDK, OpenAI Agents, Mastra, LlamaIndex
- 4 pre-built sessions — regression-gate, real-world-full, competitor-comparison, local-models
- CI drift gate with baseline management
- `judge.ts` — LLM-as-judge scoring with verifiable dimensions

#### Cortex Studio

- **Beacon** — live agent canvas (renamed Mission Control)
- **Thalamus** — run history with sub-agent hierarchy (renamed Runs)
- **Lab** — tool workshop, MCP registry, model catalog
- **Skills tab** — bridges SQLite catalog with `withSkills()` evolution
- **Streaming chat workspace** with strategy/verification/synthesis/persona controls
- Persisted chat sessions, memory API, run messages tab

#### New Packages

- **`@reactive-agents/scenarios`** — 5 pre-built benchmark scenarios
- **`@reactive-agents/trace`** — JSONL trace recorder, `expectTrace` assertion DSL

#### Runtime Builder

- `.withMinIterations()`, `.withVerificationStep()`, `.withProgressCheckpoint()`, `.withTaskContext()`
- `.withCalibration()`, `.withTerminalTools()`, `.withCustomTermination()`, `.withOutputValidator()`

#### Reasoning

- Parallel tool batching enabled by default (maxBatch: 4)
- Context pressure hard gate (final-answer only when >95% token budget used)
- Tier-aware harness — context profiles, termination oracle, output synthesis
- Single-channel guidance (8 USER injections → `pendingGuidance`)

#### CLI Built-in Tools

- `git-cli`, `gh-cli`, `gws-cli` — shell-backed built-in tool skills
- `rax trace inspect` + `rax trace compare` subcommands
- `crypto-price` skill (CoinGecko free tier)
- Serper.dev added as third web-search provider

### Bug Fixes

- Fixed routing: uncalibrated models default to `NativeFCDriver`, not `TextParseDriver`
- Fixed permanently-failed required tools blocking strategy handoffs
- Fixed Gemini array-type tool parameter compatibility
- Fixed status renderer TTY escape codes in test environments
- Fixed RI escalation gate threshold

### Migration Guide

No migration required. Existing code compiles and runs without changes.

If you use `ModelCalibration` objects directly in tests or fixtures, add `toolCallDialect: "none"` to satisfy the new required field:

```typescript
const prior: ModelCalibration = {
  // ... existing fields ...
  toolCallDialect: "none",  // new required field, defaults to "none" on decode
};
```
