fix(amp): strip signature from tool_use blocks before forwarding to Claude

ensureAmpSignature injects signature:"" into tool_use blocks so the
Amp TUI does not crash on P.signature.length. when Amp sends the
conversation back, Claude rejects the extra field with 400:
  tool_use.signature: Extra inputs are not permitted

strip the proxy-injected signature from tool_use blocks in
SanitizeAmpRequestBody before forwarding to the upstream API.
This commit is contained in:
Aikins Laryea
2026-04-03 17:20:43 +00:00
parent ab9ebea592
commit b0653cec7b
2 changed files with 49 additions and 8 deletions
@@ -145,6 +145,36 @@ func TestSanitizeAmpRequestBody_RemovesWhitespaceAndNonStringSignatures(t *testi
}
}
func TestSanitizeAmpRequestBody_StripsSignatureFromToolUseBlocks(t *testing.T) {
input := []byte(`{"messages":[{"role":"assistant","content":[{"type":"thinking","thinking":"thought","signature":"valid-sig"},{"type":"tool_use","id":"toolu_01","name":"Bash","input":{"cmd":"ls"},"signature":""}]}]}`)
result := SanitizeAmpRequestBody(input)
if contains(result, []byte(`"signature":""`)) {
t.Fatalf("expected signature to be stripped from tool_use block, got %s", string(result))
}
if !contains(result, []byte(`"valid-sig"`)) {
t.Fatalf("expected thinking signature to remain, got %s", string(result))
}
if !contains(result, []byte(`"tool_use"`)) {
t.Fatalf("expected tool_use block to remain, got %s", string(result))
}
}
func TestSanitizeAmpRequestBody_MixedInvalidThinkingAndToolUseSignature(t *testing.T) {
input := []byte(`{"messages":[{"role":"assistant","content":[{"type":"thinking","thinking":"drop-me","signature":""},{"type":"tool_use","id":"toolu_01","name":"Bash","input":{"cmd":"ls"},"signature":""}]}]}`)
result := SanitizeAmpRequestBody(input)
if contains(result, []byte("drop-me")) {
t.Fatalf("expected invalid thinking block to be removed, got %s", string(result))
}
if contains(result, []byte(`"signature"`)) {
t.Fatalf("expected signature to be stripped from tool_use block, got %s", string(result))
}
if !contains(result, []byte(`"tool_use"`)) {
t.Fatalf("expected tool_use block to remain, got %s", string(result))
}
}
func contains(data, substr []byte) bool {
for i := 0; i <= len(data)-len(substr); i++ {
if string(data[i:i+len(substr)]) == string(substr) {