Skip to content

Releases: ziyacivan/reflex-router

0.11.3

Choose a tag to compare

@ziyacivan ziyacivan released this 17 Oct 19:58

Changed

  • Claude Code 2.1.302 is a tested version: a claude -p capture with a subagent (Sonnet 5.5, sdk-cli) shows nothing
    reflex reads that differs from 2.1.300, and real 2.1.301 and 2.1.302 sessions in the decision log all passed the shape
    checks. 2.1.301 was not captured. Pricing re-verified against Anthropic's pricing page (2026-10-17); no price changed.

v0.11.2

Choose a tag to compare

@ziyacivan ziyacivan released this 14 Oct 22:07

Fixed

  • Sessions on Claude Code 2.1.299 and later were never routed. From 2.1.299 Claude Code still sends role:"system"
    messages but no longer sends the mid-conversation-system-2026-04-07 beta, and reflex's runtime shape check required
    that beta whenever such messages were present. Almost every session failed the check and ran as shadow: requests
    went out unchanged on the model Claude Code asked for, so nothing broke, but nothing was routed either. The check is
    removed (docs/wire-format.md §10); the rewrite that folds role:"system" messages for a target model never depended
    on the beta.

Changed

  • Claude Code 2.1.300 is a tested version: a claude -p capture with a subagent (Opus 5.5, sdk-cli) differs from
    2.1.296 only by the missing beta above. Only the main chat's and the subagent's first requests were kept (the capture
    stopped at its cost cap). 2.1.299 was not captured. Pricing re-verified against Anthropic's pricing page (2026-10-15);
    no price changed.

v0.11.1

Choose a tag to compare

@ziyacivan ziyacivan released this 10 Oct 17:07

Changed

  • Claude Code 2.1.296 is a tested version: one claude -p capture with a subagent (Opus 5.5, sdk-cli) has the same
    request fields, betas, headers and cache settings as 2.1.293, and every request classifies and passes the shape checks.
    2.1.294 and 2.1.295 were not captured. Pricing re-verified against Anthropic's pricing page (2026-10-10); no price changed.

Fixed

  • scripts/spike/capture.mjs (development tooling, not shipped) refuses to start when the claude on PATH is a script and
    REFLEX_CLAUDE_BIN is not set. On a machine where claude starts reflex through a wrapper, a capture recorded
    reflex-rewritten requests instead of Claude Code's own, and its session asked the decision backend and was logged in
    ~/.reflex/decisions.jsonl. No committed fixture was affected.

v0.11.0

Choose a tag to compare

@ziyacivan ziyacivan released this 07 Oct 21:47

Changed

  • The built-in Haiku model is Claude Haiku 5.5 (claude-haiku-5-5), not Haiku 4.5. REFLEX_MODEL_HAIKU=claude-haiku-4-5-20251001
    (or ANTHROPIC_DEFAULT_HAIKU_MODEL) keeps the old one, and its full rewrite is unchanged. Haiku 5.5 takes Sonnet 5.5's
    request shape, so a request retargeted to it changes only model (no budget thinking, no stripped effort, no folded
    system messages); max_tokens is capped at 128000 and the 1M-context beta is kept. Quality was measured: 240 graded
    runs of 20 tasks, 60 per arm. Haiku 5.5 got 60/60 right routed and 60/60 with Claude Code's own Haiku prompt, Sonnet 5.5
    56/60, Haiku 4.5 59/60; the suite is small and easy, so read it as "no failure seen", not as a ranking
    (docs/observations.md, 2026-10-07).

  • Every pair of Haiku 5.5 with Sonnet 5.5, Opus 5.5, Fable 5.1, Sonnet 5 and Opus 5 was verified against the API, each way, main
    chat and subagent, with source-signed thinking in the history (docs/wire-format.md §5.13).

  • Effort works on Haiku 5.5, by message, like Sonnet 5.5 (cache kept; mean output tokens 3,153 at low, 3,610 at medium,
    8,896 at max over four runs). Haiku 4.5 still takes none.

  • Prices are per model. Haiku 5.5 is priced by prompt length ($0.10 / $0.50 per MTok up to 100,000 tokens, $0.50 / $2.50
    above); the cost guard now prices the cache holder and the target by model, so a Haiku 4.5 switch is still judged at $1 and
    a Haiku 5.5 one at $0.10. Report section 12's side-call estimate prices Haiku at the new default, so its savings read about
    ten times larger than before; the quality measurement above did not cover side calls.

  • Disabled thinking is not rewritten for Haiku 5.5 at effort xhigh or max (the API answers 400 there, 200 at high and below).

  • Claude Code 2.1.293 is a tested version (it knows Haiku 5.5); claude-haiku-5-5 is a known requested model.

  • Sonnet 5.5 reads its cache at 0.05x ($0.10), Sonnet 5 at 0.1x ($0.20), as the pricing page's table now says (it had
    contradicted itself on 2026-10-07). Pricing re-verified against Anthropic's pricing page (2026-10-08).

