diff --git a/internal/translator/antigravity/claude/antigravity_claude_response.go b/internal/translator/antigravity/claude/antigravity_claude_response.go index 9b0e2756..e6fd810a 100644 --- a/internal/translator/antigravity/claude/antigravity_claude_response.go +++ b/internal/translator/antigravity/claude/antigravity_claude_response.go @@ -75,16 +75,13 @@ func ConvertAntigravityResponseToClaude(_ context.Context, _ string, originalReq HasFirstResponse: false, ResponseType: 0, ResponseIndex: 0, + ToolNameMap: util.SanitizedToolNameMap(originalRequestRawJSON), } } modelName := gjson.GetBytes(requestRawJSON, "model").String() params := (*param).(*Params) - if params.ToolNameMap == nil { - params.ToolNameMap = util.SanitizedToolNameMap(originalRequestRawJSON) - } - if bytes.Equal(rawJSON, []byte("[DONE]")) { output := make([]byte, 0, 256) // Only send final events if we have actually output content diff --git a/internal/util/sanitize_test.go b/internal/util/sanitize_test.go index 3b7714cf..f589aff4 100644 --- a/internal/util/sanitize_test.go +++ b/internal/util/sanitize_test.go @@ -93,6 +93,20 @@ func TestSanitizedToolNameMap(t *testing.T) { t.Error("expected nil for nil input") } }) + + t.Run("collision keeps first mapping", func(t *testing.T) { + raw := []byte(`{"tools":[ + {"name":"read/file","input_schema":{}}, + {"name":"read@file","input_schema":{}} + ]}`) + m := SanitizedToolNameMap(raw) + if m == nil { + t.Fatal("expected non-nil map") + } + if m["read_file"] != "read/file" { + t.Errorf("expected first mapping read/file, got %q", m["read_file"]) + } + }) } func TestRestoreSanitizedToolName(t *testing.T) { diff --git a/internal/util/translator.go b/internal/util/translator.go index 81400eee..a40609f1 100644 --- a/internal/util/translator.go +++ b/internal/util/translator.go @@ -8,6 +8,7 @@ import ( "fmt" "strings" + log "github.com/sirupsen/logrus" "github.com/tidwall/gjson" "github.com/tidwall/sjson" ) @@ -298,6 +299,8 @@ func SanitizedToolNameMap(rawJSON []byte) map[string]string { } if _, exists := out[sanitized]; !exists { out[sanitized] = name + } else { + log.Warnf("sanitized tool name collision: %q and %q both map to %q, keeping first", out[sanitized], name, sanitized) } return true })