GLOOK-45: switch to Claude Sonnet 5 - #68
Merged
Merged
Conversation
Sonnet 4 is being deprecated. Moves the deployed AWS environment and the code
defaults to Sonnet 5.
This is not a config-only change. Sonnet 5 (and the Opus 5 / Opus 4.7-4.8 /
Fable 5 generation) removed the sampling parameters: sending temperature returns
a 400, including temperature: 0. Every LLM call site in this repo passed a
temperature, so flipping llm_model alone would have 400d every LLM request in
the app.
Verified against the Smartling AI Proxy before writing code:
anthropic/claude-sonnet-4-20250514 + temperature 0.3 -> 200
anthropic/claude-sonnet-5 + temperature 0.3 -> 400
anthropic/claude-sonnet-5 + temperature 0 -> 400
anthropic/claude-sonnet-5 + top_p -> 400
anthropic/claude-sonnet-5 + stop -> 400
anthropic/claude-sonnet-5 (no sampling) -> 200
anthropic/claude-sonnet-5 + json_object -> 200
anthropic/claude-does-not-exist-9 -> 400 (negative control)
response_format: json_object still works, which the analyzer depends on. No call
site sends top_p or stop (they appear only in bedrock-adapter type defs).
Adds samplingParams() to llm-provider.ts, mirroring the existing tokenLimit()
helper: spread into chat.completions.create() and it returns {} on a model that
rejects sampling, { temperature } otherwise. Matched on the model string rather
than the provider, because the same model arrives as bare claude-sonnet-5
(direct), anthropic/claude-sonnet-5 (AI Proxy) and us.anthropic.claude-sonnet-5
(Bedrock inference profile). 12 call sites converted.
Behavioural consequence worth knowing: the analyzer ran temperature: 0 for
determinism, and on Sonnet 5 that is not expressible — output falls back to the
model default and adaptive thinking is on. Commit analysis and report generation
become less reproducible run to run. The *_TEMPERATURE env vars still exist and
still apply to models that accept sampling; they are silently inert on Sonnet 5,
which .env.example now says.
Also verified Glooker's real request shape end-to-end through the provider layer
on both models: Sonnet 5 omits temperature and returns valid JSON, Sonnet 4 still
sends temperature: 0 and returns valid JSON.
120 suites / 1160 tests pass; tsc clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Closes GLOOK-45.
Sonnet 4 is being deprecated. This moves the deployed AWS environment and the code defaults to Claude Sonnet 5 (
claude-sonnet-5).This is not a config-only change
Sonnet 5 — and the whole Opus 5 / Opus 4.7-4.8 / Fable 5 generation — removed the sampling parameters. Sending
temperaturereturns a 400, includingtemperature: 0. Every LLM call site in this repo passed a temperature, so flippingllm_modelalone would have 400'd every LLM request in the app.I verified this against the Smartling AI Proxy before writing any code:
anthropic/claude-sonnet-4-20250514+temperature 0.3anthropic/claude-sonnet-5+temperature 0.3anthropic/claude-sonnet-5+temperature 0anthropic/claude-sonnet-5+top_panthropic/claude-sonnet-5+stopanthropic/claude-sonnet-5(no sampling)anthropic/claude-sonnet-5+response_format: json_objectanthropic/claude-does-not-exist-9response_format: json_objectstill works, which the analyzer depends on. No call site sendstop_porstop— they appear only inbedrock-adaptertype definitions.The change
Adds
samplingParams()tollm-provider.ts, mirroring the existingtokenLimit()helper — spread intochat.completions.create():It returns
{}on a model that rejects sampling and{ temperature }otherwise. Matched on the model string, not the provider, because the same model arrives in three shapes: bareclaude-sonnet-5(direct Anthropic),anthropic/claude-sonnet-5(Smartling AI Proxy), andus.anthropic.claude-sonnet-5(Bedrock cross-region inference profile). 12 call sites converted.Model defaults bumped:
anthropic→claude-sonnet-5,bedrock→us.anthropic.claude-sonnet-5,aiproxy→anthropic/claude-sonnet-5.Behavioural consequence worth knowing before merge
The analyzer ran
temperature: 0for determinism. On Sonnet 5 that is not expressible — output falls back to the model default, and adaptive thinking is on by default. Commit analysis and report generation become less reproducible run-to-run. That's a property of the model, not something the helper can work around.The
*_TEMPERATUREenv vars still exist and still apply to models that accept sampling; they are silently inert on Sonnet 5..env.examplenow says so, since an env var that looks live but isn't is worse than one that's documented as conditional.Tests
New
llm-sampling-params.test.tscovers the model matcher across all three prefix shapes, both directions, and a boundary case (claude-opus-4-60must not match the4-6-adjacent alternatives). All 19 confirmed failing before the implementation.11 test files needed
samplingParamsadded to theirjest.mock('@/lib/llm-provider')factories, andllm-provider.test.tspinned the old defaults.120 suites / 1160 tests pass;
tscclean.Also verified Glooker's real request shape end-to-end through the provider layer on both models — Sonnet 5 omits temperature and returns valid JSON; Sonnet 4 still sends
temperature: 0and returns valid JSON.Deploy coordination
llm_modelinglooker-deploy/terraform/service/env/dev.tfvarsmoves toanthropic/claude-sonnet-5in a companion commit. That must not ship before this PR — the deployed image needssamplingParamsor every LLM call 400s. Deploying this PR first is safe in either order, since Sonnet 4 still accepts temperature.Note: the ticket says "production", but only
dev.tfvarsexists (tf.sh's prod path hasPROD_KMS_KEY_ID="PLACEHOLDER"), so this targets the dev AWS environment — the one that's actually stood up.🤖 Generated with Claude Code