mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-19 05:59:26 +08:00
Previously, the AI bot conversation page carried redundant chrome — a "Powered by Discourse" credit and a duplicate AI disclaimer on threaded replies — placed the "Share AI conversation" action in the topic footer, and showed a second admin wrench. This change tidies the page: it removes the redundant credit, disclaimer, and duplicate footer wrench, gives the docked composer a chat-style input background, and moves sharing into the sidebar conversation menu <img width="961" height="1262" alt="Screenshot 2026-06-01 at 11 41 10" src="https://github.com/user-attachments/assets/5750689b-32cf-4fa0-910e-3a0900628b58" /> <img width="503" height="126" alt="Screenshot 2026-06-01 at 11 41 19" src="https://github.com/user-attachments/assets/51adbf4f-831b-4399-901e-bfdc885f4d02" />
146 lines
5 KiB
Ruby
Vendored
146 lines
5 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe "AI Bot docked composer" do
|
|
let(:topic_page) { PageObjects::Pages::Topic.new }
|
|
|
|
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
|
|
|
|
fab!(:claude_2) do
|
|
Fabricate(
|
|
:llm_model,
|
|
provider: "anthropic",
|
|
url: "https://api.anthropic.com/v1/messages",
|
|
name: "claude-2",
|
|
display_name: "Claude 2",
|
|
)
|
|
end
|
|
|
|
fab!(:bot_user) do
|
|
enable_current_plugin
|
|
toggle_enabled_bots(bots: [claude_2])
|
|
SiteSetting.ai_bot_enabled = true
|
|
claude_2.reload.user
|
|
end
|
|
|
|
fab!(:pm) do
|
|
Fabricate(
|
|
:private_message_topic,
|
|
title: "A bot conversation",
|
|
user: user,
|
|
last_posted_at: Time.zone.now,
|
|
topic_allowed_users: [
|
|
Fabricate.build(:topic_allowed_user, user: user),
|
|
Fabricate.build(:topic_allowed_user, user: bot_user),
|
|
],
|
|
)
|
|
end
|
|
|
|
fab!(:first_post) { Fabricate(:post, topic: pm, user: user, post_number: 1, raw: "Hello bot") }
|
|
fab!(:bot_post) { Fabricate(:post, topic: pm, user: bot_user, post_number: 2, raw: "Hello user") }
|
|
|
|
fab!(:regular_topic) { Fabricate(:topic, user: user) }
|
|
fab!(:regular_post) { Fabricate(:post, topic: regular_topic, user: user, raw: "Regular topic") }
|
|
|
|
before do
|
|
enable_current_plugin
|
|
pm.custom_fields[DiscourseAi::AiBot::TOPIC_AI_BOT_PM_FIELD] = "t"
|
|
pm.save!
|
|
toggle_enabled_bots(bots: [claude_2])
|
|
SiteSetting.navigation_menu = "sidebar"
|
|
SiteSetting.ai_bot_allowed_groups = "#{Group::AUTO_GROUPS[:trust_level_0]}"
|
|
SiteSetting.ai_bot_enable_docked_composer = true
|
|
Jobs.run_immediately!
|
|
sign_in(user)
|
|
end
|
|
|
|
it "renders the docked composer on an AI bot PM and hides the popup reply UI" do
|
|
topic_page.visit_topic(pm)
|
|
|
|
expect(page).to have_css(".ai-bot-docked-composer")
|
|
expect(page).to have_css(".ai-bot-docked-composer .d-editor-input")
|
|
# The docked composer replaces the topic footer entirely, so it is not
|
|
# rendered (rather than hidden via CSS).
|
|
expect(page).to have_no_css("#topic-footer-buttons")
|
|
end
|
|
|
|
it "sends a reply via the docked composer when pressing Enter" do
|
|
topic_page.visit_topic(pm)
|
|
expect(page).to have_css(".ai-bot-docked-composer")
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses(["Bot reply to docked message"]) do
|
|
find(".ai-bot-docked-composer .d-editor-input").fill_in(
|
|
with: "Message from the docked composer",
|
|
)
|
|
find(".ai-bot-docked-composer .d-editor-input").send_keys(:enter)
|
|
|
|
expect(page).to have_content("Message from the docked composer")
|
|
end
|
|
end
|
|
|
|
it "does not render the docked composer on regular topics" do
|
|
topic_page.visit_topic(regular_topic)
|
|
|
|
expect(page).to have_no_css(".ai-bot-docked-composer")
|
|
expect(page).to have_css("#topic-footer-buttons .create")
|
|
end
|
|
|
|
it "cleans up when navigating from a bot PM to a regular topic" do
|
|
topic_page.visit_topic(pm)
|
|
expect(page).to have_css(".ai-bot-docked-composer")
|
|
expect(page).to have_css("body.has-ai-bot-docked-composer")
|
|
|
|
topic_page.visit_topic(regular_topic)
|
|
|
|
expect(page).to have_no_css(".ai-bot-docked-composer")
|
|
expect(page).to have_no_css("body.has-ai-bot-docked-composer")
|
|
expect(page).to have_css("#topic-footer-buttons .create")
|
|
end
|
|
|
|
it "hides the toolbar by default and shows it when the toggle button is clicked" do
|
|
topic_page.visit_topic(pm)
|
|
|
|
expect(page).to have_css(".ai-bot-docked-composer.docked-composer--toolbar-hidden")
|
|
expect(page).to have_no_css(".d-editor-button-bar__wrap", visible: true)
|
|
|
|
find(".ai-bot-docked-composer__toolbar-toggle").click
|
|
|
|
expect(page).to have_no_css(".ai-bot-docked-composer.docked-composer--toolbar-hidden")
|
|
end
|
|
|
|
it "clears the reply field after a successful submit" do
|
|
topic_page.visit_topic(pm)
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses(["Bot reply"]) do
|
|
find(".ai-bot-docked-composer .d-editor-input").fill_in(with: "First message to the bot")
|
|
find(".ai-bot-docked-composer .d-editor-input").send_keys(:enter)
|
|
|
|
expect(page).to have_content("First message to the bot")
|
|
end
|
|
|
|
expect(find(".ai-bot-docked-composer .d-editor-input").value).to eq("")
|
|
end
|
|
|
|
it "edits a post through the docked composer" do
|
|
topic_page.visit_topic(pm)
|
|
|
|
find("#post_1 button.edit").click
|
|
|
|
expect(page).to have_css(".ai-bot-docked-composer__editing")
|
|
expect(page).to have_no_css("#reply-control.composer-action-edit")
|
|
expect(find(".ai-bot-docked-composer .d-editor-input").value).to eq("Hello bot")
|
|
|
|
find(".ai-bot-docked-composer .d-editor-input").fill_in(with: "Edited bot message")
|
|
find(".ai-bot-docked-composer .docked-composer__submit-btn").click
|
|
|
|
expect(page).to have_no_css(".ai-bot-docked-composer__editing")
|
|
expect(page).to have_css("#post_1", text: "Edited bot message")
|
|
end
|
|
|
|
it "falls back to the standard composer when the docked composer is disabled" do
|
|
SiteSetting.ai_bot_enable_docked_composer = false
|
|
topic_page.visit_topic(pm)
|
|
|
|
expect(page).to have_no_css(".ai-bot-docked-composer")
|
|
expect(page).to have_css("#topic-footer-buttons .create")
|
|
end
|
|
end
|