package service import ( "encoding/json" "strings" "testing" ) func TestNormalizeWindsurfRequestCanonicalizesToolsChoiceAndHistory(t *testing.T) { req := windsurfMessagesRequest{ Tools: []windsurfRequestTool{ { Name: "list_files", Description: "List files", InputSchema: json.RawMessage(`{"type":"object"}`), }, { Name: "glob", Description: "Duplicate canonical alias", InputSchema: json.RawMessage(`{"type":"object","properties":{"path":{"type":"string"}}}`), }, { Name: "applyPatch", Description: "Patch files", InputSchema: json.RawMessage(`{"type":"object"}`), }, }, ToolChoice: map[string]any{ "type": "tool", "name": "searchFiles", }, Messages: []windsurfRequestMessage{ { Role: "assistant", Content: json.RawMessage(`[ {"type":"tool_use","id":"call-1","name":"read_file","input":{"filePath":"a.go"}}, {"type":"text","text":"done"} ]`), }, }, } normalizeWindsurfRequest(&req) if len(req.Tools) != 2 { t.Fatalf("normalized tools len = %d, want 2", len(req.Tools)) } if req.Tools[0].Name != "glob" { t.Fatalf("first tool name = %q, want glob", req.Tools[0].Name) } if req.Tools[1].Name != "edit" { t.Fatalf("second tool name = %q, want edit", req.Tools[1].Name) } toolChoice, ok := req.ToolChoice.(map[string]any) if !ok { t.Fatalf("normalized tool choice type = %T, want map[string]any", req.ToolChoice) } if toolChoice["name"] != "grep" { t.Fatalf("tool choice name = %v, want grep", toolChoice["name"]) } var blocks []windsurfContentBlock if err := json.Unmarshal(req.Messages[0].Content, &blocks); err != nil { t.Fatalf("unmarshal normalized message content: %v", err) } if len(blocks) == 0 || blocks[0].Name != "read" { t.Fatalf("tool_use name = %q, want read", blocks[0].Name) } } func TestWindsurfExtractContentTextFromRawPreservesStructuredToolResult(t *testing.T) { raw := json.RawMessage(`[ {"type":"text","text":"summary"}, {"type":"json","value":{"entries":["main.go"]}} ]`) got := windsurfExtractContentTextFromRaw(raw) if !strings.Contains(got, `"type":"json"`) { t.Fatalf("structured tool_result content should be preserved, got %q", got) } }