mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-06 01:37:48 +08:00
fix(providers): keep thinking on the newest Claude models, fix the Bedrock ids
Measured on Bedrock: Claude Opus 4.7, 4.8 and every Claude 5 model reject
a thinking budget ("thinking.type.enabled") and a temperature, and all of
them accept adaptive thinking. The retry used to drop thinking, so with
a thinking budget set these models did not think at all. It now switches
to adaptive thinking with display "summarized"; without that setting the
models think but send no thinking text to show.
The suggested Bedrock ids had no region prefix, and the newer models only
answer through an inference profile id: "anthropic.claude-sonnet-5-5"
fails with "on-demand throughput isn't supported". Each suggested id was
called once; the Claude ones now start with "global.", Llama, Pixtral and
Nova 2 Lite with "us.". Nova Premier (end of life) and the ids without a
working profile are gone. The docs example had the same problem and a
wrong date.
This commit is contained in:
@@ -149,9 +149,11 @@ AZURE_REASONING_SUMMARY=detailed # 可选:none, brief, detailed
|
||||
AWS_REGION=us-west-2
|
||||
AWS_ACCESS_KEY_ID=your_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
AI_MODEL=anthropic.claude-sonnet-4-5-20250514-v1:0
|
||||
AI_MODEL=global.anthropic.claude-sonnet-5-5
|
||||
```
|
||||
|
||||
较新的 Claude 模型只能通过推理配置文件(inference profile)的 ID 调用,这种 ID 以地区前缀开头,例如 `global.` 或 `us.`。直接用 `anthropic.claude-sonnet-5-5` 这样的 ID 会报错 “on-demand throughput isn't supported”。
|
||||
|
||||
注意:在 AWS 环境(Lambda、带有 IAM 角色的 EC2)中,凭证会自动从 IAM 角色获取。
|
||||
|
||||
### OpenRouter
|
||||
|
||||
@@ -164,9 +164,11 @@ AZURE_REASONING_SUMMARY=detailed # Optional: none, brief, detailed
|
||||
AWS_REGION=us-west-2
|
||||
AWS_ACCESS_KEY_ID=your_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
AI_MODEL=anthropic.claude-sonnet-4-5-20250514-v1:0
|
||||
AI_MODEL=global.anthropic.claude-sonnet-5-5
|
||||
```
|
||||
|
||||
Recent Claude models answer only through an inference profile id, which starts with a region prefix such as `global.` or `us.`. The plain id (`anthropic.claude-sonnet-5-5`) fails with "on-demand throughput isn't supported".
|
||||
|
||||
Note: On AWS (Lambda, EC2 with IAM role), credentials are automatically obtained from the IAM role.
|
||||
|
||||
### OpenRouter
|
||||
|
||||
@@ -149,9 +149,11 @@ AZURE_REASONING_SUMMARY=detailed # 任意: none, brief, detailed
|
||||
AWS_REGION=us-west-2
|
||||
AWS_ACCESS_KEY_ID=your_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
AI_MODEL=anthropic.claude-sonnet-4-5-20250514-v1:0
|
||||
AI_MODEL=global.anthropic.claude-sonnet-5-5
|
||||
```
|
||||
|
||||
最近の Claude モデルは、推論プロファイル(inference profile)の ID でのみ呼び出せます。この ID は `global.` や `us.` などのリージョン接頭辞で始まります。`anthropic.claude-sonnet-5-5` のような接頭辞なしの ID では「on-demand throughput isn't supported」というエラーになります。
|
||||
|
||||
注: AWS 上(IAM ロールを持つ Lambda や EC2)では、認証情報は IAM ロールから自動的に取得されます。
|
||||
|
||||
### OpenRouter
|
||||
|
||||
@@ -18,21 +18,25 @@ interface CallParams {
|
||||
providerOptions?: Record<string, Record<string, unknown> | undefined>
|
||||
}
|
||||
|
||||
/** Drop a thinking config of type "enabled" stored under key, if any. */
|
||||
function withoutEnabledThinking(
|
||||
// What these models take instead of a budget. Without display "summarized"
|
||||
// they think but send no thinking text to show.
|
||||
const ADAPTIVE_THINKING = { type: "adaptive", display: "summarized" }
|
||||
|
||||
/** Turn a thinking config of type "enabled" stored under key into adaptive */
|
||||
function adaptiveThinking(
|
||||
options: Record<string, unknown> | undefined,
|
||||
key: string,
|
||||
): Record<string, unknown> | undefined {
|
||||
const config = options?.[key] as { type?: string } | undefined
|
||||
if (config?.type !== "enabled") return options
|
||||
const { [key]: _, ...rest } = options as Record<string, unknown>
|
||||
return rest
|
||||
return { ...options, [key]: ADAPTIVE_THINKING }
|
||||
}
|
||||
|
||||
/**
|
||||
* The params without the settings newer Claude models reject, or null when
|
||||
* the error is about something else or there is nothing to drop. The model
|
||||
* then runs with its own default sampling and thinking.
|
||||
* the error is about something else or there is nothing to change. The
|
||||
* model then runs with its default sampling, and a thinking budget becomes
|
||||
* adaptive thinking.
|
||||
*/
|
||||
export function withoutDeprecatedParams<T extends CallParams>(
|
||||
error: unknown,
|
||||
@@ -43,8 +47,8 @@ export function withoutDeprecatedParams<T extends CallParams>(
|
||||
|
||||
const { temperature, topP, topK, ...rest } = params
|
||||
const options = params.providerOptions
|
||||
const anthropic = withoutEnabledThinking(options?.anthropic, "thinking")
|
||||
const bedrock = withoutEnabledThinking(options?.bedrock, "reasoningConfig")
|
||||
const anthropic = adaptiveThinking(options?.anthropic, "thinking")
|
||||
const bedrock = adaptiveThinking(options?.bedrock, "reasoningConfig")
|
||||
const changed =
|
||||
temperature !== undefined ||
|
||||
topP !== undefined ||
|
||||
@@ -80,7 +84,7 @@ export function withDeprecatedParamsFallback(
|
||||
const retry = withoutDeprecatedParams(error, params)
|
||||
if (!retry) throw error
|
||||
console.warn(
|
||||
"[model params] Rejected sampling or thinking settings, retrying with the model defaults",
|
||||
"[model params] Rejected sampling or thinking settings, retrying with default sampling and adaptive thinking",
|
||||
)
|
||||
return await inner.doStream(retry)
|
||||
}
|
||||
|
||||
+21
-18
@@ -347,32 +347,35 @@ export const SUGGESTED_MODELS: Partial<Record<ProviderName, string[]>> = {
|
||||
"o3",
|
||||
"o4-mini",
|
||||
],
|
||||
// Newer models only answer through an inference profile id (the region
|
||||
// prefix). Each id here was called once on 2026-10-04.
|
||||
bedrock: [
|
||||
// Anthropic Claude
|
||||
"anthropic.claude-opus-4-8",
|
||||
"anthropic.claude-opus-4-7",
|
||||
"anthropic.claude-sonnet-4-6",
|
||||
"anthropic.claude-opus-4-6-v1",
|
||||
"anthropic.claude-opus-4-5-20251101-v1:0",
|
||||
"anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
"anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
"anthropic.claude-opus-4-1-20250805-v1:0",
|
||||
"anthropic.claude-opus-4-20250514-v1:0",
|
||||
"anthropic.claude-sonnet-4-20250514-v1:0",
|
||||
"anthropic.claude-3-5-haiku-20241022-v1:0",
|
||||
// Anthropic Claude ("global." works from any region)
|
||||
"global.anthropic.claude-opus-5-5",
|
||||
"global.anthropic.claude-sonnet-5-5",
|
||||
"global.anthropic.claude-fable-5-1",
|
||||
"global.anthropic.claude-opus-5",
|
||||
"global.anthropic.claude-sonnet-5",
|
||||
"global.anthropic.claude-opus-4-8",
|
||||
"global.anthropic.claude-opus-4-7",
|
||||
"global.anthropic.claude-sonnet-4-6",
|
||||
"global.anthropic.claude-opus-4-6-v1",
|
||||
"global.anthropic.claude-opus-4-5-20251101-v1:0",
|
||||
"global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
"global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
"global.anthropic.claude-sonnet-4-20250514-v1:0",
|
||||
// Amazon Nova
|
||||
"amazon.nova-2-lite-v1:0",
|
||||
"amazon.nova-premier-v1:0",
|
||||
"us.amazon.nova-2-lite-v1:0",
|
||||
"amazon.nova-pro-v1:0",
|
||||
"amazon.nova-lite-v1:0",
|
||||
"amazon.nova-micro-v1:0",
|
||||
// Meta Llama
|
||||
"meta.llama4-maverick-17b-instruct-v1:0",
|
||||
"meta.llama4-scout-17b-instruct-v1:0",
|
||||
"meta.llama3-3-70b-instruct-v1:0",
|
||||
"us.meta.llama4-maverick-17b-instruct-v1:0",
|
||||
"us.meta.llama4-scout-17b-instruct-v1:0",
|
||||
"us.meta.llama3-3-70b-instruct-v1:0",
|
||||
// Mistral
|
||||
"mistral.mistral-large-3-675b-instruct",
|
||||
"mistral.pixtral-large-2502-v1:0",
|
||||
"us.mistral.pixtral-large-2502-v1:0",
|
||||
],
|
||||
openrouter: [
|
||||
// Anthropic
|
||||
|
||||
@@ -31,18 +31,25 @@ describe("withoutDeprecatedParams", () => {
|
||||
},
|
||||
}
|
||||
|
||||
it("drops sampling settings and the thinking budget", () => {
|
||||
// Measured on Bedrock: Opus 4.7, 4.8 and every Claude 5 model accept
|
||||
// adaptive thinking, and return its text only with display "summarized"
|
||||
const ADAPTIVE = { type: "adaptive", display: "summarized" }
|
||||
|
||||
it("drops sampling settings and switches to adaptive thinking", () => {
|
||||
for (const error of [TEMPERATURE, THINKING]) {
|
||||
expect(withoutDeprecatedParams(error, params)).toEqual({
|
||||
maxOutputTokens: 1000,
|
||||
providerOptions: {
|
||||
anthropic: { cacheControl: { type: "ephemeral" } },
|
||||
anthropic: {
|
||||
thinking: ADAPTIVE,
|
||||
cacheControl: { type: "ephemeral" },
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it("drops a Bedrock thinking budget", () => {
|
||||
it("switches a Bedrock thinking budget to adaptive thinking", () => {
|
||||
const bedrock = {
|
||||
providerOptions: {
|
||||
bedrock: {
|
||||
@@ -51,7 +58,7 @@ describe("withoutDeprecatedParams", () => {
|
||||
},
|
||||
}
|
||||
expect(withoutDeprecatedParams(THINKING, bedrock)).toEqual({
|
||||
providerOptions: { bedrock: {} },
|
||||
providerOptions: { bedrock: { reasoningConfig: ADAPTIVE } },
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user