refactor: move backend files to backend/ directory

Reorganize project structure:
- backend/cmd/openteam/ — entry point
- backend/internal/ — core packages
- backend/middleware/ — HTTP middleware
- backend/router/ — route setup
- backend/wire/ — dependency injection
- backend/pkg/ — shared utilities
- backend/go.mod, go.sum — Go module files

Updated Makefile to work from backend/ directory.
Removed old lowercase makefile.
This commit is contained in:
Sakurasan
2026-08-30 12:02:52 +08:00
parent ef3025dd80
commit 902ecaeacc
64 changed files with 12 additions and 107 deletions
@@ -0,0 +1,231 @@
package convert
import (
"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) != 1 {
t.Errorf("Input length = %d, want 1", len(result.Input))
}
if result.Input[0].Role != "user" {
t.Errorf("Input[0].Role = %q, want %q", result.Input[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")
}
}