package chat import ( "encoding/json" "strings" "testing" ) func TestQwen3Renderer_ToolsAndToolCalls(t *testing.T) { r := &Qwen3Renderer{} toolSchema := map[string]any{ "name": "get_weather", "description": "Get current weather", "parameters": map[string]any{ "type": "object", "properties": map[string]any{ "city": map[string]any{"type": "string"}, }, }, } args, err := json.Marshal(map[string]any{"city": "Istanbul"}) if err != nil { t.Fatal(err) } out, err := r.Render( []Message{ {Role: "user", Content: "Weather?"}, {Role: "assistant", Content: "", ToolCalls: []ToolCall{{Name: "get_weather", Arguments: args}}}, }, Options{AddGenerationPrompt: false, EnableThinking: true, Tools: []any{toolSchema}}, ) if err != nil { t.Fatalf("render failed: %v", err) } if !strings.Contains(out, "# Tools") { t.Fatalf("missing tools header") } if !strings.Contains(out, "") || !strings.Contains(out, "") { t.Fatalf("missing wrapper") } if !strings.Contains(out, "") || !strings.Contains(out, "\"name\": \"get_weather\"") { t.Fatalf("missing tool_call encoding: %q", out) } } func TestQwen3Renderer_ToolResponseGroup(t *testing.T) { r := &Qwen3Renderer{} out, err := r.Render( []Message{ {Role: "user", Content: "Do thing"}, {Role: "tool", Content: "{\"ok\":true}"}, {Role: "assistant", Content: "Done"}, }, Options{AddGenerationPrompt: false, EnableThinking: true}, ) if err != nil { t.Fatalf("render failed: %v", err) } if !strings.Contains(out, "") || !strings.Contains(out, "") { t.Fatalf("missing tool_response wrapper: %q", out) } if !strings.Contains(out, "<|im_start|>user\n") { t.Fatalf("tool response not wrapped as user group: %q", out) } }