Completes the prose-CLI scrub the spec already documents as shipped: deletes tools/cli (the @openprose/prose-cli Oclif binary + eval harnesses), drops tools/cli from the workspace and lockfile, and removes the separately-authored `### Criteria` section from the reactor and reactor-cli contract loaders (postconditions live solely in `### Maintains`). Updates the accompanying skill tests, changelog, and release docs. Verified green: reactor SDK 458/0/10, reactor-cli 186/1 (pre-existing doctor test), devtools 96/0, skill 413/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Anthropic's OpenAI-compat endpoint is documented as testing-only and ignores
response_format, so it rejects Reactor's JSON-schema structured outputs with
400 response_format.json_schema.strict. That made `provider: anthropic` a
footgun for the structured compile/render path (compile + render are both
structured, and renders drive tools).
Route the built-in `anthropic` provider through the official @openai/agents
AI-SDK adapter over @ai-sdk/anthropic (native Messages API), where structured
outputs and tools both work. Mechanism:
- ProviderPlan gains a keyless `transport` discriminator (openai-compat |
anthropic-native); the anthropic built-in resolves to anthropic-native. The
module stays keyless, so the offline boundary holds.
- live-provider builds an AI-SDK-backed ModelProvider for that transport; every
other vendor keeps the scoped OpenAIProvider compat path. Both are scoped (no
global mutation). The compile/run/serve call sites are unchanged.
- doctor --live smokes the native provider for an anthropic project.
- A new gated live test drives a structured render + tool through the native
adapter (proven live: structured output parsed + tool called); it offline-skips
like every live test. The reactor BYO live test notes the compat subtest is
plain-text reachability only.
Bundles @openai/agents-extensions, ai, @ai-sdk/anthropic as CLI deps so an
installed reactor needs no extra setup. reactor-cli 0.2.1 -> 0.2.2.
Reactor was hard-wired to OpenRouter on the CLI (only OPENROUTER_API_KEY was
ever read), stranding users holding OpenAI / Anthropic / Google keys. The SDK
already supported a scoped provider; this makes it real and elegant at the CLI.
reactor-cli (0.2.0 -> 0.2.1):
- reactor.yml model.provider now switches the live provider; built-ins
openrouter|openai|anthropic|google resolve their endpoint + key env, and any
OpenAI-compatible vendor works via model.base_url + model.api_key_env.
- A keyless ProviderPlan resolver + a model-bearing OpenAIProvider factory
(reached only past the dynamic-import offline boundary), threaded into compile
sessions and the run/serve render (incl. the configured render_model, which
the run phase previously ignored).
- doctor reports the configured provider's key (not only OPENROUTER_API_KEY) and
doctor --live smokes the configured endpoint; a missing key fails non-zero with
the exact env var (never misdirects to OpenRouter, never exits 0).
- Tests: ProviderPlan resolver + a hermetic missing-key compile.
reactor (0.3.0 -> 0.3.1):
- Receipt Cost now reports the real provider + model instead of a hardcoded
openrouter / gemini-3.5-flash (cost-only labels, never fingerprinted). New
optional RunProjectRender.providerLabel + CostLabels.
- Tests: cost-labels + a key-gated bring-your-own-provider live smoke.
Build: each reactor package cleans its output dir before tsc, so local
incremental builds cannot accumulate orphaned dist test artifacts.
Known limitation: Anthropic's direct OpenAI-compat endpoint rejects our
structured-output response_format unless strict:true; route Anthropic models
through OpenRouter today (documented).
CLI-only, content-free, opt-out telemetry reusing the live POST /analytics backend (context.library + reactor.* discriminator). Zero SDK changes, zero new deps. 174 tests pass.
Ships @openprose/reactor 0.3.0, @openprose/reactor-cli 0.2.0, @openprose/reactor-devtools 0.2.0: the Reactor harness (compile-once-intelligent then dumb reconciler, content-addressed receipts, cost scales with surprise) with the distilled ideal public API — curated front door, full @openai/agents passthrough, one typed handle, one Substrate, unified observe, branded ids, and additive forward seams for the fixpoint.