Skip to content

Commit

Permalink
AIChat: new welcome opt-in ux and contextual toggle (#20966)
Browse files Browse the repository at this point in the history
* aichat: new opt-in ux

* simplify siteInfo

* aichat: toggle page context responses from LLM

* moved build site info to conversation driver

* special summarize button visibility depends on toggle

* MakeAPIRequestWithConversationHistoryUpdate accepts a flag

* show model intro on all pages

* AI Chat: Don't show suggested questions when conversation isn't associated with content

* AI Chat: conversation entry should also be pending if content isn't ready yet

---------

Co-authored-by: Pete Miller <[email protected]>
  • Loading branch information
nullhook and petemill committed Dec 8, 2023
1 parent 7955dc5 commit 2427700
Show file tree
Hide file tree
Showing 29 changed files with 712 additions and 329 deletions.
75 changes: 36 additions & 39 deletions browser/ui/webui/ai_chat/ai_chat_ui_page_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/url_constants.h"
#include "ui/base/l10n/l10n_util.h"

#if BUILDFLAG(IS_ANDROID)
#include "brave/browser/ui/android/ai_chat/brave_leo_settings_launcher_helper.h"
Expand Down Expand Up @@ -90,6 +91,14 @@ AIChatUIPageHandler::~AIChatUIPageHandler() = default;
void AIChatUIPageHandler::SetClientPage(
mojo::PendingRemote<ai_chat::mojom::ChatUIPage> page) {
page_.Bind(std::move(page));

// In some cases, this page handler hasn't been created and remote might not
// have been set yet.
// ex. A user may ask a question from the location bar
if (active_chat_tab_helper_ &&
active_chat_tab_helper_->HasPendingConversationEntry()) {
OnConversationEntryPending();
}
}

void AIChatUIPageHandler::GetModels(GetModelsCallback callback) {
Expand Down Expand Up @@ -124,6 +133,12 @@ void AIChatUIPageHandler::SubmitHumanConversationEntry(
std::move(turn));
}

void AIChatUIPageHandler::SubmitSummarizationRequest() {
if (active_chat_tab_helper_) {
active_chat_tab_helper_->SubmitSummarizationRequest();
}
}

void AIChatUIPageHandler::GetConversationHistory(
GetConversationHistoryCallback callback) {
if (!active_chat_tab_helper_) {
Expand Down Expand Up @@ -168,16 +183,12 @@ void AIChatUIPageHandler::GenerateQuestions() {
void AIChatUIPageHandler::GetSiteInfo(GetSiteInfoCallback callback) {
if (!active_chat_tab_helper_) {
VLOG(2) << "Chat tab helper is not set";
std::move(callback).Run(false, nullptr);
std::move(callback).Run({});
return;
}

auto site_info = BuildSiteInfo();
const bool is_fetching_content = active_chat_tab_helper_->HasPageContent() ==
PageContentAssociation::FETCHING_CONTENT;
std::move(callback).Run(is_fetching_content, site_info.has_value()
? site_info.value().Clone()
: nullptr);
auto site_info = active_chat_tab_helper_->BuildSiteInfo();
std::move(callback).Run(site_info.Clone());
}

void AIChatUIPageHandler::OpenBraveLeoSettings() {
Expand Down Expand Up @@ -218,9 +229,17 @@ void AIChatUIPageHandler::OpenURL(const GURL& url) {
#endif
}

void AIChatUIPageHandler::DisconnectPageContents() {
void AIChatUIPageHandler::SetShouldSendPageContents(bool should_send) {
if (active_chat_tab_helper_) {
active_chat_tab_helper_->SetShouldSendPageContents(should_send);
}
}

void AIChatUIPageHandler::GetShouldSendPageContents(
GetShouldSendPageContentsCallback callback) {
if (active_chat_tab_helper_) {
active_chat_tab_helper_->DisconnectPageContents();
std::move(callback).Run(
active_chat_tab_helper_->GetShouldSendPageContents());
}
}

Expand Down Expand Up @@ -390,22 +409,15 @@ void AIChatUIPageHandler::OnFaviconImageDataChanged() {
}
}

void AIChatUIPageHandler::OnPageHasContent(bool page_contents_is_truncated) {
void AIChatUIPageHandler::OnPageHasContent(mojom::SiteInfoPtr site_info) {
if (page_.is_bound()) {
page_->OnSiteInfoChanged(std::move(site_info));
}
}

void AIChatUIPageHandler::OnConversationEntryPending() {
if (page_.is_bound()) {
// TODO(petemill): Looking at the target webcontents'
// |IsDocumentOnLoadCompletedInPrimaryMainFrame| could be improved with
// a function on TabHelper / Conversation, e.g. IsContentLoading so that
// MaybeGeneratePageText and this function are looking at the same thing.
// This should be refactored with iOS support.
const bool is_fetching_content =
(active_chat_tab_helper_->HasPageContent() ==
PageContentAssociation::FETCHING_CONTENT) ||
!active_chat_tab_helper_->web_contents()
->IsDocumentOnLoadCompletedInPrimaryMainFrame();
auto site_info = BuildSiteInfo();
page_->OnSiteInfoChanged(
is_fetching_content,
site_info.has_value() ? site_info.value().Clone() : nullptr);
page_->OnConversationEntryPending();
}
}

Expand Down Expand Up @@ -441,21 +453,6 @@ void AIChatUIPageHandler::GetFaviconImageData(
&favicon_task_tracker_);
}

absl::optional<mojom::SiteInfo> AIChatUIPageHandler::BuildSiteInfo() {
if (active_chat_tab_helper_ && active_chat_tab_helper_->HasPageContent() ==
PageContentAssociation::HAS_CONTENT) {
mojom::SiteInfo site_info;
site_info.title =
base::UTF16ToUTF8(active_chat_tab_helper_->web_contents()->GetTitle());
site_info.is_content_truncated =
active_chat_tab_helper_->IsPageContentsTruncated();

return site_info;
}

return absl::nullopt;
}

void AIChatUIPageHandler::OnVisibilityChanged(content::Visibility visibility) {
// WebUI visibility changed (not target tab)
if (!active_chat_tab_helper_) {
Expand Down
9 changes: 6 additions & 3 deletions browser/ui/webui/ai_chat/ai_chat_ui_page_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@ class AIChatUIPageHandler : public ai_chat::mojom::PageHandler,
void GetModels(GetModelsCallback callback) override;
void ChangeModel(const std::string& model_key) override;
void SubmitHumanConversationEntry(const std::string& input) override;
void SubmitSummarizationRequest() override;
void GetConversationHistory(GetConversationHistoryCallback callback) override;
void MarkAgreementAccepted() override;
void GetSuggestedQuestions(GetSuggestedQuestionsCallback callback) override;
void GenerateQuestions() override;
void GetSiteInfo(GetSiteInfoCallback callback) override;
void OpenBraveLeoSettings() override;
void OpenURL(const GURL& url) override;
void DisconnectPageContents() override;
void SetShouldSendPageContents(bool should_send) override;
void GetShouldSendPageContents(
GetShouldSendPageContentsCallback callback) override;
void ClearConversationHistory() override;
void RetryAPIRequest() override;
void GetAPIResponseError(GetAPIResponseErrorCallback callback) override;
Expand Down Expand Up @@ -89,10 +92,10 @@ class AIChatUIPageHandler : public ai_chat::mojom::PageHandler,
std::vector<std::string> questions,
mojom::SuggestionGenerationStatus suggestion_generation_status) override;
void OnFaviconImageDataChanged() override;
void OnPageHasContent(bool page_contents_is_truncated) override;
void OnPageHasContent(mojom::SiteInfoPtr site_info) override;
void OnConversationEntryPending() override;

void GetFaviconImageData(GetFaviconImageDataCallback callback) override;
absl::optional<mojom::SiteInfo> BuildSiteInfo();

mojo::Remote<ai_chat::mojom::ChatUIPage> page_;

Expand Down
4 changes: 4 additions & 0 deletions components/ai_chat/content/browser/ai_chat_tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ bool AIChatTabHelper::IsDocumentOnLoadCompletedInPrimaryMainFrame() const {
return web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame();
}

std::u16string AIChatTabHelper::GetPageTitle() const {
return web_contents()->GetTitle();
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(AIChatTabHelper);

} // namespace ai_chat
1 change: 1 addition & 0 deletions components/ai_chat/content/browser/ai_chat_tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class AIChatTabHelper : public content::WebContentsObserver,
callback) const override;
bool HasPrimaryMainFrame() const override;
bool IsDocumentOnLoadCompletedInPrimaryMainFrame() const override;
std::u16string GetPageTitle() const override;

raw_ptr<AIChatMetrics> ai_chat_metrics_;

Expand Down
16 changes: 15 additions & 1 deletion components/ai_chat/core/browser/constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,21 @@ base::span<const webui::LocalizedString> GetLocalizedStrings() {
{"gotItButtonLabel", IDS_CHAT_UI_GOT_IT_BUTTON_LABEL},
{"pageContentTooLongWarning", IDS_CHAT_UI_PAGE_CONTENT_TOO_LONG_WARNING},
{"errorConversationEnd", IDS_CHAT_UI_CONVERSATION_END_ERROR},
{"leoSettingsTooltipLabel", IDS_CHAT_UI_LEO_SETTINGS_TOOLTIP_LABEL}};
{"leoSettingsTooltipLabel", IDS_CHAT_UI_LEO_SETTINGS_TOOLTIP_LABEL},
{"summarizePageButtonLabel", IDS_CHAT_UI_SUMMARIZE_PAGE},
{"welcomeGuideTitle", IDS_CHAT_UI_WELCOME_GUIDE_TITLE},
{"welcomeGuideSubtitle", IDS_CHAT_UI_WELCOME_GUIDE_SUBTITLE},
{"welcomeGuideSiteHelpCardTitle",
IDS_CHAT_UI_WELCOME_GUIDE_SITE_HELP_CARD_TITLE},
{"welcomeGuideSiteHelpCardDesc",
IDS_CHAT_UI_WELCOME_GUIDE_SITE_HELP_CARD_DESC},
{"welcomeGuideSiteHelpCardDescWithAction",
IDS_CHAT_UI_WELCOME_GUIDE_SITE_HELP_CARD_WITH_ACTION},
{"welcomeGuideShatCardTitle", IDS_CHAT_UI_WELCOME_GUIDE_CHAT_CARD_TITLE},
{"welcomeGuideShatCardDesc", IDS_CHAT_UI_WELCOME_GUIDE_CHAT_CARD_DESC},
{"privacyTitle", IDS_CHAT_UI_PRIVACY_TITLE},
{"contextToggleLabel", IDS_CHAT_UI_CONTEXT_TOGGLE_LABEL},
{"contextToggleTooltipInfo", IDS_CHAT_UI_CONTEXT_TOGGLE_TOOLTIP_INFO}};

return kLocalizedStrings;
}
Expand Down
Loading

0 comments on commit 2427700

Please sign in to comment.