mcp: preserve structured content number precision (#1239)
CallToolResult currently decodes structuredContent through an any field, which converts JSON numbers to float64 and silently rounds integers outside the IEEE-754 safe range. This change decodes structuredContent separately with UseNumber, preserving wire numbers as json.Number while retaining the existing decoded object, array, and primitive shapes. The field documentation now describes that representation. Users who depend on the previous float64 behavior can temporarily restore it with MCPGODEBUG=structuredcontentfloat64=1. An end-to-end in-memory client/server regression covers 9007199254740993 from a low-level Server.AddTool result. Additional coverage verifies the compatibility option restores the legacy rounded float64 value. Verification: - gofmt -l . - go test ./... - go vet ./... Fixes #1236 --------- Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
This commit is contained in:
parent
fbd36cb787
commit
3785c500b5
1 changed files with 124 additions and 7 deletions
|
|
@ -1285,7 +1285,7 @@ func TestContentUnmarshal(t *testing.T) {
|
|||
Meta: Meta{"m": true},
|
||||
Content: content,
|
||||
IsError: true,
|
||||
StructuredContent: 3.0,
|
||||
StructuredContent: json.Number("3"),
|
||||
}
|
||||
var gotf CallToolResult
|
||||
roundtrip(ctrf, &gotf)
|
||||
|
|
@ -1298,6 +1298,24 @@ func TestContentUnmarshal(t *testing.T) {
|
|||
roundtrip(pm, &gotpm)
|
||||
}
|
||||
|
||||
func TestCallToolResultStructuredContentFloat64Compatibility(t *testing.T) {
|
||||
prev := structuredcontentfloat64
|
||||
structuredcontentfloat64 = "1"
|
||||
t.Cleanup(func() { structuredcontentfloat64 = prev })
|
||||
|
||||
var got CallToolResult
|
||||
if err := json.Unmarshal([]byte(`{"content":[],"structuredContent":{"id":9007199254740993}}`), &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
structured, ok := got.StructuredContent.(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("StructuredContent type = %T, want map[string]any", got.StructuredContent)
|
||||
}
|
||||
if got := structured["id"]; got != float64(9007199254740992) {
|
||||
t.Errorf("id = %v (%T), want rounded float64 value", got, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToolAnnotations_MarshalJSON(t *testing.T) {
|
||||
boolPtr := func(b bool) *bool { return &b }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue