@tanstack/ai-anthropic 0.18.13 → 0.19.3
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/dist/esm/adapters/files.d.ts +25 -0
- package/dist/esm/adapters/files.js +61 -0
- package/dist/esm/adapters/files.js.map +1 -0
- package/dist/esm/adapters/text.d.ts +11 -3
- package/dist/esm/adapters/text.js +47 -22
- package/dist/esm/adapters/text.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/model-meta.d.ts +23 -1
- package/dist/esm/model-meta.js +32 -1
- package/dist/esm/model-meta.js.map +1 -1
- package/dist/esm/text/text-provider-options.d.ts +3 -3
- package/dist/esm/text/text-provider-options.js.map +1 -1
- package/package.json +4 -3
- package/src/adapters/files.ts +85 -0
- package/src/adapters/text.ts +105 -40
- package/src/index.ts +8 -0
- package/src/model-meta.ts +55 -0
- package/src/text/text-provider-options.ts +3 -5
package/src/adapters/text.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
EventType,
|
|
3
|
+
fileReferenceFor,
|
|
4
|
+
isFileSource,
|
|
5
|
+
normalizeSystemPrompts,
|
|
6
|
+
} from '@tanstack/ai'
|
|
2
7
|
import { toRunErrorRawEvent } from '@tanstack/ai/adapter-internals'
|
|
3
8
|
import { BaseTextAdapter } from '@tanstack/ai/adapters'
|
|
4
9
|
import { convertToolsToProviderFormat } from '../tools/tool-converter'
|
|
@@ -30,20 +35,25 @@ import type {
|
|
|
30
35
|
} from '@tanstack/ai/adapters'
|
|
31
36
|
import type { InternalLogger } from '@tanstack/ai/adapter-internals'
|
|
32
37
|
import type {
|
|
33
|
-
Base64ImageSource,
|
|
34
|
-
Base64PDFSource,
|
|
35
|
-
ContentBlockParam,
|
|
36
|
-
DocumentBlockParam,
|
|
37
|
-
ImageBlockParam,
|
|
38
38
|
ServerToolUseBlockParam,
|
|
39
39
|
TextBlockParam,
|
|
40
40
|
ThinkingBlockParam,
|
|
41
41
|
ToolUseBlockParam,
|
|
42
|
-
URLImageSource,
|
|
43
|
-
URLPDFSource,
|
|
44
42
|
WebFetchToolResultBlockParam,
|
|
45
43
|
WebSearchToolResultBlockParam,
|
|
46
44
|
} from '@anthropic-ai/sdk/resources/messages'
|
|
45
|
+
import type {
|
|
46
|
+
BetaBase64ImageSource,
|
|
47
|
+
BetaBase64PDFSource,
|
|
48
|
+
BetaContentBlockParam,
|
|
49
|
+
BetaFileDocumentSource,
|
|
50
|
+
BetaFileImageSource,
|
|
51
|
+
BetaImageBlockParam,
|
|
52
|
+
BetaRequestDocumentBlock,
|
|
53
|
+
BetaTextBlockParam,
|
|
54
|
+
BetaURLImageSource,
|
|
55
|
+
BetaURLPDFSource,
|
|
56
|
+
} from '@anthropic-ai/sdk/resources/beta/messages'
|
|
47
57
|
import type Anthropic_SDK from '@anthropic-ai/sdk'
|
|
48
58
|
import type { AnthropicBeta } from '@anthropic-ai/sdk/resources/beta/beta'
|
|
49
59
|
import type {
|
|
@@ -147,12 +157,27 @@ function buildServerToolResultBlock(
|
|
|
147
157
|
}
|
|
148
158
|
}
|
|
149
159
|
|
|
160
|
+
/**
|
|
161
|
+
* True when any message carries a provider file-handle source, so the request
|
|
162
|
+
* must send the Files API beta header.
|
|
163
|
+
*/
|
|
164
|
+
export function messagesHaveFileSource(messages: Array<ModelMessage>): boolean {
|
|
165
|
+
return messages.some(
|
|
166
|
+
(message) =>
|
|
167
|
+
Array.isArray(message.content) &&
|
|
168
|
+
message.content.some(
|
|
169
|
+
(part) => 'source' in part && isFileSource(part.source),
|
|
170
|
+
),
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
150
174
|
/**
|
|
151
175
|
* Computes the `betas` array for a Messages request. Unions:
|
|
152
176
|
* - `interleaved-thinking-2025-05-14` when interleaved thinking is enabled,
|
|
153
177
|
* - `code-execution-2025-08-25` when a `code_execution` tool is present,
|
|
154
178
|
* - `skills-2025-10-02` when that tool carries skills,
|
|
155
|
-
* - `context-management-2025-06-27` when `context_management` is set
|
|
179
|
+
* - `context-management-2025-06-27` when `context_management` is set,
|
|
180
|
+
* - `files-api-2025-04-14` when a message references an uploaded file handle.
|
|
156
181
|
* Returns `undefined` when none apply (so the call site omits `betas`).
|
|
157
182
|
*/
|
|
158
183
|
export function computeAnthropicBetas(
|
|
@@ -164,11 +189,15 @@ export function computeAnthropicBetas(
|
|
|
164
189
|
budget_tokens?: number
|
|
165
190
|
}
|
|
166
191
|
context_management?: unknown | null
|
|
192
|
+
mcp_servers?: ReadonlyArray<unknown>
|
|
167
193
|
}
|
|
168
194
|
| undefined,
|
|
195
|
+
hasFileSource = false,
|
|
169
196
|
): Array<AnthropicBeta> | undefined {
|
|
170
197
|
const betas = new Set<AnthropicBeta>()
|
|
171
198
|
|
|
199
|
+
if (hasFileSource) betas.add('files-api-2025-04-14')
|
|
200
|
+
|
|
172
201
|
const useInterleavedThinking =
|
|
173
202
|
modelOptions?.thinking?.type === 'enabled' &&
|
|
174
203
|
typeof modelOptions.thinking.budget_tokens === 'number' &&
|
|
@@ -181,6 +210,15 @@ export function computeAnthropicBetas(
|
|
|
181
210
|
betas.add('context-management-2025-06-27')
|
|
182
211
|
}
|
|
183
212
|
|
|
213
|
+
// The MCP connector needs its beta header as well (same shape as #1074);
|
|
214
|
+
// an empty array is a typed "unset" — do not enable the beta.
|
|
215
|
+
// ponytail: 2025-04-04 matches the `mcp_servers` shape we type
|
|
216
|
+
// (`tool_configuration` on each server). 2025-11-20 needs an `mcp_toolset`
|
|
217
|
+
// in `tools` for every server, which this adapter does not send yet.
|
|
218
|
+
if (modelOptions?.mcp_servers && modelOptions.mcp_servers.length > 0) {
|
|
219
|
+
betas.add('mcp-client-2025-04-04')
|
|
220
|
+
}
|
|
221
|
+
|
|
184
222
|
// Code-execution beta is version-aware: select from the FIRST code_execution
|
|
185
223
|
// tool's config type.
|
|
186
224
|
const codeExecTool = tools?.find(
|
|
@@ -301,6 +339,8 @@ export class AnthropicTextAdapter<
|
|
|
301
339
|
> {
|
|
302
340
|
override readonly kind = 'text' as const
|
|
303
341
|
readonly name = 'anthropic' as const
|
|
342
|
+
// Consumes `file_id` sources issued by anthropicFiles() (Files API beta).
|
|
343
|
+
override readonly supportsFileSources = true
|
|
304
344
|
|
|
305
345
|
private readonly client: SdkAnthropicMessagesClient
|
|
306
346
|
|
|
@@ -326,7 +366,11 @@ export class AnthropicTextAdapter<
|
|
|
326
366
|
|
|
327
367
|
// `betas` is attached at the call site rather than in the shared mapper
|
|
328
368
|
// because the beta set depends on both the tools and the modelOptions.
|
|
329
|
-
const betas = computeAnthropicBetas(
|
|
369
|
+
const betas = computeAnthropicBetas(
|
|
370
|
+
options.tools,
|
|
371
|
+
options.modelOptions,
|
|
372
|
+
messagesHaveFileSource(options.messages),
|
|
373
|
+
)
|
|
330
374
|
|
|
331
375
|
// `client.beta.messages` is Anthropic's permanent staging surface, not a
|
|
332
376
|
// sunset path: it's a superset of `client.messages` that additionally
|
|
@@ -416,6 +460,7 @@ export class AnthropicTextAdapter<
|
|
|
416
460
|
const betas = computeAnthropicBetas(
|
|
417
461
|
chatOptions.tools,
|
|
418
462
|
chatOptions.modelOptions,
|
|
463
|
+
messagesHaveFileSource(chatOptions.messages),
|
|
419
464
|
)
|
|
420
465
|
// Make non-streaming request with tool_choice forced to our structured output tool
|
|
421
466
|
const response = await this.client.beta.messages.create(
|
|
@@ -657,7 +702,7 @@ export class AnthropicTextAdapter<
|
|
|
657
702
|
|
|
658
703
|
private convertContentPartToAnthropic(
|
|
659
704
|
part: ContentPart,
|
|
660
|
-
):
|
|
705
|
+
): BetaTextBlockParam | BetaImageBlockParam | BetaRequestDocumentBlock {
|
|
661
706
|
switch (part.type) {
|
|
662
707
|
case 'text': {
|
|
663
708
|
const metadata = part.metadata as AnthropicTextMetadata | undefined
|
|
@@ -670,21 +715,31 @@ export class AnthropicTextAdapter<
|
|
|
670
715
|
|
|
671
716
|
case 'image': {
|
|
672
717
|
const metadata = part.metadata as AnthropicImageMetadata | undefined
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
:
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
718
|
+
let imageSource:
|
|
719
|
+
| BetaBase64ImageSource
|
|
720
|
+
| BetaURLImageSource
|
|
721
|
+
| BetaFileImageSource
|
|
722
|
+
if (isFileSource(part.source)) {
|
|
723
|
+
imageSource = {
|
|
724
|
+
type: 'file',
|
|
725
|
+
file_id: fileReferenceFor(part.source, this.name),
|
|
726
|
+
}
|
|
727
|
+
} else if (part.source.type === 'data') {
|
|
728
|
+
imageSource = {
|
|
729
|
+
type: 'base64',
|
|
730
|
+
data: part.source.value,
|
|
731
|
+
media_type: part.source.mimeType as
|
|
732
|
+
| 'image/jpeg'
|
|
733
|
+
| 'image/png'
|
|
734
|
+
| 'image/gif'
|
|
735
|
+
| 'image/webp',
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
imageSource = {
|
|
739
|
+
type: 'url',
|
|
740
|
+
url: part.source.value,
|
|
741
|
+
}
|
|
742
|
+
}
|
|
688
743
|
return {
|
|
689
744
|
type: 'image',
|
|
690
745
|
source: imageSource,
|
|
@@ -696,17 +751,27 @@ export class AnthropicTextAdapter<
|
|
|
696
751
|
case 'document': {
|
|
697
752
|
const metadata = part.metadata as AnthropicDocumentMetadata | undefined
|
|
698
753
|
const title = metadata?.title ?? metadata?.filename
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
:
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
754
|
+
let docSource:
|
|
755
|
+
| BetaBase64PDFSource
|
|
756
|
+
| BetaURLPDFSource
|
|
757
|
+
| BetaFileDocumentSource
|
|
758
|
+
if (isFileSource(part.source)) {
|
|
759
|
+
docSource = {
|
|
760
|
+
type: 'file',
|
|
761
|
+
file_id: fileReferenceFor(part.source, this.name),
|
|
762
|
+
}
|
|
763
|
+
} else if (part.source.type === 'data') {
|
|
764
|
+
docSource = {
|
|
765
|
+
type: 'base64',
|
|
766
|
+
data: part.source.value,
|
|
767
|
+
media_type: part.source.mimeType as 'application/pdf',
|
|
768
|
+
}
|
|
769
|
+
} else {
|
|
770
|
+
docSource = {
|
|
771
|
+
type: 'url',
|
|
772
|
+
url: part.source.value,
|
|
773
|
+
}
|
|
774
|
+
}
|
|
710
775
|
return {
|
|
711
776
|
type: 'document',
|
|
712
777
|
source: docSource,
|
|
@@ -766,7 +831,7 @@ export class AnthropicTextAdapter<
|
|
|
766
831
|
}
|
|
767
832
|
|
|
768
833
|
if (role === 'assistant' && message.toolCalls?.length) {
|
|
769
|
-
const contentBlocks: Array<
|
|
834
|
+
const contentBlocks: Array<BetaContentBlockParam> = []
|
|
770
835
|
|
|
771
836
|
this.appendThinkingBlocks(contentBlocks, message.thinking)
|
|
772
837
|
|
|
@@ -828,7 +893,7 @@ export class AnthropicTextAdapter<
|
|
|
828
893
|
}
|
|
829
894
|
|
|
830
895
|
if (role === 'assistant') {
|
|
831
|
-
const contentBlocks: Array<
|
|
896
|
+
const contentBlocks: Array<BetaContentBlockParam> = []
|
|
832
897
|
this.appendThinkingBlocks(contentBlocks, message.thinking)
|
|
833
898
|
|
|
834
899
|
if (Array.isArray(message.content)) {
|
|
@@ -880,7 +945,7 @@ export class AnthropicTextAdapter<
|
|
|
880
945
|
}
|
|
881
946
|
|
|
882
947
|
private appendThinkingBlocks(
|
|
883
|
-
contentBlocks: Array<
|
|
948
|
+
contentBlocks: Array<BetaContentBlockParam>,
|
|
884
949
|
thinkingParts: ModelMessage['thinking'],
|
|
885
950
|
): void {
|
|
886
951
|
if (!thinkingParts?.length) return
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,14 @@ export {
|
|
|
22
22
|
type AnthropicSummarizeConfig,
|
|
23
23
|
type AnthropicSummarizeModel,
|
|
24
24
|
} from './adapters/summarize'
|
|
25
|
+
|
|
26
|
+
// Files adapter - upload media to the Anthropic Files API (beta) by file_id
|
|
27
|
+
export {
|
|
28
|
+
AnthropicFilesAdapter,
|
|
29
|
+
createAnthropicFiles,
|
|
30
|
+
anthropicFiles,
|
|
31
|
+
type AnthropicFilesConfig,
|
|
32
|
+
} from './adapters/files'
|
|
25
33
|
// ============================================================================
|
|
26
34
|
// Type Exports
|
|
27
35
|
// ============================================================================
|
package/src/model-meta.ts
CHANGED
|
@@ -608,7 +608,48 @@ const CLAUDE_FABLE_5_1 = {
|
|
|
608
608
|
AnthropicOutputConfigOptions
|
|
609
609
|
>
|
|
610
610
|
|
|
611
|
+
const CLAUDE_OPUS_5_5 = {
|
|
612
|
+
name: 'claude-opus-5-5',
|
|
613
|
+
id: 'claude-opus-5-5',
|
|
614
|
+
context_window: 1_000_000,
|
|
615
|
+
max_output_tokens: 128_000,
|
|
616
|
+
supports: {
|
|
617
|
+
input: ['text', 'image', 'document'],
|
|
618
|
+
// No 'computer_use': this model accepts only `computer_toolset_20260801`,
|
|
619
|
+
// and `computerUseTool()` sends the older versions, which return a 400.
|
|
620
|
+
tools: [
|
|
621
|
+
'web_search',
|
|
622
|
+
'web_fetch',
|
|
623
|
+
'code_execution',
|
|
624
|
+
'bash',
|
|
625
|
+
'text_editor',
|
|
626
|
+
'memory',
|
|
627
|
+
],
|
|
628
|
+
},
|
|
629
|
+
pricing: {
|
|
630
|
+
input: {
|
|
631
|
+
normal: 4,
|
|
632
|
+
cached: 0.2,
|
|
633
|
+
},
|
|
634
|
+
output: {
|
|
635
|
+
normal: 20,
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
} as const satisfies ModelMeta<
|
|
639
|
+
AnthropicCacheControlOptions &
|
|
640
|
+
AnthropicContainerOptions &
|
|
641
|
+
AnthropicContextManagementOptions &
|
|
642
|
+
AnthropicMCPOptions &
|
|
643
|
+
AnthropicServiceTierOptions &
|
|
644
|
+
AnthropicStopSequencesOptions &
|
|
645
|
+
AnthropicAdaptiveOnlyThinkingOptions &
|
|
646
|
+
AnthropicToolChoiceOptions &
|
|
647
|
+
AnthropicSamplingOptions &
|
|
648
|
+
AnthropicOutputConfigOptions
|
|
649
|
+
>
|
|
650
|
+
|
|
611
651
|
export const ANTHROPIC_MODELS = [
|
|
652
|
+
CLAUDE_OPUS_5_5.id,
|
|
612
653
|
CLAUDE_FABLE_5_1.id,
|
|
613
654
|
CLAUDE_OPUS_5.id,
|
|
614
655
|
CLAUDE_OPUS_5_FAST.id,
|
|
@@ -686,6 +727,7 @@ const ANTHROPIC_MODEL_MAX_OUTPUT_TOKENS: Record<string, number> = {
|
|
|
686
727
|
[CLAUDE_OPUS_5.id]: CLAUDE_OPUS_5.max_output_tokens,
|
|
687
728
|
[CLAUDE_OPUS_5_FAST.id]: CLAUDE_OPUS_5_FAST.max_output_tokens,
|
|
688
729
|
[CLAUDE_FABLE_5_1.id]: CLAUDE_FABLE_5_1.max_output_tokens,
|
|
730
|
+
[CLAUDE_OPUS_5_5.id]: CLAUDE_OPUS_5_5.max_output_tokens,
|
|
689
731
|
}
|
|
690
732
|
|
|
691
733
|
/**
|
|
@@ -741,6 +783,7 @@ export const ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS = new Set<string>([
|
|
|
741
783
|
CLAUDE_OPUS_5.id,
|
|
742
784
|
CLAUDE_FABLE_5.id,
|
|
743
785
|
CLAUDE_FABLE_5_1.id,
|
|
786
|
+
CLAUDE_OPUS_5_5.id,
|
|
744
787
|
CLAUDE_SONNET_5.id,
|
|
745
788
|
CLAUDE_SONNET_4_5.id,
|
|
746
789
|
CLAUDE_SONNET_4_6.id,
|
|
@@ -891,6 +934,16 @@ export type AnthropicChatModelProviderOptionsByName = {
|
|
|
891
934
|
AnthropicToolChoiceOptions &
|
|
892
935
|
AnthropicMaxTokensOptions &
|
|
893
936
|
AnthropicOutputConfigOptions
|
|
937
|
+
[CLAUDE_OPUS_5_5.id]: AnthropicCacheControlOptions &
|
|
938
|
+
AnthropicContainerOptions &
|
|
939
|
+
AnthropicContextManagementOptions &
|
|
940
|
+
AnthropicMCPOptions &
|
|
941
|
+
AnthropicServiceTierOptions &
|
|
942
|
+
AnthropicStopSequencesOptions &
|
|
943
|
+
AnthropicAdaptiveOnlyThinkingOptions &
|
|
944
|
+
AnthropicToolChoiceOptions &
|
|
945
|
+
AnthropicSamplingOptions &
|
|
946
|
+
AnthropicOutputConfigOptions
|
|
894
947
|
}
|
|
895
948
|
|
|
896
949
|
export type AnthropicChatModelToolCapabilitiesByName = {
|
|
@@ -907,6 +960,7 @@ export type AnthropicChatModelToolCapabilitiesByName = {
|
|
|
907
960
|
[CLAUDE_OPUS_5.id]: typeof CLAUDE_OPUS_5.supports.tools
|
|
908
961
|
[CLAUDE_OPUS_5_FAST.id]: typeof CLAUDE_OPUS_5_FAST.supports.tools
|
|
909
962
|
[CLAUDE_FABLE_5_1.id]: typeof CLAUDE_FABLE_5_1.supports.tools
|
|
963
|
+
[CLAUDE_OPUS_5_5.id]: typeof CLAUDE_OPUS_5_5.supports.tools
|
|
910
964
|
}
|
|
911
965
|
|
|
912
966
|
/**
|
|
@@ -934,4 +988,5 @@ export type AnthropicModelInputModalitiesByName = {
|
|
|
934
988
|
[CLAUDE_OPUS_5.id]: typeof CLAUDE_OPUS_5.supports.input
|
|
935
989
|
[CLAUDE_OPUS_5_FAST.id]: typeof CLAUDE_OPUS_5_FAST.supports.input
|
|
936
990
|
[CLAUDE_FABLE_5_1.id]: typeof CLAUDE_FABLE_5_1.supports.input
|
|
991
|
+
[CLAUDE_OPUS_5_5.id]: typeof CLAUDE_OPUS_5_5.supports.input
|
|
937
992
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BetaContextManagementConfig,
|
|
3
|
+
BetaMessageParam,
|
|
3
4
|
BetaToolChoiceAny,
|
|
4
5
|
BetaToolChoiceAuto,
|
|
5
6
|
BetaToolChoiceTool,
|
|
6
7
|
} from '@anthropic-ai/sdk/resources/beta/messages/messages'
|
|
7
8
|
import type { CacheControlEphemeral } from '@anthropic-ai/sdk/resources'
|
|
8
9
|
import type { AnthropicContainerSkill, AnthropicTool } from '../tools/index'
|
|
9
|
-
import type {
|
|
10
|
-
MessageParam,
|
|
11
|
-
TextBlockParam,
|
|
12
|
-
} from '@anthropic-ai/sdk/resources/messages'
|
|
10
|
+
import type { TextBlockParam } from '@anthropic-ai/sdk/resources/messages'
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
13
|
* Per-prompt metadata Anthropic understands on `systemPrompts` entries.
|
|
@@ -320,7 +318,7 @@ export type ExternalTextProviderOptions = AnthropicCacheControlOptions &
|
|
|
320
318
|
export interface InternalTextProviderOptions extends ExternalTextProviderOptions {
|
|
321
319
|
model: string
|
|
322
320
|
|
|
323
|
-
messages: Array<
|
|
321
|
+
messages: Array<BetaMessageParam>
|
|
324
322
|
|
|
325
323
|
/**
|
|
326
324
|
* The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.
|