package convert import ( "encoding/json" "testing" ) func TestChatToMessages(t *testing.T) { maxTokens := 1024 temp := 0.7 req := &ChatCompletionRequest{ Model: "claude-3-sonnet-20240229", Messages: []Message{ {Role: "system", Content: "You are a helpful assistant."}, {Role: "user", Content: "Hello!"}, }, MaxTokens: &maxTokens, Temperature: &temp, } result, err := ChatToMessages(req) if err != nil { t.Fatalf("ChatToMessages() error = %v", err) } if result.Model != "claude-3-sonnet-20240229" { t.Errorf("Model = %q, want %q", result.Model, "claude-3-sonnet-20240229") } if len(result.Messages) != 1 { t.Errorf("Messages length = %d, want 1", len(result.Messages)) } if result.Messages[0].Role != "user" { t.Errorf("Messages[0].Role = %q, want %q", result.Messages[0].Role, "user") } if result.System == nil { t.Error("System is nil, want non-nil") } if result.MaxTokens != 1024 { t.Errorf("MaxTokens = %d, want 1024", result.MaxTokens) } } func TestMessagesToChat(t *testing.T) { resp := &MessagesResponse{ ID: "msg-123", Model: "claude-3-sonnet-20240229", Content: []ContentBlock{ {Type: "text", Text: "Hello! How can I help?"}, }, StopReason: "end_turn", Usage: Usage{ PromptTokens: 10, CompletionTokens: 20, }, } result, err := MessagesToChat(resp) if err != nil { t.Fatalf("MessagesToChat() error = %v", err) } if result.ID != "msg-123" { t.Errorf("ID = %q, want %q", result.ID, "msg-123") } if result.Object != "chat.completion" { t.Errorf("Object = %q, want %q", result.Object, "chat.completion") } if len(result.Choices) != 1 { t.Errorf("Choices length = %d, want 1", len(result.Choices)) return } if result.Choices[0].Message.Role != "assistant" { t.Errorf("Choices[0].Message.Role = %q, want %q", result.Choices[0].Message.Role, "assistant") } if result.Choices[0].Message.Content != "Hello! How can I help?" { t.Errorf("Choices[0].Message.Content = %q, want %q", result.Choices[0].Message.Content, "Hello! How can I help?") } if result.Choices[0].FinishReason != "stop" { t.Errorf("FinishReason = %q, want %q", result.Choices[0].FinishReason, "stop") } if result.Usage.TotalTokens != 30 { t.Errorf("Usage.TotalTokens = %d, want 30", result.Usage.TotalTokens) } } func TestChatToResponses(t *testing.T) { maxTokens := 2048 req := &ChatCompletionRequest{ Model: "gpt-4o", Messages: []Message{ {Role: "system", Content: "You are a helpful assistant."}, {Role: "user", Content: "What is 2+2?"}, }, MaxTokens: &maxTokens, } result, err := ChatToResponses(req) if err != nil { t.Fatalf("ChatToResponses() error = %v", err) } if result.Model != "gpt-4o" { t.Errorf("Model = %q, want %q", result.Model, "gpt-4o") } if len(result.Input) == 0 { t.Errorf("Input empty, want 1 item") } else { var items []InputItem if err := json.Unmarshal(result.Input, &items); err != nil { t.Fatalf("Input unmarshal = %v", err) } if len(items) != 1 { t.Errorf("Input length = %d, want 1", len(items)) } else if items[0].Role != "user" { t.Errorf("Input[0].Role = %q, want %q", items[0].Role, "user") } } if result.Instructions != "You are a helpful assistant." { t.Errorf("Instructions = %q, want %q", result.Instructions, "You are a helpful assistant.") } } func TestResponsesToChat(t *testing.T) { resp := &ResponsesResponse{ ID: "resp-123", Model: "gpt-4o", Status: "completed", Output: []OutputItem{ { Type: "message", Content: []OutputContent{ {Type: "output_text", Text: "2+2 equals 4."}, }, }, }, Usage: Usage{ PromptTokens: 15, CompletionTokens: 10, }, } result, err := ResponsesToChat(resp) if err != nil { t.Fatalf("ResponsesToChat() error = %v", err) } if result.ID != "resp-123" { t.Errorf("ID = %q, want %q", result.ID, "resp-123") } if len(result.Choices) != 1 { t.Errorf("Choices length = %d, want 1", len(result.Choices)) return } if result.Choices[0].Message.Content != "2+2 equals 4." { t.Errorf("Content = %q, want %q", result.Choices[0].Message.Content, "2+2 equals 4.") } } func TestMapStopReason(t *testing.T) { tests := []struct { input string expected string }{ {"end_turn", "stop"}, {"stop_sequence", "stop"}, {"tool_use", "tool_calls"}, {"max_tokens", "length"}, {"unknown", "stop"}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { result := mapStopReason(tt.input) if result != tt.expected { t.Errorf("mapStopReason(%q) = %q, want %q", tt.input, result, tt.expected) } }) } } func TestMessagesToChatToolUse(t *testing.T) { resp := &MessagesResponse{ ID: "msg-456", Model: "claude-3-sonnet-20240229", Content: []ContentBlock{ {Type: "text", Text: "Let me search for that."}, {Type: "tool_use", ID: "toolu-123", Name: "web_search"}, }, StopReason: "tool_use", Usage: Usage{ PromptTokens: 20, CompletionTokens: 30, }, } result, err := MessagesToChat(resp) if err != nil { t.Fatalf("MessagesToChat() error = %v", err) } if len(result.Choices) != 1 { t.Errorf("Choices length = %d, want 1", len(result.Choices)) return } if result.Choices[0].FinishReason != "tool_calls" { t.Errorf("FinishReason = %q, want %q", result.Choices[0].FinishReason, "tool_calls") } if len(result.Choices[0].Message.ToolCalls) != 1 { t.Errorf("ToolCalls length = %d, want 1", len(result.Choices[0].Message.ToolCalls)) return } if result.Choices[0].Message.ToolCalls[0].ID != "toolu-123" { t.Errorf("ToolCall ID = %q, want %q", result.Choices[0].Message.ToolCalls[0].ID, "toolu-123") } if result.Choices[0].Message.ToolCalls[0].Function.Name != "web_search" { t.Errorf("Function.Name = %q, want %q", result.Choices[0].Message.ToolCalls[0].Function.Name, "web_search") } }