package engine import ( "testing" "git.flytoex.net/yuanwei/flyto-agent/pkg/query" ) // TestNormalizeMessagesForAPI_Empty 测试空消息列表 func TestNormalizeMessagesForAPI_Empty(t *testing.T) { result := NormalizeMessagesForAPI(nil) if len(result) != 0 { t.Errorf("expected 0 messages, got %d", len(result)) } result = NormalizeMessagesForAPI([]query.Message{}) if len(result) != 0 { t.Errorf("expected 0 messages, got %d", len(result)) } } // TestNormalizeMessagesForAPI_RemoveOrphanedToolResult 测试移除孤立的 tool_result func TestNormalizeMessagesForAPI_RemoveOrphanedToolResult(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "hello"}, }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentToolUse, ID: "tool_1", Name: "bash"}, }, }, { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentToolResult, ToolUseID: "tool_1", Text: "ok"}, // 有对应的 tool_use {Type: query.ContentToolResult, ToolUseID: "tool_999", Text: "orphan"}, // 孤立的 }, }, } result := NormalizeMessagesForAPI(messages) // 第三条消息应该只保留一个 tool_result if len(result) != 3 { t.Fatalf("expected 3 messages, got %d", len(result)) } if len(result[2].Content) != 1 { t.Fatalf("expected 1 content block in msg[2], got %d", len(result[2].Content)) } if result[2].Content[0].ToolUseID != "tool_1" { t.Errorf("expected tool_1, got %s", result[2].Content[0].ToolUseID) } } // TestNormalizeMessagesForAPI_RemoveEmptyMessages 测试移除空消息 func TestNormalizeMessagesForAPI_RemoveEmptyMessages(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "hello"}, }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentText, Text: ""}, // 空文本 }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentText, Text: "response"}, }, }, } result := NormalizeMessagesForAPI(messages) // 空消息应该被移除 if len(result) != 2 { t.Fatalf("expected 2 messages, got %d", len(result)) } } // TestNormalizeMessagesForAPI_MergeConsecutiveSameRole 测试合并连续同角色消息 func TestNormalizeMessagesForAPI_MergeConsecutiveSameRole(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "first"}, }, }, { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "second"}, }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentText, Text: "response"}, }, }, } result := NormalizeMessagesForAPI(messages) // 两个连续 user 消息应被合并为一个 if len(result) != 2 { t.Fatalf("expected 2 messages, got %d", len(result)) } // 合并后的消息应有 2 个内容块 if len(result[0].Content) != 2 { t.Fatalf("expected 2 content blocks in merged msg, got %d", len(result[0].Content)) } if result[0].Content[0].Text != "first" || result[0].Content[1].Text != "second" { t.Error("merged content blocks should preserve order") } } // TestNormalizeMessagesForAPI_CompleteOrphanRemoval 测试全部内容被移除的消息 func TestNormalizeMessagesForAPI_CompleteOrphanRemoval(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "hello"}, }, }, { Role: query.RoleUser, Content: []query.Content{ // 这条消息只有一个孤立的 tool_result,移除后整条消息也应移除 {Type: query.ContentToolResult, ToolUseID: "nonexistent", Text: "orphan"}, }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentText, Text: "response"}, }, }, } result := NormalizeMessagesForAPI(messages) // 孤立消息应被完全移除 if len(result) != 2 { t.Fatalf("expected 2 messages, got %d", len(result)) } } // TestNormalizeMessagesForAPI_NoContent 测试无内容块的消息 func TestNormalizeMessagesForAPI_NoContent(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: nil, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentText, Text: "response"}, }, }, } result := NormalizeMessagesForAPI(messages) if len(result) != 1 { t.Fatalf("expected 1 messages, got %d", len(result)) } } // TestNormalizeMessagesForAPI_ToolUsePreserved 测试 tool_use 块被保留 func TestNormalizeMessagesForAPI_ToolUsePreserved(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "do something"}, }, }, { Role: query.RoleAssistant, Content: []query.Content{ {Type: query.ContentToolUse, ID: "tool_1", Name: "bash"}, }, }, { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentToolResult, ToolUseID: "tool_1", Text: "done"}, }, }, } result := NormalizeMessagesForAPI(messages) if len(result) != 3 { t.Fatalf("expected 3 messages, got %d", len(result)) } if result[1].Content[0].Type != query.ContentToolUse { t.Error("tool_use block should be preserved") } } // TestNormalizeMessagesForAPI_SingleMessage 测试单条消息 func TestNormalizeMessagesForAPI_SingleMessage(t *testing.T) { messages := []query.Message{ { Role: query.RoleUser, Content: []query.Content{ {Type: query.ContentText, Text: "hello"}, }, }, } result := NormalizeMessagesForAPI(messages) if len(result) != 1 { t.Fatalf("expected 1 message, got %d", len(result)) } }