Repository: sashabaranov/go-openai
Pull request #864 (2024-09-26 19:16:57)

add jailbreak filter result, add ContentFilterResults on output
Adding field for prompt_filter_results which is in the open content filters to assess the content of the user input. Current implementation in go-openai will only return content filter information on the model output using ChatCompletionResponse. This is for AzureOpenAI spec.

Adding field for content_filter_results which is in the open content filters to assess the content of the user input. Current implementation in go-openai will only return content filter information on the model output using ChatCompletionChoice. This is for AzureOpenAI spec.

Adding field for jailbreak which is in a content filter. Current implementation in go-openai will only return content filter information on the error output using InnerError.ContentFilterResults. This is for AzureOpenAI spec.

Provide OpenAI documentation link
Relevant API doc: https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/content-filter

Describe your solution
Change struct

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/sashabaranov/go-openai/pull/864?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Alex+Baranov) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.04%. Comparing base [(`774fc9d`)](https://app.codecov.io/gh/sashabaranov/go-openai/commit/774fc9dd12ed60c10a9f9f03319ddb9cd5f8780c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Alex+Baranov) to head [(`37540d2`)](https://app.codecov.io/gh/sashabaranov/go-openai/commit/37540d2a9acf6b104cdea09e8944d765a08bf6e8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Alex+Baranov).
> Report is 57 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #864      +/-   ##
==========================================
+ Coverage   98.46%   99.04%   +0.58%     
==========================================
  Files          24       26       +2     
  Lines        1364     1461      +97     
==========================================
+ Hits         1343     1447     +104     
+ Misses         15        8       -7     
  Partials        6        6              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/sashabaranov/go-openai/pull/864?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Alex+Baranov).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Alex+Baranov).


Patch:
diff --git a/chat.go b/chat.go
index dd99c53..a7dee8e 100644
--- a/chat.go
+++ b/chat.go
@@ -41,11 +41,23 @@ type Violence struct {
 	Severity string `json:"severity,omitempty"`
 }
 
