fix(providers): stop zed-hosted claude-haiku-4-5 thinking from inflating max_tokens (#13364) (#13780)

Merged in the 2026-09-16 sweep of the maintainer's own open PRs, at the owner's explicit instruction. No push was made to the PR branch: the merge took the head as the owning session left it (verified OPEN, non-draft and MERGEABLE against the release tip immediately before merging).
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-09-16 06:15:00 -03:00
committed by GitHub
parent 05b44fa48e
commit 94220af289
3 changed files with 48 additions and 0 deletions

View File

@@ -0,0 +1 @@
- **fix(providers):** stop zed-hosted `claude-haiku-4-5` extended-thinking requests from inflating `max_tokens` past the model's real 64000 output cap (#13364) — thanks @ThiagoMafra-Integrare

View File

@@ -73,6 +73,14 @@ const PROVIDER_MODEL_ALIASES: ProviderModelAliasMap = {
"claude-sonnet-4-5": "claude-sonnet-4.5",
"claude-haiku-4-5": "claude-haiku-4.5",
},
// #13364: zed-hosted's passthrough catalog exposes short hyphenated Claude ids
// that don't match modelSpecs' dotted canonical alias, so capMaxOutputTokens()
// resolves no cap and thinking+tools requests inflate max_tokens unbounded.
// Scoped to claude-haiku-4-5 (the reported/reproduced model) — add Sonnet/Opus
// entries only once confirmed against the live Zed catalog.
"zed-hosted": {
"claude-haiku-4-5": "claude-haiku-4.5",
},
};
const CROSS_PROXY_MODEL_ALIASES: Record<string, string> = {

View File

@@ -0,0 +1,39 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import { openaiToClaudeRequest } from "../../open-sse/translator/request/openai-to-claude.ts";
// #13364 — zed-hosted/claude-haiku-4-5: extended thinking + tools inflates
// max_tokens to 163072 (> Anthropic's real 64000 cap for this model), causing
// Zed's proxy to reject the request in-stream with:
// "max_tokens: 163072 > 64000, which is the maximum allowed number of
// output tokens for claude-haiku-4-5-20251001"
//
// Root cause: zed-hosted's passthrough catalog exposes the short hyphenated id
// "claude-haiku-4-5", but modelSpecs' registered alias for that model is the
// dotted "claude-haiku-4.5" — a spelling mismatch (not a missing spec) means
// capMaxOutputTokens() resolves no cap for zed-hosted, so fitThinkingToMaxTokens
// adds the requested budget instead of fitting it under the model's real ceiling.
test("zed-hosted/claude-haiku-4-5 thinking+tools must not inflate max_tokens past the real 64000 output cap", () => {
const body = {
model: "claude-haiku-4-5",
max_tokens: 16000,
reasoning_effort: "high", // what claude-to-openai produces for the client's budget_tokens:15999
tools: [
{
type: "function",
function: { name: "read_file", parameters: { type: "object", properties: {} } },
},
],
messages: [{ role: "user", content: "hello" }],
};
const credentials = { _provider: "zed-hosted" };
const result = openaiToClaudeRequest("claude-haiku-4-5", body, false, credentials);
const claudeHaiku45OutputCap = 64000; // src/shared/constants/modelSpecs.ts "claude-haiku-4-5-20251001"
assert.ok(
(result.max_tokens as number) <= claudeHaiku45OutputCap,
`max_tokens (${result.max_tokens}) must not exceed the model's real output cap ` +
`(${claudeHaiku45OutputCap}) — Anthropic/Zed rejects the request otherwise`
);
});