AI Chat: remove distinction between basic and freemium models, as they are all rate-limited at the same level
Fix labelling and rate-limit messaging and remove the "switch to basic model" button for rate-limiting (not for premium models for non-premium users)
This commit is contained in:
@@ -73,8 +73,8 @@ You can obtain one at https://mozilla.org/MPL/2.0/. -->
|
||||
<div>[[item.model.displayName]]</div>
|
||||
<p class="model-subtitle">[[item.subtitle]]</p>
|
||||
</div>
|
||||
<template is="dom-if" if="[[isModelPremium_(item.model.access)]]">
|
||||
<leo-icon name="lock-plain"></leo-icon>
|
||||
<template is="dom-if" if="[[shouldShowModelPremiumLabel_(item.model.access)]]">
|
||||
<leo-label mode="outline" color="blue">$i18n{braveLeoPremiumLabelNonPremium}</leo-label>
|
||||
</template>
|
||||
</div>
|
||||
</leo-option>
|
||||
@@ -85,7 +85,7 @@ You can obtain one at https://mozilla.org/MPL/2.0/. -->
|
||||
label="$i18n{braveLeoAssistantAutocompleteLink}"
|
||||
on-click="openAutocompleteSetting_">
|
||||
</cr-link-row>
|
||||
<template is="dom-if" if="[[shouldShowManageSubscriptionLink_]]">
|
||||
<template is="dom-if" if="[[isPremium_]]">
|
||||
<cr-link-row on-click="openManageAccountPage_" external="true" class="hr" label="$i18n{braveLeoAssistantManageUrlLabel}"></cr-link-row>
|
||||
</template>
|
||||
<div class="settings-box " on-click="onResetAssistantData_">
|
||||
|
||||
@@ -45,14 +45,15 @@ class BraveLeoAssistantPageElement extends BraveLeoAssistantPageBase {
|
||||
type: String,
|
||||
computed: 'computeDisplayName_(models_, defaultModelKeyPrefValue_)'
|
||||
},
|
||||
shouldShowManageSubscriptionLink_: {
|
||||
isPremiumUser_: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
computed: 'computeShouldShowManageSubscriptionLink_(premiumStatus_)'
|
||||
computed: 'computeIsPremiumUser_(premiumStatus_)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isPremiumUser_: boolean
|
||||
leoAssistantShowOnToolbarPref_: boolean
|
||||
defaultModelKeyPrefValue_: string
|
||||
models_: ModelWithSubtitle[]
|
||||
@@ -121,14 +122,6 @@ class BraveLeoAssistantPageElement extends BraveLeoAssistantPageBase {
|
||||
return model.model.displayName
|
||||
}
|
||||
|
||||
isModelPremium_(modelAccess: ModelAccess) {
|
||||
if (modelAccess === ModelAccess.PREMIUM) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
onModelSelectionChange_(e: any) {
|
||||
this.setPrefValue(MODEL_PREF_PATH, e.value)
|
||||
this.defaultModelKeyPrefValue_ = e.value
|
||||
@@ -155,14 +148,18 @@ class BraveLeoAssistantPageElement extends BraveLeoAssistantPageBase {
|
||||
Router.getInstance().navigateTo(routes.APPEARANCE, new URLSearchParams("highlight=#autocomplete-suggestion-sources"))
|
||||
}
|
||||
|
||||
computeShouldShowManageSubscriptionLink_() {
|
||||
if (this.premiumStatus_ === PremiumStatus.Active) {
|
||||
computeIsPremiumUser_() {
|
||||
if (this.premiumStatus_ === PremiumStatus.Active || this.premiumStatus_ === PremiumStatus.ActiveDisconnected) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
shouldShowModelPremiumLabel_(modelAccess: ModelAccess) {
|
||||
return (modelAccess === ModelAccess.PREMIUM && !this.isPremiumUser_)
|
||||
}
|
||||
|
||||
openManageAccountPage_() {
|
||||
window.open(this.manageUrl_, "_self", "noopener noreferrer")
|
||||
}
|
||||
|
||||
@@ -419,6 +419,8 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source,
|
||||
IDS_SETTINGS_LEO_ASSISTANT_CLEAR_HISTORY_DATA_LABEL},
|
||||
{"leoClearHistoryDataSubLabel",
|
||||
IDS_SETTINGS_LEO_ASSISTANT_CLEAR_HISTORY_DATA_SUBLABEL},
|
||||
{"braveLeoPremiumLabelNonPremium",
|
||||
IDS_CHAT_UI_MODEL_PREMIUM_LABEL_NON_PREMIUM},
|
||||
{"braveLeoAssistantModelSelectionLabel",
|
||||
IDS_SETTINGS_LEO_ASSISTANT_MODEL_SELECTION_LABEL},
|
||||
{"braveLeoModelCategory-chat", IDS_CHAT_UI_MODEL_CATEGORY_CHAT},
|
||||
|
||||
@@ -37,9 +37,8 @@ base::span<const webui::LocalizedString> GetLocalizedStrings() {
|
||||
{"introMessage-chat-claude-sonnet",
|
||||
IDS_CHAT_UI_INTRO_MESSAGE_CHAT_LEO_CLAUDE_SONNET},
|
||||
{"modelNameSyntax", IDS_CHAT_UI_MODEL_NAME_SYNTAX},
|
||||
{"modelFreemiumLabelNonPremium",
|
||||
IDS_CHAT_UI_MODEL_FREEMIUM_LABEL_NON_PREMIUM},
|
||||
{"modelFreemiumLabelPremium", IDS_CHAT_UI_MODEL_FREEMIUM_LABEL_PREMIUM},
|
||||
{"modelPremiumLabelNonPremium",
|
||||
IDS_CHAT_UI_MODEL_PREMIUM_LABEL_NON_PREMIUM},
|
||||
{"modelCategory-chat", IDS_CHAT_UI_MODEL_CATEGORY_CHAT},
|
||||
{"menuNewChat", IDS_CHAT_UI_MENU_NEW_CHAT},
|
||||
{"menuGoPremium", IDS_CHAT_UI_MENU_GO_PREMIUM},
|
||||
|
||||
@@ -1130,6 +1130,7 @@ void ConversationDriver::OnPremiumStatusReceived(
|
||||
// Maybe switch to premium model when user is newly premium and on a basic
|
||||
// model
|
||||
const bool should_switch_model =
|
||||
features::kFreemiumAvailable.Get() &&
|
||||
// This isn't the first retrieval (that's handled in the constructor)
|
||||
last_premium_status_ != mojom::PremiumStatus::Unknown &&
|
||||
last_premium_status_ != premium_status &&
|
||||
|
||||
@@ -36,6 +36,9 @@ namespace ai_chat {
|
||||
// - Long conversation warning threshold: 100k * 0.80 = 80k tokens
|
||||
|
||||
const std::vector<ai_chat::mojom::Model>& GetAllModels() {
|
||||
// TODO(petemill): When removing kFreemiumAvailable flag, and not having any
|
||||
// BASIC and PREMIUM-only models, remove all the `switchToBasicModel`-related
|
||||
// functions.
|
||||
static const auto kFreemiumAccess =
|
||||
features::kFreemiumAvailable.Get() ? mojom::ModelAccess::BASIC_AND_PREMIUM
|
||||
: mojom::ModelAccess::PREMIUM;
|
||||
@@ -56,7 +59,11 @@ const std::vector<ai_chat::mojom::Model>& GetAllModels() {
|
||||
{"chat-basic", "llama-2-13b-chat", "Llama 2 13b", "Meta",
|
||||
conversation_api ? mojom::ModelEngineType::BRAVE_CONVERSATION_API
|
||||
: mojom::ModelEngineType::LLAMA_REMOTE,
|
||||
mojom::ModelCategory::CHAT, mojom::ModelAccess::BASIC, 8000, 9700},
|
||||
mojom::ModelCategory::CHAT,
|
||||
features::kFreemiumAvailable.Get()
|
||||
? mojom::ModelAccess::BASIC_AND_PREMIUM
|
||||
: mojom::ModelAccess::BASIC,
|
||||
8000, 9700},
|
||||
});
|
||||
return *kModels;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as React from 'react'
|
||||
import { getLocale } from '$web-common/locale'
|
||||
import Alert from '@brave/leo/react/alert'
|
||||
import Button from '@brave/leo/react/button'
|
||||
import getPageHandlerInstance, * as mojom from '../../api/page_handler'
|
||||
import getPageHandlerInstance from '../../api/page_handler'
|
||||
import DataContext from '../../state/context'
|
||||
import PremiumSuggestion from '../premium_suggestion'
|
||||
import styles from './alerts.module.scss'
|
||||
@@ -16,22 +16,6 @@ function ErrorRateLimit() {
|
||||
const context = React.useContext(DataContext)
|
||||
|
||||
if (!context.isPremiumUser) {
|
||||
// Freemium model with non-premium user has stricter rate limits. Secondary
|
||||
// action is to switch to completely free model.
|
||||
if (context.currentModel?.access === mojom.ModelAccess.BASIC_AND_PREMIUM) {
|
||||
return (
|
||||
<PremiumSuggestion
|
||||
title={getLocale('rateLimitReachedTitle')}
|
||||
description={getLocale('rateLimitReachedDesc')}
|
||||
secondaryActionButton={
|
||||
<Button kind='plain-faint' onClick={context.handleSwitchToBasicModelAndRetry}>
|
||||
{getLocale('switchToBasicModelButtonLabel')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<PremiumSuggestion
|
||||
title={getLocale('rateLimitReachedTitle')}
|
||||
|
||||
@@ -57,21 +57,13 @@ export default function FeatureMenu() {
|
||||
{getLocale(`braveLeoModelSubtitle-${model.key}`)}
|
||||
</p>
|
||||
</div>
|
||||
{model.access === mojom.ModelAccess.PREMIUM && (
|
||||
<Icon
|
||||
className={classnames({
|
||||
[styles.lockOpen]: context.isPremiumUser
|
||||
})}
|
||||
name={context.isPremiumUser ? 'lock-open' : 'lock-plain'}
|
||||
/>
|
||||
)}
|
||||
{model.access === mojom.ModelAccess.BASIC_AND_PREMIUM && (
|
||||
{model.access === mojom.ModelAccess.PREMIUM && !context.isPremiumUser && (
|
||||
<Label
|
||||
className={styles.modelFreemiumLabel}
|
||||
mode={context.isPremiumUser ? 'loud' : 'default'}
|
||||
className={styles.modelLabel}
|
||||
mode={'outline'}
|
||||
color='blue'
|
||||
>
|
||||
{context.isPremiumUser ? getLocale('modelFreemiumLabelPremium') : getLocale('modelFreemiumLabelNonPremium')}
|
||||
{getLocale('modelPremiumLabelNonPremium')}
|
||||
</Label>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modelFreemiumLabel {
|
||||
.modelLabel {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ export interface AIChatContext {
|
||||
updateShouldSendPageContents: (shouldSend: boolean) => void
|
||||
setInputText: (text: string) => void
|
||||
handleMaybeLater: () => void
|
||||
handleSwitchToBasicModelAndRetry: () => void
|
||||
submitInputTextToAPI: () => void
|
||||
resetSelectedActionType: () => void
|
||||
handleActionTypeClick: (actionType: mojom.ActionType) => void
|
||||
@@ -96,7 +95,6 @@ export const defaultContext: AIChatContext = {
|
||||
updateShouldSendPageContents: () => {},
|
||||
setInputText: () => {},
|
||||
handleMaybeLater: () => {},
|
||||
handleSwitchToBasicModelAndRetry: () => {},
|
||||
submitInputTextToAPI: () => {},
|
||||
resetSelectedActionType: () => {},
|
||||
handleActionTypeClick: () => {},
|
||||
|
||||
@@ -191,9 +191,11 @@ function DataContextProvider (props: DataContextProviderProps) {
|
||||
setCanShowPremiumPrompt(false)
|
||||
}
|
||||
|
||||
// TODO(petemill): rename to switchToNonPremiumModel as there are no longer
|
||||
// a different in limitations between basic and freemium models.
|
||||
const switchToBasicModel = () => {
|
||||
// Select the first non-premium model
|
||||
const nonPremium = allModels.find(m => m.access === mojom.ModelAccess.BASIC)
|
||||
const nonPremium = allModels.find(m => m.access !== mojom.ModelAccess.PREMIUM)
|
||||
if (!nonPremium) {
|
||||
console.error('Could not find a non-premium model!')
|
||||
return
|
||||
@@ -263,11 +265,6 @@ function DataContextProvider (props: DataContextProviderProps) {
|
||||
.then((res) => { setInputText(res.turn.text) })
|
||||
}
|
||||
|
||||
const handleSwitchToBasicModelAndRetry = () => {
|
||||
switchToBasicModel()
|
||||
getPageHandlerInstance().pageHandler.retryAPIRequest()
|
||||
}
|
||||
|
||||
const resetSelectedActionType = () => {
|
||||
setSelectedActionType(undefined)
|
||||
}
|
||||
@@ -428,7 +425,6 @@ function DataContextProvider (props: DataContextProviderProps) {
|
||||
updateShouldSendPageContents,
|
||||
setInputText,
|
||||
handleMaybeLater,
|
||||
handleSwitchToBasicModelAndRetry,
|
||||
submitInputTextToAPI,
|
||||
resetSelectedActionType,
|
||||
handleActionTypeClick,
|
||||
|
||||
@@ -15,14 +15,14 @@ provideStrings({
|
||||
acceptButtonLabel: 'Accept and begin',
|
||||
pageContentWarning: 'Disconnect to stop sending this page content to Leo, and start a new conversation',
|
||||
errorNetworkLabel: 'There was a network issue connecting to Leo, check your connection and try again.',
|
||||
errorRateLimit: 'Leo is too busy right now. Please try again in a few minutes.',
|
||||
errorRateLimit: 'You\'ve reached the premium rate limit. Please try again in a few hours.',
|
||||
retryButtonLabel: 'Retry',
|
||||
dismissButtonLabel: 'Dismiss',
|
||||
'introMessage-0': `I'm here to help. What can I assist you with today? $1Learn more$2`,
|
||||
'introMessage-1': 'I have a vast base of knowledge and a large memory able to help with more complex challenges. $1Learn more$2',
|
||||
modelNameSyntax: '$1 by $2',
|
||||
modelFreemiumLabelNonPremium: 'Limited',
|
||||
modelFreemiumLabelPremium: 'Unlimited',
|
||||
modelPremiumLabelNonPremium: 'Premium',
|
||||
'modelCategory-chat': 'Chat',
|
||||
menuNewChat: 'New chat',
|
||||
menuSettings: 'Advanced Settings',
|
||||
@@ -31,7 +31,7 @@ provideStrings({
|
||||
suggestQuestionsTitle: 'Suggest questions…',
|
||||
upgradeButtonLabel: 'Upgrade now',
|
||||
rateLimitReachedTitle: 'Response rate limit reached',
|
||||
rateLimitReachedDesc: "Unlock a higher response rate by subscribing to Premium. You can also switch to our less powerful Llama2 13b free model to continue.",
|
||||
rateLimitReachedDesc: "You've reached the rate limit for Leo. Unlock a higher response rate by subscribing to Premium, or try again soon.",
|
||||
premiumFeature_1: 'Explore different AI models',
|
||||
premiumFeature_1_desc: 'Priority access to powerful models with different skills',
|
||||
premiumFeature_2: 'Unlock your creativity',
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
There was a network issue connecting to Leo, check your connection and try again.
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_ERROR_RATE_LIMIT" desc="An error presented when the user has exhausted the API request limit">
|
||||
Leo is too busy right now. Please try again in a few minutes.
|
||||
You've reached the premium rate limit. Please try again in a few hours.
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_RETRY_BUTTON_LABEL" desc="A button label to retry API again">
|
||||
Retry
|
||||
@@ -66,11 +66,8 @@
|
||||
<message name="IDS_CHAT_UI_MODEL_NAME_SYNTAX" desc="Sentence structure for model name">
|
||||
<ph name="MODEL_NAME">$1<ex>llama2-13b</ex></ph> by <ph name="COMPANY_NAME">$2<ex>Meta</ex></ph>
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_MODEL_FREEMIUM_LABEL_NON_PREMIUM" desc="Label indentifying that a model is limited in functionality due to user's non-premium status">
|
||||
Limited
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_MODEL_FREEMIUM_LABEL_PREMIUM" desc="Label indentifying that a model is not limited in functionality as the user is a premium subscriber">
|
||||
Unlimited
|
||||
<message name="IDS_CHAT_UI_MODEL_PREMIUM_LABEL_NON_PREMIUM" desc="Label indentifying that an AI Chat model is a premium model">
|
||||
Premium
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_MODEL_CATEGORY_CHAT" desc="Category name for Chat">
|
||||
Chat
|
||||
@@ -97,7 +94,7 @@
|
||||
Response rate limit reached
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_RATE_LIMIT_REACHED_DESC" desc="A description to unlock premium features">
|
||||
Unlock a higher response rate by subscribing to Premium. You can also switch to our less powerful Llama2 13b free model to continue.
|
||||
You've reached the rate limit for Leo. Unlock a higher response rate by subscribing to Premium, or try again soon.
|
||||
</message>
|
||||
<message name="IDS_CHAT_UI_PREMIUM_FEATURE_1" desc="A premium feature">
|
||||
Explore different AI models
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import '@brave/leo/web-components/button'
|
||||
import '@brave/leo/web-components/dropdown'
|
||||
import '@brave/leo/web-components/checkbox'
|
||||
import '@brave/leo/web-components/label'
|
||||
import '@brave/leo/web-components/progressRing'
|
||||
import '@brave/leo/web-components/toggle'
|
||||
import { setIconBasePath } from '@brave/leo/web-components/icon'
|
||||
|
||||
Reference in New Issue
Block a user