DEV: Log information about errors from the completions OpenAI API (#26)
This commit is contained in:
parent
1d14f7ffaf
commit
4c960970fa
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue