package schema_test import ( "encoding/json" "github.com/mudler/LocalAI/core/schema" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("Anthropic Schema", func() { Describe("AnthropicRequest", func() { It("should unmarshal a valid request", func() { jsonData := `{ "model": "claude-3-sonnet-20240229", "max_tokens": 1024, "messages": [ {"role": "user", "content": "Hello, world!"} ], "system": "You are a helpful assistant.", "temperature": 0.7 }` var req schema.AnthropicRequest err := json.Unmarshal([]byte(jsonData), &req) Expect(err).ToNot(HaveOccurred()) Expect(req.Model).To(Equal("claude-3-sonnet-20240229")) Expect(req.MaxTokens).To(Equal(1024)) Expect(len(req.Messages)).To(Equal(1)) Expect(string(req.System)).To(Equal("You are a helpful assistant.")) Expect(*req.Temperature).To(Equal(0.7)) }) It("should unmarshal a request with tools", func() { jsonData := `{ "model": "claude-3-sonnet-20240229", "max_tokens": 1024, "messages": [ {"role": "user", "content": "What's the weather?"} ], "tools": [ { "name": "get_weather", "description": "Get the current weather", "input_schema": { "type": "object", "properties": { "location": {"type": "string"} } } } ], "tool_choice": {"type": "tool", "name": "get_weather"} }` var req schema.AnthropicRequest err := json.Unmarshal([]byte(jsonData), &req) Expect(err).ToNot(HaveOccurred()) Expect(len(req.Tools)).To(Equal(1)) Expect(req.Tools[0].Name).To(Equal("get_weather")) Expect(req.Tools[0].Description).To(Equal("Get the current weather")) Expect(req.ToolChoice).ToNot(BeNil()) }) It("should implement LocalAIRequest interface", func() { req := &schema.AnthropicRequest{Model: "test-model"} Expect(req.ModelName(nil)).To(Equal("test-model")) newModel := "new-model" Expect(req.ModelName(&newModel)).To(Equal("new-model")) Expect(req.Model).To(Equal("new-model")) }) }) Describe("AnthropicMessage", func() { It("should get string content from string content", func() { msg := schema.AnthropicMessage{ Role: "user", Content: "Hello, world!", } Expect(msg.GetStringContent()).To(Equal("Hello, world!")) }) It("should get string content from array content", func() { msg := schema.AnthropicMessage{ Role: "user", Content: []interface{}{ map[string]interface{}{"type": "text", "text": "Hello, "}, map[string]interface{}{"type": "text", "text": "world!"}, }, } Expect(msg.GetStringContent()).To(Equal("Hello, world!")) }) It("should get content blocks from string content", func() { msg := schema.AnthropicMessage{ Role: "user", Content: "Hello, world!", } blocks := msg.GetContentBlocks() Expect(len(blocks)).To(Equal(1)) Expect(blocks[0].Type).To(Equal("text")) Expect(blocks[0].Text).To(Equal("Hello, world!")) }) It("should get content blocks from array content", func() { msg := schema.AnthropicMessage{ Role: "user", Content: []interface{}{ map[string]interface{}{"type": "text", "text": "Hello"}, map[string]interface{}{"type": "image", "source": map[string]interface{}{"type": "base64", "data": "abc123"}}, }, } blocks := msg.GetContentBlocks() Expect(len(blocks)).To(Equal(2)) Expect(blocks[0].Type).To(Equal("text")) Expect(blocks[0].Text).To(Equal("Hello")) }) }) Describe("AnthropicResponse", func() { It("should marshal a valid response", func() { stopReason := "end_turn" resp := schema.AnthropicResponse{ ID: "msg_123", Type: "message", Role: "assistant", Model: "claude-3-sonnet-20240229", StopReason: &stopReason, Content: []schema.AnthropicContentBlock{ {Type: "text", Text: "Hello!"}, }, Usage: schema.AnthropicUsage{ InputTokens: 10, OutputTokens: 5, }, } data, err := json.Marshal(resp) Expect(err).ToNot(HaveOccurred()) var result map[string]interface{} err = json.Unmarshal(data, &result) Expect(err).ToNot(HaveOccurred()) Expect(result["id"]).To(Equal("msg_123")) Expect(result["type"]).To(Equal("message")) Expect(result["role"]).To(Equal("assistant")) Expect(result["stop_reason"]).To(Equal("end_turn")) }) It("should marshal a response with tool use", func() { stopReason := "tool_use" resp := schema.AnthropicResponse{ ID: "msg_123", Type: "message", Role: "assistant", Model: "claude-3-sonnet-20240229", StopReason: &stopReason, Content: []schema.AnthropicContentBlock{ { Type: "tool_use", ID: "toolu_123", Name: "get_weather", Input: map[string]interface{}{ "location": "San Francisco", }, }, }, Usage: schema.AnthropicUsage{ InputTokens: 10, OutputTokens: 5, }, } data, err := json.Marshal(resp) Expect(err).ToNot(HaveOccurred()) var result map[string]interface{} err = json.Unmarshal(data, &result) Expect(err).ToNot(HaveOccurred()) Expect(result["stop_reason"]).To(Equal("tool_use")) content := result["content"].([]interface{}) Expect(len(content)).To(Equal(1)) toolUse := content[0].(map[string]interface{}) Expect(toolUse["type"]).To(Equal("tool_use")) Expect(toolUse["id"]).To(Equal("toolu_123")) Expect(toolUse["name"]).To(Equal("get_weather")) }) }) Describe("AnthropicErrorResponse", func() { It("should marshal an error response", func() { resp := schema.AnthropicErrorResponse{ Type: "error", Error: schema.AnthropicError{ Type: "invalid_request_error", Message: "max_tokens is required", }, } data, err := json.Marshal(resp) Expect(err).ToNot(HaveOccurred()) var result map[string]interface{} err = json.Unmarshal(data, &result) Expect(err).ToNot(HaveOccurred()) Expect(result["type"]).To(Equal("error")) errorObj := result["error"].(map[string]interface{}) Expect(errorObj["type"]).To(Equal("invalid_request_error")) Expect(errorObj["message"]).To(Equal("max_tokens is required")) }) }) })