@vellumai/assistant 0.12.5-dev.202609282216.bb92e6d → 0.12.5-dev.202609290048.637f7a7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -3653,6 +3653,8 @@ describe("AnthropicProvider — deprecated sampling params (temperature / top_p
|
|
|
3653
3653
|
"claude-opus-4-7",
|
|
3654
3654
|
"claude-sonnet-5",
|
|
3655
3655
|
"anthropic/claude-sonnet-5",
|
|
3656
|
+
"claude-sonnet-5-5",
|
|
3657
|
+
"anthropic/claude-sonnet-5.5",
|
|
3656
3658
|
"claude-fable-5",
|
|
3657
3659
|
"claude-fable-5-1",
|
|
3658
3660
|
"anthropic/claude-fable-5.1",
|
|
@@ -144,6 +144,53 @@ describe("retry normalization: thinking + forced tool_choice", () => {
|
|
|
144
144
|
expect(lastConfig()?.thinking).toEqual({ type: "adaptive" });
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
for (const [providerName, model] of [
|
|
148
|
+
["anthropic", "claude-sonnet-5-5"],
|
|
149
|
+
["anthropic", "claude-opus-5-5"],
|
|
150
|
+
["openrouter", "anthropic/claude-sonnet-5.5"],
|
|
151
|
+
["vercel-ai-gateway", "anthropic/claude-sonnet-5.5"],
|
|
152
|
+
] as const) {
|
|
153
|
+
test(`downgrades forced tool_choice to auto for ${providerName} ${model}`, async () => {
|
|
154
|
+
// These models always reason and reject forced tool use, so stripping
|
|
155
|
+
// `thinking` is not enough: the forced choice itself has to go.
|
|
156
|
+
setLlmConfig({
|
|
157
|
+
callSites: {
|
|
158
|
+
memoryExtraction: { provider: providerName, model },
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
const { provider, lastConfig } = makePipeline(providerName);
|
|
162
|
+
await provider.sendMessage([userMessage], {
|
|
163
|
+
config: {
|
|
164
|
+
callSite: "memoryExtraction",
|
|
165
|
+
tool_choice: { type: "tool", name: "extract_graph_diff" },
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
expect(lastConfig()?.tool_choice).toEqual({ type: "auto" });
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
test("keeps forced tool_choice for an adaptive-only model off the Anthropic wire", async () => {
|
|
173
|
+
setLlmConfig({
|
|
174
|
+
callSites: {
|
|
175
|
+
memoryExtraction: {
|
|
176
|
+
provider: "fireworks",
|
|
177
|
+
model: "accounts/fireworks/models/glm-5p3",
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
const { provider, lastConfig } = makePipeline("fireworks");
|
|
182
|
+
await provider.sendMessage([userMessage], {
|
|
183
|
+
config: {
|
|
184
|
+
callSite: "memoryExtraction",
|
|
185
|
+
tool_choice: { type: "tool", name: "extract_graph_diff" },
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
expect(lastConfig()?.tool_choice).toEqual({
|
|
189
|
+
type: "tool",
|
|
190
|
+
name: "extract_graph_diff",
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
147
194
|
test("preserves explicit thinking: disabled with forced tool_choice", async () => {
|
|
148
195
|
// Callers like the retriever explicitly set thinking: { type: "disabled" }
|
|
149
196
|
// alongside forced tool_choice. This should pass through unchanged since
|
|
@@ -1008,7 +1008,7 @@ export class AnthropicProvider implements Provider {
|
|
|
1008
1008
|
const isHaiku = effectiveModel.includes("haiku");
|
|
1009
1009
|
// Effort support is per-model: Haiku and Sonnet 4.5 reject the param (see isEffortSupported).
|
|
1010
1010
|
const supportsEffort = isEffortSupported(effectiveModel);
|
|
1011
|
-
// opus-4-7 / opus-4-8 / opus-5 / opus-5-5 and sonnet-5 reject `temperature`,
|
|
1011
|
+
// opus-4-7 / opus-4-8 / opus-5 / opus-5-5 and sonnet-5 / sonnet-5-5 reject `temperature`,
|
|
1012
1012
|
// `top_p`, and `top_k` with a 400 "`temperature`/`top_p` is deprecated
|
|
1013
1013
|
// for this model" — model-wide, not effort-conditional (verified
|
|
1014
1014
|
// 2026-06-23). opus-4-6 / sonnet-4-6 / haiku-4-5 still accept them.
|
|
@@ -331,6 +331,24 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
|
|
331
331
|
cacheReadPer1mTokens: 0.5,
|
|
332
332
|
},
|
|
333
333
|
},
|
|
334
|
+
{
|
|
335
|
+
id: "claude-sonnet-5-5",
|
|
336
|
+
displayName: "Claude Sonnet 5.5",
|
|
337
|
+
contextWindowTokens: 1000000,
|
|
338
|
+
maxOutputTokens: 128000,
|
|
339
|
+
longContextPricingThresholdTokens: 200000,
|
|
340
|
+
supportsThinking: true,
|
|
341
|
+
adaptiveThinkingOnly: true,
|
|
342
|
+
supportsCaching: true,
|
|
343
|
+
supportsVision: true,
|
|
344
|
+
supportsToolUse: true,
|
|
345
|
+
pricing: {
|
|
346
|
+
inputPer1mTokens: 2,
|
|
347
|
+
outputPer1mTokens: 10,
|
|
348
|
+
cacheWritePer1mTokens: 2.5,
|
|
349
|
+
cacheReadPer1mTokens: 0.2,
|
|
350
|
+
},
|
|
351
|
+
},
|
|
334
352
|
{
|
|
335
353
|
id: "claude-sonnet-5",
|
|
336
354
|
displayName: "Claude Sonnet 5",
|
|
@@ -1336,6 +1354,24 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
|
|
1336
1354
|
cacheReadPer1mTokens: 0.5,
|
|
1337
1355
|
},
|
|
1338
1356
|
},
|
|
1357
|
+
{
|
|
1358
|
+
id: "anthropic/claude-sonnet-5.5",
|
|
1359
|
+
displayName: "Claude Sonnet 5.5",
|
|
1360
|
+
contextWindowTokens: 1000000,
|
|
1361
|
+
maxOutputTokens: 128000,
|
|
1362
|
+
longContextPricingThresholdTokens: 200000,
|
|
1363
|
+
supportsThinking: true,
|
|
1364
|
+
adaptiveThinkingOnly: true,
|
|
1365
|
+
supportsCaching: true,
|
|
1366
|
+
supportsVision: true,
|
|
1367
|
+
supportsToolUse: true,
|
|
1368
|
+
pricing: {
|
|
1369
|
+
inputPer1mTokens: 2,
|
|
1370
|
+
outputPer1mTokens: 10,
|
|
1371
|
+
cacheWritePer1mTokens: 2.5,
|
|
1372
|
+
cacheReadPer1mTokens: 0.2,
|
|
1373
|
+
},
|
|
1374
|
+
},
|
|
1339
1375
|
{
|
|
1340
1376
|
id: "anthropic/claude-sonnet-5",
|
|
1341
1377
|
displayName: "Claude Sonnet 5",
|
|
@@ -2390,6 +2426,24 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
|
|
2390
2426
|
cacheReadPer1mTokens: 0.5,
|
|
2391
2427
|
},
|
|
2392
2428
|
},
|
|
2429
|
+
{
|
|
2430
|
+
id: "anthropic/claude-sonnet-5.5",
|
|
2431
|
+
displayName: "Claude Sonnet 5.5",
|
|
2432
|
+
contextWindowTokens: 1000000,
|
|
2433
|
+
maxOutputTokens: 128000,
|
|
2434
|
+
longContextPricingThresholdTokens: 200000,
|
|
2435
|
+
supportsThinking: true,
|
|
2436
|
+
adaptiveThinkingOnly: true,
|
|
2437
|
+
supportsCaching: true,
|
|
2438
|
+
supportsVision: true,
|
|
2439
|
+
supportsToolUse: true,
|
|
2440
|
+
pricing: {
|
|
2441
|
+
inputPer1mTokens: 2,
|
|
2442
|
+
outputPer1mTokens: 10,
|
|
2443
|
+
cacheWritePer1mTokens: 2.5,
|
|
2444
|
+
cacheReadPer1mTokens: 0.2,
|
|
2445
|
+
},
|
|
2446
|
+
},
|
|
2393
2447
|
{
|
|
2394
2448
|
id: "anthropic/claude-sonnet-5",
|
|
2395
2449
|
displayName: "Claude Sonnet 5",
|
package/src/providers/retry.ts
CHANGED
|
@@ -928,6 +928,36 @@ function normalizeSendMessageOptions(
|
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
930
|
|
|
931
|
+
// Adaptive-thinking-only Claude models (Fable, Opus 5.5, Sonnet 5.5) cannot
|
|
932
|
+
// turn reasoning off, so stripping `thinking` below does not clear the
|
|
933
|
+
// forced-tool conflict and Anthropic 400s the request. Downgrade the forced
|
|
934
|
+
// choice to `auto` so the call goes out. The tool is no longer guaranteed:
|
|
935
|
+
// forced-tool call sites already treat a missing tool call as a failed
|
|
936
|
+
// result, which is what the 400 gave them on every request.
|
|
937
|
+
const forcedToolModel =
|
|
938
|
+
typeof nextConfig.model === "string" ? nextConfig.model : "";
|
|
939
|
+
const forcedToolChoice = nextConfig.tool_choice as
|
|
940
|
+
| Record<string, unknown>
|
|
941
|
+
| undefined;
|
|
942
|
+
if (
|
|
943
|
+
forcedToolChoice != null &&
|
|
944
|
+
(forcedToolChoice.type === "tool" || forcedToolChoice.type === "any") &&
|
|
945
|
+
isAdaptiveThinkingOnlyModel(forcedToolModel) &&
|
|
946
|
+
targetsAnthropicWire(providerName, forcedToolModel)
|
|
947
|
+
) {
|
|
948
|
+
log.warn(
|
|
949
|
+
{
|
|
950
|
+
providerName,
|
|
951
|
+
callSite: config.callSite,
|
|
952
|
+
model: forcedToolModel,
|
|
953
|
+
droppedToolChoice: forcedToolChoice,
|
|
954
|
+
},
|
|
955
|
+
"Downgrading forced `tool_choice` to `auto` because this model always " +
|
|
956
|
+
"reasons and rejects forced tool use.",
|
|
957
|
+
);
|
|
958
|
+
nextConfig.tool_choice = { type: "auto" };
|
|
959
|
+
}
|
|
960
|
+
|
|
931
961
|
// Anthropic (and the gateways fronting Anthropic) rejects requests that
|
|
932
962
|
// combine extended thinking with forced tool use (`tool_choice.type` of
|
|
933
963
|
// `"tool"` or `"any"`). Strip thinking when both are present so the
|