Skip to content

Conversation

yorinasub17
Copy link
Contributor

@yorinasub17 yorinasub17 commented Mar 22, 2023

This adds support for calling the Moderations API endpoint which is a part of the OpenAI API.

Manual test

main.go contents
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	gpt3 "github.com/PullRequestInc/go-gpt3"
)

func main() {
	client := gpt3.NewClient(os.Getenv("OPENAI_API_TOKEN"))
	resp, err := client.Moderation(context.Background(), gpt3.ModerationRequest{Input: "Experiment"})
	if err != nil {
		panic(err)
	}
	jsonBytes, err := json.MarshalIndent(resp, "", "  ")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(jsonBytes))
}
go.mod contents
module github.com/yorinasub17/experiments/gpt3/moderation

go 1.19

require github.com/PullRequestInc/go-gpt3 v1.1.14

replace github.com/PullRequestInc/go-gpt3 => github.com/yorinasub17/go-gpt3 v0.0.0-20230322033212-4be7420a9e1a
Run output:
%~> go run .
{
  "id": "modr-6wjiZbyvPmVGpB6uykiQLK0NV8HPY",
  "model": "text-moderation-004",
  "results": [
    {
      "flagged": false,
      "categories": {
        "hate": false,
        "hate/threatening": false,
        "self-harm": false,
        "sexual": false,
        "sexual/minors": false,
        "violence": false,
        "violence/graphic": false
      },
      "category_scores": {
        "hate": 0.000018651568,
        "hate/threatening": 5.507919e-10,
        "self-harm": 2.8584697e-9,
        "sexual": 0.000060261966,
        "sexual/minors": 0.0000026142309,
        "violence": 0.000004531721,
        "violence/graphic": 5.7995995e-9
      }
    }
  ]
}

Unit test results

go test -v .
=== RUN   TestInitNewClient
--- PASS: TestInitNewClient (0.00s)
=== RUN   TestRequestCreationFails
=== RUN   TestRequestCreationFails/Engines
=== RUN   TestRequestCreationFails/Engine
=== RUN   TestRequestCreationFails/ChatCompletion
=== RUN   TestRequestCreationFails/Completion
=== RUN   TestRequestCreationFails/CompletionStream
=== RUN   TestRequestCreationFails/CompletionWithEngine
=== RUN   TestRequestCreationFails/CompletionStreamWithEngine
=== RUN   TestRequestCreationFails/Edits
=== RUN   TestRequestCreationFails/Search
=== RUN   TestRequestCreationFails/SearchWithEngine
=== RUN   TestRequestCreationFails/Embeddings
=== RUN   TestRequestCreationFails/Moderation
--- PASS: TestRequestCreationFails (0.00s)
    --- PASS: TestRequestCreationFails/Engines (0.00s)
    --- PASS: TestRequestCreationFails/Engine (0.00s)
    --- PASS: TestRequestCreationFails/ChatCompletion (0.00s)
    --- PASS: TestRequestCreationFails/Completion (0.00s)
    --- PASS: TestRequestCreationFails/CompletionStream (0.00s)
    --- PASS: TestRequestCreationFails/CompletionWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/CompletionStreamWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/Edits (0.00s)
    --- PASS: TestRequestCreationFails/Search (0.00s)
    --- PASS: TestRequestCreationFails/SearchWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/Embeddings (0.00s)
    --- PASS: TestRequestCreationFails/Moderation (0.00s)
