77 lines
2.3 KiB
Ruby
77 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module ::Jobs
|
|
class CreateAiReply < ::Jobs::Base
|
|
sidekiq_options retry: false
|
|
|
|
def execute(args)
|
|
return unless post = Post.includes(:topic).find_by(id: args[:post_id])
|
|
|
|
prompt = CompletionPrompt.bot_prompt_with_topic_context(post)
|
|
|
|
redis_stream_key = nil
|
|
reply = +""
|
|
bot_reply_post = nil
|
|
start = Time.now
|
|
|
|
DiscourseAi::Inference::OpenAiCompletions.perform!(
|
|
prompt,
|
|
temperature: 0.4,
|
|
top_p: 0.9,
|
|
max_tokens: 3000,
|
|
) do |partial, cancel|
|
|
content_delta = partial.dig(:choices, 0, :delta, :content)
|
|
reply << content_delta if content_delta
|
|
|
|
if redis_stream_key && !Discourse.redis.get(redis_stream_key)
|
|
cancel&.call
|
|
|
|
bot_reply_post.update!(raw: reply, cooked: PrettyText.cook(reply)) if bot_reply_post
|
|
end
|
|
|
|
next if reply.length < SiteSetting.min_personal_message_post_length
|
|
# Minor hack to skip the delay during tests.
|
|
next if (Time.now - start < 0.5) && !Rails.env.test?
|
|
|
|
if bot_reply_post
|
|
Discourse.redis.expire(redis_stream_key, 60)
|
|
start = Time.now
|
|
|
|
MessageBus.publish(
|
|
"discourse-ai/ai-bot/topic/#{post.topic_id}",
|
|
{ raw: reply.dup, post_id: bot_reply_post.id, post_number: bot_reply_post.post_number },
|
|
user_ids: post.topic.allowed_user_ids,
|
|
)
|
|
else
|
|
bot_reply_post =
|
|
PostCreator.create!(
|
|
Discourse.gpt_bot,
|
|
topic_id: post.topic_id,
|
|
raw: reply,
|
|
skip_validations: false,
|
|
)
|
|
redis_stream_key = "gpt_cancel:#{bot_reply_post.id}"
|
|
Discourse.redis.setex(redis_stream_key, 60, 1)
|
|
end
|
|
end
|
|
|
|
MessageBus.publish(
|
|
"discourse-ai/ai-bot/topic/#{post.topic_id}",
|
|
{ done: true, post_id: bot_reply_post.id, post_number: bot_reply_post.post_number },
|
|
user_ids: post.topic.allowed_user_ids,
|
|
)
|
|
|
|
if bot_reply_post
|
|
bot_reply_post.revise(
|
|
Discourse.gpt_bot,
|
|
{ raw: reply },
|
|
skip_validations: true,
|
|
skip_revision: true,
|
|
)
|
|
end
|
|
rescue => e
|
|
Discourse.warn_exception(e, message: "ai-bot: Reply failed")
|
|
end
|
|
end
|
|
end
|