@ai-sdk/anthropic 4.0.78 → 4.0.80
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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +349 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -27
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +6 -3
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +89 -24
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +41 -0
- package/package.json +3 -3
- package/src/anthropic-api.ts +1 -0
- package/src/anthropic-batch.ts +20 -7
- package/src/anthropic-language-model.ts +84 -31
- package/src/anthropic-prepare-tools.ts +11 -7
- package/src/anthropic-provider-metadata.ts +16 -0
- package/src/convert-to-anthropic-prompt.ts +24 -0
- package/src/index.ts +4 -0
- package/src/map-anthropic-citation.ts +51 -0
package/docs/05-anthropic.mdx
CHANGED
|
@@ -742,6 +742,13 @@ room for both, the provider adds `budgetTokens` to `maxOutputTokens` when
|
|
|
742
742
|
setting `max_tokens`. For known models, the combined value is capped at the
|
|
743
743
|
model's maximum output token limit.
|
|
744
744
|
|
|
745
|
+
With manual thinking (`thinking.type: 'enabled'`), a `required` or named
|
|
746
|
+
`toolChoice` falls back to `auto` with a warning. For a named tool choice, only
|
|
747
|
+
the selected tool is sent. This also applies when the top-level `reasoning`
|
|
748
|
+
option enables manual thinking, including when structured output uses the
|
|
749
|
+
internal JSON response tool. Tool use is no longer guaranteed: instruct the
|
|
750
|
+
model to use the tool in your prompt and verify that a tool call was made.
|
|
751
|
+
|
|
745
752
|
See [AI SDK UI: Chatbot](/docs/ai-sdk-ui/chatbot#reasoning) for more details
|
|
746
753
|
on how to integrate reasoning into your chatbot.
|
|
747
754
|
|
|
@@ -1420,6 +1427,40 @@ const result = await generateText({
|
|
|
1420
1427
|
settings](https://console.anthropic.com/settings/privacy).
|
|
1421
1428
|
</Note>
|
|
1422
1429
|
|
|
1430
|
+
#### Sources and Citations
|
|
1431
|
+
|
|
1432
|
+
`result.sources` and source stream events expose web-search results. Inline
|
|
1433
|
+
references are attached separately to generated text as `part.citations`, and
|
|
1434
|
+
to streamed text as `text-end.citations`. This shared citation representation
|
|
1435
|
+
includes the referenced URL or document and its supporting passage. If web-search
|
|
1436
|
+
results are unavailable, web citations also provide source references for
|
|
1437
|
+
compatibility. Indexed document references retain their existing document source
|
|
1438
|
+
parts when the original prompt supplies document information.
|
|
1439
|
+
|
|
1440
|
+
Raw citations remain available as
|
|
1441
|
+
`text.providerMetadata.anthropic.citations`, including on streamed `text-end`
|
|
1442
|
+
events. Import `AnthropicTextProviderMetadata` and `AnthropicCitation` for typed
|
|
1443
|
+
access. `AnthropicCitation` is a union of `web_search_result_location`,
|
|
1444
|
+
`search_result_location`, `page_location`, `char_location`, and
|
|
1445
|
+
`content_block_location`. Document page, character, and block locations refer to
|
|
1446
|
+
the source document, rather than the generated answer.
|
|
1447
|
+
|
|
1448
|
+
```ts
|
|
1449
|
+
import type { AnthropicTextProviderMetadata } from '@ai-sdk/anthropic';
|
|
1450
|
+
|
|
1451
|
+
for (const part of result.content) {
|
|
1452
|
+
if (part.type === 'text') {
|
|
1453
|
+
console.log(part.citations);
|
|
1454
|
+
const metadata = part.providerMetadata as
|
|
1455
|
+
| AnthropicTextProviderMetadata
|
|
1456
|
+
| undefined;
|
|
1457
|
+
for (const citation of metadata?.anthropic.citations ?? []) {
|
|
1458
|
+
console.log(citation.type, citation.cited_text);
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
```
|
|
1463
|
+
|
|
1423
1464
|
#### Configuration Options
|
|
1424
1465
|
|
|
1425
1466
|
Use `webSearch_20260318` for dynamic filtering and response inclusion control.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/anthropic",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.80",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ai-sdk/provider": "4.0.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
38
|
+
"@ai-sdk/provider": "4.0.27",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.60"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.4",
|
package/src/anthropic-api.ts
CHANGED
|
@@ -594,6 +594,7 @@ export type AnthropicSpeed = 'fast' | 'standard';
|
|
|
594
594
|
|
|
595
595
|
export type AnthropicToolChoice =
|
|
596
596
|
| { type: 'auto' | 'any'; disable_parallel_tool_use?: boolean }
|
|
597
|
+
| { type: 'none' }
|
|
597
598
|
| { type: 'tool'; name: string; disable_parallel_tool_use?: boolean };
|
|
598
599
|
|
|
599
600
|
export type AnthropicContainer = {
|
package/src/anthropic-batch.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mapAnthropicCitation } from './map-anthropic-citation';
|
|
1
2
|
import {
|
|
2
3
|
InvalidArgumentError,
|
|
3
4
|
InvalidResponseDataError,
|
|
@@ -44,8 +45,8 @@ import {
|
|
|
44
45
|
} from './anthropic-api';
|
|
45
46
|
import { anthropicFailedResponseHandler } from './anthropic-error';
|
|
46
47
|
import {
|
|
47
|
-
AnthropicLanguageModel,
|
|
48
48
|
createCitationSource,
|
|
49
|
+
AnthropicLanguageModel,
|
|
49
50
|
type AnthropicLanguageModelConfig,
|
|
50
51
|
} from './anthropic-language-model';
|
|
51
52
|
import {
|
|
@@ -746,6 +747,12 @@ function convertAnthropicBatchResponse(
|
|
|
746
747
|
> = {};
|
|
747
748
|
const serverToolCalls: Record<string, string> = {};
|
|
748
749
|
|
|
750
|
+
const hasWebSearchResults = response.content.some(
|
|
751
|
+
part =>
|
|
752
|
+
part.type === 'web_search_tool_result' &&
|
|
753
|
+
Array.isArray(part.content) &&
|
|
754
|
+
part.content.length > 0,
|
|
755
|
+
);
|
|
749
756
|
for (const part of response.content) {
|
|
750
757
|
switch (part.type) {
|
|
751
758
|
case 'text':
|
|
@@ -754,6 +761,12 @@ function convertAnthropicBatchResponse(
|
|
|
754
761
|
content.push({
|
|
755
762
|
type: 'text',
|
|
756
763
|
text: part.text,
|
|
764
|
+
...(citations != null &&
|
|
765
|
+
citations.length > 0 && {
|
|
766
|
+
citations: citations.map(citation =>
|
|
767
|
+
mapAnthropicCitation(citation, []),
|
|
768
|
+
),
|
|
769
|
+
}),
|
|
757
770
|
...(citations != null &&
|
|
758
771
|
citations.length > 0 && {
|
|
759
772
|
providerMetadata: {
|
|
@@ -762,12 +775,12 @@ function convertAnthropicBatchResponse(
|
|
|
762
775
|
}),
|
|
763
776
|
});
|
|
764
777
|
for (const citation of part.citations ?? []) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
content.push(source);
|
|
778
|
+
if (
|
|
779
|
+
citation.type === 'web_search_result_location' &&
|
|
780
|
+
!hasWebSearchResults
|
|
781
|
+
) {
|
|
782
|
+
const source = createCitationSource(citation, [], generateId);
|
|
783
|
+
if (source) content.push(source);
|
|
771
784
|
}
|
|
772
785
|
}
|
|
773
786
|
break;
|
|
@@ -46,6 +46,8 @@ import type {
|
|
|
46
46
|
AnthropicMessageMetadata,
|
|
47
47
|
AnthropicUsageIteration,
|
|
48
48
|
} from './anthropic-message-metadata';
|
|
49
|
+
import { mapAnthropicCitation } from './map-anthropic-citation';
|
|
50
|
+
import type { AnthropicTextProviderMetadata } from './anthropic-provider-metadata';
|
|
49
51
|
import {
|
|
50
52
|
anthropicChunkSchema,
|
|
51
53
|
anthropicResponseSchema,
|
|
@@ -130,8 +132,8 @@ export function createCitationSource(
|
|
|
130
132
|
): LanguageModelV4Source | undefined {
|
|
131
133
|
if (citation.type === 'web_search_result_location') {
|
|
132
134
|
return {
|
|
133
|
-
type: 'source'
|
|
134
|
-
sourceType: 'url'
|
|
135
|
+
type: 'source',
|
|
136
|
+
sourceType: 'url',
|
|
135
137
|
id: generateId(),
|
|
136
138
|
url: citation.url,
|
|
137
139
|
title: citation.title ?? undefined,
|
|
@@ -140,7 +142,7 @@ export function createCitationSource(
|
|
|
140
142
|
citedText: citation.cited_text,
|
|
141
143
|
encryptedIndex: citation.encrypted_index,
|
|
142
144
|
},
|
|
143
|
-
}
|
|
145
|
+
},
|
|
144
146
|
};
|
|
145
147
|
}
|
|
146
148
|
|
|
@@ -253,6 +255,12 @@ export type AnthropicLanguageModelConfig = {
|
|
|
253
255
|
args: Record<string, any>,
|
|
254
256
|
betas: Set<string>,
|
|
255
257
|
) => Record<string, any>;
|
|
258
|
+
transformRequestHeaders?: (
|
|
259
|
+
headers: Record<string, string | undefined>,
|
|
260
|
+
providerOptions: LanguageModelV4CallOptions['providerOptions'],
|
|
261
|
+
) =>
|
|
262
|
+
| Record<string, string | undefined>
|
|
263
|
+
| PromiseLike<Record<string, string | undefined>>;
|
|
256
264
|
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
257
265
|
generateId?: () => string;
|
|
258
266
|
supportsNativeStructuredOutput?: boolean;
|
|
@@ -1065,7 +1073,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1065
1073
|
supportsStructuredOutput: false,
|
|
1066
1074
|
supportsStrictTools,
|
|
1067
1075
|
defaultEagerInputStreaming,
|
|
1068
|
-
rejectsForcedToolUse
|
|
1076
|
+
rejectsForcedToolUse:
|
|
1077
|
+
rejectsForcedToolUse || thinkingType === 'enabled',
|
|
1069
1078
|
}
|
|
1070
1079
|
: {
|
|
1071
1080
|
tools: tools ?? [],
|
|
@@ -1075,7 +1084,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1075
1084
|
supportsStructuredOutput,
|
|
1076
1085
|
supportsStrictTools,
|
|
1077
1086
|
defaultEagerInputStreaming,
|
|
1078
|
-
rejectsForcedToolUse
|
|
1087
|
+
rejectsForcedToolUse:
|
|
1088
|
+
rejectsForcedToolUse || thinkingType === 'enabled',
|
|
1079
1089
|
},
|
|
1080
1090
|
);
|
|
1081
1091
|
|
|
@@ -1119,15 +1129,21 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1119
1129
|
private async getHeaders({
|
|
1120
1130
|
betas,
|
|
1121
1131
|
headers,
|
|
1132
|
+
providerOptions,
|
|
1122
1133
|
}: {
|
|
1123
1134
|
betas: Set<string>;
|
|
1124
1135
|
headers: Record<string, string | undefined> | undefined;
|
|
1136
|
+
providerOptions: LanguageModelV4CallOptions['providerOptions'];
|
|
1125
1137
|
}) {
|
|
1126
|
-
|
|
1138
|
+
const combinedHeaders = combineHeaders(
|
|
1127
1139
|
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
1128
1140
|
headers,
|
|
1129
1141
|
betas.size > 0 ? { 'anthropic-beta': Array.from(betas).join(',') } : {},
|
|
1130
1142
|
);
|
|
1143
|
+
|
|
1144
|
+
return this.config.transformRequestHeaders
|
|
1145
|
+
? this.config.transformRequestHeaders(combinedHeaders, providerOptions)
|
|
1146
|
+
: combinedHeaders;
|
|
1131
1147
|
}
|
|
1132
1148
|
|
|
1133
1149
|
private async getBetasFromHeaders(
|
|
@@ -1238,7 +1254,11 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1238
1254
|
rawValue: rawResponse,
|
|
1239
1255
|
} = await postJsonToApi({
|
|
1240
1256
|
url: this.buildRequestUrl(false),
|
|
1241
|
-
headers: await this.getHeaders({
|
|
1257
|
+
headers: await this.getHeaders({
|
|
1258
|
+
betas,
|
|
1259
|
+
headers: options.headers,
|
|
1260
|
+
providerOptions: options.providerOptions,
|
|
1261
|
+
}),
|
|
1242
1262
|
body: this.transformRequestBody(args, betas),
|
|
1243
1263
|
failedResponseHandler: anthropicFailedResponseHandler,
|
|
1244
1264
|
successfulResponseHandler: createJsonResponseHandler(
|
|
@@ -1253,31 +1273,45 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1253
1273
|
const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
|
|
1254
1274
|
let isJsonResponseFromTool = false;
|
|
1255
1275
|
|
|
1276
|
+
const hasWebSearchResults = response.content.some(
|
|
1277
|
+
part =>
|
|
1278
|
+
part.type === 'web_search_tool_result' &&
|
|
1279
|
+
Array.isArray(part.content) &&
|
|
1280
|
+
part.content.length > 0,
|
|
1281
|
+
);
|
|
1256
1282
|
// map response content to content array
|
|
1257
1283
|
for (const part of response.content) {
|
|
1258
1284
|
switch (part.type) {
|
|
1259
1285
|
case 'text': {
|
|
1260
1286
|
if (!usesJsonResponseTool) {
|
|
1261
|
-
const
|
|
1262
|
-
citation => citation.type === 'web_search_result_location',
|
|
1263
|
-
);
|
|
1287
|
+
const citations = part.citations ?? [];
|
|
1264
1288
|
|
|
1265
1289
|
content.push({
|
|
1266
1290
|
type: 'text',
|
|
1267
1291
|
text: part.text,
|
|
1268
|
-
...(
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1292
|
+
...(citations.length > 0 && {
|
|
1293
|
+
citations: citations.map(citation =>
|
|
1294
|
+
mapAnthropicCitation(citation, citationDocuments),
|
|
1295
|
+
),
|
|
1296
|
+
}),
|
|
1297
|
+
...(citations.length > 0 && {
|
|
1298
|
+
providerMetadata: {
|
|
1299
|
+
anthropic: {
|
|
1300
|
+
citations,
|
|
1274
1301
|
},
|
|
1275
|
-
}
|
|
1302
|
+
} satisfies AnthropicTextProviderMetadata,
|
|
1303
|
+
}),
|
|
1276
1304
|
});
|
|
1277
1305
|
|
|
1278
1306
|
// Process citations if present
|
|
1279
1307
|
if (part.citations) {
|
|
1280
1308
|
for (const citation of part.citations) {
|
|
1309
|
+
if (
|
|
1310
|
+
citation.type === 'web_search_result_location' &&
|
|
1311
|
+
hasWebSearchResults
|
|
1312
|
+
) {
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1281
1315
|
const source = createCitationSource(
|
|
1282
1316
|
citation,
|
|
1283
1317
|
citationDocuments,
|
|
@@ -1864,7 +1898,11 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1864
1898
|
const url = this.buildRequestUrl(true);
|
|
1865
1899
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
1866
1900
|
url,
|
|
1867
|
-
headers: await this.getHeaders({
|
|
1901
|
+
headers: await this.getHeaders({
|
|
1902
|
+
betas,
|
|
1903
|
+
headers: options.headers,
|
|
1904
|
+
providerOptions: options.providerOptions,
|
|
1905
|
+
}),
|
|
1868
1906
|
body: this.transformRequestBody(body, betas),
|
|
1869
1907
|
failedResponseHandler: anthropicFailedResponseHandler,
|
|
1870
1908
|
successfulResponseHandler:
|
|
@@ -1926,6 +1964,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1926
1964
|
let safeguardResults: AnthropicMessageMetadata['safeguardResults'];
|
|
1927
1965
|
let container: AnthropicMessageMetadata['container'] | null = null;
|
|
1928
1966
|
let isJsonResponseFromTool = false;
|
|
1967
|
+
let hasWebSearchResults = false;
|
|
1968
|
+
const fallbackWebCitations: Citation[] = [];
|
|
1929
1969
|
let isMessageOpen = false;
|
|
1930
1970
|
let activeMessageId: string | null | undefined;
|
|
1931
1971
|
let hasInvalidMessageSequence = false;
|
|
@@ -2345,6 +2385,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2345
2385
|
});
|
|
2346
2386
|
|
|
2347
2387
|
for (const result of part.content) {
|
|
2388
|
+
hasWebSearchResults = true;
|
|
2348
2389
|
controller.enqueue({
|
|
2349
2390
|
type: 'source',
|
|
2350
2391
|
sourceType: 'url',
|
|
@@ -2587,11 +2628,14 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2587
2628
|
type: 'text-end',
|
|
2588
2629
|
id: String(value.index),
|
|
2589
2630
|
...(contentBlock.citations.length > 0 && {
|
|
2631
|
+
citations: contentBlock.citations.map(citation =>
|
|
2632
|
+
mapAnthropicCitation(citation, citationDocuments),
|
|
2633
|
+
),
|
|
2590
2634
|
providerMetadata: {
|
|
2591
2635
|
anthropic: {
|
|
2592
2636
|
citations: contentBlock.citations,
|
|
2593
2637
|
},
|
|
2594
|
-
},
|
|
2638
|
+
} satisfies AnthropicTextProviderMetadata,
|
|
2595
2639
|
}),
|
|
2596
2640
|
});
|
|
2597
2641
|
break;
|
|
@@ -2828,21 +2872,19 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2828
2872
|
const citation = value.delta.citation;
|
|
2829
2873
|
const contentBlock = contentBlocks[value.index];
|
|
2830
2874
|
|
|
2831
|
-
if (
|
|
2832
|
-
contentBlock?.type === 'text' &&
|
|
2833
|
-
citation.type === 'web_search_result_location'
|
|
2834
|
-
) {
|
|
2875
|
+
if (contentBlock?.type === 'text') {
|
|
2835
2876
|
contentBlock.citations.push(citation);
|
|
2836
2877
|
}
|
|
2837
2878
|
|
|
2838
|
-
|
|
2839
|
-
citation
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2879
|
+
if (citation.type === 'web_search_result_location') {
|
|
2880
|
+
fallbackWebCitations.push(citation);
|
|
2881
|
+
} else {
|
|
2882
|
+
const source = createCitationSource(
|
|
2883
|
+
citation,
|
|
2884
|
+
citationDocuments,
|
|
2885
|
+
generateId,
|
|
2886
|
+
);
|
|
2887
|
+
if (source) controller.enqueue(source);
|
|
2846
2888
|
}
|
|
2847
2889
|
|
|
2848
2890
|
return;
|
|
@@ -3101,6 +3143,17 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
3101
3143
|
providerMetadata[providerOptionsName] = anthropicMetadata;
|
|
3102
3144
|
}
|
|
3103
3145
|
|
|
3146
|
+
if (!hasWebSearchResults) {
|
|
3147
|
+
for (const citation of fallbackWebCitations) {
|
|
3148
|
+
const source = createCitationSource(
|
|
3149
|
+
citation,
|
|
3150
|
+
citationDocuments,
|
|
3151
|
+
generateId,
|
|
3152
|
+
);
|
|
3153
|
+
if (source) controller.enqueue(source);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
fallbackWebCitations.length = 0;
|
|
3104
3157
|
controller.enqueue({
|
|
3105
3158
|
type: 'finish',
|
|
3106
3159
|
finishReason,
|
|
@@ -56,9 +56,9 @@ export async function prepareTools({
|
|
|
56
56
|
defaultEagerInputStreaming?: boolean;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Whether the model rejects forced tool use
|
|
60
|
-
* named tool). When true, `required` and `tool`
|
|
61
|
-
* `auto` with a warning.
|
|
59
|
+
* Whether the model or thinking configuration rejects forced tool use
|
|
60
|
+
* (`tool_choice` `any` or a named tool). When true, `required` and `tool`
|
|
61
|
+
* tool choices fall back to `auto` with a warning.
|
|
62
62
|
*/
|
|
63
63
|
rejectsForcedToolUse?: boolean;
|
|
64
64
|
}): Promise<{
|
|
@@ -492,7 +492,7 @@ export async function prepareTools({
|
|
|
492
492
|
type: 'unsupported',
|
|
493
493
|
feature: 'toolChoice',
|
|
494
494
|
details:
|
|
495
|
-
`toolChoice 'required' is not supported
|
|
495
|
+
`toolChoice 'required' is not supported with this model or thinking configuration. ` +
|
|
496
496
|
`Using 'auto' instead. Instruct the model to use a tool in the prompt and verify that a tool call was made.`,
|
|
497
497
|
});
|
|
498
498
|
return {
|
|
@@ -515,15 +515,19 @@ export async function prepareTools({
|
|
|
515
515
|
betas,
|
|
516
516
|
};
|
|
517
517
|
case 'none':
|
|
518
|
-
|
|
519
|
-
|
|
518
|
+
return {
|
|
519
|
+
tools: anthropicTools,
|
|
520
|
+
toolChoice: { type: 'none' },
|
|
521
|
+
toolWarnings,
|
|
522
|
+
betas,
|
|
523
|
+
};
|
|
520
524
|
case 'tool':
|
|
521
525
|
if (rejectsForcedToolUse) {
|
|
522
526
|
toolWarnings.push({
|
|
523
527
|
type: 'unsupported',
|
|
524
528
|
feature: 'toolChoice',
|
|
525
529
|
details:
|
|
526
|
-
`toolChoice 'tool' is not supported
|
|
530
|
+
`toolChoice 'tool' is not supported with this model or thinking configuration. ` +
|
|
527
531
|
`Only the '${toolChoice.toolName}' tool is sent with 'auto' tool choice. ` +
|
|
528
532
|
`Instruct the model to use the tool in the prompt and verify that a tool call was made.`,
|
|
529
533
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Citation } from './anthropic-api';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Citation metadata returned by Anthropic for generated text.
|
|
5
|
+
*/
|
|
6
|
+
export type AnthropicCitation = Citation;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Anthropic provider metadata attached to generated text that contains
|
|
10
|
+
* citations.
|
|
11
|
+
*/
|
|
12
|
+
export type AnthropicTextProviderMetadata = {
|
|
13
|
+
anthropic: {
|
|
14
|
+
citations: AnthropicCitation[];
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -1342,6 +1342,30 @@ export async function convertToAnthropicPrompt({
|
|
|
1342
1342
|
) {
|
|
1343
1343
|
const output = part.output;
|
|
1344
1344
|
|
|
1345
|
+
if (
|
|
1346
|
+
output.type === 'error-json' ||
|
|
1347
|
+
(output.type === 'json' &&
|
|
1348
|
+
output.value != null &&
|
|
1349
|
+
typeof output.value === 'object' &&
|
|
1350
|
+
!Array.isArray(output.value) &&
|
|
1351
|
+
'type' in output.value &&
|
|
1352
|
+
output.value.type === 'tool_search_tool_result_error')
|
|
1353
|
+
) {
|
|
1354
|
+
anthropicContent.push({
|
|
1355
|
+
type: 'tool_search_tool_result',
|
|
1356
|
+
tool_use_id: part.toolCallId,
|
|
1357
|
+
content: {
|
|
1358
|
+
type: 'tool_search_tool_result_error',
|
|
1359
|
+
error_code:
|
|
1360
|
+
extractErrorValue(output.value).errorCode ??
|
|
1361
|
+
'unavailable',
|
|
1362
|
+
},
|
|
1363
|
+
cache_control: cacheControl,
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1345
1369
|
if (output.type !== 'json') {
|
|
1346
1370
|
warnings.push({
|
|
1347
1371
|
type: 'other',
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,10 @@ export type {
|
|
|
2
2
|
AnthropicMessageMetadata,
|
|
3
3
|
AnthropicUsageIteration,
|
|
4
4
|
} from './anthropic-message-metadata';
|
|
5
|
+
export type {
|
|
6
|
+
AnthropicCitation,
|
|
7
|
+
AnthropicTextProviderMetadata,
|
|
8
|
+
} from './anthropic-provider-metadata';
|
|
5
9
|
export type {
|
|
6
10
|
AnthropicLanguageModelOptions,
|
|
7
11
|
/** @deprecated Use `AnthropicLanguageModelOptions` instead. */
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { LanguageModelV4Citation } from '@ai-sdk/provider';
|
|
2
|
+
import type { Citation } from './anthropic-api';
|
|
3
|
+
|
|
4
|
+
export type CitationDocument = {
|
|
5
|
+
title: string;
|
|
6
|
+
filename?: string;
|
|
7
|
+
mediaType: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function mapAnthropicCitation(
|
|
11
|
+
citation: Citation,
|
|
12
|
+
documents: Array<CitationDocument>,
|
|
13
|
+
): LanguageModelV4Citation {
|
|
14
|
+
if (
|
|
15
|
+
citation.type === 'web_search_result_location' ||
|
|
16
|
+
citation.type === 'search_result_location'
|
|
17
|
+
) {
|
|
18
|
+
const url =
|
|
19
|
+
citation.type === 'web_search_result_location'
|
|
20
|
+
? citation.url
|
|
21
|
+
: citation.source;
|
|
22
|
+
return {
|
|
23
|
+
source: {
|
|
24
|
+
type: 'source',
|
|
25
|
+
sourceType: 'url',
|
|
26
|
+
id: url,
|
|
27
|
+
url,
|
|
28
|
+
title: citation.title ?? undefined,
|
|
29
|
+
providerMetadata: { anthropic: { ...citation } },
|
|
30
|
+
},
|
|
31
|
+
citedText: citation.cited_text,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const document = documents[citation.document_index];
|
|
36
|
+
return {
|
|
37
|
+
source: {
|
|
38
|
+
type: 'source',
|
|
39
|
+
sourceType: 'document',
|
|
40
|
+
id: citation.file_id ?? String(citation.document_index),
|
|
41
|
+
mediaType: document?.mediaType ?? 'text/plain',
|
|
42
|
+
title:
|
|
43
|
+
citation.document_title ??
|
|
44
|
+
document?.title ??
|
|
45
|
+
`Document ${citation.document_index}`,
|
|
46
|
+
filename: document?.filename,
|
|
47
|
+
providerMetadata: { anthropic: { ...citation } },
|
|
48
|
+
},
|
|
49
|
+
citedText: citation.cited_text,
|
|
50
|
+
};
|
|
51
|
+
}
|