| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- package message
- import (
- "encoding/base64"
- "fmt"
- "strings"
- "testing"
- "charm.land/fantasy"
- "github.com/stretchr/testify/require"
- )
- func makeTestAttachments(n int, contentSize int) []Attachment {
- attachments := make([]Attachment, n)
- content := []byte(strings.Repeat("x", contentSize))
- for i := range n {
- attachments[i] = Attachment{
- FilePath: fmt.Sprintf("/path/to/file%d.txt", i),
- MimeType: "text/plain",
- Content: content,
- }
- }
- return attachments
- }
- func TestToAIMessage_CorruptedMediaData(t *testing.T) {
- t.Parallel()
- msg := &Message{
- Role: Tool,
- Parts: []ContentPart{
- ToolResult{
- ToolCallID: "call_123",
- Name: "screenshot",
- Content: "Loaded image/png content",
- Data: "abc\x80def",
- MIMEType: "image/png",
- },
- },
- }
- messages := msg.ToAIMessage()
- require.Len(t, messages, 1)
- require.Len(t, messages[0].Content, 1)
- part, ok := messages[0].Content[0].(fantasy.ToolResultPart)
- require.True(t, ok)
- require.Equal(t, "call_123", part.ToolCallID)
- textContent, ok := part.Output.(fantasy.ToolResultOutputContentText)
- require.True(t, ok, "corrupted media should be downgraded to text")
- require.Equal(t, mediaLoadFailedPlaceholder, textContent.Text)
- }
- func TestToAIMessage_ValidMediaData(t *testing.T) {
- t.Parallel()
- validBase64 := base64.StdEncoding.EncodeToString([]byte{0x89, 0x50, 0x4E, 0x47})
- msg := &Message{
- Role: Tool,
- Parts: []ContentPart{
- ToolResult{
- ToolCallID: "call_456",
- Name: "screenshot",
- Content: "Loaded image/png content",
- Data: validBase64,
- MIMEType: "image/png",
- },
- },
- }
- messages := msg.ToAIMessage()
- require.Len(t, messages, 1)
- require.Len(t, messages[0].Content, 1)
- part, ok := messages[0].Content[0].(fantasy.ToolResultPart)
- require.True(t, ok)
- require.Equal(t, "call_456", part.ToolCallID)
- mediaContent, ok := part.Output.(fantasy.ToolResultOutputContentMedia)
- require.True(t, ok, "valid media should remain as media")
- require.Equal(t, validBase64, mediaContent.Data)
- require.Equal(t, "image/png", mediaContent.MediaType)
- }
- func TestToAIMessage_ASCIIButInvalidBase64(t *testing.T) {
- t.Parallel()
- msg := &Message{
- Role: Tool,
- Parts: []ContentPart{
- ToolResult{
- ToolCallID: "call_789",
- Name: "screenshot",
- Content: "Loaded image/png content",
- Data: "not-valid-base64!!!",
- MIMEType: "image/png",
- },
- },
- }
- messages := msg.ToAIMessage()
- require.Len(t, messages, 1)
- require.Len(t, messages[0].Content, 1)
- part, ok := messages[0].Content[0].(fantasy.ToolResultPart)
- require.True(t, ok)
- require.Equal(t, "call_789", part.ToolCallID)
- textContent, ok := part.Output.(fantasy.ToolResultOutputContentText)
- require.True(t, ok, "ASCII but invalid base64 should be downgraded to text")
- require.Equal(t, mediaLoadFailedPlaceholder, textContent.Text)
- }
- func BenchmarkPromptWithTextAttachments(b *testing.B) {
- cases := []struct {
- name string
- numFiles int
- contentSize int
- }{
- {"1file_100bytes", 1, 100},
- {"5files_1KB", 5, 1024},
- {"10files_10KB", 10, 10 * 1024},
- {"20files_50KB", 20, 50 * 1024},
- }
- for _, tc := range cases {
- attachments := makeTestAttachments(tc.numFiles, tc.contentSize)
- prompt := "Process these files"
- b.Run(tc.name, func(b *testing.B) {
- b.ReportAllocs()
- for range b.N {
- _ = PromptWithTextAttachments(prompt, attachments)
- }
- })
- }
- }
|