Skip to content

GLOOK-45: switch to Claude Sonnet 5 - #68

Merged
msogin merged 1 commit into
mainfrom
feat/glook-45-sonnet-5
Aug 27, 2026
Merged

msogin merged 1 commit into
mainfrom
feat/glook-45-sonnet-5

Conversation

@msogin

@msogin msogin commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

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 temperature returns a 400, including temperature: 0. Every LLM call site in this repo passed a temperature, so flipping llm_model alone would have 400'd every LLM request in the app.

I verified this against the Smartling AI Proxy before writing any code:

request result
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 + response_format: json_object 200
anthropic/claude-does-not-exist-9 400 (negative control — the proxy does validate)

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 definitions.

The change

Adds samplingParams() to llm-provider.ts, mirroring the existing tokenLimit() helper — spread into chat.completions.create():

...samplingParams(getAppConfig().analyzer.temperature),

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: bare claude-sonnet-5 (direct Anthropic), anthropic/claude-sonnet-5 (Smartling AI Proxy), and us.anthropic.claude-sonnet-5 (Bedrock cross-region inference profile). 12 call sites converted.

Model defaults bumped: anthropicclaude-sonnet-5, bedrockus.anthropic.claude-sonnet-5, aiproxyanthropic/claude-sonnet-5.

Behavioural consequence worth knowing before merge

The analyzer ran temperature: 0 for 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 *_TEMPERATURE env vars still exist and still apply to models that accept sampling; they are silently inert on Sonnet 5. .env.example now 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.ts covers the model matcher across all three prefix shapes, both directions, and a boundary case (claude-opus-4-60 must not match the 4-6-adjacent alternatives). All 19 confirmed failing before the implementation.

11 test files needed samplingParams added to their jest.mock('@/lib/llm-provider') factories, and llm-provider.test.ts pinned the old defaults.

120 suites / 1160 tests pass; tsc clean.

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.

Deploy coordination

llm_model in glooker-deploy/terraform/service/env/dev.tfvars moves to anthropic/claude-sonnet-5 in a companion commit. That must not ship before this PR — the deployed image needs samplingParams or 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.tfvars exists (tf.sh's prod path has PROD_KMS_KEY_ID="PLACEHOLDER"), so this targets the dev AWS environment — the one that's actually stood up.

🤖 Generated with Claude Code

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>
@msogin
msogin merged commit ac6d4ba into main Aug 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant