WorkbenchRateLimiter.mjs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // @ts-check
  2. import SplitTestHandler from '../../Features/SplitTests/SplitTestHandler.mjs'
  3. import SplitTestUserGetter from '../../Features/SplitTests/SplitTestUserGetter.mjs'
  4. import UserGetter from '../../Features/User/UserGetter.mjs'
  5. import TokenUsageRateLimiter from './TokenUsageRateLimiter.mjs'
  6. /** @typedef {{usage?: number | null, periodStart?: Date | null}} FeatureUsage */
  7. const DEFAULT_USER_TOKEN_ALLOWANCE = 8_000_000
  8. const ALPHA_USER_TOKEN_ALLOWANCE = 8_000_000
  9. class WorkbenchRateLimiter extends TokenUsageRateLimiter {
  10. constructor() {
  11. super('aiWorkbench')
  12. }
  13. /**
  14. * @param {string} userId
  15. * @returns {Promise<number>}
  16. */
  17. async _getAllowance(userId) {
  18. const splitTestAssignment =
  19. await SplitTestHandler.promises.getAssignmentForUser(
  20. userId,
  21. 'ai-workbench-release'
  22. )
  23. const inSplitTest = splitTestAssignment.variant === 'enabled'
  24. if (!inSplitTest) {
  25. return 0
  26. }
  27. const user = await UserGetter.promises.getUser(userId, {
  28. features: 1,
  29. writefull: 1,
  30. ...SplitTestUserGetter.getProjection('plans-2026-phase-1'),
  31. })
  32. if (user?.alphaProgram) {
  33. return ALPHA_USER_TOKEN_ALLOWANCE
  34. }
  35. // todo: quota clean-up: remove split test
  36. let hasAddOn
  37. const inQuotaSplitTest =
  38. await SplitTestHandler.promises.featureFlagEnabledForMongoUser(
  39. user,
  40. 'plans-2026-phase-1'
  41. )
  42. if (inQuotaSplitTest) {
  43. // post rollout, all users have the same token limit (fair usage)
  44. return DEFAULT_USER_TOKEN_ALLOWANCE
  45. } else {
  46. hasAddOn = user.features.aiErrorAssistant || user.writefull?.isPremium
  47. return hasAddOn ? DEFAULT_USER_TOKEN_ALLOWANCE : 0
  48. }
  49. }
  50. }
  51. export default new WorkbenchRateLimiter()