Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: unable to share conversations with persona user #479

Merged
merged 3 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions assets/javascripts/discourse/lib/copy-conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,5 @@ async function generateClipboard(topic, fromPostNumber, toPostNumber) {

const text = buffer.join("\n");

if (window.discourseAiTestClipboard) {
window.discourseAiClipboard = text;
}

return text;
}
13 changes: 11 additions & 2 deletions assets/javascripts/initializers/ai-bot-replies.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ function initializePersonaDecorator(api) {
);
}

const MAX_PERSONA_USER_ID = -1200;

function initializeShareButton(api) {
const currentUser = api.getCurrentUser();
if (!currentUser || !currentUser.ai_enabled_chat_bots) {
Expand All @@ -159,13 +161,20 @@ function initializeShareButton(api) {
};

api.addPostMenuButton("share", (post) => {
// very hacky and ugly, but there is no `.topic` in attrs
// for backwards compat so we don't break if topic is undefined
if (post.topic?.archetype !== "private_message") {
return;
}

if (
!currentUser.ai_enabled_chat_bots.any(
(bot) => post.username === bot.username
)
) {
return;
// special handling for personas (persona bot users start at ID -1200 and go down)
if (post.user_id > MAX_PERSONA_USER_ID) {
return;
}
}

return {
Expand Down
2 changes: 1 addition & 1 deletion lib/ai_bot/personas/discourse_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def system_prompt
- Discourse Helper Bot understand *markdown* and responds in Discourse **markdown**.
- Discourse Helper Bot has access to the search function on meta.discourse.org and can help you find answers to your questions.
- Discourse Helper Bot ALWAYS backs up answers with actual search results from meta.discourse.org, even if the information is in your training set
- Discourse Helper Bot does not use the word siscourse in searches, search function is restricted to Discourse Meta and Discourse specific discussions
- Discourse Helper Bot does not use the word Discourse in searches, search function is restricted to Discourse Meta and Discourse specific discussions
- Discourse Helper Bot understands that search is keyword based (terms are joined using AND) and that it is important to simplify search terms to find things.
- Discourse Helper Bot understands that users often badly phrase and misspell words, it will compensate for that by guessing what user means.

Expand Down
65 changes: 51 additions & 14 deletions spec/system/ai_bot/share_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
posts
end

let(:cdp) { PageObjects::CDP.new }

before do
SiteSetting.ai_bot_enabled = true
SiteSetting.ai_bot_enabled_chat_bots = "gpt-4"
Expand All @@ -35,26 +37,62 @@
bot_user.update!(username: "gpt-4")

Group.refresh_automatic_groups!
pm
pm_posts

cdp.allow_clipboard
page.execute_script("window.navigator.clipboard.writeText('')")
end

it "can share a conversation" do
it "can share a conversation with a persona user" do
clip_text = nil

persona = Fabricate(:ai_persona, name: "Tester")
persona.create_user!

Fabricate(:post, topic: pm, user: admin, raw: "How do I do stuff?")
Fabricate(:post, topic: pm, user: persona.user, raw: "No idea")

visit(pm.url)

# clipboard functionality is extremely hard to test
# we would need special permissions in chrome driver to enable full access
# instead we use a secret variable to signal that we want to store clipboard
# data in window.discourseAiClipboard
page.execute_script("window.discourseAiTestClipboard = true")
find("#post_2 .post-action-menu__share").click

try_until_success do
clip_text = cdp.read_clipboard
expect(clip_text).not_to eq("")
end

conversation = (<<~TEXT).strip
<details class='ai-quote'>
<summary>
<span>This is my special PM</span>
<span title='Conversation with AI'>AI</span>
</summary>

**ai_sharer:**

How do I do stuff?

**Tester_bot:**

No idea
</details>
TEXT

expect(conversation).to eq(clip_text)
end

it "can share a conversation" do
clip_text = nil

pm
pm_posts

visit(pm.url)

find("#post_2 .post-action-menu__share").click

try_until_success do
clip_text = page.evaluate_script("window.discourseAiClipboard")
expect(clip_text).to be_present
clip_text = cdp.read_clipboard
expect(clip_text).not_to eq("")
end

conversation = (<<~TEXT).strip
Expand All @@ -76,16 +114,15 @@

expect(conversation).to eq(clip_text)

# Test modal functionality as well
page.evaluate_script("window.discourseAiClipboard = null")
page.execute_script("window.navigator.clipboard.writeText('')")

find("#post_6 .post-action-menu__share").click
find(".ai-share-modal__slider input").set("2")
find(".ai-share-modal button.btn-primary").click

try_until_success do
clip_text = page.evaluate_script("window.discourseAiClipboard")
expect(clip_text).to be_present
clip_text = cdp.read_clipboard
expect(clip_text).not_to eq("")
end

conversation = (<<~TEXT).strip
Expand Down