FEATURE: allow sending AI based report to a topic (#377)

This makes the reporting far more flexible cause it can target a
far wider audience by pointing it at a topic in a secure category
or an existing PM
This commit is contained in:
Sam 2023-12-22 11:46:23 +11:00 committed by GitHub
parent 37dd98c937
commit a5d240991f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 20 deletions

View File

@ -20,7 +20,10 @@ en:
description: "The user that will send the report"
receivers:
label: "Receivers"
description: "The users that will receive the report (can be email or usernames)"
description: "The users that will receive the report (emails will be sent direct emails, usernames will be sent a PM)"
topic_id:
label: "Topic ID"
description: "The topic id to post the report to"
title:
label: "Title"
description: "The title of the report"

View File

@ -11,8 +11,9 @@ if defined?(DiscourseAutomation)
triggerables %i[recurring]
field :sender, component: :user, required: true
field :receivers, component: :users, required: true
field :title, component: :text, required: true
field :receivers, component: :users
field :topic_id, component: :text
field :title, component: :text
field :days, component: :text, required: true, default_value: 7
field :offset, component: :text, required: true, default_value: 0
field :instructions,
@ -40,6 +41,7 @@ if defined?(DiscourseAutomation)
begin
sender = fields.dig("sender", "value")
receivers = fields.dig("receivers", "value")
topic_id = fields.dig("topic_id", "value")
title = fields.dig("title", "value")
model = fields.dig("model", "value")
category_ids = fields.dig("categories", "value")
@ -56,6 +58,7 @@ if defined?(DiscourseAutomation)
DiscourseAi::Automation::ReportRunner.run!(
sender_username: sender,
receivers: receivers,
topic_id: topic_id,
title: title,
model: model,
category_ids: category_ids,

View File

@ -35,25 +35,30 @@ module DiscourseAi
def initialize(
sender_username:,
receivers:,
title:,
model:,
category_ids:,
tags:,
allow_secure_categories:,
debug_mode:,
sample_size:,
instructions:,
tokens_per_post:,
days:,
offset:,
priority_group_id:,
tokens_per_post:
receivers: nil,
topic_id: nil,
title: nil,
category_ids: nil,
tags: nil,
priority_group_id: nil,
allow_secure_categories: false,
debug_mode: false
)
@sender = User.find_by(username: sender_username)
@receivers = User.where(username: receivers)
@email_receivers = receivers.filter { |r| r.include? "@" }
@title = title
@email_receivers = receivers&.filter { |r| r.include? "@" }
@title =
if title.present?
title
else
I18n.t("discourse_automation.llm_report.title")
end
@model = model
@llm = DiscourseAi::Completions::Llm.proxy(model)
@category_ids = category_ids
@ -66,13 +71,18 @@ module DiscourseAi
@offset = offset.to_i
@priority_group_id = priority_group_id
@tokens_per_post = tokens_per_post.to_i
@topic_id = topic_id.presence&.to_i
if !@topic_id && !@receivers.present? && !@email_receivers.present?
raise ArgumentError, "Must specify topic_id or receivers"
end
end
def run!
start_date = (@offset + @days).days.ago
end_date = start_date + @days.days
@title =
title =
@title.gsub(
"%DATE%",
start_date.strftime("%Y-%m-%d") + " - " + end_date.strftime("%Y-%m-%d"),
@ -102,7 +112,7 @@ module DiscourseAi
INPUT
prompt = {
insts: "You are a helpful bot specializing in summarizing activity Discourse sites",
insts: "You are a helpful bot specializing in summarizing activity on Discourse sites",
input: input,
final_insts: "Here is the report I generated for you",
params: {
@ -123,12 +133,17 @@ module DiscourseAi
receiver_usernames = @receivers.map(&:username).join(",")
if @topic_id
PostCreator.create!(@sender, raw: result, topic_id: @topic_id, skip_validations: true)
# no debug mode for topics, it is too noisy
end
if receiver_usernames.present?
post =
PostCreator.create!(
@sender,
raw: result,
title: @title,
title: title,
archetype: Archetype.private_message,
target_usernames: receiver_usernames,
skip_validations: true,
@ -157,7 +172,7 @@ module DiscourseAi
if @email_receivers.present?
@email_receivers.each do |to_address|
Email::Sender.new(
::AiReportMailer.send_report(to_address, subject: @title, body: result),
::AiReportMailer.send_report(to_address, subject: title, body: result),
:ai_report,
).send
end

View File

@ -5,6 +5,9 @@ return if !defined?(DiscourseAutomation)
describe DiscourseAutomation do
let(:automation) { Fabricate(:automation, script: "llm_report", enabled: true) }
fab!(:user)
fab!(:post)
def add_automation_field(name, value, type: "text")
automation.fields.create!(
component: type,
@ -17,8 +20,6 @@ describe DiscourseAutomation do
end
it "can trigger via automation" do
user = Fabricate(:user)
add_automation_field("sender", user.username, type: "user")
add_automation_field("receivers", [user.username], type: "users")
add_automation_field("model", "gpt-4-turbo")
@ -31,4 +32,16 @@ describe DiscourseAutomation do
pm = Topic.where(title: "Weekly report").first
expect(pm.posts.first.raw).to eq("An Amazing Report!!!")
end
it "can target a topic" do
add_automation_field("sender", user.username, type: "user")
add_automation_field("topic_id", "#{post.topic_id}")
add_automation_field("model", "gpt-4-turbo")
DiscourseAi::Completions::Llm.with_prepared_responses(["An Amazing Report!!!"]) do
automation.trigger!
end
expect(post.topic.reload.ordered_posts.last.raw).to eq("An Amazing Report!!!")
end
end