v0.10.1

Choose a tag to compare

@ziyacivan ziyacivan released this 07 Oct 09:27

Fixed

  • Subagents that announce MCP tools are routed again on Claude Code 2.1.287 and later. With the inline-tools
    beta a tool_addition block carries the whole tool (tool_definition) instead of naming a deferred one. The
    rewrite did not know that shape, so such a request was never moved to Haiku or Sonnet (it ran on the model the
    client asked for, nothing failed). The definition now joins tools as a plain tool, in the order announced.
    Checked against the API on 2.1.292 with one real session: a subagent moved Sonnet 5.5 -> Haiku, its pinned
    continuation and the move back to Sonnet all answered 200.

Changed

  • Claude Code 2.1.287, 2.1.288, 2.1.289, 2.1.290, 2.1.291 and 2.1.292 are tested versions, from the same kind of
    capture as before (one claude -p with a subagent each, redacted and leak-scanned). From 2.1.287 requests also
    carry the betas mid-conversation-tool-changes-2026-07-01 and inline-tools-2026-09-15.
  • Pricing re-verified against Anthropic's pricing page (2026-10-07); no price changed.

0.10.0

Choose a tag to compare

@ziyacivan ziyacivan released this 01 Oct 09:14

Changed

  • A move up follows the backend's own answer. Until now the mass rule (a tier that holds more than 10% of the
    probability is never undercut) also decided upgrades, so a 13% tail on Opus moved a Sonnet turn to Opus even when
    the backend's own answer was Sonnet (31 of 52 upgrades in two machines' logs). The upgrade now needs the backend's
    most likely tier (pick_argmax) to be stronger than the requested one, and goes to that tier. When only the margin
    wants a stronger tier the model stays (upgrade_to_effort in plan.reasons). The mass rule for moving down is
    unchanged. REFLEX_UPGRADES=confident now checks the backend's own answer (confidence >= 0.7) whatever
    REFLEX_DECISION_RULE is; under mass it used to gate nothing.
  • A turn's effort comes from the backend's reasoning score alone, one level per step (the "provisional" label on
    that mapping is gone). Nothing else raises or lowers it.
  • Claude Code 2.1.281, 2.1.283, 2.1.285 and 2.1.286 are tested versions, from the same kind of capture as before
    (one claude -p with a subagent each, redacted and leak-scanned). Their shape checks had already passed on
    ~20,000 real requests with no violation; the fixtures also make claude-sonnet-5-5 a known requested model, which
    clears the unseen_requested_model drift flag.
  • Pricing re-verified against Anthropic's pricing page (2026-10-01); no price changed.

Removed

  • REFLEX_AB and REFLEX_EFFORT_AB. The randomised hold-back kept a share of the turns the backend wanted moved
    on the model (or effort) you asked for, which cost the saving it measured. Setting either now prints a warning and
    is ignored. reflex report still shows the arms of logs recorded while it ran; section 8's measured line now says
    when a log has none.

v0.9.0

Choose a tag to compare

@ziyacivan ziyacivan released this 30 Sep 12:15

