DEV: Log information about errors from the completions OpenAI API (#26)

This commit is contained in:
Roman Rizzi 2023-03-22 16:00:28 -03:00 committed by GitHub
parent 1d14f7ffaf
commit 4c960970fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 18 deletions

View File

@ -32,6 +32,9 @@ module DiscourseAi
), ),
status: 200 status: 200
end end
rescue DiscourseAi::Inference::OpenAiCompletions::CompletionFailed
render_json_error I18n.t("discourse_ai.ai_helper.errors.completion_request_failed"),
status: 502
end end
private private

View File

@ -57,6 +57,8 @@ en:
discourse_ai: discourse_ai:
ai_helper: ai_helper:
errors:
completion_request_failed: "Something went wrong while trying to provide suggestions. Please, try again."
prompts: prompts:
translate: Translate to English translate: Translate to English
generate_titles: Suggest topic titles generate_titles: Suggest topic titles

View File

@ -3,12 +3,6 @@
module DiscourseAi module DiscourseAi
module AiHelper module AiHelper
class OpenAiPrompt class OpenAiPrompt
TRANSLATE = "translate"
GENERATE_TITLES = "generate_titles"
PROOFREAD = "proofread"
MARKDOWN_TABLE = "markdown_table"
VALID_TYPES = [TRANSLATE, GENERATE_TITLES, PROOFREAD, MARKDOWN_TABLE]
def available_prompts def available_prompts
CompletionPrompt CompletionPrompt
.where(enabled: true) .where(enabled: true)

View File

@ -3,6 +3,8 @@
module ::DiscourseAi module ::DiscourseAi
module Inference module Inference
class OpenAiCompletions class OpenAiCompletions
CompletionFailed = Class.new(StandardError)
def self.perform!(messages, model = "gpt-3.5-turbo") def self.perform!(messages, model = "gpt-3.5-turbo")
headers = { headers = {
"Authorization" => "Bearer #{SiteSetting.ai_openai_api_key}", "Authorization" => "Bearer #{SiteSetting.ai_openai_api_key}",
@ -18,7 +20,12 @@ module ::DiscourseAi
headers, headers,
) )
raise Net::HTTPBadResponse unless response.status == 200 if response.status != 200
Rails.logger.error(
"OpenAiCompletions: status: #{response.status} - body: #{response.body}",
)
raise CompletionFailed
end
JSON.parse(response.body, symbolize_names: true) JSON.parse(response.body, symbolize_names: true)
end end

View File

@ -7,7 +7,7 @@ RSpec.describe DiscourseAi::AiHelper::OpenAiPrompt do
describe "#generate_and_send_prompt" do describe "#generate_and_send_prompt" do
context "when using the translate mode" do context "when using the translate mode" do
let(:mode) { "translate" } let(:mode) { OpenAiCompletionsInferenceStubs::TRANSLATE }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }
@ -22,7 +22,7 @@ RSpec.describe DiscourseAi::AiHelper::OpenAiPrompt do
end end
context "when using the proofread mode" do context "when using the proofread mode" do
let(:mode) { "proofread" } let(:mode) { OpenAiCompletionsInferenceStubs::PROOFREAD }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }
@ -40,7 +40,7 @@ RSpec.describe DiscourseAi::AiHelper::OpenAiPrompt do
end end
context "when generating titles" do context "when generating titles" do
let(:mode) { "generate_titles" } let(:mode) { OpenAiCompletionsInferenceStubs::GENERATE_TITLES }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }

View File

@ -53,6 +53,16 @@ RSpec.describe DiscourseAi::AiHelper::AssistantController do
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "returns a generic error when the completion call fails" do
WebMock.stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return(
status: 500,
)
post "/discourse-ai/ai-helper/suggest", params: { mode: mode, text: text }
expect(response.status).to eq(502)
end
it "returns a suggestion" do it "returns a suggestion" do
OpenAiCompletionsInferenceStubs.stub_prompt(mode) OpenAiCompletionsInferenceStubs.stub_prompt(mode)

View File

@ -1,6 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class OpenAiCompletionsInferenceStubs class OpenAiCompletionsInferenceStubs
TRANSLATE = "translate"
PROOFREAD = "proofread"
GENERATE_TITLES = "generate_titles"
class << self class << self
def spanish_text def spanish_text
<<~STRING <<~STRING
@ -69,19 +73,18 @@ class OpenAiCompletionsInferenceStubs
def response_text_for(type) def response_text_for(type)
case type case type
when DiscourseAi::AiHelper::OpenAiPrompt::TRANSLATE when TRANSLATE
translated_response translated_response
when DiscourseAi::AiHelper::OpenAiPrompt::PROOFREAD when PROOFREAD
proofread_response proofread_response
when DiscourseAi::AiHelper::OpenAiPrompt::GENERATE_TITLES when GENERATE_TITLES
generated_titles generated_titles
end end
end end
def stub_prompt(type) def stub_prompt(type)
prompt_builder = DiscourseAi::AiHelper::OpenAiPrompt.new prompt_builder = DiscourseAi::AiHelper::OpenAiPrompt.new
text = text = type == TRANSLATE ? spanish_text : translated_response
type == DiscourseAi::AiHelper::OpenAiPrompt::TRANSLATE ? spanish_text : translated_response
prompt_messages = CompletionPrompt.find_by(name: type).messages_with_user_input(text) prompt_messages = CompletionPrompt.find_by(name: type).messages_with_user_input(text)

View File

@ -15,7 +15,7 @@ RSpec.describe "AI Composer helper", type: :system, js: true do
let(:ai_helper_modal) { PageObjects::Modals::AiHelper.new } let(:ai_helper_modal) { PageObjects::Modals::AiHelper.new }
context "when using the translation mode" do context "when using the translation mode" do
let(:mode) { DiscourseAi::AiHelper::OpenAiPrompt::TRANSLATE } let(:mode) { OpenAiCompletionsInferenceStubs::TRANSLATE }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }
@ -38,7 +38,7 @@ RSpec.describe "AI Composer helper", type: :system, js: true do
end end
context "when using the proofreading mode" do context "when using the proofreading mode" do
let(:mode) { DiscourseAi::AiHelper::OpenAiPrompt::PROOFREAD } let(:mode) { OpenAiCompletionsInferenceStubs::PROOFREAD }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }
@ -61,7 +61,7 @@ RSpec.describe "AI Composer helper", type: :system, js: true do
end end
context "when selecting an AI generated title" do context "when selecting an AI generated title" do
let(:mode) { DiscourseAi::AiHelper::OpenAiPrompt::GENERATE_TITLES } let(:mode) { OpenAiCompletionsInferenceStubs::GENERATE_TITLES }
before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) } before { OpenAiCompletionsInferenceStubs.stub_prompt(mode) }