Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc473106

Browse files
committed
initial stab at beta accumulation
1 parent66f406a commitc473106

File tree

3 files changed

+184
-9
lines changed

3 files changed

+184
-9
lines changed

‎betamessage.go

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,10 +1141,10 @@ type BetaContentBlockUnion struct {
11411141
// Any of "text", "tool_use", "server_tool_use", "web_search_tool_result",
11421142
// "code_execution_tool_result", "mcp_tool_use", "mcp_tool_result",
11431143
// "container_upload", "thinking", "redacted_thinking".
1144-
Typestring`json:"type"`
1145-
IDstring`json:"id"`
1146-
Inputany`json:"input"`
1147-
Namestring`json:"name"`
1144+
Typestring`json:"type"`
1145+
IDstring`json:"id"`
1146+
Inputjson.RawMessage`json:"input"`
1147+
Namestring`json:"name"`
11481148
// This field is a union of [BetaWebSearchToolResultBlockContentUnion],
11491149
// [BetaCodeExecutionToolResultBlockContentUnion],
11501150
// [BetaMCPToolResultBlockContentUnion]
@@ -3138,6 +3138,82 @@ func (r *BetaRawMessageStreamEventUnionDelta) UnmarshalJSON(data []byte) error {
31383138
returnapijson.UnmarshalRoot(data,r)
31393139
}
31403140

3141+
// Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as
3142+
// any other Message, except with the caveat that the Message.JSON field which normally can be used to inspect
3143+
// the JSON sent over the network may not be populated fully.
3144+
//
3145+
//message := anthropic.Message{}
3146+
//for stream.Next() {
3147+
//event := stream.Current()
3148+
//message.Accumulate(event)
3149+
//}
3150+
func (acc*BetaMessage)Accumulate(eventBetaRawMessageStreamEventUnion)error {
3151+
ifacc==nil {
3152+
returnfmt.Errorf("accumulate: cannot accumlate into nil Message")
3153+
}
3154+
3155+
switchevent:=event.AsAny().(type) {
3156+
caseBetaRawMessageStartEvent:
3157+
*acc=event.Message
3158+
caseBetaRawMessageDeltaEvent:
3159+
acc.StopReason=event.Delta.StopReason
3160+
acc.StopSequence=event.Delta.StopSequence
3161+
acc.Usage.OutputTokens=event.Usage.OutputTokens
3162+
caseBetaRawMessageStopEvent:
3163+
accJson,err:=json.Marshal(acc)
3164+
iferr!=nil {
3165+
returnfmt.Errorf("error converting content block to JSON: %w",err)
3166+
}
3167+
acc.JSON.raw=string(accJson)
3168+
caseBetaRawContentBlockStartEvent:
3169+
acc.Content=append(acc.Content,BetaContentBlockUnion{})
3170+
err:=acc.Content[len(acc.Content)-1].UnmarshalJSON([]byte(event.ContentBlock.RawJSON()))
3171+
iferr!=nil {
3172+
returnerr
3173+
}
3174+
caseBetaRawContentBlockDeltaEvent:
3175+
iflen(acc.Content)==0 {
3176+
returnfmt.Errorf("received event of type %s but there was no content block",event.Type)
3177+
}
3178+
cb:=&acc.Content[len(acc.Content)-1]
3179+
switchdelta:=event.Delta.AsAny().(type) {
3180+
caseBetaTextDelta:
3181+
cb.Text+=delta.Text
3182+
caseBetaInputJSONDelta:
3183+
iflen(delta.PartialJSON)!=0 {
3184+
ifstring(cb.Input)=="{}" {
3185+
cb.Input= []byte(delta.PartialJSON)
3186+
}else {
3187+
cb.Input=append(cb.Input, []byte(delta.PartialJSON)...)
3188+
}
3189+
}
3190+
caseBetaThinkingDelta:
3191+
cb.Thinking+=delta.Thinking
3192+
caseBetaSignatureDelta:
3193+
cb.Signature+=delta.Signature
3194+
caseBetaCitationsDelta:
3195+
citation:=BetaTextCitationUnion{}
3196+
err:=citation.UnmarshalJSON([]byte(delta.Citation.RawJSON()))
3197+
iferr!=nil {
3198+
returnfmt.Errorf("could not unmarshal citation delta into citation type: %w",err)
3199+
}
3200+
cb.Citations=append(cb.Citations,citation)
3201+
}
3202+
caseBetaRawContentBlockStopEvent:
3203+
iflen(acc.Content)==0 {
3204+
returnfmt.Errorf("received event of type %s but there was no content block",event.Type)
3205+
}
3206+
contentBlock:=&acc.Content[len(acc.Content)-1]
3207+
cbJson,err:=json.Marshal(contentBlock)
3208+
iferr!=nil {
3209+
returnfmt.Errorf("error converting content block to JSON: %w",err)
3210+
}
3211+
contentBlock.JSON.raw=string(cbJson)
3212+
}
3213+
3214+
returnnil
3215+
}
3216+
31413217
typeBetaRedactedThinkingBlockstruct {
31423218
Datastring`json:"data,required"`
31433219
Type constant.RedactedThinking`json:"type,required"`

‎examples/message-mcp-streaming/main.go

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,64 @@ import (
44
"context"
55
"fmt"
66
"github.com/anthropics/anthropic-sdk-go/option"
7+
"github.com/anthropics/anthropic-sdk-go/packages/param"
8+
"io"
9+
"net/http"
710

811
"github.com/anthropics/anthropic-sdk-go"
912
)
1013

14+
funcVerboseLoggingMiddleware() option.Middleware {
15+
returnfunc(req*http.Request,next option.MiddlewareNext) (*http.Response,error) {
16+
fmt.Printf("Request: %s %s\n",req.Method,req.URL.String())
17+
18+
ifreq.Header!=nil {
19+
forkey,values:=rangereq.Header {
20+
for_,value:=rangevalues {
21+
fmt.Printf("Header: %s: %s\n",key,value)
22+
}
23+
}
24+
}
25+
ifreq.Body!=nil {
26+
body,err:=req.GetBody()
27+
iferr!=nil {
28+
fmt.Printf("Error getting request body: %v\n",err)
29+
returnnil,err
30+
}
31+
bodyBytes,err:=io.ReadAll(body)
32+
iferr!=nil {
33+
fmt.Printf("Error reading request body: %v\n",err)
34+
returnnil,err
35+
}
36+
fmt.Printf("Request body: %s\n",string(bodyBytes))
37+
38+
}
39+
resp,err:=next(req)
40+
ifresp.Header!=nil {
41+
forkey,values:=rangeresp.Header {
42+
for_,value:=rangevalues {
43+
fmt.Printf("Response Header: %s: %s\n",key,value)
44+
}
45+
}
46+
}
47+
iferr!=nil {
48+
fmt.Printf("Error: %v\n",err)
49+
returnnil,err
50+
}
51+
fmt.Printf("Response: %d\n",resp.StatusCode)
52+
returnresp,nil
53+
}
54+
}
55+
1156
funcmain() {
12-
client:=anthropic.NewClient(option.WithHeader("anthropic-beta","mcp-client-2025-04-04"))
57+
client:=anthropic.NewClient(option.WithHeader("anthropic-beta",anthropic.AnthropicBetaMCPClient2025_04_04),
58+
option.WithMiddleware(VerboseLoggingMiddleware()))
1359

1460
mcpServers:= []anthropic.BetaRequestMCPServerURLDefinitionParam{
1561
{
16-
URL:"http://example-server.modelcontextprotocol.io/sse",
17-
Name:"example",
62+
URL:"http://example-server.modelcontextprotocol.io/sse",
63+
Name:"example",
64+
AuthorizationToken:param.NewOpt("YOUR_TOKEN"),
1865
ToolConfiguration: anthropic.BetaRequestMCPServerToolConfigurationParam{
1966
Enabled:anthropic.Bool(true),
2067
AllowedTools: []string{"echo","add"},
@@ -25,15 +72,21 @@ func main() {
2572
stream:=client.Beta.Messages.NewStreaming(context.TODO(), anthropic.BetaMessageNewParams{
2673
MaxTokens:1024,
2774
Messages: []anthropic.BetaMessageParam{
28-
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Calculate 1+2")),
75+
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("what is 1+1?")),
2976
},
3077
MCPServers:mcpServers,
3178
Model:anthropic.ModelClaude3_7Sonnet20250219,
3279
StopSequences: []string{"```\n"},
3380
})
3481

82+
message:= anthropic.BetaMessage{}
3583
forstream.Next() {
3684
event:=stream.Current()
85+
err:=message.Accumulate(event)
86+
iferr!=nil {
87+
fmt.Printf("error accumulating event: %v\n",err)
88+
continue
89+
}
3790

3891
switcheventVariant:=event.AsAny().(type) {
3992
case anthropic.BetaRawMessageDeltaEvent:

‎examples/message-streaming/main.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,58 @@ package main
22

33
import (
44
"context"
5+
"fmt"
6+
"github.com/anthropics/anthropic-sdk-go/option"
7+
"io"
8+
"net/http"
59

610
"github.com/anthropics/anthropic-sdk-go"
711
)
812

13+
funcVerboseLoggingMiddleware() option.Middleware {
14+
returnfunc(req*http.Request,next option.MiddlewareNext) (*http.Response,error) {
15+
fmt.Printf("Request: %s %s\n",req.Method,req.URL.String())
16+
17+
ifreq.Header!=nil {
18+
forkey,values:=rangereq.Header {
19+
for_,value:=rangevalues {
20+
fmt.Printf("Header: %s: %s\n",key,value)
21+
}
22+
}
23+
}
24+
ifreq.Body!=nil {
25+
body,err:=req.GetBody()
26+
iferr!=nil {
27+
fmt.Printf("Error getting request body: %v\n",err)
28+
returnnil,err
29+
}
30+
bodyBytes,err:=io.ReadAll(body)
31+
iferr!=nil {
32+
fmt.Printf("Error reading request body: %v\n",err)
33+
returnnil,err
34+
}
35+
fmt.Printf("Request body: %s\n",string(bodyBytes))
36+
37+
}
38+
resp,err:=next(req)
39+
ifresp.Header!=nil {
40+
forkey,values:=rangeresp.Header {
41+
for_,value:=rangevalues {
42+
fmt.Printf("Response Header: %s: %s\n",key,value)
43+
}
44+
}
45+
}
46+
iferr!=nil {
47+
fmt.Printf("Error: %v\n",err)
48+
returnnil,err
49+
}
50+
fmt.Printf("Response: %d\n",resp.StatusCode)
51+
returnresp,nil
52+
}
53+
}
54+
955
funcmain() {
10-
client:=anthropic.NewClient()
56+
client:=anthropic.NewClient(option.WithMiddleware(VerboseLoggingMiddleware()))
1157

1258
content:="Write me a function to call the Anthropic message API in Node.js using the Anthropic Typescript SDK."
1359

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp