package client import ( "bytes" "context" "net/url" "testing" "time" "reichard.io/aethera/internal/store" ) const model = "qwen3-8b-vision" func TestSendMessage(t *testing.T) { t.Skip("requires live LLM API - run manually with: go test -run TestSendMessage ./internal/client/") // Initialize Client baseURL, err := url.Parse("https://llm-api.va.reichard.io/v1") if err != nil { t.Fatalf("Failed to parse base URL: %v", err) } client := NewClient(baseURL) // Create Context ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) defer cancel() // Generate Text Stream var contentBuf, thinkingBuf bytes.Buffer _, err = client.SendMessage(ctx, []*store.Message{{ Role: "user", Content: "What is 2+2? Think step by step.", }}, model, func(mc *MessageChunk) error { if mc.Thinking != nil { _, err := thinkingBuf.Write([]byte(*mc.Thinking)) return err } if mc.Message != nil { _, err := contentBuf.Write([]byte(*mc.Message)) return err } return nil }) if err != nil { t.Fatalf("Failed to generate text stream: %v", err) } // Verify Thinking thinking := thinkingBuf.String() if thinking == "" { t.Error("No thinking content was received") } else { t.Logf("Thinking (%d bytes): %s", len(thinking), thinking) } // Verify Content output := contentBuf.String() if output == "" { t.Error("No content was written to the buffer") } else { t.Logf("Content (%d bytes): %s", len(output), output) } } func TestSummarizeChat(t *testing.T) { t.Skip("requires live LLM API - run manually with: go test -run TestSummarizeChat ./internal/client/") // Initialize Client baseURL, err := url.Parse("https://llm-api.va.reichard.io/v1") if err != nil { t.Fatalf("Failed to parse base URL: %v", err) } client := NewClient(baseURL) // Create Context ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Generate Text Stream userMessage := "Write me a go program that reads in a zip file and prints the contents along with their sizes and mimetype." output, err := client.CreateTitle(ctx, userMessage, model) if err != nil { t.Fatalf("Failed to generate text stream: %v", err) } // Verify Results if output == "" { t.Error("No content was written to the buffer") } else { t.Logf("Successfully received %d bytes from the stream", len(output)) t.Logf("Output: %s", output) } } func TestSendMessageWithImage(t *testing.T) { // Skip: qwen3-8b-vision on LlamaSwap returns 502 for vision requests. // Run manually when a stable vision backend is available: // go test -run TestSendMessageWithImage ./internal/client/ t.Skip("requires stable vision backend - LlamaSwap qwen3-8b-vision returns 502 for image inputs") // Initialize Client baseURL, err := url.Parse("https://llm-api.va.reichard.io/v1") if err != nil { t.Fatalf("Failed to parse base URL: %v", err) } client := NewClient(baseURL) // Create Context ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) defer cancel() // Build Data URL from embedded test image (10x10 red PNG) const dataURL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAADklEQVR42mNk+P/k/wEAn6gE9QxN+7QAAAAASUVORK5CYII=" // Generate Text Stream _, err = client.SendMessage(ctx, []*store.Message{{ Role: "user", Content: "What is in this image?", Images: []string{dataURL}, }}, model, func(mc *MessageChunk) error { if mc.Message != nil { t.Logf("Received: %s", *mc.Message) } return nil }) if err != nil { t.Fatalf("Failed to generate text stream: %v", err) } }