@ai-sdk/anthropic 3.0.19 → 3.0.21
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 +12 -0
- package/dist/index.js +58 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -26
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +57 -25
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +57 -25
- package/dist/internal/index.mjs.map +1 -1
- package/docs/05-anthropic.mdx +1096 -0
- package/package.json +8 -4
- package/src/__fixtures__/anthropic-tool-search-deferred-bm25.2.json +65 -0
- package/src/__fixtures__/anthropic-tool-search-deferred-bm25.chunks.txt +115 -0
- package/src/__fixtures__/anthropic-tool-search-deferred-regex.2.json +69 -0
- package/src/__fixtures__/anthropic-tool-search-deferred-regex.chunks.txt +119 -0
- package/src/anthropic-messages-language-model.test.ts +198 -0
- package/src/anthropic-messages-language-model.ts +38 -5
- package/src/tool/tool-search-bm25_20251119.ts +1 -0
- package/src/tool/tool-search-regex_20251119.ts +1 -0
|
@@ -3020,6 +3020,104 @@ describe('AnthropicMessagesLanguageModel', () => {
|
|
|
3020
3020
|
expect(result.content).toMatchSnapshot();
|
|
3021
3021
|
});
|
|
3022
3022
|
});
|
|
3023
|
+
|
|
3024
|
+
describe('deferred result - bm25 variant', () => {
|
|
3025
|
+
it('should correctly map tool_search_tool_result when result comes without server_tool_use in same response', async () => {
|
|
3026
|
+
prepareJsonFixtureResponse('anthropic-tool-search-deferred-bm25.2');
|
|
3027
|
+
|
|
3028
|
+
const result = await provider('claude-sonnet-4-5').doGenerate({
|
|
3029
|
+
prompt: [
|
|
3030
|
+
{
|
|
3031
|
+
role: 'user',
|
|
3032
|
+
content: [
|
|
3033
|
+
{
|
|
3034
|
+
type: 'text',
|
|
3035
|
+
text: 'What is the weather in San Francisco?',
|
|
3036
|
+
},
|
|
3037
|
+
],
|
|
3038
|
+
},
|
|
3039
|
+
],
|
|
3040
|
+
tools: [
|
|
3041
|
+
{
|
|
3042
|
+
type: 'provider',
|
|
3043
|
+
id: 'anthropic.tool_search_bm25_20251119',
|
|
3044
|
+
name: 'tool_search',
|
|
3045
|
+
args: {},
|
|
3046
|
+
},
|
|
3047
|
+
{
|
|
3048
|
+
type: 'function',
|
|
3049
|
+
name: 'get_weather',
|
|
3050
|
+
description: 'Get the current weather at a specific location',
|
|
3051
|
+
inputSchema: {
|
|
3052
|
+
type: 'object',
|
|
3053
|
+
properties: {
|
|
3054
|
+
location: { type: 'string' },
|
|
3055
|
+
},
|
|
3056
|
+
},
|
|
3057
|
+
providerOptions: {
|
|
3058
|
+
anthropic: { deferLoading: true },
|
|
3059
|
+
},
|
|
3060
|
+
},
|
|
3061
|
+
],
|
|
3062
|
+
});
|
|
3063
|
+
|
|
3064
|
+
// The tool result should be correctly mapped to 'tool_search' (the user's custom name)
|
|
3065
|
+
// even though serverToolCalls map is empty (no server_tool_use in this response)
|
|
3066
|
+
const toolResult = result.content.find(
|
|
3067
|
+
part => part.type === 'tool-result',
|
|
3068
|
+
);
|
|
3069
|
+
expect(toolResult).toBeDefined();
|
|
3070
|
+
expect(toolResult?.toolName).toBe('tool_search');
|
|
3071
|
+
});
|
|
3072
|
+
});
|
|
3073
|
+
|
|
3074
|
+
describe('deferred result - regex variant', () => {
|
|
3075
|
+
it('should correctly map tool_search_tool_result when result comes without server_tool_use in same response', async () => {
|
|
3076
|
+
prepareJsonFixtureResponse('anthropic-tool-search-deferred-regex.2');
|
|
3077
|
+
|
|
3078
|
+
const result = await provider('claude-sonnet-4-5').doGenerate({
|
|
3079
|
+
prompt: [
|
|
3080
|
+
{
|
|
3081
|
+
role: 'user',
|
|
3082
|
+
content: [
|
|
3083
|
+
{
|
|
3084
|
+
type: 'text',
|
|
3085
|
+
text: 'Find weather data in NYC',
|
|
3086
|
+
},
|
|
3087
|
+
],
|
|
3088
|
+
},
|
|
3089
|
+
],
|
|
3090
|
+
tools: [
|
|
3091
|
+
{
|
|
3092
|
+
type: 'provider',
|
|
3093
|
+
id: 'anthropic.tool_search_regex_20251119',
|
|
3094
|
+
name: 'tool_search',
|
|
3095
|
+
args: {},
|
|
3096
|
+
},
|
|
3097
|
+
{
|
|
3098
|
+
type: 'function',
|
|
3099
|
+
name: 'get_temp_data',
|
|
3100
|
+
description: 'For a location',
|
|
3101
|
+
inputSchema: {
|
|
3102
|
+
type: 'object',
|
|
3103
|
+
properties: {
|
|
3104
|
+
location: { type: 'string' },
|
|
3105
|
+
},
|
|
3106
|
+
},
|
|
3107
|
+
providerOptions: {
|
|
3108
|
+
anthropic: { deferLoading: true },
|
|
3109
|
+
},
|
|
3110
|
+
},
|
|
3111
|
+
],
|
|
3112
|
+
});
|
|
3113
|
+
|
|
3114
|
+
const toolResult = result.content.find(
|
|
3115
|
+
part => part.type === 'tool-result',
|
|
3116
|
+
);
|
|
3117
|
+
expect(toolResult).toBeDefined();
|
|
3118
|
+
expect(toolResult?.toolName).toBe('tool_search');
|
|
3119
|
+
});
|
|
3120
|
+
});
|
|
3023
3121
|
});
|
|
3024
3122
|
|
|
3025
3123
|
describe('mcp servers', () => {
|
|
@@ -6845,6 +6943,106 @@ describe('AnthropicMessagesLanguageModel', () => {
|
|
|
6845
6943
|
).toMatchSnapshot();
|
|
6846
6944
|
});
|
|
6847
6945
|
});
|
|
6946
|
+
|
|
6947
|
+
describe('deferred result - bm25 variant', () => {
|
|
6948
|
+
it('should correctly map tool_search_tool_result when result comes without server_tool_use in same response', async () => {
|
|
6949
|
+
prepareChunksFixtureResponse('anthropic-tool-search-deferred-bm25');
|
|
6950
|
+
|
|
6951
|
+
const result = await provider('claude-sonnet-4-5').doStream({
|
|
6952
|
+
prompt: [
|
|
6953
|
+
{
|
|
6954
|
+
role: 'user',
|
|
6955
|
+
content: [
|
|
6956
|
+
{
|
|
6957
|
+
type: 'text',
|
|
6958
|
+
text: 'What is the weather in San Francisco?',
|
|
6959
|
+
},
|
|
6960
|
+
],
|
|
6961
|
+
},
|
|
6962
|
+
],
|
|
6963
|
+
tools: [
|
|
6964
|
+
{
|
|
6965
|
+
type: 'provider',
|
|
6966
|
+
id: 'anthropic.tool_search_bm25_20251119',
|
|
6967
|
+
name: 'tool_search',
|
|
6968
|
+
args: {},
|
|
6969
|
+
},
|
|
6970
|
+
{
|
|
6971
|
+
type: 'function',
|
|
6972
|
+
name: 'get_weather',
|
|
6973
|
+
description: 'Get the current weather at a specific location',
|
|
6974
|
+
inputSchema: {
|
|
6975
|
+
type: 'object',
|
|
6976
|
+
properties: {
|
|
6977
|
+
location: { type: 'string' },
|
|
6978
|
+
},
|
|
6979
|
+
},
|
|
6980
|
+
providerOptions: {
|
|
6981
|
+
anthropic: { deferLoading: true },
|
|
6982
|
+
},
|
|
6983
|
+
},
|
|
6984
|
+
],
|
|
6985
|
+
});
|
|
6986
|
+
|
|
6987
|
+
const chunks = await convertReadableStreamToArray(result.stream);
|
|
6988
|
+
|
|
6989
|
+
const toolResultChunk = chunks.find(
|
|
6990
|
+
chunk => chunk.type === 'tool-result',
|
|
6991
|
+
);
|
|
6992
|
+
expect(toolResultChunk).toBeDefined();
|
|
6993
|
+
expect(toolResultChunk?.toolName).toBe('tool_search');
|
|
6994
|
+
});
|
|
6995
|
+
});
|
|
6996
|
+
|
|
6997
|
+
describe('deferred result - regex variant', () => {
|
|
6998
|
+
it('should correctly map tool_search_tool_result when result comes without server_tool_use in same response', async () => {
|
|
6999
|
+
prepareChunksFixtureResponse('anthropic-tool-search-deferred-regex');
|
|
7000
|
+
|
|
7001
|
+
const result = await provider('claude-sonnet-4-5').doStream({
|
|
7002
|
+
prompt: [
|
|
7003
|
+
{
|
|
7004
|
+
role: 'user',
|
|
7005
|
+
content: [
|
|
7006
|
+
{
|
|
7007
|
+
type: 'text',
|
|
7008
|
+
text: 'Find weather data in NYC',
|
|
7009
|
+
},
|
|
7010
|
+
],
|
|
7011
|
+
},
|
|
7012
|
+
],
|
|
7013
|
+
tools: [
|
|
7014
|
+
{
|
|
7015
|
+
type: 'provider',
|
|
7016
|
+
id: 'anthropic.tool_search_regex_20251119',
|
|
7017
|
+
name: 'tool_search',
|
|
7018
|
+
args: {},
|
|
7019
|
+
},
|
|
7020
|
+
{
|
|
7021
|
+
type: 'function',
|
|
7022
|
+
name: 'get_temp_data',
|
|
7023
|
+
description: 'For a location',
|
|
7024
|
+
inputSchema: {
|
|
7025
|
+
type: 'object',
|
|
7026
|
+
properties: {
|
|
7027
|
+
location: { type: 'string' },
|
|
7028
|
+
},
|
|
7029
|
+
},
|
|
7030
|
+
providerOptions: {
|
|
7031
|
+
anthropic: { deferLoading: true },
|
|
7032
|
+
},
|
|
7033
|
+
},
|
|
7034
|
+
],
|
|
7035
|
+
});
|
|
7036
|
+
|
|
7037
|
+
const chunks = await convertReadableStreamToArray(result.stream);
|
|
7038
|
+
|
|
7039
|
+
const toolResultChunk = chunks.find(
|
|
7040
|
+
chunk => chunk.type === 'tool-result',
|
|
7041
|
+
);
|
|
7042
|
+
expect(toolResultChunk).toBeDefined();
|
|
7043
|
+
expect(toolResultChunk?.toolName).toBe('tool_search');
|
|
7044
|
+
});
|
|
7045
|
+
});
|
|
6848
7046
|
});
|
|
6849
7047
|
|
|
6850
7048
|
it('should throw an api error when the server is returning a 529 overloaded error', async () => {
|
|
@@ -987,8 +987,25 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
987
987
|
|
|
988
988
|
// tool search tool results:
|
|
989
989
|
case 'tool_search_tool_result': {
|
|
990
|
-
|
|
991
|
-
|
|
990
|
+
let providerToolName = serverToolCalls[part.tool_use_id];
|
|
991
|
+
|
|
992
|
+
if (providerToolName == null) {
|
|
993
|
+
const bm25CustomName = toolNameMapping.toCustomToolName(
|
|
994
|
+
'tool_search_tool_bm25',
|
|
995
|
+
);
|
|
996
|
+
const regexCustomName = toolNameMapping.toCustomToolName(
|
|
997
|
+
'tool_search_tool_regex',
|
|
998
|
+
);
|
|
999
|
+
|
|
1000
|
+
if (bm25CustomName !== 'tool_search_tool_bm25') {
|
|
1001
|
+
providerToolName = 'tool_search_tool_bm25';
|
|
1002
|
+
} else if (regexCustomName !== 'tool_search_tool_regex') {
|
|
1003
|
+
providerToolName = 'tool_search_tool_regex';
|
|
1004
|
+
} else {
|
|
1005
|
+
providerToolName = 'tool_search_tool_regex';
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
992
1009
|
if (part.content.type === 'tool_search_tool_search_result') {
|
|
993
1010
|
content.push({
|
|
994
1011
|
type: 'tool-result',
|
|
@@ -1480,9 +1497,25 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1480
1497
|
|
|
1481
1498
|
// tool search tool results:
|
|
1482
1499
|
case 'tool_search_tool_result': {
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1500
|
+
let providerToolName = serverToolCalls[part.tool_use_id];
|
|
1501
|
+
|
|
1502
|
+
if (providerToolName == null) {
|
|
1503
|
+
const bm25CustomName = toolNameMapping.toCustomToolName(
|
|
1504
|
+
'tool_search_tool_bm25',
|
|
1505
|
+
);
|
|
1506
|
+
const regexCustomName = toolNameMapping.toCustomToolName(
|
|
1507
|
+
'tool_search_tool_regex',
|
|
1508
|
+
);
|
|
1509
|
+
|
|
1510
|
+
if (bm25CustomName !== 'tool_search_tool_bm25') {
|
|
1511
|
+
providerToolName = 'tool_search_tool_bm25';
|
|
1512
|
+
} else if (regexCustomName !== 'tool_search_tool_regex') {
|
|
1513
|
+
providerToolName = 'tool_search_tool_regex';
|
|
1514
|
+
} else {
|
|
1515
|
+
providerToolName = 'tool_search_tool_regex';
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1486
1519
|
if (part.content.type === 'tool_search_tool_search_result') {
|
|
1487
1520
|
controller.enqueue({
|
|
1488
1521
|
type: 'tool-result',
|
|
@@ -76,6 +76,7 @@ const factory = createProviderToolFactoryWithOutputSchema<
|
|
|
76
76
|
id: 'anthropic.tool_search_regex_20251119',
|
|
77
77
|
inputSchema: toolSearchRegex_20251119InputSchema,
|
|
78
78
|
outputSchema: toolSearchRegex_20251119OutputSchema,
|
|
79
|
+
supportsDeferredResults: true,
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
/**
|