mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
Cleanup AiErrorAssistant todos post plans changes (#35067)
* feat: cleaning up ai quota leftovers fix: removing more straggler invos * fix: featureUpdater still need analyticsId in the user projection * feat: updating cypress tests to also check for fair usage text GitOrigin-RevId: 09c1167106c144084c111beea56867f6aa4a0906
This commit is contained in:
committed by
Copybot
parent
275d381656
commit
ba76fda37b
@@ -18,10 +18,8 @@ async function _getInstitutionsAddons(userId) {
|
||||
)
|
||||
|
||||
// todo: seperate quota value depending on source of entitlement if needed
|
||||
// todo: quota clean-up: remove aiErrorAssistant once migration finishes
|
||||
const bundleFeatures = {
|
||||
aiUsageQuota: Settings.writefull.quotaTierGranted,
|
||||
aiErrorAssistant: true,
|
||||
}
|
||||
return hasAssistBundle ? bundleFeatures : {}
|
||||
}
|
||||
|
||||
@@ -492,7 +492,6 @@ const _ProjectController = {
|
||||
'editor-popup-ux-survey-03-2026',
|
||||
'chat-edit-delete',
|
||||
'comment-mentions',
|
||||
'ai-workbench-release',
|
||||
'compile-timeout-target-plans',
|
||||
'writefull-figure-generator',
|
||||
'writefull-toolbar-migration',
|
||||
|
||||
@@ -181,7 +181,7 @@ async function projectListPage(req, res, next) {
|
||||
userId,
|
||||
`email isAdmin emails features alphaProgram betaProgram lastPrimaryEmailCheck lastActive signUpDate ace refProviders${
|
||||
isSaas
|
||||
? ' enrollment writefull completedTutorials aiFeatures aiErrorAssistant labsProgram'
|
||||
? ' enrollment writefull completedTutorials aiFeatures labsProgram'
|
||||
: ''
|
||||
}`
|
||||
)
|
||||
@@ -538,8 +538,8 @@ async function projectListPage(req, res, next) {
|
||||
|
||||
const aiBlocked =
|
||||
Features.hasFeature('saas') && !(await _canUseAIAssist(user))
|
||||
const hasAiAssist =
|
||||
Features.hasFeature('saas') && (await _userHasAIAssist(user))
|
||||
const hasUnlimitedAi =
|
||||
Features.hasFeature('saas') && (await _userHasUnlimitedAiTier(user))
|
||||
|
||||
const splitTests = [
|
||||
// Split tests that will be made available to the frontend
|
||||
@@ -591,7 +591,7 @@ async function projectListPage(req, res, next) {
|
||||
best_subscription_type: usersBestSubscription.type,
|
||||
}),
|
||||
ai_blocked: aiBlocked,
|
||||
has_ai_assist: hasAiAssist,
|
||||
has_ai_assist: hasUnlimitedAi,
|
||||
...(subjectArea && { subject_area: subjectArea }),
|
||||
...(role && { role }),
|
||||
...(primaryOccupation && { primary_occupation: primaryOccupation }),
|
||||
@@ -951,18 +951,19 @@ function _hasActiveFilter(filters) {
|
||||
/**
|
||||
* @param {any} user
|
||||
*/
|
||||
async function _userHasAIAssist(user) {
|
||||
async function _userHasUnlimitedAiTier(user) {
|
||||
const hasPremiumAiFeatures =
|
||||
user.features?.aiUsageQuota === Settings.aiFeatures.unlimitedQuota
|
||||
// Check if the user has a non free trial version of our AI features
|
||||
|
||||
// Check if the user has highest tier version of our AI features
|
||||
if (hasPremiumAiFeatures) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if the user has AI Assist enabled via Writefull
|
||||
const { isPremium: hasAiAssistViaWritefull } =
|
||||
// Check if the user has Unlimited AI quota via Writefull
|
||||
const { isPremium: hasUnlimitedAiViaWritefull } =
|
||||
await UserGetter.promises.getWritefullData(user._id)
|
||||
if (hasAiAssistViaWritefull) {
|
||||
if (hasUnlimitedAiViaWritefull) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -365,10 +365,7 @@ function hasPlanAiEnabled(plan) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
plan.features.aiUsageQuota === Settings.aiFeatures.unlimitedQuota ||
|
||||
plan.features.aiErrorAssistant === true
|
||||
)
|
||||
return plan.features.aiUsageQuota === Settings.aiFeatures.unlimitedQuota
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import CustomerIoPlanHelpers from './CustomerIoPlanHelpers.mjs'
|
||||
import { GroupPolicy } from '../../models/GroupPolicy.mjs'
|
||||
import { AI_ADD_ON_CODE } from './AiHelper.mjs'
|
||||
import { fetchNothing } from '@overleaf/fetch-utils'
|
||||
import SplitTestUserGetter from '../SplitTests/SplitTestUserGetter.mjs'
|
||||
|
||||
/**
|
||||
* Enqueue a job for refreshing features for the given user
|
||||
@@ -46,8 +47,7 @@ async function refreshFeatures(userId, reason) {
|
||||
_id: 1,
|
||||
features: 1,
|
||||
email: 1,
|
||||
analyticsId: 1,
|
||||
labsProgram: 1,
|
||||
...SplitTestUserGetter.getProjection(),
|
||||
})
|
||||
const oldFeatures = _.clone(user.features)
|
||||
const features = await computeFeatures(userId)
|
||||
@@ -104,6 +104,7 @@ async function refreshFeatures(userId, reason) {
|
||||
json: {
|
||||
userOverleafId: userId,
|
||||
// todo: quota clean-up: collab with writefull to rename this, and check if still needed
|
||||
// AiAssist is legacy naming for our old one tier AI subscription, which is now our "Unlimited" quota tier
|
||||
hasAiAssist: hasPremiumAiFeatures,
|
||||
aiUsageQuota: newFeatures.aiUsageQuota,
|
||||
},
|
||||
@@ -271,7 +272,7 @@ async function _getIndividualFeatures(userId) {
|
||||
featureSets.push(_subscriptionToFeatures(subscription))
|
||||
}
|
||||
|
||||
// todo: quota clean-up - remove
|
||||
// todo: quota clean-up - remove once we finish transitioning all users to other plans
|
||||
// if they are in the quota split test, we no longer look at the add-on, since every plan will now have the same quota
|
||||
// standalone plan will receive correct state since their plan will provide the correct quota
|
||||
featureSets.push(_aiAddOnFeatures(subscription))
|
||||
@@ -323,8 +324,6 @@ function _subscriptionToFeatures(subscription) {
|
||||
function _aiAddOnFeatures(subscription) {
|
||||
if (subscription?.addOns?.some(addOn => addOn.addOnCode === AI_ADD_ON_CODE)) {
|
||||
return {
|
||||
// allow both naming systems to work
|
||||
aiErrorAssistant: true,
|
||||
aiUsageQuota: Settings.aiFeatures.unlimitedQuota,
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -9,8 +9,6 @@ import UserAuditLogHandler from '../../Features/User/UserAuditLogHandler.mjs'
|
||||
const PERIOD = 24 // hours
|
||||
const PERIOD_IN_MILLISECONDS = PERIOD * 60 * 60 * 1000
|
||||
|
||||
// todo: quota clean-up: extend this off base RateLimitController and unify behaviour where possible.
|
||||
|
||||
export default class TokenUsageRateLimiter {
|
||||
/**
|
||||
* @param {string} featureName
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
// @ts-check
|
||||
import SplitTestHandler from '../../Features/SplitTests/SplitTestHandler.mjs'
|
||||
import UserGetter from '../../Features/User/UserGetter.mjs'
|
||||
import TokenUsageRateLimiter from './TokenUsageRateLimiter.mjs'
|
||||
/** @typedef {{usage?: number | null, periodStart?: Date | null}} FeatureUsage */
|
||||
|
||||
const DEFAULT_USER_TOKEN_ALLOWANCE = 8_000_000
|
||||
const ALPHA_USER_TOKEN_ALLOWANCE = 8_000_000
|
||||
|
||||
class WorkbenchRateLimiter extends TokenUsageRateLimiter {
|
||||
constructor() {
|
||||
super('aiWorkbench')
|
||||
@@ -17,23 +13,6 @@ class WorkbenchRateLimiter extends TokenUsageRateLimiter {
|
||||
* @returns {Promise<number>}
|
||||
*/
|
||||
async _getAllowance(userId) {
|
||||
const splitTestAssignment =
|
||||
await SplitTestHandler.promises.getAssignmentForUser(
|
||||
userId,
|
||||
'ai-workbench-release'
|
||||
)
|
||||
const inSplitTest = splitTestAssignment.variant === 'enabled'
|
||||
if (!inSplitTest) {
|
||||
return 0
|
||||
}
|
||||
const user = await UserGetter.promises.getUser(userId, {
|
||||
alphaProgram: 1,
|
||||
})
|
||||
|
||||
if (user?.alphaProgram) {
|
||||
return ALPHA_USER_TOKEN_ALLOWANCE
|
||||
}
|
||||
|
||||
// all users have the same token limit (fair usage)
|
||||
return DEFAULT_USER_TOKEN_ALLOWANCE
|
||||
}
|
||||
|
||||
@@ -153,10 +153,6 @@ export const UserSchema = new Schema(
|
||||
type: Boolean,
|
||||
default: Settings.defaultFeatures.symbolPalette,
|
||||
},
|
||||
aiErrorAssistant: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
aiUsageQuota: { type: String, default: 'basic' },
|
||||
},
|
||||
featuresOverrides: [
|
||||
@@ -170,8 +166,6 @@ export const UserSchema = new Schema(
|
||||
expiresAt: { type: Date },
|
||||
note: { type: String },
|
||||
features: {
|
||||
// todo: quota clean-up: remove aiErrorAssistant
|
||||
aiErrorAssistant: { type: Boolean },
|
||||
aiUsageQuota: { type: String },
|
||||
collaborators: { type: Number },
|
||||
versioning: { type: Boolean },
|
||||
|
||||
Reference in New Issue
Block a user