Repository navigation
feat(ai): move chat models to Opus/Sonnet/Haiku 5.5 - #460
Merged
Merged
Conversation
- Catalog: claude-haiku-5-5 (adaptive, effort low), claude-sonnet-5-5 (adaptive, effort medium, max output 32K), claude-opus-5-5 unchanged. Default chat model is now claude-sonnet-5-5. - Pricing: Sonnet 5.5 $2/$10 with cache reads at 0.05x ($0.10), Haiku 5.5 $0.10/$0.50 with a long-prompt card ($0.50/$2.50) for requests whose prompt (fresh + cache read + cache write) exceeds 100K tokens. Each call is classified on its own in the turn tracker, the turn budget and the Conversation API settle; a summed total without a per-call split is priced on the long card (never below cost). Legacy IDs keep their pricing for past usage rows. - Compatibility: resolveChatModelId maps retired haiku/sonnet/opus IDs to the family's current model in the chat route, the chat picker storage and conversation keys; unknown IDs still fall back to the default. - Refusal: stop_reason "refusal" ends the turn with a "refused" error and a dictionary message instead of running tools (Haiku 5.5 has no server-side fallback). - Migration 051 moves the conversation_api_keys.ai_model column default to claude-sonnet-5-5; existing rows resolve at read time.
- Move fixtures to the 5.5 IDs; heavy-turn shapes now sit on the Haiku 5.5 long card so the credit expectations stay the same. - New cases: per-call long-prompt split, planCall on the long card, adaptive thinking + effort per catalog model with no sampling or tool_choice params, refusal handling, retired-ID resolution in the server and the chat picker storage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
The Studio chat catalog moves to the 5.5 generation. This covers Studio chat and the ee Conversation API: request params, pricing and credits, compatibility for stored IDs, and handling of refusals.
shared/utils/ai-models.ts: the catalog, the default model (DEFAULT_CHAT_MODEL = 'claude-sonnet-5-5', :199), the newModelPricing.longPromptcard (:151) andresolveChatModelId(:220).shared/utils/ai-credits.ts: legacy pricing kept for old IDs (:77-79),ratesForPrompt(:129), andestimateMessageCostUsd(:158), which now prices the long-prompt part on its own card.server/utils/turn-budget.ts:ratesForEstimate(:108);TurnUsageTracker.pricedUsage(model)(:256) classifies each call against the threshold, including the call in flight.server/utils/conversation-engine.ts: the refusal branch (:497). The done event carrieslongPrompt.server/providers/ai.ts:160,183:'refusal'stop reason.chat.post.ts:163settles fromtracker.pricedUsage(still infinally).chat.post.ts:246resolves the requested ID before the plan gate.ee/enterprise/conversation-api.ts:422-483: carries the per-call long split into the settle.server/utils/conversation-keys.ts:73,84andee/enterprise/conversation-keys.ts:48,109,187: key list, create and update resolve stored and sent IDs.app/composables/useChat.ts:253-262: a retired ID in the picker's localStorage moves to the current one and is saved again.:759shows the refusal message..contentrain/content/system/ui-strings/en.json: the newchat.refusedkey, edited in the JSON directly with no MCP write.supabase/migrations/051_conversation_key_model_default.sql: new migration (see below).001_baseline.sqlis untouched.Old → new model IDs
claude-haiku-4-5-20251001,claude-haiku-4-5, anyclaude-haiku-*claude-haiku-5-5claude-sonnet-5,claude-sonnet-4-*,claude-3-5-sonnet-*, anyclaude-sonnet-*claude-sonnet-5-5claude-opus-5,claude-opus-4-*, anyclaude-opus-*claude-opus-5-5gpt-4o,claude-fable-5-1, ...)null, so the caller's existing default fallback appliesPricing (USD per MTok, from the live pricing page)
CACHE_WRITE_MULTIPLIER = 2stays.pricedUsagesplits out the calls over 100K, and the settle, turn budget and Conversation API all use that split. When a summed total arrives without a split, it is classified as a single request. A multi-call turn over 100K in total is then priced on the long card, which is above real cost and never below.claude-sonnet-5$2/$10,claude-haiku-4-5*$1/$5), so past usage rows still price correctly.API-breaking changes handled
thinking: {type: "adaptive"}+ an explicit effort (server/providers/anthropic-ai.ts:254-270,requestThinking).disabledis sent only for IDs outside the catalog. This fixes Sonnet 5.5's 400 ondisabled, and Haiku 5.5 never getsbudget_tokens.low, Sonnetmedium, Opusmedium, always sent explicitly so the recalibrated defaults (Sonnet high, Haiku medium) never apply.tool_choice,temperature,top_p,top_k, prefill orfallbacks. A unit test asserts this for every catalog model (tests/unit/anthropic-ai.test.ts). The engine is the only request path for both Studio chat and the Conversation API.block_binding: drop_blockas before. Persisted rows are not rewritten.stop_reason: "refusal"now ends the turn with anerrorevent,code: 'refused'(conversation-engine.ts:497), and runs no tools. The UI showschat.refused. Credits still settle infinallyfrom real usage.system.Stored-ID compatibility
chat.post.ts:246resolvesbody.modelbefore the plan gate. A retired ID becomes the family's current model. An unknown ID falls back to the default as before.useChatreads the stored ID throughresolveChatModelIdand saves the new ID straight away.resolveConversationModel, which resolves and then requires a non-premium API model (haiku-5-5 / sonnet-5-5), else falls back to the default. Update writesai_modelonly when the sent ID resolves.conversation_api_keys.ai_modeltoclaude-sonnet-5-5. It rewrites no rows, because read-time resolution covers them. It is one lineage: the next number after 050, applied by both runners.Credit and gate impact (plan prices and limits unchanged)
medium(Sonnet 5 ran thinking-off), so output tokens per turn will rise.AI_CREDIT_UNIT_USDfloor holds: settle prices at or above real cost in every path.Questions for ORK
cacheReadMultiplier: 0.05→0.1inai-models.ts).lowand Sonnetmediumwere not checked against evals (no live calls in this PR).Known limits
Tests
pnpm lint: 0 errors. The 7v-html/console warnings were already there.pnpm typecheck: clean.#contentrainclient (contentrain-query generate). Without it, the billing webhook suites fail on import.