Skip to content

Commit

Permalink
FIX: refine image and read command (#131)
Browse files Browse the repository at this point in the history
- Attempt to hint reading is done by sending complete:true
- Do not include post_number in result unless it was sent in
- Rush visual feedback when a command is run (ensure we always revise)
- Include hyperlink in read command description
- Stop round tripping to GPT after image generation (speeds up images by a lot)
- Add a test for image command
  • Loading branch information
SamSaffron committed Aug 9, 2023
1 parent 958dfc3 commit 7eedbf2
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 19 deletions.
2 changes: 1 addition & 1 deletion config/locales/server.en.yml
Expand Up @@ -102,7 +102,7 @@ en:
google: "Search Google"
read: "Read topic"
command_description:
read: "Reading: %{title}"
read: "Reading: <a href='%{url}'>%{title}</a>"
time: "Time in %{timezone} is %{time}"
summarize: "Summarized <a href='%{url}'>%{title}</a>"
image: "%{prompt}"
Expand Down
6 changes: 4 additions & 2 deletions lib/modules/ai_bot/commands/command.rb
Expand Up @@ -125,11 +125,13 @@ def invoke_and_attach_result_to(post, parent_post)

raw = post.raw.sub(placeholder, raw)

post.revise(bot_user, { raw: raw }, skip_validations: true, skip_revision: true)

if chain_next_response
# somewhat annoying but whitespace was stripped in revise
# so we need to save again
post.raw = raw
post.save!(validate: false)
else
post.revise(bot_user, { raw: raw }, skip_validations: true, skip_revision: true)
end

[chain_next_response, post]
Expand Down
22 changes: 10 additions & 12 deletions lib/modules/ai_bot/commands/image_command.rb
Expand Up @@ -15,20 +15,13 @@ def parameters
[
Parameter.new(
name: "prompt",
description: "The prompt used to generate or create or draw the image",
description:
"The prompt used to generate or create or draw the image (40 words or less, be creative)",
type: "string",
required: true,
),
]
end

def custom_system_message
<<~TEXT
In Discourse the markdown (description|SIZE, ZOOM%)[upload://SOMETEXT] is used to denote images and uploads. NEVER try changing the to http or https links.
ALWAYS prefer the upload:// format if available.
When rendering multiple images place them in a [grid] ... [/grid] block
TEXT
end
end

def result_name
Expand All @@ -40,7 +33,11 @@ def description_args
end

def chain_next_response
true
false
end

def custom_raw
@custom_raw
end

def process(prompt:)
Expand All @@ -58,7 +55,8 @@ def process(prompt:)
f.unlink
end

raw = <<~RAW
@custom_raw = <<~RAW
[grid]
#{
uploads
Expand All @@ -68,7 +66,7 @@ def process(prompt:)
[/grid]
RAW

{ prompt: prompt, markdown: raw, display_to_user: true }
{ prompt: prompt, displayed_to_user: true }
end
end
end
8 changes: 6 additions & 2 deletions lib/modules/ai_bot/commands/read_command.rb
Expand Up @@ -30,7 +30,7 @@ def parameters
end

def description_args
{ title: @title }
{ title: @title, url: @url }
end

def process(topic_id:, post_number: nil)
Expand All @@ -46,6 +46,8 @@ def process(topic_id:, post_number: nil)
@title = topic.title

posts = Post.secured(Guardian.new).where(topic_id: topic_id).order(:post_number).limit(40)
@url = topic.relative_url(post_number)

posts = posts.where("post_number = ?", post_number) if post_number

content = +"title: #{topic.title}\n\n"
Expand All @@ -55,7 +57,9 @@ def process(topic_id:, post_number: nil)
# TODO: 16k or 100k models can handle a lot more tokens
content = ::DiscourseAi::Tokenizer::BertTokenizer.truncate(content, 1500).squish

{ topic_id: topic_id, post_number: post_number, content: content }
result = { topic_id: topic_id, content: content, complete: true }
result[:post_number] = post_number if post_number
result
end
end
end
2 changes: 0 additions & 2 deletions spec/lib/modules/ai_bot/commands/google_command_spec.rb
@@ -1,7 +1,5 @@
#frozen_string_literal: true

require_relative "../../../../support/openai_completions_inference_stubs"

RSpec.describe DiscourseAi::AiBot::Commands::GoogleCommand do
fab!(:bot_user) { User.find(DiscourseAi::AiBot::EntryPoint::GPT3_5_TURBO_ID) }

Expand Down
36 changes: 36 additions & 0 deletions spec/lib/modules/ai_bot/commands/image_command_spec.rb
@@ -0,0 +1,36 @@
#frozen_string_literal: true

RSpec.describe DiscourseAi::AiBot::Commands::ImageCommand do
fab!(:bot_user) { User.find(DiscourseAi::AiBot::EntryPoint::GPT3_5_TURBO_ID) }

describe "#process" do
it "can generate correct info" do
post = Fabricate(:post)

SiteSetting.ai_stability_api_url = "https://api.stability.dev"
SiteSetting.ai_stability_api_key = "abc"

image =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="

stub_request(
:post,
"https://api.stability.dev/v1/generation/#{SiteSetting.ai_stability_engine}/text-to-image",
)
.with do |request|
json = JSON.parse(request.body)
expect(json["text_prompts"][0]["text"]).to eq("a pink cow")
true
end
.to_return(status: 200, body: { artifacts: [{ base64: image }, { base64: image }] }.to_json)

image = described_class.new(bot_user, post)
info = image.process(prompt: "a pink cow").to_json

expect(JSON.parse(info)).to eq("prompt" => "a pink cow", "displayed_to_user" => true)
expect(image.custom_raw).to include("upload://")
expect(image.custom_raw).to include("[grid]")
expect(image.custom_raw).to include("a pink cow")
end
end
end
1 change: 1 addition & 0 deletions spec/lib/modules/ai_bot/commands/read_command_spec.rb
Expand Up @@ -15,6 +15,7 @@
expect(results[:topic_id]).to eq(post1.topic_id)
expect(results[:content]).to include("hello")
expect(results[:content]).to include("sam")
expect(read.description_args).to eq(title: post1.topic.title, url: post1.topic.relative_url)
end
end
end

0 comments on commit 7eedbf2

Please sign in to comment.