# Claude Code v2.1.197

> Claude Code v2.1.197, released 30 Jun 2026 (2026-06-30). 6 entries read out of the shipped bundle. Unofficial, and not affiliated with Anthropic.

Web version: https://changelogs.core-directive.com/v/2.1.197

This release introduces **Claude Sonnet 5** (`claude-sonnet-5`) as the new default Sonnet model for Claude Code, replacing Claude Sonnet 4.6. The model picker gains a promotional pricing display that shows the launch promo price alongside the struck-through list price, and a new "Sonnet 5 (1M context)" option appears alongside the renamed "Sonnet 4.6 (1M context)" entry. Alias-to-canonical-ID resolution was added so that settings referencing saved model IDs survive the transition.

## New Features

### Claude Sonnet 5 Is Now the Default Model

**What**

Claude Sonnet 5 (`claude-sonnet-5`) becomes the default Sonnet tier model, replacing Claude Sonnet 4.6. The `sonnet` alias now resolves to `claude-sonnet-5`.

**Details**

- Model ID: `claude-sonnet-5`
- 1M context window, 64K default output tokens, 128K max output tokens
- Full adaptive thinking support (`max` effort level enabled)
- Available on all providers: first-party Anthropic API, Bedrock (`us.anthropic.claude-sonnet-5`), Vertex (`claude-sonnet-5`), Foundry, Gateway, and Mantle (`anthropic.claude-sonnet-5`)
- Sonnet 4.6 is retained in the model picker as "Sonnet 4.6 · Previous Sonnet version"
- Hook examples in settings/CLAUDE.md now reference `claude-sonnet-5`

**Evidence**

`SONNET_ID` constant updated (search for `"claude-sonnet-5"` in model constants; `SONNET_NAME: "Claude Sonnet 5"`)

### Promotional Launch Pricing in Model Picker

**What**

When Sonnet 5 is on a launch promotion, the model picker displays the promo price with the regular list price struck through next to it.

**Details**

- During the promo period, the Sonnet 5 entry shows: `~~$3/$15~~ $2/$10 per Mtok · promo through [date]`
- The promo expiry date is read from the `cedar_basin` key in the remote server config (`AI()?.cedar_basin`). `Dlo()` parses the value and returns it only if `Date.now() < parsedMs` (live gate); once the date has passed `Dlo()` returns `undefined` and no promo UI is rendered
- `Rlo()` formats the raw date string using `toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: "UTC" })`, producing e.g. `"Jun 29"`
- The `description` field carries the promo price (`$2/$10 per Mtok · promo through …`) so plain-text consumers read it unambiguously; rich pickers (the CLI model-selector component) additionally prepend `chalk.dim.strikethrough(promoListPrice)` before the first `$X/$Y` token in `description`, producing the struck-through display
- When no promo is active the description falls back to `C1(jte)` — the standard pricing description string
- The "Sonnet 5 (1M context)" entry (`Nlo()`) follows the same pattern; when running in a standalone/operator context (`Ao()` returns `true`) all pricing is omitted and only `"Sonnet 5 for long sessions"` is shown
- Third-party provider users (Bedrock, Vertex, etc.) do not see promo pricing: `gBn()` applies the promo display block only when `ud()` returns `false` (first-party API key users)
- This is a new UI field: `promoListPrice` added to the model row schema specifically to support struck-through rendering in rich pickers; `description` always carries only the promo price so plain-text consumers are unaffected

**Evidence**

Promo gate function `Dlo()` reading `AI()?.cedar_basin`; formatter `Rlo()` (search for `"$2/$10 per Mtok"` and `"promoListPrice"`); rich-picker rendering (search for `"dim.strikethrough"`); schema documentation (search for `"@internal List price (e.g. \`$3/$15\`)"`)

### Sonnet 5 Added to the 1M Context Picker

**What**

A "Sonnet 5 (1M context)" option now appears in the extended-context model picker, and the previous "Sonnet (1M context)" entry is renamed to "Sonnet 4.6 (1M context)".

