228 lines · 9.5 KB · Go
RawDownload
package executor import (	"bytes"	"testing" 	"github.com/tidwall/gjson") func TestApplyClaudeToolPrefix(t *testing.T) {	input := []byte(`{"tools":[{"name":"alpha"},{"name":"proxy_bravo"}],"tool_choice":{"type":"tool","name":"charlie"},"messages":[{"role":"assistant","content":[{"type":"tool_use","name":"delta","id":"t1","input":{}}]}]}`)	out := applyClaudeToolPrefix(input, "proxy_") 	if got := gjson.GetBytes(out, "tools.0.name").String(); got != "proxy_alpha" {		t.Fatalf("tools.0.name = %q, want %q", got, "proxy_alpha")	}	if got := gjson.GetBytes(out, "tools.1.name").String(); got != "proxy_bravo" {		t.Fatalf("tools.1.name = %q, want %q", got, "proxy_bravo")	}	if got := gjson.GetBytes(out, "tool_choice.name").String(); got != "proxy_charlie" {		t.Fatalf("tool_choice.name = %q, want %q", got, "proxy_charlie")	}	if got := gjson.GetBytes(out, "messages.0.content.0.name").String(); got != "proxy_delta" {		t.Fatalf("messages.0.content.0.name = %q, want %q", got, "proxy_delta")	}} func TestApplyClaudeToolPrefix_WithToolReference(t *testing.T) {	input := []byte(`{"tools":[{"name":"alpha"}],"messages":[{"role":"user","content":[{"type":"tool_reference","tool_name":"beta"},{"type":"tool_reference","tool_name":"proxy_gamma"}]}]}`)	out := applyClaudeToolPrefix(input, "proxy_") 	if got := gjson.GetBytes(out, "messages.0.content.0.tool_name").String(); got != "proxy_beta" {		t.Fatalf("messages.0.content.0.tool_name = %q, want %q", got, "proxy_beta")	}	if got := gjson.GetBytes(out, "messages.0.content.1.tool_name").String(); got != "proxy_gamma" {		t.Fatalf("messages.0.content.1.tool_name = %q, want %q", got, "proxy_gamma")	}} func TestApplyClaudeToolPrefix_SkipsBuiltinTools(t *testing.T) {	input := []byte(`{"tools":[{"type":"web_search_20250305","name":"web_search"},{"name":"my_custom_tool","input_schema":{"type":"object"}}]}`)	out := applyClaudeToolPrefix(input, "proxy_") 	if got := gjson.GetBytes(out, "tools.0.name").String(); got != "web_search" {		t.Fatalf("built-in tool name should not be prefixed: tools.0.name = %q, want %q", got, "web_search")	}	if got := gjson.GetBytes(out, "tools.1.name").String(); got != "proxy_my_custom_tool" {		t.Fatalf("custom tool should be prefixed: tools.1.name = %q, want %q", got, "proxy_my_custom_tool")	}} func TestApplyClaudeToolPrefix_BuiltinToolSkipped(t *testing.T) {	body := []byte(`{		"tools": [			{"type": "web_search_20250305", "name": "web_search", "max_uses": 5},			{"name": "Read"}		],		"messages": [			{"role": "user", "content": [				{"type": "tool_use", "name": "web_search", "id": "ws1", "input": {}},				{"type": "tool_use", "name": "Read", "id": "r1", "input": {}}			]}		]	}`)	out := applyClaudeToolPrefix(body, "proxy_") 	if got := gjson.GetBytes(out, "tools.0.name").String(); got != "web_search" {		t.Fatalf("tools.0.name = %q, want %q", got, "web_search")	}	if got := gjson.GetBytes(out, "messages.0.content.0.name").String(); got != "web_search" {		t.Fatalf("messages.0.content.0.name = %q, want %q", got, "web_search")	}	if got := gjson.GetBytes(out, "tools.1.name").String(); got != "proxy_Read" {		t.Fatalf("tools.1.name = %q, want %q", got, "proxy_Read")	}	if got := gjson.GetBytes(out, "messages.0.content.1.name").String(); got != "proxy_Read" {		t.Fatalf("messages.0.content.1.name = %q, want %q", got, "proxy_Read")	}} func TestApplyClaudeToolPrefix_KnownBuiltinInHistoryOnly(t *testing.T) {	body := []byte(`{		"tools": [			{"name": "Read"}		],		"messages": [			{"role": "user", "content": [				{"type": "tool_use", "name": "web_search", "id": "ws1", "input": {}}			]}		]	}`)	out := applyClaudeToolPrefix(body, "proxy_") 	if got := gjson.GetBytes(out, "messages.0.content.0.name").String(); got != "web_search" {		t.Fatalf("messages.0.content.0.name = %q, want %q", got, "web_search")	}	if got := gjson.GetBytes(out, "tools.0.name").String(); got != "proxy_Read" {		t.Fatalf("tools.0.name = %q, want %q", got, "proxy_Read")	}} func TestApplyClaudeToolPrefix_CustomToolsPrefixed(t *testing.T) {	body := []byte(`{		"tools": [{"name": "Read"}, {"name": "Write"}],		"messages": [			{"role": "user", "content": [				{"type": "tool_use", "name": "Read", "id": "r1", "input": {}},				{"type": "tool_use", "name": "Write", "id": "w1", "input": {}}			]}		]	}`)	out := applyClaudeToolPrefix(body, "proxy_") 	if got := gjson.GetBytes(out, "tools.0.name").String(); got != "proxy_Read" {		t.Fatalf("tools.0.name = %q, want %q", got, "proxy_Read")	}	if got := gjson.GetBytes(out, "tools.1.name").String(); got != "proxy_Write" {		t.Fatalf("tools.1.name = %q, want %q", got, "proxy_Write")	}	if got := gjson.GetBytes(out, "messages.0.content.0.name").String(); got != "proxy_Read" {		t.Fatalf("messages.0.content.0.name = %q, want %q", got, "proxy_Read")	}	if got := gjson.GetBytes(out, "messages.0.content.1.name").String(); got != "proxy_Write" {		t.Fatalf("messages.0.content.1.name = %q, want %q", got, "proxy_Write")	}} func TestApplyClaudeToolPrefix_ToolChoiceBuiltin(t *testing.T) {	body := []byte(`{		"tools": [			{"type": "web_search_20250305", "name": "web_search"},			{"name": "Read"}		],		"tool_choice": {"type": "tool", "name": "web_search"}	}`)	out := applyClaudeToolPrefix(body, "proxy_") 	if got := gjson.GetBytes(out, "tool_choice.name").String(); got != "web_search" {		t.Fatalf("tool_choice.name = %q, want %q", got, "web_search")	}} func TestStripClaudeToolPrefixFromResponse(t *testing.T) {	input := []byte(`{"content":[{"type":"tool_use","name":"proxy_alpha","id":"t1","input":{}},{"type":"tool_use","name":"bravo","id":"t2","input":{}}]}`)	out := stripClaudeToolPrefixFromResponse(input, "proxy_") 	if got := gjson.GetBytes(out, "content.0.name").String(); got != "alpha" {		t.Fatalf("content.0.name = %q, want %q", got, "alpha")	}	if got := gjson.GetBytes(out, "content.1.name").String(); got != "bravo" {		t.Fatalf("content.1.name = %q, want %q", got, "bravo")	}} func TestStripClaudeToolPrefixFromResponse_WithToolReference(t *testing.T) {	input := []byte(`{"content":[{"type":"tool_reference","tool_name":"proxy_alpha"},{"type":"tool_reference","tool_name":"bravo"}]}`)	out := stripClaudeToolPrefixFromResponse(input, "proxy_") 	if got := gjson.GetBytes(out, "content.0.tool_name").String(); got != "alpha" {		t.Fatalf("content.0.tool_name = %q, want %q", got, "alpha")	}	if got := gjson.GetBytes(out, "content.1.tool_name").String(); got != "bravo" {		t.Fatalf("content.1.tool_name = %q, want %q", got, "bravo")	}} func TestStripClaudeToolPrefixFromStreamLine(t *testing.T) {	line := []byte(`data: {"type":"content_block_start","content_block":{"type":"tool_use","name":"proxy_alpha","id":"t1"},"index":0}`)	out := stripClaudeToolPrefixFromStreamLine(line, "proxy_") 	payload := bytes.TrimSpace(out)	if bytes.HasPrefix(payload, []byte("data:")) {		payload = bytes.TrimSpace(payload[len("data:"):])	}	if got := gjson.GetBytes(payload, "content_block.name").String(); got != "alpha" {		t.Fatalf("content_block.name = %q, want %q", got, "alpha")	}} func TestStripClaudeToolPrefixFromStreamLine_WithToolReference(t *testing.T) {	line := []byte(`data: {"type":"content_block_start","content_block":{"type":"tool_reference","tool_name":"proxy_beta"},"index":0}`)	out := stripClaudeToolPrefixFromStreamLine(line, "proxy_") 	payload := bytes.TrimSpace(out)	if bytes.HasPrefix(payload, []byte("data:")) {		payload = bytes.TrimSpace(payload[len("data:"):])	}	if got := gjson.GetBytes(payload, "content_block.tool_name").String(); got != "beta" {		t.Fatalf("content_block.tool_name = %q, want %q", got, "beta")	}} func TestApplyClaudeToolPrefix_NestedToolReference(t *testing.T) {	input := []byte(`{"messages":[{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_123","content":[{"type":"tool_reference","tool_name":"mcp__nia__manage_resource"}]}]}]}`)	out := applyClaudeToolPrefix(input, "proxy_")	got := gjson.GetBytes(out, "messages.0.content.0.content.0.tool_name").String()	if got != "proxy_mcp__nia__manage_resource" {		t.Fatalf("nested tool_reference tool_name = %q, want %q", got, "proxy_mcp__nia__manage_resource")	}} func TestStripClaudeToolPrefixFromResponse_NestedToolReference(t *testing.T) {	input := []byte(`{"content":[{"type":"tool_result","tool_use_id":"toolu_123","content":[{"type":"tool_reference","tool_name":"proxy_mcp__nia__manage_resource"}]}]}`)	out := stripClaudeToolPrefixFromResponse(input, "proxy_")	got := gjson.GetBytes(out, "content.0.content.0.tool_name").String()	if got != "mcp__nia__manage_resource" {		t.Fatalf("nested tool_reference tool_name = %q, want %q", got, "mcp__nia__manage_resource")	}} func TestApplyClaudeToolPrefix_NestedToolReferenceWithStringContent(t *testing.T) {	// tool_result.content can be a string - should not be processed	input := []byte(`{"messages":[{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_123","content":"plain string result"}]}]}`)	out := applyClaudeToolPrefix(input, "proxy_")	got := gjson.GetBytes(out, "messages.0.content.0.content").String()	if got != "plain string result" {		t.Fatalf("string content should remain unchanged = %q", got)	}} func TestApplyClaudeToolPrefix_SkipsBuiltinToolReference(t *testing.T) {	input := []byte(`{"tools":[{"type":"web_search_20250305","name":"web_search"}],"messages":[{"role":"user","content":[{"type":"tool_result","tool_use_id":"t1","content":[{"type":"tool_reference","tool_name":"web_search"}]}]}]}`)	out := applyClaudeToolPrefix(input, "proxy_")	got := gjson.GetBytes(out, "messages.0.content.0.content.0.tool_name").String()	if got != "web_search" {		t.Fatalf("built-in tool_reference should not be prefixed, got %q", got)	}}