+type JailBreak struct {
+	Filtered bool `json:"filtered"`
+	Detected bool `json:"detected"`
+}
+
+type Profanity struct {
+	Filtered bool `json:"filtered"`
+	Detected bool `json:"detected"`
+}
+
 type ContentFilterResults struct {
-	Hate     Hate     `json:"hate,omitempty"`
-	SelfHarm SelfHarm `json:"self_harm,omitempty"`
-	Sexual   Sexual   `json:"sexual,omitempty"`
-	Violence Violence `json:"violence,omitempty"`
+	Hate      Hate      `json:"hate,omitempty"`
+	SelfHarm  SelfHarm  `json:"self_harm,omitempty"`
+	Sexual    Sexual    `json:"sexual,omitempty"`
+	Violence  Violence  `json:"violence,omitempty"`
+	JailBreak JailBreak `json:"jailbreak,omitempty"`
+	Profanity Profanity `json:"profanity,omitempty"`
 }
 
 type PromptAnnotation struct {
@@ -207,18 +219,18 @@ type ChatCompletionRequest struct {
 	// This value is now deprecated in favor of max_completion_tokens, and is not compatible with o1 series models.
 	// refs: https://platform.openai.com/docs/api-reference/chat/create#chat-create-max_tokens
 	MaxTokens int `json:"max_tokens,omitempty"`
-	// MaxCompletionsTokens An upper bound for the number of tokens that can be generated for a completion,
+	// MaxCompletionTokens An upper bound for the number of tokens that can be generated for a completion,
 	// including visible output tokens and reasoning tokens https://platform.openai.com/docs/guides/reasoning
-	MaxCompletionsTokens int                           `json:"max_completion_tokens,omitempty"`
-	Temperature          float32                       `json:"temperature,omitempty"`
-	TopP                 float32                       `json:"top_p,omitempty"`
-	N                    int                           `json:"n,omitempty"`
-	Stream               bool                          `json:"stream,omitempty"`
-	Stop                 []string                      `json:"stop,omitempty"`
-	PresencePenalty      float32                       `json:"presence_penalty,omitempty"`
-	ResponseFormat       *ChatCompletionResponseFormat `json:"response_format,omitempty"`
-	Seed                 *int                          `json:"seed,omitempty"`
-	FrequencyPenalty     float32                       `json:"frequency_penalty,omitempty"`
+	MaxCompletionTokens int                           `json:"max_completion_tokens,omitempty"`
+	Temperature         float32                       `json:"temperature,omitempty"`
+	TopP                float32                       `json:"top_p,omitempty"`
+	N                   int                           `json:"n,omitempty"`
+	Stream              bool                          `json:"stream,omitempty"`
+	Stop                []string                      `json:"stop,omitempty"`
+	PresencePenalty     float32                       `json:"presence_penalty,omitempty"`
+	ResponseFormat      *ChatCompletionResponseFormat `json:"response_format,omitempty"`
+	Seed                *int                          `json:"seed,omitempty"`
+	FrequencyPenalty    float32                       `json:"frequency_penalty,omitempty"`
 	// LogitBias is must be a token id string (specified by their token ID in the tokenizer), not a word string.
 	// incorrect: `"logit_bias":{"You": 6}`, correct: `"logit_bias":{"1639": 6}`
 	// refs: https://platform.openai.com/docs/api-reference/chat/create#chat/create-logit_bias
@@ -338,19 +350,21 @@ type ChatCompletionChoice struct {
 	// function_call: The model decided to call a function
 	// content_filter: Omitted content due to a flag from our content filters
 	// null: API response still in progress or incomplete
-	FinishReason FinishReason `json:"finish_reason"`
-	LogProbs     *LogProbs    `json:"logprobs,omitempty"`
+	FinishReason         FinishReason         `json:"finish_reason"`
+	LogProbs             *LogProbs            `json:"logprobs,omitempty"`
+	ContentFilterResults ContentFilterResults `json:"content_filter_results,omitempty"`
 }
 
 // ChatCompletionResponse represents a response structure for chat completion API.
 type ChatCompletionResponse struct {
-	ID                string                 `json:"id"`
-	Object            string                 `json:"object"`
-	Created           int64                  `json:"created"`
-	Model             string                 `json:"model"`
-	Choices           []ChatCompletionChoice `json:"choices"`
-	Usage             Usage                  `json:"usage"`
-	SystemFingerprint string                 `json:"system_fingerprint"`
+	ID                  string                 `json:"id"`
+	Object              string                 `json:"object"`
+	Created             int64                  `json:"created"`
+	Model               string                 `json:"model"`
+	Choices             []ChatCompletionChoice `json:"choices"`
+	Usage               Usage                  `json:"usage"`
+	SystemFingerprint   string                 `json:"system_fingerprint"`
+	PromptFilterResults []PromptFilterResult   `json:"prompt_filter_results,omitempty"`
 
 	httpHeader
 }
diff --git a/completion.go b/completion.go
index 8e3172a..80c4d39 100644
--- a/completion.go
+++ b/completion.go
@@ -7,7 +7,7 @@ import (
 )
 
 var (
-	ErrO1MaxTokensDeprecated                   = errors.New("this model is not supported MaxTokens, please use MaxCompletionsTokens")                              //nolint:lll
+	ErrO1MaxTokensDeprecated                   = errors.New("this model is not supported MaxTokens, please use MaxCompletionTokens")                               //nolint:lll
 	ErrCompletionUnsupportedModel              = errors.New("this model is not supported with this method, please use CreateChatCompletion client method instead") //nolint:lll
 	ErrCompletionStreamNotSupported            = errors.New("streaming is not supported with this method, please use CreateCompletionStream")                      //nolint:lll
 	ErrCompletionRequestPromptTypeNotSupported = errors.New("the type of CompletionRequest.Prompt only supports string and []string")                              //nolint:lll


Test patch:
diff --git a/chat_test.go b/chat_test.go
index a54dd35..134026c 100644
--- a/chat_test.go
+++ b/chat_test.go
@@ -100,17 +100,17 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "log_probs_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				LogProbs:             true,
-				Model:                openai.O1Preview,
+				MaxCompletionTokens: 1000,
+				LogProbs:            true,
+				Model:               openai.O1Preview,
 			},
 			expectedError: openai.ErrO1BetaLimitationsLogprobs,
 		},
 		{
 			name: "message_type_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleSystem,
@@ -122,8 +122,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "tool_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -143,8 +143,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "set_temperature_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -160,8 +160,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "set_top_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -178,8 +178,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "set_n_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -197,8 +197,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "set_presence_penalty_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -214,8 +214,8 @@ func TestO1ModelsChatCompletionsBetaLimitations(t *testing.T) {
 		{
 			name: "set_frequency_penalty_unsupported",
 			in: openai.ChatCompletionRequest{
-				MaxCompletionsTokens: 1000,
-				Model:                openai.O1Mini,
+				MaxCompletionTokens: 1000,
+				Model:               openai.O1Mini,
 				Messages: []openai.ChatCompletionMessage{
 					{
 						Role: openai.ChatMessageRoleUser,
@@ -296,8 +296,8 @@ func TestO1ModelChatCompletions(t *testing.T) {
 	defer teardown()
 	server.RegisterHandler("/v1/chat/completions", handleChatCompletionEndpoint)
 	_, err := client.CreateChatCompletion(context.Background(), openai.ChatCompletionRequest{
-		Model:                openai.O1Preview,
-		MaxCompletionsTokens: 1000,
+		Model:               openai.O1Preview,
+		MaxCompletionTokens: 1000,
 		Messages: []openai.ChatCompletionMessage{
 			{
 				Role:    openai.ChatMessageRoleUser,