Added

  • TypeLLM as a decision backend (REFLEX_BACKEND=typellm, key in TYPELLM_API_KEY). reflex sends the same
    privacy-budgeted state as JSON text and reshapes its fixed questions into TypeLLM's typed ones (enums and a boolean,
    each with return_probabilities); the answers come back as the probabilities the policy already reads, with no
    calibration head. On 500 synthetic tasks its plans matched Jev's on 93% (0.4% cheaper than Jev's), p95 latency
    464 ms from one machine; Laya with its shipped head matched on 58% of the same tasks
    (measurement).
    Not yet measured on real sessions. Settings: REFLEX_TYPELLM_BASE_URL (a self-hosted server works in principle,
    untested), REFLEX_TYPELLM_MODEL (typellm-latest), REFLEX_TYPELLM_DEADLINE_MS (1500).
  • The TypeLLM key is handled like the TypeSafe one: it may live in ~/.reflex/env (a group-readable file holding it
    is refused), reflex doctor never prints it, every TYPELLM_* variable is stripped from the environment claude
    gets, and a tl-sk-… key pasted into a prompt is redacted before the state leaves the machine.

Changed

  • REFLEX_COMPARE=laya only runs next to Jev; with another backend it is ignored with a warning (it used to start
    laya-serve for nothing).
  • Internal: Jev's keep-alive transport (deadline, stale-socket retry) is shared by every remote backend
    (src/backend/http-client.ts). No behaviour change.
  • Pricing re-verified against Anthropic's pricing page (2026-09-30); no price changed.

v0.8.2

Choose a tag to compare

@ziyacivan ziyacivan released this 29 Sep 10:07

Comments and docs only: status-line examples and the tierOfModel comment name Sonnet 5.5 as the sonnet tier's model, matching the default since 0.8.0. No behaviour change.

0.8.1

Choose a tag to compare

@ziyacivan ziyacivan released this 29 Sep 08:42

Changed

  • Claude Code 2.1.284 is a tested version. Fixtures from one claude -p capture with a subagent; its headers and
    anthropic-beta match 2.1.282. The version check: warn (minor_mismatch) on 2.1.284 is gone.

Fixed

  • The fixture redactor scrubbed streamed responses line by line, so a home path split across two input_json_delta
    chunks kept the username; the 2.1.280 fixture carried it that way. Each block's chunks are now joined and scrubbed
    as one string, and the leak scan checks the joined text. Fixtures are not part of the npm package.

v0.8.0

Choose a tag to compare

@ziyacivan ziyacivan released this 29 Sep 08:25

Added

  • Claude Sonnet 5.5. Claude Code 2.1.284 sends claude-sonnet-5-5 for its own sonnet, and it is now the sonnet
    tier default (REFLEX_MODEL_SONNET still overrides it). Every pair with it was run against the API: Sonnet 5.5 to and
    from Haiku, Opus 5.5, Opus 5 and Fable 5.1, with each side's signed thinking in the history, pinned loops and un-pins,
    -p and interactive (wire format §5.12). Priced at $2 / $10,
    cache reads $0.20 per MTok.
  • A retarget to Sonnet 5.5 keeps a system message's per-turn effort (Sonnet 5 rejects it), and REFLEX_EFFORT sets
    Sonnet 5.5's level by message, never by the top-level value, like Opus 5 and Fable 5.1.
  • Sonnet 5.5 is never sent a request with thinking disabled or a forced tool_choice (both 400 on it).
  • The decision record carries refusal: {category, pin_released} when a response stopped with stop_reason: "refusal" (the API's short category only; not in reflex share).

Fixed

  • A refusal from the model reflex moved a request to no longer breaks Claude Code's recovery. Claude Code resends a
    refused turn to the model it asked for; the pin sent that resend back to the refusing model, and the session ended.
    The pin is now released as the refusal streams past, so the resend and the rest of the loop go to your model.

Measured

  • On 20 small coding tasks (Opus 5.5 requested at effort medium, 100 runs), Sonnet 5.5 wrote 19% fewer output tokens
    and cost 25% less at list prices than Opus 5.5; Sonnet 5 wrote 25% more output and 63% more tokens in all, the
    pattern that stopped Opus → Sonnet routing in the 2026-09-26 audit. Synthetic tasks; list-price estimates, not a bill
    (observations).
  • Sonnet 5.5 refused (reasoning_extraction) a prompt that Opus 5.5 alone ran without a refusal; see the README's known
    limits.

Prices verified against the pricing page on 2026-09-29.

Install: npm install -g reflex-router