diff --git a/app/brave_settings_strings.grdp b/app/brave_settings_strings.grdp index e3e4aa21543..1bf83d531ba 100644 --- a/app/brave_settings_strings.grdp +++ b/app/brave_settings_strings.grdp @@ -1605,6 +1605,9 @@ Enable tab organization in Tab Search page. When opened, this will automatically send the titles and origins of all non-private tabs to Leo to classify them. <a target="_blank" href="$1">Learn more</a> + + Default model for tab focus + Show suggested prompts in the conversation diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index dc3d1cf527c..1e0cf0142a3 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -281,6 +281,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { settings_api::PrefType::kBoolean; (*s_brave_allowlist)[ai_chat::prefs::kBraveAIChatTabOrganizationEnabled] = settings_api::PrefType::kBoolean; + (*s_brave_allowlist)[ai_chat::prefs::kBraveAIChatTabOrganizationModelKey] = + settings_api::PrefType::kString; (*s_brave_allowlist)[ai_chat::prefs::kBraveAIChatUserCustomizationEnabled] = settings_api::PrefType::kBoolean; (*s_brave_allowlist)[ai_chat::prefs::kBraveAIChatUserMemoryEnabled] = diff --git a/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.html b/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.html index 36030a4bc3b..786a19c6dbf 100644 --- a/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.html +++ b/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.html @@ -42,12 +42,15 @@ You can obtain one at https://mozilla.org/MPL/2.0/. --> label="$i18n{braveLeoAssistantShowInContextMenuLabel}" sub-label="$i18n{braveLeoAssistantShowInContextMenuDesc}"> - - + diff --git a/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.ts b/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.ts index 32f0beac034..0b2d8c1973e 100644 --- a/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.ts +++ b/browser/resources/settings/brave_leo_assistant_page/brave_leo_assistant_page.ts @@ -13,7 +13,9 @@ import {Router} from '../router.js' import {loadTimeData} from '../i18n_setup.js' import {routes} from '../route.js'; import {getTemplate} from './brave_leo_assistant_page.html.js' -import {BraveLeoAssistantBrowserProxy, BraveLeoAssistantBrowserProxyImpl, PremiumStatus, ModelWithSubtitle, PremiumInfo, ModelAccess, Model} +import {BraveLeoAssistantBrowserProxy, + BraveLeoAssistantBrowserProxyImpl, PremiumStatus, + PremiumInfo} from './brave_leo_assistant_browser_proxy.js' const BraveLeoAssistantPageBase = @@ -48,12 +50,18 @@ class BraveLeoAssistantPageElement extends BraveLeoAssistantPageBase { type: Boolean, value: () => loadTimeData.getBoolean('isLeoAssistantHistoryAllowed') }, + isTabOrganizationFeatureEnabled_: { + type: Boolean, + value: () => loadTimeData.getBoolean( + 'isTabOrganizationFeatureEnabled') + }, } } private declare isPremiumUser_: boolean declare isHistoryFeatureEnabled_: boolean + declare isTabOrganizationFeatureEnabled_: boolean declare leoAssistantShowOnToolbarPref_: boolean premiumStatus_: PremiumStatus = PremiumStatus.Unknown browserProxy_: BraveLeoAssistantBrowserProxy = diff --git a/browser/resources/settings/brave_leo_assistant_page/model_selector.css b/browser/resources/settings/brave_leo_assistant_page/model_selector.css new file mode 100644 index 00000000000..9e077c36364 --- /dev/null +++ b/browser/resources/settings/brave_leo_assistant_page/model_selector.css @@ -0,0 +1,40 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +/* #css_wrapper_metadata_start + * #type=style-lit + * #css_wrapper_metadata_end */ + +.menu-item-with-icon { + --leo-icon-size: 20px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 22px; +} + +.model-subtitle { + font: var(--leo-font-small-regular); + color: var(--leo-color-text-tertiary); + padding: 0; + margin: 0; +} + +.menu-section-title { + background-color: var(--leo-color-page-background); + padding: var(--leo-spacing-l) var(--leo-spacing-xl); + color: var(--leo-color-text-tertiary); + font: var(--leo-font-components-label); + text-transform: uppercase; +} + +leo-dropdown { + min-width: 240px; +} + +leo-option { + padding: var(--leo-spacing-m); +} diff --git a/browser/resources/settings/brave_leo_assistant_page/model_selector.html.ts b/browser/resources/settings/brave_leo_assistant_page/model_selector.html.ts new file mode 100644 index 00000000000..e001a25ab41 --- /dev/null +++ b/browser/resources/settings/brave_leo_assistant_page/model_selector.html.ts @@ -0,0 +1,51 @@ +// Copyright (c) 2026 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +import {html, nothing} from + '//resources/lit/v3_0/lit.rollup.js' + +import type {LeoModelSelectorElement} from + './model_selector.js' + +export function getHtml(this: LeoModelSelectorElement) { + return html` + +
${this.selectedDisplayName}
+ + ${this.models.map((entry) => html` + + + + `)} +
+ ` +} diff --git a/browser/resources/settings/brave_leo_assistant_page/model_selector.ts b/browser/resources/settings/brave_leo_assistant_page/model_selector.ts new file mode 100644 index 00000000000..80bfeec1722 --- /dev/null +++ b/browser/resources/settings/brave_leo_assistant_page/model_selector.ts @@ -0,0 +1,74 @@ +/* Copyright (c) 2026 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +import 'chrome://resources/brave/leo.bundle.js' + +import {CrLitElement} from + '//resources/lit/v3_0/lit.rollup.js' + +import { + ModelWithSubtitle, + ModelAccess, +} from './brave_leo_assistant_browser_proxy.js' +import {getCss} from './model_selector.css.js' +import {getHtml} from './model_selector.html.js' + +export class LeoModelSelectorElement extends CrLitElement { + static get is() { + return 'leo-model-selector' + } + + static override get properties() { + return { + selectedKey: {type: String}, + models: {type: Array}, + isPremiumUser: {type: Boolean}, + } + } + + static override get styles() { + return getCss() + } + + override render() { + return getHtml.bind(this)() + } + + accessor selectedKey: string = '' + accessor models: ModelWithSubtitle[] = [] + accessor isPremiumUser: boolean = false + + get selectedDisplayName(): string { + return this.models?.find( + (entry) => entry.model.key === this.selectedKey + )?.model.displayName ?? '' + } + + onSelectionChange_(e: any) { + this.dispatchEvent(new CustomEvent('model-changed', { + detail: {value: e.value}, + bubbles: true, + composed: true, + })) + } + + shouldShowPremiumLabel_(entry: ModelWithSubtitle): + boolean { + if (!entry.model.options.leoModelOptions) { + return false + } + return entry.model.options.leoModelOptions.access + === ModelAccess.PREMIUM && !this.isPremiumUser + } +} + +declare global { + interface HTMLElementTagNameMap { + 'leo-model-selector': LeoModelSelectorElement + } +} + +customElements.define( + LeoModelSelectorElement.is, LeoModelSelectorElement) diff --git a/browser/resources/settings/brave_leo_assistant_page/personalization.html b/browser/resources/settings/brave_leo_assistant_page/personalization.html index 2a14d149495..305ae829a30 100644 --- a/browser/resources/settings/brave_leo_assistant_page/personalization.html +++ b/browser/resources/settings/brave_leo_assistant_page/personalization.html @@ -11,37 +11,6 @@ You can obtain one at https://mozilla.org/MPL/2.0/. --> .main-header { font: var(--leo-font-heading-h4); } - - .menu-item-with-icon { - --leo-icon-size: 20px; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - gap: 22px; - } - - .model-subtitle { - font: var(--leo-font-small-regular); - color: var(--leo-color-text-tertiary); - padding: 0; - margin: 0; - } - - .menu-section-title { - background-color: var(--leo-color-page-background); - padding: var(--leo-spacing-l) var(--leo-spacing-xl); - color: var(--leo-color-text-tertiary); - font: var(--leo-font-components-label); - text-transform: uppercase; - } - leo-dropdown { - min-width: 240px; - } - - leo-option { - padding: var(--leo-spacing-m); - }
$i18n{braveLeoAssistantModelSelectionLabel}
- -
[[selectedModelDisplayName_]]
- - -
+ selected-key="[[defaultModelKeyPrefValue_]]" + models="[[models_]]" + is-premium-user="[[isPremiumUser_]]" + on-model-changed="onModelSelectionChange_"> + +