@ai-sdk/anthropic 3.0.80 → 3.0.82

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.
@@ -18,6 +18,8 @@ export type AnthropicMessagesModelId =
18
18
  | 'claude-sonnet-4-6'
19
19
  | 'claude-opus-4-6'
20
20
  | 'claude-opus-4-7'
21
+ | 'claude-opus-4-8'
22
+ | 'claude-fable-5'
21
23
  | (string & {});
22
24
 
23
25
  /**
@@ -223,6 +225,34 @@ export const anthropicLanguageModelOptions = z.object({
223
225
  */
224
226
  inferenceGeo: z.enum(['us', 'global']).optional(),
225
227
 
228
+ /**
229
+ * Server-side fallback chain.
230
+ *
231
+ * When the primary model's safety classifiers block a turn, the API
232
+ * automatically retries it on the next model in the chain, server-side. A
233
+ * `content-filter` finish reason means the entire chain refused.
234
+ *
235
+ * Each entry is merged into the request as a direct request to that entry's
236
+ * model, so it must be formatted accordingly: `model` is required, and an
237
+ * entry may additionally override `max_tokens`, `thinking`, `output_config`,
238
+ * and `speed` for that attempt only (`speed` additionally requires the speed
239
+ * beta). The value is passed through to the API as-is.
240
+ *
241
+ * The required `server-side-fallback-2026-06-01` beta is added automatically
242
+ * when this option is set.
243
+ */
244
+ fallbacks: z
245
+ .array(
246
+ z.object({
247
+ model: z.string(),
248
+ max_tokens: z.number().int().optional(),
249
+ thinking: z.record(z.string(), z.unknown()).optional(),
250
+ output_config: z.record(z.string(), z.unknown()).optional(),
251
+ speed: z.enum(['fast', 'standard']).optional(),
252
+ }),
253
+ )
254
+ .optional(),
255
+
226
256
  /**
227
257
  * A set of beta features to enable.
228
258
  * Allow a provider to receive the full `betas` set if it needs it.
@@ -42,7 +42,7 @@ export const anthropicTools = {
42
42
  * Supported executor models: Claude Haiku 4.5, Sonnet 4.6, Opus 4.6,
43
43
  * Opus 4.7. The advisor must be at least as capable as the executor.
44
44
  *
45
- * @param model - The advisor model ID (required), e.g. `"claude-opus-4-7"`.
45
+ * @param model - The advisor model ID (required), e.g. `"claude-opus-4-8"`.
46
46
  * @param maxUses - Maximum advisor calls per request (per-request cap).
47
47
  * @param caching - Enables prompt caching for the advisor's transcript
48
48
  * across calls within a conversation. Worthwhile from ~3 advisor calls
@@ -5,26 +5,25 @@ import type { JSONObject, LanguageModelV3Usage } from '@ai-sdk/provider';
5
5
  *
6
6
  * - `compaction` / `message`: executor iterations, billed at executor rates.
7
7
  * - `advisor_message`: advisor sub-inference, billed at the advisor model's
8
- * rates. The `model` field carries the advisor model ID. Advisor tokens
9
- * are NOT rolled into the top-level totals because they bill at a
10
- * different rate; inspect this array for advisor cost tracking.
8
+ * rates. Advisor tokens are NOT rolled into the top-level totals because
9
+ * they bill at a different rate; inspect this array for advisor cost
10
+ * tracking.
11
+ * - `fallback_message`: a server-side fallback attempt that served the turn.
12
+ * When present, the top-level usage already reflects the served answer, so
13
+ * it is used as-is.
14
+ *
15
+ * The `model` field carries the model that produced the iteration. The API
16
+ * populates it for the per-model attribution cases (the fallback chain and
17
+ * advisor sub-inferences) and omits it otherwise.
11
18
  */
12
- export type AnthropicUsageIteration =
13
- | {
14
- type: 'compaction' | 'message';
15
- input_tokens: number;
16
- output_tokens: number;
17
- cache_creation_input_tokens?: number | null;
18
- cache_read_input_tokens?: number | null;
19
- }
20
- | {
21
- type: 'advisor_message';
22
- model: string;
23
- input_tokens: number;
24
- output_tokens: number;
25
- cache_creation_input_tokens?: number | null;
26
- cache_read_input_tokens?: number | null;
27
- };
19
+ export type AnthropicUsageIteration = {
20
+ type: 'compaction' | 'message' | 'advisor_message' | 'fallback_message';
21
+ model?: string | null;
22
+ input_tokens: number;
23
+ output_tokens: number;
24
+ cache_creation_input_tokens?: number | null;
25
+ cache_read_input_tokens?: number | null;
26
+ };
28
27
 
29
28
  export type AnthropicMessagesUsage = {
30
29
  input_tokens: number;
@@ -57,10 +56,19 @@ export function convertAnthropicMessagesUsage({
57
56
  // and output_tokens exclude compaction usage. Advisor (`advisor_message`)
58
57
  // iterations are filtered out: they bill at the advisor model's rates,
59
58
  // not the executor's, so they don't belong in the top-level totals.
59
+ //
60
+ // A turn served by a server-side fallback is the exception: the served
61
+ // answer comes from the fallback model, so the executor `message` iteration
62
+ // is the blocked primary attempt (zero output). The top-level totals already
63
+ // reflect the fallback answer, so they are used directly.
60
64
  let inputTokens: number;
61
65
  let outputTokens: number;
62
66
 
63
- if (usage.iterations && usage.iterations.length > 0) {
67
+ const servedByFallback = usage.iterations?.some(
68
+ iter => iter.type === 'fallback_message',
69
+ );
70
+
71
+ if (usage.iterations && usage.iterations.length > 0 && !servedByFallback) {
64
72
  const executorIterations = usage.iterations.filter(
65
73
  iter => iter.type === 'compaction' || iter.type === 'message',
66
74
  );
@@ -157,15 +157,8 @@ export async function convertToAnthropicMessagesPrompt({
157
157
 
158
158
  switch (type) {
159
159
  case 'system': {
160
- if (system != null) {
161
- throw new UnsupportedFunctionalityError({
162
- functionality:
163
- 'Multiple system messages that are separated by user/assistant messages',
164
- });
165
- }
166
-
167
- system = block.messages.map(({ content, providerOptions }) => ({
168
- type: 'text',
160
+ const content = block.messages.map(({ content, providerOptions }) => ({
161
+ type: 'text' as const,
169
162
  text: content,
170
163
  cache_control: validator.getCacheControl(providerOptions, {
171
164
  type: 'system message',
@@ -173,6 +166,13 @@ export async function convertToAnthropicMessagesPrompt({
173
166
  }),
174
167
  }));
175
168
 
169
+ if (system == null) {
170
+ system = content;
171
+ } else {
172
+ messages.push({ role: 'system', content });
173
+ betas.add('mid-conversation-system-2026-04-07');
174
+ }
175
+
176
176
  break;
177
177
  }
178
178
 
@@ -77,7 +77,7 @@ const factory = createProviderToolFactoryWithOutputSchema<
77
77
  },
78
78
  {
79
79
  /**
80
- * The advisor model ID, such as `"claude-opus-4-7"`. Billed at this
80
+ * The advisor model ID, such as `"claude-opus-4-8"`. Billed at this
81
81
  * model's rates for the sub-inference.
82
82
  *
83
83
  * The advisor must be at least as capable as the executor; an invalid