@@ -2,6 +2,7 @@ package amp
22
33import (
44 "bytes"
5+ "encoding/json"
56 "fmt"
67 "net/http"
78 "strings"
@@ -290,8 +291,10 @@ func (rw *ResponseRewriter) rewriteStreamEvent(data []byte) []byte {
290291}
291292
292293// SanitizeAmpRequestBody removes thinking blocks with empty/missing/invalid signatures
293- // from the messages array in a request body before forwarding to the upstream API.
294- // This prevents 400 errors from the API which requires valid signatures on thinking blocks.
294+ // and strips the proxy-injected "signature" field from tool_use blocks in the messages
295+ // array before forwarding to the upstream API.
296+ // This prevents 400 errors from the API which requires valid signatures on thinking
297+ // blocks and does not accept a signature field on tool_use blocks.
295298func SanitizeAmpRequestBody (body []byte ) []byte {
296299 messages := gjson .GetBytes (body , "messages" )
297300 if ! messages .Exists () || ! messages .IsArray () {
@@ -309,21 +312,30 @@ func SanitizeAmpRequestBody(body []byte) []byte {
309312 }
310313
311314 var keepBlocks []interface {}
312- removedCount := 0
315+ contentModified := false
313316
314317 for _ , block := range content .Array () {
315318 blockType := block .Get ("type" ).String ()
316319 if blockType == "thinking" {
317320 sig := block .Get ("signature" )
318321 if ! sig .Exists () || sig .Type != gjson .String || strings .TrimSpace (sig .String ()) == "" {
319- removedCount ++
322+ contentModified = true
320323 continue
321324 }
322325 }
323- keepBlocks = append (keepBlocks , block .Value ())
326+
327+ // Use raw JSON to prevent float64 rounding of large integers in tool_use inputs
328+ blockRaw := []byte (block .Raw )
329+ if blockType == "tool_use" && block .Get ("signature" ).Exists () {
330+ blockRaw , _ = sjson .DeleteBytes (blockRaw , "signature" )
331+ contentModified = true
332+ }
333+
334+ // sjson.SetBytes supports raw JSON strings if wrapped in gjson.Raw
335+ keepBlocks = append (keepBlocks , json .RawMessage (blockRaw ))
324336 }
325337
326- if removedCount > 0 {
338+ if contentModified {
327339 contentPath := fmt .Sprintf ("messages.%d.content" , msgIdx )
328340 var err error
329341 if len (keepBlocks ) == 0 {
@@ -332,11 +344,10 @@ func SanitizeAmpRequestBody(body []byte) []byte {
332344 body , err = sjson .SetBytes (body , contentPath , keepBlocks )
333345 }
334346 if err != nil {
335- log .Warnf ("Amp RequestSanitizer: failed to remove thinking blocks from message %d: %v" , msgIdx , err )
347+ log .Warnf ("Amp RequestSanitizer: failed to sanitize message %d: %v" , msgIdx , err )
336348 continue
337349 }
338350 modified = true
339- log .Debugf ("Amp RequestSanitizer: removed %d thinking blocks with invalid signatures from message %d" , removedCount , msgIdx )
340351 }
341352 }
342353
0 commit comments