@ai-sdk/anthropic 4.0.15 → 4.0.17

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.
@@ -1489,7 +1489,7 @@ To use skills, you need to:
1489
1489
  1. Enable the code execution tool
1490
1490
  2. Specify the container with skills in `providerOptions`
1491
1491
 
1492
- ```ts highlight="4,9-17,19-23"
1492
+ ```ts highlight="6-8,10-23"
1493
1493
  import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
1494
1494
  import { generateText } from 'ai';
1495
1495
 
@@ -1519,7 +1519,7 @@ const result = await generateText({
1519
1519
 
1520
1520
  You can also use custom skills by specifying `type: 'custom'`:
1521
1521
 
1522
- ```ts highlight="9-11"
1522
+ ```ts highlight="11-15"
1523
1523
  const result = await generateText({
1524
1524
  model: anthropic('claude-sonnet-4-5'),
1525
1525
  tools: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "4.0.15",
3
+ "version": "4.0.17",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@ai-sdk/provider": "4.0.3",
39
- "@ai-sdk/provider-utils": "5.0.10"
39
+ "@ai-sdk/provider-utils": "5.0.12"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "22.19.19",
@@ -67,6 +67,7 @@ export interface AnthropicCompactionContent {
67
67
  export interface AnthropicTextContent {
68
68
  type: 'text';
69
69
  text: string;
70
+ citations?: Citation[];
70
71
  cache_control: AnthropicCacheControl | undefined;
71
72
  }
72
73
 
@@ -356,6 +356,19 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
356
356
  }
357
357
  : undefined;
358
358
 
359
+ if (
360
+ jsonResponseTool != null &&
361
+ anthropicOptions?.disableParallelToolUse === false
362
+ ) {
363
+ warnings.push({
364
+ type: 'unsupported',
365
+ feature: 'providerOptions.anthropic.disableParallelToolUse',
366
+ details:
367
+ '`disableParallelToolUse: false` is ignored when using the JSON response tool. ' +
368
+ 'Parallel tool use is disabled to ensure a single coherent JSON tool call.',
369
+ });
370
+ }
371
+
359
372
  const contextManagement = anthropicOptions?.contextManagement;
360
373
 
361
374
  // Create a shared cache control validator to track breakpoints across tools and messages
@@ -927,7 +940,22 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
927
940
  switch (part.type) {
928
941
  case 'text': {
929
942
  if (!usesJsonResponseTool) {
930
- content.push({ type: 'text', text: part.text });
943
+ const webSearchCitations = part.citations?.filter(
944
+ citation => citation.type === 'web_search_result_location',
945
+ );
946
+
947
+ content.push({
948
+ type: 'text',
949
+ text: part.text,
950
+ ...(webSearchCitations != null &&
951
+ webSearchCitations.length > 0 && {
952
+ providerMetadata: {
953
+ anthropic: {
954
+ citations: webSearchCitations,
955
+ },
956
+ },
957
+ }),
958
+ });
931
959
 
932
960
  // Process citations if present
933
961
  if (part.citations) {
@@ -1509,7 +1537,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1509
1537
  toolId?: string;
1510
1538
  };
1511
1539
  }
1512
- | { type: 'text' | 'reasoning' }
1540
+ | { type: 'text'; citations: Citation[] }
1541
+ | { type: 'reasoning' }
1513
1542
  > = {};
1514
1543
  const mcpToolCalls: Record<string, LanguageModelV4ToolCall> = {};
1515
1544
  const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
@@ -1590,7 +1619,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1590
1619
  return;
1591
1620
  }
1592
1621
 
1593
- contentBlocks[value.index] = { type: 'text' };
1622
+ contentBlocks[value.index] = {
1623
+ type: 'text',
1624
+ citations: [],
1625
+ };
1594
1626
  controller.enqueue({
1595
1627
  type: 'text-start',
1596
1628
  id: String(value.index),
@@ -1622,7 +1654,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1622
1654
  }
1623
1655
 
1624
1656
  case 'compaction': {
1625
- contentBlocks[value.index] = { type: 'text' };
1657
+ contentBlocks[value.index] = {
1658
+ type: 'text',
1659
+ citations: [],
1660
+ };
1626
1661
  controller.enqueue({
1627
1662
  type: 'text-start',
1628
1663
  id: String(value.index),
@@ -1642,7 +1677,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1642
1677
  if (isJsonResponseTool) {
1643
1678
  isJsonResponseFromTool = true;
1644
1679
 
1645
- contentBlocks[value.index] = { type: 'text' };
1680
+ contentBlocks[value.index] = {
1681
+ type: 'text',
1682
+ citations: [],
1683
+ };
1646
1684
 
1647
1685
  controller.enqueue({
1648
1686
  type: 'text-start',
@@ -2101,6 +2139,13 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
2101
2139
  controller.enqueue({
2102
2140
  type: 'text-end',
2103
2141
  id: String(value.index),
2142
+ ...(contentBlock.citations.length > 0 && {
2143
+ providerMetadata: {
2144
+ anthropic: {
2145
+ citations: contentBlock.citations,
2146
+ },
2147
+ },
2148
+ }),
2104
2149
  });
2105
2150
  break;
2106
2151
  }
@@ -2291,6 +2336,15 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
2291
2336
 
2292
2337
  case 'citations_delta': {
2293
2338
  const citation = value.delta.citation;
2339
+ const contentBlock = contentBlocks[value.index];
2340
+
2341
+ if (
2342
+ contentBlock?.type === 'text' &&
2343
+ citation.type === 'web_search_result_location'
2344
+ ) {
2345
+ contentBlock.citations.push(citation);
2346
+ }
2347
+
2294
2348
  const source = createCitationSource(
2295
2349
  citation,
2296
2350
  citationDocuments,
@@ -26,6 +26,7 @@ import {
26
26
  type AnthropicToolResultContent,
27
27
  type AnthropicUserMessage,
28
28
  type AnthropicWebFetchToolResultContent,
29
+ type Citation,
29
30
  } from './anthropic-api';
30
31
  import { anthropicFilePartProviderOptions } from './anthropic-language-model-options';
31
32
  import { CacheControlValidator } from './get-cache-control';
@@ -585,7 +586,7 @@ export async function convertToAnthropicPrompt({
585
586
  case 'text': {
586
587
  // Check if this is a compaction block (via providerMetadata)
587
588
  const textMetadata = part.providerOptions?.anthropic as
588
- | { type?: string }
589
+ | { type?: string; citations?: Citation[] }
589
590
  | undefined;
590
591
 
591
592
  if (textMetadata?.type === 'compaction') {
@@ -604,7 +605,9 @@ export async function convertToAnthropicPrompt({
604
605
  isLastBlock && isLastMessage && isLastContentPart
605
606
  ? part.text.trim()
606
607
  : part.text,
607
-
608
+ ...(textMetadata?.citations != null && {
609
+ citations: textMetadata.citations,
610
+ }),
608
611
  cache_control: cacheControl,
609
612
  });
610
613
  }
@@ -12,4 +12,5 @@ export type {
12
12
  AnthropicModelId as AnthropicMessagesModelId,
13
13
  } from '../anthropic-language-model-options';
14
14
  export { prepareTools } from '../anthropic-prepare-tools';
15
+ export { sanitizeJsonSchema } from '../sanitize-json-schema';
15
16
  export { AnthropicSkills } from '../skills/anthropic-skills';