=== RUN   TestResponses
=== RUN   TestResponses/Engines
=== RUN   TestResponses/Engines/bad_status_codes
=== RUN   TestResponses/Engines/success_code_json_decode_failure
=== RUN   TestResponses/Engines/successful_response
=== RUN   TestResponses/Engine
=== RUN   TestResponses/Engine/bad_status_codes
=== RUN   TestResponses/Engine/success_code_json_decode_failure
=== RUN   TestResponses/Engine/successful_response
=== RUN   TestResponses/ChatCompletion
=== RUN   TestResponses/ChatCompletion/bad_status_codes
=== RUN   TestResponses/ChatCompletion/success_code_json_decode_failure
=== RUN   TestResponses/ChatCompletion/successful_response
=== RUN   TestResponses/Completion
=== RUN   TestResponses/Completion/bad_status_codes
=== RUN   TestResponses/Completion/success_code_json_decode_failure
=== RUN   TestResponses/Completion/successful_response
=== RUN   TestResponses/CompletionStream
=== RUN   TestResponses/CompletionStream/bad_status_codes
=== RUN   TestResponses/CompletionStream/success_code_json_decode_failure
=== RUN   TestResponses/CompletionWithEngine
=== RUN   TestResponses/CompletionWithEngine/bad_status_codes
=== RUN   TestResponses/CompletionWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/CompletionWithEngine/successful_response
=== RUN   TestResponses/CompletionStreamWithEngine
=== RUN   TestResponses/CompletionStreamWithEngine/bad_status_codes
=== RUN   TestResponses/CompletionStreamWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/Search
=== RUN   TestResponses/Search/bad_status_codes
=== RUN   TestResponses/Search/success_code_json_decode_failure
=== RUN   TestResponses/Search/successful_response
=== RUN   TestResponses/SearchWithEngine
=== RUN   TestResponses/SearchWithEngine/bad_status_codes
=== RUN   TestResponses/SearchWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/SearchWithEngine/successful_response
=== RUN   TestResponses/Embeddings
=== RUN   TestResponses/Embeddings/bad_status_codes
=== RUN   TestResponses/Embeddings/success_code_json_decode_failure
=== RUN   TestResponses/Embeddings/successful_response
=== RUN   TestResponses/Moderation
=== RUN   TestResponses/Moderation/bad_status_codes
=== RUN   TestResponses/Moderation/success_code_json_decode_failure
=== RUN   TestResponses/Moderation/successful_response
--- PASS: TestResponses (0.00s)
    --- PASS: TestResponses/Engines (0.00s)
        --- PASS: TestResponses/Engines/bad_status_codes (0.00s)
        --- PASS: TestResponses/Engines/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Engines/successful_response (0.00s)
    --- PASS: TestResponses/Engine (0.00s)
        --- PASS: TestResponses/Engine/bad_status_codes (0.00s)
        --- PASS: TestResponses/Engine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Engine/successful_response (0.00s)
    --- PASS: TestResponses/ChatCompletion (0.00s)
        --- PASS: TestResponses/ChatCompletion/bad_status_codes (0.00s)
        --- PASS: TestResponses/ChatCompletion/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/ChatCompletion/successful_response (0.00s)
    --- PASS: TestResponses/Completion (0.00s)
        --- PASS: TestResponses/Completion/bad_status_codes (0.00s)
        --- PASS: TestResponses/Completion/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Completion/successful_response (0.00s)
    --- PASS: TestResponses/CompletionStream (0.00s)
        --- PASS: TestResponses/CompletionStream/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionStream/success_code_json_decode_failure (0.00s)
    --- PASS: TestResponses/CompletionWithEngine (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/successful_response (0.00s)
    --- PASS: TestResponses/CompletionStreamWithEngine (0.00s)
        --- PASS: TestResponses/CompletionStreamWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionStreamWithEngine/success_code_json_decode_failure (0.00s)
    --- PASS: TestResponses/Search (0.00s)
        --- PASS: TestResponses/Search/bad_status_codes (0.00s)
        --- PASS: TestResponses/Search/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Search/successful_response (0.00s)
    --- PASS: TestResponses/SearchWithEngine (0.00s)
        --- PASS: TestResponses/SearchWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/SearchWithEngine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/SearchWithEngine/successful_response (0.00s)
    --- PASS: TestResponses/Embeddings (0.00s)
        --- PASS: TestResponses/Embeddings/bad_status_codes (0.00s)
        --- PASS: TestResponses/Embeddings/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Embeddings/successful_response (0.00s)
    --- PASS: TestResponses/Moderation (0.00s)
        --- PASS: TestResponses/Moderation/bad_status_codes (0.00s)
        --- PASS: TestResponses/Moderation/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Moderation/successful_response (0.00s)
PASS
ok  	github.com/PullRequestInc/go-gpt3	(cached)

[yoriy] ~/projects/github/forks/go-gpt3 git:(features/moderations)                                           [go:1.19.5][njs:18.13.0][tf:1.3.7]
%~> go test -count 1 -v .                                                                                                                  [0]
=== RUN   TestInitNewClient
--- PASS: TestInitNewClient (0.00s)
=== RUN   TestRequestCreationFails
=== RUN   TestRequestCreationFails/Engines
=== RUN   TestRequestCreationFails/Engine
=== RUN   TestRequestCreationFails/ChatCompletion
=== RUN   TestRequestCreationFails/Completion
=== RUN   TestRequestCreationFails/CompletionStream
=== RUN   TestRequestCreationFails/CompletionWithEngine
=== RUN   TestRequestCreationFails/CompletionStreamWithEngine
=== RUN   TestRequestCreationFails/Edits
=== RUN   TestRequestCreationFails/Search
=== RUN   TestRequestCreationFails/SearchWithEngine
=== RUN   TestRequestCreationFails/Embeddings
=== RUN   TestRequestCreationFails/Moderation
--- PASS: TestRequestCreationFails (0.00s)
    --- PASS: TestRequestCreationFails/Engines (0.00s)
    --- PASS: TestRequestCreationFails/Engine (0.00s)
    --- PASS: TestRequestCreationFails/ChatCompletion (0.00s)
    --- PASS: TestRequestCreationFails/Completion (0.00s)
    --- PASS: TestRequestCreationFails/CompletionStream (0.00s)
    --- PASS: TestRequestCreationFails/CompletionWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/CompletionStreamWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/Edits (0.00s)
    --- PASS: TestRequestCreationFails/Search (0.00s)
    --- PASS: TestRequestCreationFails/SearchWithEngine (0.00s)
    --- PASS: TestRequestCreationFails/Embeddings (0.00s)
    --- PASS: TestRequestCreationFails/Moderation (0.00s)
=== RUN   TestResponses
=== RUN   TestResponses/Engines
=== RUN   TestResponses/Engines/bad_status_codes
=== RUN   TestResponses/Engines/success_code_json_decode_failure
=== RUN   TestResponses/Engines/successful_response
=== RUN   TestResponses/Engine
=== RUN   TestResponses/Engine/bad_status_codes
=== RUN   TestResponses/Engine/success_code_json_decode_failure
=== RUN   TestResponses/Engine/successful_response
=== RUN   TestResponses/ChatCompletion
=== RUN   TestResponses/ChatCompletion/bad_status_codes
=== RUN   TestResponses/ChatCompletion/success_code_json_decode_failure
=== RUN   TestResponses/ChatCompletion/successful_response
=== RUN   TestResponses/Completion
=== RUN   TestResponses/Completion/bad_status_codes
=== RUN   TestResponses/Completion/success_code_json_decode_failure
=== RUN   TestResponses/Completion/successful_response
=== RUN   TestResponses/CompletionStream
=== RUN   TestResponses/CompletionStream/bad_status_codes
=== RUN   TestResponses/CompletionStream/success_code_json_decode_failure
=== RUN   TestResponses/CompletionWithEngine
=== RUN   TestResponses/CompletionWithEngine/bad_status_codes
=== RUN   TestResponses/CompletionWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/CompletionWithEngine/successful_response
=== RUN   TestResponses/CompletionStreamWithEngine
=== RUN   TestResponses/CompletionStreamWithEngine/bad_status_codes
=== RUN   TestResponses/CompletionStreamWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/Search
=== RUN   TestResponses/Search/bad_status_codes
=== RUN   TestResponses/Search/success_code_json_decode_failure
=== RUN   TestResponses/Search/successful_response
=== RUN   TestResponses/SearchWithEngine
=== RUN   TestResponses/SearchWithEngine/bad_status_codes
=== RUN   TestResponses/SearchWithEngine/success_code_json_decode_failure
=== RUN   TestResponses/SearchWithEngine/successful_response
=== RUN   TestResponses/Embeddings
=== RUN   TestResponses/Embeddings/bad_status_codes
=== RUN   TestResponses/Embeddings/success_code_json_decode_failure
=== RUN   TestResponses/Embeddings/successful_response
=== RUN   TestResponses/Moderation
=== RUN   TestResponses/Moderation/bad_status_codes
=== RUN   TestResponses/Moderation/success_code_json_decode_failure
=== RUN   TestResponses/Moderation/successful_response
--- PASS: TestResponses (0.00s)
    --- PASS: TestResponses/Engines (0.00s)
        --- PASS: TestResponses/Engines/bad_status_codes (0.00s)
        --- PASS: TestResponses/Engines/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Engines/successful_response (0.00s)
    --- PASS: TestResponses/Engine (0.00s)
        --- PASS: TestResponses/Engine/bad_status_codes (0.00s)
        --- PASS: TestResponses/Engine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Engine/successful_response (0.00s)
    --- PASS: TestResponses/ChatCompletion (0.00s)
        --- PASS: TestResponses/ChatCompletion/bad_status_codes (0.00s)
        --- PASS: TestResponses/ChatCompletion/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/ChatCompletion/successful_response (0.00s)
    --- PASS: TestResponses/Completion (0.00s)
        --- PASS: TestResponses/Completion/bad_status_codes (0.00s)
        --- PASS: TestResponses/Completion/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Completion/successful_response (0.00s)
    --- PASS: TestResponses/CompletionStream (0.00s)
        --- PASS: TestResponses/CompletionStream/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionStream/success_code_json_decode_failure (0.00s)
    --- PASS: TestResponses/CompletionWithEngine (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/CompletionWithEngine/successful_response (0.00s)
    --- PASS: TestResponses/CompletionStreamWithEngine (0.00s)
        --- PASS: TestResponses/CompletionStreamWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/CompletionStreamWithEngine/success_code_json_decode_failure (0.00s)
    --- PASS: TestResponses/Search (0.00s)
        --- PASS: TestResponses/Search/bad_status_codes (0.00s)
        --- PASS: TestResponses/Search/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Search/successful_response (0.00s)
    --- PASS: TestResponses/SearchWithEngine (0.00s)
        --- PASS: TestResponses/SearchWithEngine/bad_status_codes (0.00s)
        --- PASS: TestResponses/SearchWithEngine/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/SearchWithEngine/successful_response (0.00s)
    --- PASS: TestResponses/Embeddings (0.00s)
        --- PASS: TestResponses/Embeddings/bad_status_codes (0.00s)
        --- PASS: TestResponses/Embeddings/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Embeddings/successful_response (0.00s)
    --- PASS: TestResponses/Moderation (0.00s)
        --- PASS: TestResponses/Moderation/bad_status_codes (0.00s)
        --- PASS: TestResponses/Moderation/success_code_json_decode_failure (0.00s)
        --- PASS: TestResponses/Moderation/successful_response (0.00s)
PASS
ok  	github.com/PullRequestInc/go-gpt3	0.257s

Signed-off-by: Yoriyasu Yano <430092+yorinasub17@users.noreply.github.com>
Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ This pull request was sent to the PullRequest network.


@yorinasub17 you can click here to see the review status or cancel the code review job.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PullRequest Breakdown

Reviewable lines of change

+ 112
- 0

66% Go
34% Go (tests)

Type of change

Feature - These changes are adding a new feature or improvement to existing code.

Copy link

@pullrequest pullrequest bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request, which adds support for the OpenAI moderations endpoint, looks good to me. It is clean, organized, well document, and relatively straightforward. I don't notice any major issues with the approach.

Image of Ryan Ryan


Reviewed with ❤️ by PullRequest

type ModerationRequest struct {
// Input is the input text that should be classified. Required.
Input string `json:"input"`
// Model is the content moderation model to use. If not specified, will default to OpenAI API defaults, which is
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the TextModerationLatest value being used anywhere to specify it as a default. Is this requirement being satisfied?

🔹 Clarify Intent (Nice to have)

Image of Ryan Ryan

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup this is being satisfied at the OpenAI API level as mentioned in the comment. See related API docs on openai.com: https://platform.openai.com/docs/api-reference/moderations/create

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my mistake, I misread that. Thanks for clarifying.

Image of Ryan Ryan

@yorinasub17
Copy link
Contributor Author

Thanks for the review!

Copy link
Contributor

@tylermann tylermann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding support for this @yorinasub17 . This looks fairly straightforward to me and should be good to go.

@tylermann tylermann merged commit e348aa5 into PullRequestInc:main Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants