feat: Support Structured Outputs (#813)
* feat: Support Structured Outputs * feat: Support Structured Outputs * update imports * add integration test * update JSON schema comments
This commit is contained in:
@@ -4,6 +4,7 @@ package openai_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
@@ -178,3 +179,63 @@ func TestAPIError(t *testing.T) {
|
||||
t.Fatal("Empty error message occurred")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChatCompletionResponseFormat_JSONSchema(t *testing.T) {
|
||||
apiToken := os.Getenv("OPENAI_TOKEN")
|
||||
if apiToken == "" {
|
||||
t.Skip("Skipping testing against production OpenAI API. Set OPENAI_TOKEN environment variable to enable it.")
|
||||
}
|
||||
|
||||
var err error
|
||||
c := openai.NewClient(apiToken)
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := c.CreateChatCompletion(
|
||||
ctx,
|
||||
openai.ChatCompletionRequest{
|
||||
Model: openai.GPT4oMini,
|
||||
Messages: []openai.ChatCompletionMessage{
|
||||
{
|
||||
Role: openai.ChatMessageRoleSystem,
|
||||
Content: "Please enter a string, and we will convert it into the following naming conventions:" +
|
||||
"1. PascalCase: Each word starts with an uppercase letter, with no spaces or separators." +
|
||||
"2. CamelCase: The first word starts with a lowercase letter, " +
|
||||
"and subsequent words start with an uppercase letter, with no spaces or separators." +
|
||||
"3. KebabCase: All letters are lowercase, with words separated by hyphens `-`." +
|
||||
"4. SnakeCase: All letters are lowercase, with words separated by underscores `_`.",
|
||||
},
|
||||
{
|
||||
Role: openai.ChatMessageRoleUser,
|
||||
Content: "Hello World",
|
||||
},
|
||||
},
|
||||
ResponseFormat: &openai.ChatCompletionResponseFormat{
|
||||
Type: openai.ChatCompletionResponseFormatTypeJSONSchema,
|
||||
JSONSchema: openai.ChatCompletionResponseFormatJSONSchema{
|
||||
Name: "cases",
|
||||
Schema: jsonschema.Definition{
|
||||
Type: jsonschema.Object,
|
||||
Properties: map[string]jsonschema.Definition{
|
||||
"PascalCase": jsonschema.Definition{Type: jsonschema.String},
|
||||
"CamelCase": jsonschema.Definition{Type: jsonschema.String},
|
||||
"KebabCase": jsonschema.Definition{Type: jsonschema.String},
|
||||
"SnakeCase": jsonschema.Definition{Type: jsonschema.String},
|
||||
},
|
||||
Required: []string{"PascalCase", "CamelCase", "KebabCase", "SnakeCase"},
|
||||
AdditionalProperties: false,
|
||||
},
|
||||
Strict: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
checks.NoError(t, err, "CreateChatCompletion (use json_schema response) returned error")
|
||||
var result = make(map[string]string)
|
||||
err = json.Unmarshal([]byte(resp.Choices[0].Message.Content), &result)
|
||||
checks.NoError(t, err, "CreateChatCompletion (use json_schema response) unmarshal error")
|
||||
for _, key := range []string{"PascalCase", "CamelCase", "KebabCase", "SnakeCase"} {
|
||||
if _, ok := result[key]; !ok {
|
||||
t.Errorf("key:%s does not exist.", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user