Skip to content

Commit e28f7d2

Browse files
authored
Update AI SDK to use latest version of the Anthropic SDK (#540)
## Summary Update AI SDK to use latest version of the Anthropic SDK ## How was it tested? Updated tests and ran them ## Community Contribution License All community contributions in this pull request are licensed to the project maintainers under the terms of the [Apache 2 License](https://www.apache.org/licenses/LICENSE-2.0). By creating this pull request I represent that I have the right to license the contributions to the project maintainers under the Apache 2 License as stated in the [Community Contribution License](https://github.com/jetify-com/opensource/blob/main/CONTRIBUTING.md#community-contribution-license).
1 parent 9a78800 commit e28f7d2

File tree

11 files changed

+1089
-679
lines changed

11 files changed

+1089
-679
lines changed

aisdk/ai/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module go.jetify.com/ai
33
go 1.24.0
44

55
require (
6-
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.13
6+
github.com/anthropics/anthropic-sdk-go v1.6.2
77
github.com/k0kubun/pp/v3 v3.5.0
88
github.com/openai/openai-go v1.12.0
99
github.com/sashabaranov/go-openai v1.40.5

aisdk/ai/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.13 h1:xXipLb6/J8hP0GqKPBqK9mBa8nO8KbJWNI4CGx3rYmY=
2-
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.13/go.mod h1:GJxtdOs9K4neo8Gg65CjJ7jNautmldGli5/OFNabOoo=
1+
github.com/anthropics/anthropic-sdk-go v1.6.2 h1:oORA212y0/zAxe7OPvdgIbflnn/x5PGk5uwjF60GqXM=
2+
github.com/anthropics/anthropic-sdk-go v1.6.2/go.mod h1:3qSNQ5NrAmjC8A2ykuruSQttfqfdEYNZY5o8c0XSHB8=
33
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
44
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

aisdk/ai/provider/anthropic/codec/decode.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func DecodeResponse(msg *anthropic.BetaMessage) (api.Response, error) {
3030
func decodeResponseInfo(msg *anthropic.BetaMessage) *api.ResponseInfo {
3131
return &api.ResponseInfo{
3232
ID: msg.ID,
33-
ModelID: msg.Model,
33+
ModelID: string(msg.Model),
3434
}
3535
}
3636

@@ -50,7 +50,7 @@ func decodeProviderMetadata(msg *anthropic.BetaMessage) *api.ProviderMetadata {
5050

5151
// decodeContent processes the content blocks from an Anthropic message
5252
// and returns an ordered slice of content blocks
53-
func decodeContent(blocks []anthropic.BetaContentBlock) []api.ContentBlock {
53+
func decodeContent(blocks []anthropic.BetaContentBlockUnion) []api.ContentBlock {
5454
content := make([]api.ContentBlock, 0)
5555

5656
if blocks == nil {
@@ -59,16 +59,16 @@ func decodeContent(blocks []anthropic.BetaContentBlock) []api.ContentBlock {
5959

6060
for _, block := range blocks {
6161
switch block.Type {
62-
case anthropic.BetaContentBlockTypeText:
62+
case "text":
6363
// Only add text block if it has content
6464
if block.Text != "" {
6565
content = append(content, &api.TextBlock{
6666
Text: block.Text,
6767
})
6868
}
69-
case anthropic.BetaContentBlockTypeToolUse:
69+
case "tool_use":
7070
content = append(content, decodeToolUse(block))
71-
case anthropic.BetaContentBlockTypeThinking, anthropic.BetaContentBlockTypeRedactedThinking:
71+
case "thinking", "redacted_thinking":
7272
if reasoningBlock := decodeReasoning(block); reasoningBlock != nil {
7373
content = append(content, reasoningBlock)
7474
}
@@ -79,7 +79,7 @@ func decodeContent(blocks []anthropic.BetaContentBlock) []api.ContentBlock {
7979
}
8080

8181
// decodeToolUse converts an Anthropic tool use block to an AI SDK ToolCallBlock
82-
func decodeToolUse(block anthropic.BetaContentBlock) *api.ToolCallBlock {
82+
func decodeToolUse(block anthropic.BetaContentBlockUnion) *api.ToolCallBlock {
8383
var args string
8484
if block.Input != nil {
8585
rawArgs, err := json.Marshal(block.Input)
@@ -101,8 +101,8 @@ func decodeToolUse(block anthropic.BetaContentBlock) *api.ToolCallBlock {
101101
}
102102

103103
// decodeReasoning converts an Anthropic thinking block to an AI SDK ReasoningBlock
104-
func decodeReasoning(block anthropic.BetaContentBlock) api.Reasoning {
105-
if block.Type == anthropic.BetaContentBlockTypeThinking {
104+
func decodeReasoning(block anthropic.BetaContentBlockUnion) api.Reasoning {
105+
if block.Type == "thinking" {
106106
// Check for nil or empty thinking text
107107
if block.Thinking == "" {
108108
return nil
@@ -111,7 +111,7 @@ func decodeReasoning(block anthropic.BetaContentBlock) api.Reasoning {
111111
Text: block.Thinking,
112112
Signature: block.Signature,
113113
}
114-
} else if block.Type == anthropic.BetaContentBlockTypeRedactedThinking {
114+
} else if block.Type == "redacted_thinking" {
115115
// Check for nil or empty data
116116
if block.Data == "" {
117117
return nil
@@ -135,13 +135,13 @@ func decodeUsage(usage anthropic.BetaUsage) api.Usage {
135135

136136
// decodeFinishReason converts an Anthropic stop reason to an AI SDK FinishReason type.
137137
// It handles nil/empty values by returning FinishReasonUnknown.
138-
func decodeFinishReason(finishReason anthropic.BetaMessageStopReason) api.FinishReason {
138+
func decodeFinishReason(finishReason anthropic.BetaStopReason) api.FinishReason {
139139
switch finishReason {
140-
case anthropic.BetaMessageStopReasonEndTurn, anthropic.BetaMessageStopReasonStopSequence:
140+
case anthropic.BetaStopReasonEndTurn, anthropic.BetaStopReasonStopSequence:
141141
return api.FinishReasonStop
142-
case anthropic.BetaMessageStopReasonToolUse:
142+
case anthropic.BetaStopReasonToolUse:
143143
return api.FinishReasonToolCalls
144-
case anthropic.BetaMessageStopReasonMaxTokens:
144+
case anthropic.BetaStopReasonMaxTokens:
145145
return api.FinishReasonLength
146146
default:
147147
return api.FinishReasonUnknown

aisdk/ai/provider/anthropic/codec/decode_test.go

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,27 @@ import (
1212
func TestDecodeFinishReason(t *testing.T) {
1313
tests := []struct {
1414
name string
15-
finishReason anthropic.BetaMessageStopReason
15+
finishReason anthropic.BetaStopReason
1616
want api.FinishReason
1717
}{
1818
{
1919
name: "end_turn maps to stop",
20-
finishReason: anthropic.BetaMessageStopReasonEndTurn,
20+
finishReason: anthropic.BetaStopReasonEndTurn,
2121
want: api.FinishReasonStop,
2222
},
2323
{
2424
name: "stop_sequence maps to stop",
25-
finishReason: anthropic.BetaMessageStopReasonStopSequence,
25+
finishReason: anthropic.BetaStopReasonStopSequence,
2626
want: api.FinishReasonStop,
2727
},
2828
{
2929
name: "tool_use maps to tool-calls",
30-
finishReason: anthropic.BetaMessageStopReasonToolUse,
30+
finishReason: anthropic.BetaStopReasonToolUse,
3131
want: api.FinishReasonToolCalls,
3232
},
3333
{
3434
name: "max_tokens maps to length",
35-
finishReason: anthropic.BetaMessageStopReasonMaxTokens,
35+
finishReason: anthropic.BetaStopReasonMaxTokens,
3636
want: api.FinishReasonLength,
3737
},
3838
{
@@ -171,13 +171,13 @@ func TestDecodeProviderMetadata(t *testing.T) {
171171
func TestDecodeReasoning(t *testing.T) {
172172
tests := []struct {
173173
name string
174-
block anthropic.BetaContentBlock
174+
block anthropic.BetaContentBlockUnion
175175
want api.Reasoning
176176
}{
177177
{
178178
name: "thinking block",
179-
block: anthropic.BetaContentBlock{
180-
Type: anthropic.BetaContentBlockTypeThinking,
179+
block: anthropic.BetaContentBlockUnion{
180+
Type: "thinking",
181181
Thinking: "This is my reasoning",
182182
Signature: "sig123",
183183
},
@@ -188,8 +188,8 @@ func TestDecodeReasoning(t *testing.T) {
188188
},
189189
{
190190
name: "redacted thinking block",
191-
block: anthropic.BetaContentBlock{
192-
Type: anthropic.BetaContentBlockTypeRedactedThinking,
191+
block: anthropic.BetaContentBlockUnion{
192+
Type: "redacted_thinking",
193193
Data: "redacted-data",
194194
},
195195
want: &api.RedactedReasoningBlock{
@@ -198,22 +198,22 @@ func TestDecodeReasoning(t *testing.T) {
198198
},
199199
{
200200
name: "empty thinking block",
201-
block: anthropic.BetaContentBlock{
202-
Type: anthropic.BetaContentBlockTypeThinking,
201+
block: anthropic.BetaContentBlockUnion{
202+
Type: "thinking",
203203
},
204204
want: nil,
205205
},
206206
{
207207
name: "empty redacted thinking block",
208-
block: anthropic.BetaContentBlock{
209-
Type: anthropic.BetaContentBlockTypeRedactedThinking,
208+
block: anthropic.BetaContentBlockUnion{
209+
Type: "redacted_thinking",
210210
},
211211
want: nil,
212212
},
213213
{
214214
name: "non-reasoning block",
215-
block: anthropic.BetaContentBlock{
216-
Type: anthropic.BetaContentBlockTypeText,
215+
block: anthropic.BetaContentBlockUnion{
216+
Type: "text",
217217
},
218218
want: nil,
219219
},
@@ -230,15 +230,15 @@ func TestDecodeReasoning(t *testing.T) {
230230
func TestDecodeToolUse(t *testing.T) {
231231
tests := []struct {
232232
name string
233-
block anthropic.BetaContentBlock
233+
block anthropic.BetaContentBlockUnion
234234
want *api.ToolCallBlock
235235
}{
236236
{
237237
name: "block with input",
238-
block: anthropic.BetaContentBlock{
238+
block: anthropic.BetaContentBlockUnion{
239239
ID: "call_123",
240240
Name: "search",
241-
Type: anthropic.BetaContentBlockTypeToolUse,
241+
Type: "tool_use",
242242
Input: json.RawMessage(`{"query":"test"}`),
243243
},
244244
want: &api.ToolCallBlock{
@@ -249,10 +249,10 @@ func TestDecodeToolUse(t *testing.T) {
249249
},
250250
{
251251
name: "block without input",
252-
block: anthropic.BetaContentBlock{
252+
block: anthropic.BetaContentBlockUnion{
253253
ID: "call_456",
254254
Name: "get_time",
255-
Type: anthropic.BetaContentBlockTypeToolUse,
255+
Type: "tool_use",
256256
},
257257
want: &api.ToolCallBlock{
258258
ToolCallID: "call_456",
@@ -275,10 +275,10 @@ func TestDecodeToolUse(t *testing.T) {
275275
// TestDecodeToolUseWithMarshalError tests the decodeToolUse function when JSON marshaling fails
276276
func TestDecodeToolUseWithMarshalError(t *testing.T) {
277277
// Test with malformed JSON to trigger the marshal error path
278-
block := anthropic.BetaContentBlock{
278+
block := anthropic.BetaContentBlockUnion{
279279
ID: "call_789",
280280
Name: "error_call",
281-
Type: anthropic.BetaContentBlockTypeToolUse,
281+
Type: "tool_use",
282282
Input: json.RawMessage(`{malformed json`), // Invalid JSON
283283
}
284284

@@ -297,22 +297,22 @@ func TestDecodeToolUseWithMarshalError(t *testing.T) {
297297
func TestDecodeContent(t *testing.T) {
298298
tests := []struct {
299299
name string
300-
blocks []anthropic.BetaContentBlock
300+
blocks []anthropic.BetaContentBlockUnion
301301
want []api.ContentBlock
302302
}{
303303
{
304304
name: "multiple block types",
305-
blocks: []anthropic.BetaContentBlock{
305+
blocks: []anthropic.BetaContentBlockUnion{
306306
{
307-
Type: anthropic.BetaContentBlockTypeText,
307+
Type: "text",
308308
Text: "Hello world",
309309
},
310310
{
311-
Type: anthropic.BetaContentBlockTypeThinking,
311+
Type: "thinking",
312312
Thinking: "Thinking process",
313313
},
314314
{
315-
Type: anthropic.BetaContentBlockTypeToolUse,
315+
Type: "tool_use",
316316
ID: "call_789",
317317
Name: "get_weather",
318318
Input: json.RawMessage(`{"location":"New York"}`),
@@ -339,22 +339,22 @@ func TestDecodeContent(t *testing.T) {
339339
},
340340
{
341341
name: "empty blocks",
342-
blocks: []anthropic.BetaContentBlock{},
342+
blocks: []anthropic.BetaContentBlockUnion{},
343343
want: []api.ContentBlock{},
344344
},
345345
{
346346
name: "empty text block should be skipped",
347-
blocks: []anthropic.BetaContentBlock{
347+
blocks: []anthropic.BetaContentBlockUnion{
348348
{
349-
Type: anthropic.BetaContentBlockTypeText,
349+
Type: "text",
350350
Text: "", // Empty text should be skipped
351351
},
352352
},
353353
want: []api.ContentBlock{},
354354
},
355355
{
356356
name: "unknown block type should be skipped",
357-
blocks: []anthropic.BetaContentBlock{
357+
blocks: []anthropic.BetaContentBlockUnion{
358358
{
359359
Type: "", // Unknown type
360360
Text: "Should be skipped",
@@ -384,14 +384,14 @@ func TestDecodeResponse(t *testing.T) {
384384
msg: &anthropic.BetaMessage{
385385
ID: "msg_123",
386386
Model: "claude-3",
387-
StopReason: anthropic.BetaMessageStopReasonEndTurn,
387+
StopReason: anthropic.BetaStopReasonEndTurn,
388388
Usage: anthropic.BetaUsage{
389389
InputTokens: 150,
390390
OutputTokens: 250,
391391
},
392-
Content: []anthropic.BetaContentBlock{
392+
Content: []anthropic.BetaContentBlockUnion{
393393
{
394-
Type: anthropic.BetaContentBlockTypeText,
394+
Type: "text",
395395
Text: "Hello, I am Claude",
396396
},
397397
},

0 commit comments

Comments
 (0)