Spaces:
Configuration error
Configuration error
| package e2e_test | |
| import ( | |
| "bytes" | |
| "context" | |
| "encoding/json" | |
| "fmt" | |
| "io" | |
| "net/http" | |
| "os" | |
| "github.com/mudler/LocalAI/core/schema" | |
| . "github.com/onsi/ginkgo/v2" | |
| . "github.com/onsi/gomega" | |
| "github.com/sashabaranov/go-openai" | |
| "github.com/sashabaranov/go-openai/jsonschema" | |
| ) | |
| var _ = Describe("E2E test", func() { | |
| Context("Generating", func() { | |
| BeforeEach(func() { | |
| // | |
| }) | |
| // Check that the GPU was used | |
| AfterEach(func() { | |
| // | |
| }) | |
| Context("text", func() { | |
| It("correctly", func() { | |
| model := "gpt-4" | |
| resp, err := client.CreateChatCompletion(context.TODO(), | |
| openai.ChatCompletionRequest{ | |
| Model: model, Messages: []openai.ChatCompletionMessage{ | |
| { | |
| Role: "user", | |
| Content: "How much is 2+2?", | |
| }, | |
| }}) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Choices)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Choices[0].Message.Content).To(Or(ContainSubstring("4"), ContainSubstring("four")), fmt.Sprint(resp.Choices[0].Message.Content)) | |
| }) | |
| }) | |
| Context("function calls", func() { | |
| It("correctly invoke", func() { | |
| params := jsonschema.Definition{ | |
| Type: jsonschema.Object, | |
| Properties: map[string]jsonschema.Definition{ | |
| "location": { | |
| Type: jsonschema.String, | |
| Description: "The city and state, e.g. San Francisco, CA", | |
| }, | |
| "unit": { | |
| Type: jsonschema.String, | |
| Enum: []string{"celsius", "fahrenheit"}, | |
| }, | |
| }, | |
| Required: []string{"location"}, | |
| } | |
| f := openai.FunctionDefinition{ | |
| Name: "get_current_weather", | |
| Description: "Get the current weather in a given location", | |
| Parameters: params, | |
| } | |
| t := openai.Tool{ | |
| Type: openai.ToolTypeFunction, | |
| Function: &f, | |
| } | |
| dialogue := []openai.ChatCompletionMessage{ | |
| {Role: openai.ChatMessageRoleUser, Content: "What is the weather in Boston today?"}, | |
| } | |
| resp, err := client.CreateChatCompletion(context.TODO(), | |
| openai.ChatCompletionRequest{ | |
| Model: openai.GPT4, | |
| Messages: dialogue, | |
| Tools: []openai.Tool{t}, | |
| }, | |
| ) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Choices)).To(Equal(1), fmt.Sprint(resp)) | |
| msg := resp.Choices[0].Message | |
| Expect(len(msg.ToolCalls)).To(Equal(1), fmt.Sprint(msg.ToolCalls)) | |
| Expect(msg.ToolCalls[0].Function.Name).To(Equal("get_current_weather"), fmt.Sprint(msg.ToolCalls[0].Function.Name)) | |
| Expect(msg.ToolCalls[0].Function.Arguments).To(ContainSubstring("Boston"), fmt.Sprint(msg.ToolCalls[0].Function.Arguments)) | |
| }) | |
| }) | |
| Context("json", func() { | |
| It("correctly", func() { | |
| model := "gpt-4" | |
| req := openai.ChatCompletionRequest{ | |
| ResponseFormat: &openai.ChatCompletionResponseFormat{Type: openai.ChatCompletionResponseFormatTypeJSONObject}, | |
| Model: model, | |
| Messages: []openai.ChatCompletionMessage{ | |
| { | |
| Role: "user", | |
| Content: "An animal with 'name', 'gender' and 'legs' fields", | |
| }, | |
| }, | |
| } | |
| resp, err := client.CreateChatCompletion(context.TODO(), req) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Choices)).To(Equal(1), fmt.Sprint(resp)) | |
| var i map[string]interface{} | |
| err = json.Unmarshal([]byte(resp.Choices[0].Message.Content), &i) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(i).To(HaveKey("name")) | |
| Expect(i).To(HaveKey("gender")) | |
| Expect(i).To(HaveKey("legs")) | |
| }) | |
| }) | |
| Context("images", func() { | |
| It("correctly", func() { | |
| resp, err := client.CreateImage(context.TODO(), | |
| openai.ImageRequest{ | |
| Prompt: "test", | |
| Size: openai.CreateImageSize512x512, | |
| }, | |
| ) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Data)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Data[0].URL).To(ContainSubstring("png"), fmt.Sprint(resp.Data[0].URL)) | |
| }) | |
| It("correctly changes the response format to url", func() { | |
| resp, err := client.CreateImage(context.TODO(), | |
| openai.ImageRequest{ | |
| Prompt: "test", | |
| Size: openai.CreateImageSize512x512, | |
| ResponseFormat: openai.CreateImageResponseFormatURL, | |
| }, | |
| ) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Data)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Data[0].URL).To(ContainSubstring("png"), fmt.Sprint(resp.Data[0].URL)) | |
| }) | |
| It("correctly changes the response format to base64", func() { | |
| resp, err := client.CreateImage(context.TODO(), | |
| openai.ImageRequest{ | |
| Prompt: "test", | |
| Size: openai.CreateImageSize512x512, | |
| ResponseFormat: openai.CreateImageResponseFormatB64JSON, | |
| }, | |
| ) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Data)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Data[0].B64JSON).ToNot(BeEmpty(), fmt.Sprint(resp.Data[0].B64JSON)) | |
| }) | |
| }) | |
| Context("embeddings", func() { | |
| It("correctly", func() { | |
| resp, err := client.CreateEmbeddings(context.TODO(), | |
| openai.EmbeddingRequestStrings{ | |
| Input: []string{"doc"}, | |
| Model: openai.AdaEmbeddingV2, | |
| }, | |
| ) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Data)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Data[0].Embedding).ToNot(BeEmpty()) | |
| }) | |
| }) | |
| Context("vision", func() { | |
| It("correctly", func() { | |
| model := "gpt-4o" | |
| resp, err := client.CreateChatCompletion(context.TODO(), | |
| openai.ChatCompletionRequest{ | |
| Model: model, Messages: []openai.ChatCompletionMessage{ | |
| { | |
| Role: "user", | |
| MultiContent: []openai.ChatMessagePart{ | |
| { | |
| Type: openai.ChatMessagePartTypeText, | |
| Text: "What is in the image?", | |
| }, | |
| { | |
| Type: openai.ChatMessagePartTypeImageURL, | |
| ImageURL: &openai.ChatMessageImageURL{ | |
| URL: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg", | |
| Detail: openai.ImageURLDetailLow, | |
| }, | |
| }, | |
| }, | |
| }, | |
| }}) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(len(resp.Choices)).To(Equal(1), fmt.Sprint(resp)) | |
| Expect(resp.Choices[0].Message.Content).To(Or(ContainSubstring("wooden"), ContainSubstring("grass")), fmt.Sprint(resp.Choices[0].Message.Content)) | |
| }) | |
| }) | |
| Context("text to audio", func() { | |
| It("correctly", func() { | |
| res, err := client.CreateSpeech(context.Background(), openai.CreateSpeechRequest{ | |
| Model: openai.TTSModel1, | |
| Input: "Hello!", | |
| Voice: openai.VoiceAlloy, | |
| }) | |
| Expect(err).ToNot(HaveOccurred()) | |
| defer res.Close() | |
| _, err = io.ReadAll(res) | |
| Expect(err).ToNot(HaveOccurred()) | |
| }) | |
| }) | |
| Context("audio to text", func() { | |
| It("correctly", func() { | |
| downloadURL := "https://cdn.openai.com/whisper/draft-20220913a/micro-machines.wav" | |
| file, err := downloadHttpFile(downloadURL) | |
| Expect(err).ToNot(HaveOccurred()) | |
| req := openai.AudioRequest{ | |
| Model: openai.Whisper1, | |
| FilePath: file, | |
| } | |
| resp, err := client.CreateTranscription(context.Background(), req) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(resp.Text).To(ContainSubstring("This is the"), fmt.Sprint(resp.Text)) | |
| }) | |
| }) | |
| Context("reranker", func() { | |
| It("correctly", func() { | |
| modelName := "jina-reranker-v1-base-en" | |
| req := schema.JINARerankRequest{ | |
| Model: modelName, | |
| Query: "Organic skincare products for sensitive skin", | |
| Documents: []string{ | |
| "Eco-friendly kitchenware for modern homes", | |
| "Biodegradable cleaning supplies for eco-conscious consumers", | |
| "Organic cotton baby clothes for sensitive skin", | |
| "Natural organic skincare range for sensitive skin", | |
| "Tech gadgets for smart homes: 2024 edition", | |
| "Sustainable gardening tools and compost solutions", | |
| "Sensitive skin-friendly facial cleansers and toners", | |
| "Organic food wraps and storage solutions", | |
| "All-natural pet food for dogs with allergies", | |
| "Yoga mats made from recycled materials", | |
| }, | |
| TopN: 3, | |
| } | |
| serialized, err := json.Marshal(req) | |
| Expect(err).To(BeNil()) | |
| Expect(serialized).ToNot(BeNil()) | |
| rerankerEndpoint := apiEndpoint + "/rerank" | |
| resp, err := http.Post(rerankerEndpoint, "application/json", bytes.NewReader(serialized)) | |
| Expect(err).To(BeNil()) | |
| Expect(resp).ToNot(BeNil()) | |
| body, err := io.ReadAll(resp.Body) | |
| Expect(err).ToNot(HaveOccurred()) | |
| Expect(resp.StatusCode).To(Equal(200), fmt.Sprintf("body: %s, response: %+v", body, resp)) | |
| deserializedResponse := schema.JINARerankResponse{} | |
| err = json.Unmarshal(body, &deserializedResponse) | |
| Expect(err).To(BeNil()) | |
| Expect(deserializedResponse).ToNot(BeZero()) | |
| Expect(deserializedResponse.Model).To(Equal(modelName)) | |
| Expect(len(deserializedResponse.Results)).To(BeNumerically(">", 0)) | |
| }) | |
| }) | |
| }) | |
| }) | |
| func downloadHttpFile(url string) (string, error) { | |
| resp, err := http.Get(url) | |
| if err != nil { | |
| return "", err | |
| } | |
| defer resp.Body.Close() | |
| tmpfile, err := os.CreateTemp("", "example") | |
| if err != nil { | |
| return "", err | |
| } | |
| defer tmpfile.Close() | |
| _, err = io.Copy(tmpfile, resp.Body) | |
| if err != nil { | |
| return "", err | |
| } | |
| return tmpfile.Name(), nil | |
| } | |