**Details**

- New entry: `value: "sonnet[1m]"` → "Sonnet 5 (1M context)" — "Sonnet 5 with 1M context window - for long sessions with large codebases"
- Renamed entry: `value: "claude-sonnet-4-6[1m]"` → "Sonnet 4.6 (1M context)"
- Sonnet 5 has `native_1m` support on all 3rd-party providers (Bedrock, Vertex, Foundry, Gateway); availability is checked per-provider against a new `native_1m_3p` capability flag
- The "not available for your account" error message updated from "Sonnet 4.6 with 1M context is not available…" to "Sonnet with 1M context is not available…"

**Evidence**

New picker option (search for `"Sonnet 5 (1M context)"`); renamed entry (search for `"Sonnet 4.6 (1M context)"`); availability check function (search for `"native_1m_3p"`)

## Improvements

### Alias-to-Canonical-ID Resolution for Persisted Model Preferences

**What**

Model alias matching now uses a canonical wire model ID to let hosts correctly match a stored explicit model ID (e.g., a saved `claude-sonnet-4-6`) against the alias row that covers it, surviving model transitions without breaking saved settings.

**Details**

- New `resolvedModel` field (previously documented as `canonicalId`) in the model row schema: `"Canonical wire model id this row's value resolves to (e.g. 'sonnet' → 'claude-sonnet-5'). Lets hosts match a persisted explicit id against the alias row that covers it."` — populated by `Y4t()` via `Bo(value)`, which resolves an alias to its concrete wire model ID
- New `cda(options, persistedId)` function: if `persistedId` already exists verbatim in the option list it is returned unchanged; otherwise a `z4t()` scan finds a covering alias by checking in order — exact `value` match, fable-family membership, same model family AND (same 1M-context flag OR model is natively 1M-capable)
- When `cda()` finds a match it returns the alias option's `value` (e.g., `"sonnet"`), so the picker highlights the correct alias row for the persisted model; if no alias covers the persisted ID the call-site expression `cda(options, initial) ?? initial` keeps the original persisted value as the initial selection rather than discarding it

**Evidence**

Schema field `resolvedModel` and description (search for `"Canonical wire model id this row's"`); `cda(e, t)` function definition; `z4t()` matcher (search for `"Lets hosts match a persisted explicit id"`)

### Explicit Error for Missing Bedrock Fallback ID

**What**

The function that resolves default 3rd-party model IDs now throws a descriptive error if a model tier is configured with `bedrock: null`, instead of silently passing `null` downstream.

**Details**

- Previous behavior: `null` was passed as the Bedrock fallback ID, which could produce cryptic downstream failures
- New behavior: immediately throws `"A DEFAULT_3P_*_KEY points at a model config with bedrock: null — Bedrock setup has no fallback id for that tier"`
- This surfaces misconfiguration at the resolution point rather than at API call time

**Evidence**

Error message (search for `"A DEFAULT_3P_*_KEY points at a model config with bedrock: null"`)

### Model Documentation Updated in API Reference Context

**What**

The built-in API reference context used by the `claude-api` skill has been updated to reflect the Claude 5 family.

**Details**

- Model Migration Guide updated with Sonnet 5 migration guidance including: unchanged features (1M context window, 128K max output, prompt caching, batch, Files API, PDF, vision, tools), plus Sonnet 5-specific notes
- Model Catalog updated: Sonnet 5 listed as active; Sonnet 4.6 reclassified as "Previous-generation Sonnet" with max output corrected to 128K (was shown as 64K in previous version's docs)
- Hook examples in the agent/prompt hook documentation now default to `claude-sonnet-5`
- The model migration table now includes `claude-sonnet-5` in the source column

**Evidence**

Model catalog entry (search for `"Claude Sonnet 5"` in model catalog strings); migration table (search for `"claude-sonnet-5" / "claude-opus-4-8"`)
