-
Notifications
You must be signed in to change notification settings - Fork 85
Open
Description
Go version: go version go1.25.0 linux/amd64
SDK version: github.com/anthropics/anthropic-sdk-go v1.13.0
Steps to reproduce
- Construct a
Messageby unmarshalling an API response payload - Modify the content of a text content block
- Call
ToParamto convertMessagetoMessageParam - Expected: text block modifications are reflected in
MessageParam - Actual: text block modifications are not reflected in
MessageParam
Code to reproduce
package main
import (
"encoding/json"
"fmt"
"github.com/anthropics/anthropic-sdk-go"
)
func main() {
// Response content copied from https://docs.claude.com/en/api/messages
respJSON := `{"content":[{"citations":null,"text":"Hi! My name is Claude.","type":"text"}],"id":"msg_013Zva2CMHLNnXjNJJKqJ2EF","model":"claude-sonnet-4-20250514","role":"assistant","stop_reason":"end_turn","stop_sequence":null,"type":"message","usage":{"input_tokens":2095,"output_tokens":503}}`
// Simulate receiving this response
var message anthropic.Message
err := json.Unmarshal([]byte(respJSON), &message)
if err != nil {
panic(err)
}
// Modify content blocks, e.g. to manipulate conversation history for next exchange
message.Content[0].Text = "Yarrr! Me name be Claude."
// Call ToParam to create MessageParam in preparation for next call to Messages.New or Messages.NewStreaming
messageParam := message.ToParam()
// Output: "Hi! My name is Claude."
// Expected: "Yarrr! Me name be Claude."
fmt.Println(messageParam.Content[0].OfText.Text)
}The change to message.Content[0].Text is not effective because AsText() on ContentBlockUnion unmarshals TextBlock from u.JSON.raw, ignoring the unmarshalled fields on TextBlock. Stack for reference:
anthropic-sdk-go.ContentBlockUnion.AsText (...\github.com\anthropics\[email protected]\message.go:726)
anthropic-sdk-go.ContentBlockUnion.AsAny (...\github.com\anthropics\[email protected]\message.go:710)
anthropic-sdk-go.ContentBlockUnion.ToParam (...\github.com\anthropics\[email protected]\message.go:665)
anthropic-sdk-go.Message.ToParam (...\github.com\anthropics\[email protected]\message.go:1790)
Impact
It's convenient to store assistant messages in conversation history as Message objects because they include useful information like Usage that is not available in MessageParam. Some use cases require manipulating conversation history, and if Message is immutable it's difficult to modify conversation history stored this way.
Suggested fix
- If
Message,ContentBlockUnion, etc are intended to be immutable, this should be documented, and maybe enforced with getters over unexported fields. - If they are not intended to be immutable,
ContentBlockUnion'sAs*()functions should copy over the values of relevant fields after unmarshalling the raw content.
Metadata
Metadata
Assignees
Labels
No labels