Path: blob/master/src/packages/util/db-schema/purchase-quotas.ts
1447 views
import { CREATED_BY, ID } from "./crm";1import { SCHEMA as schema } from "./index";2import { LLM_USERNAMES } from "./llm-utils";3import type { Service } from "./purchases";4import { Table } from "./types";56export type { Service };78// Users will set their spend limits for these broad categories.9// TODO: right now there is a separate limit for each quota spec,10// which has got ridiculous.11const SERVICE_CATEGORIES = ["money", "compute", "license", "ai"];12type ServiceCategory = (typeof SERVICE_CATEGORIES)[number];1314export interface Spec {15display: string; // what to show user to describe this service16noSet?: boolean; // if true, then no spend limits are set for this.17color: string;18category: ServiceCategory;19// tooltip more detailed description20description?: string;21}2223export type QuotaSpec = Record<Service, Spec>;2425// for each category of service, this says whether or not it is a pay as you go service,26// which can impact how spend options are determined.27const IS_PAYG: { [name: ServiceCategory]: boolean } = {28money: false,29compute: true,30license: false,31ai: true,32} as const;3334export function isPaygService(service: Service): boolean {35const category = QUOTA_SPEC[service]?.category;36return IS_PAYG[category ?? ""] ?? false;37}3839const GPT_TURBO_128k: Spec = {40display: "OpenAI GPT-4 Turbo 128k",41color: "#10a37f",42category: "ai",43} as const;4445const GPT_TURBO_8K: Spec = {46...GPT_TURBO_128k,47display: "OpenAI GPT-4 Turbo",48} as const;4950const GPT_OMNI_128k: Spec = {51display: "OpenAI GPT-4o 128k",52color: "#10a37f",53category: "ai",54} as const;5556const GPT_OMNI_8K: Spec = {57...GPT_OMNI_128k,58display: "OpenAI GPT-4o",59} as const;6061const GPT_OMNI_MINI_128k: Spec = {62...GPT_OMNI_128k,63display: "OpenAI GPT-4o Mini 128k",64} as const;6566const GPT_OMNI_MINI_8K: Spec = {67...GPT_OMNI_MINI_128k,68display: "OpenAI GPT-4o Mini",69} as const;7071const GPT_41_8K: Spec = {72display: "OpenAI GPT-4.1",73color: "#10a37f",74category: "ai",75} as const;7677const GPT_41_MINI_8K: Spec = {78...GPT_41_8K,79display: "OpenAI GPT-4.1 Mini",80} as const;8182const GPT_O1_8K: Spec = {83...GPT_OMNI_128k,84display: "OpenAI o1",85} as const;8687const GPT_O1_MINI_8K: Spec = {88...GPT_O1_8K,89display: "OpenAI o1 mini",90} as const;9192const GOOGLE_AI_COLOR = "#ff4d4f";9394// NOTE: all-quotas-config.tsx will automatically filter out those, which are free or not selectable by the user95export const QUOTA_SPEC: QuotaSpec = {96credit: {97display: "Credit",98noSet: true,99color: "green",100category: "money",101description:102"Credit that was added to your account as a result of a manual or subscription payment (e.g., from a credit card)",103},104"auto-credit": {105display: "Automatic Credit",106noSet: true,107color: "green",108category: "money",109description:110"Credited that was automatically added to your account as a result of a payment because of your balance became low.",111},112refund: {113display: "Refund",114noSet: true,115color: "red",116category: "money",117description:118"Money that was refunded to your account as a result of a support request.",119},120"compute-server": {121display: "Compute Server",122color: "#2196f3",123category: "compute",124description: "Charge for creating or using a compute server.",125},126"compute-server-network-usage": {127display: "Network Data",128color: "#2196f3",129category: "compute",130description: "Charge due to network traffic out of a compute server.",131},132"compute-server-storage": {133display: "Cloud Storage",134color: "#fbbd05",135category: "compute",136description: "Charge due to storage of data on a cloud filesystem.",137},138license: {139display: "License",140color: "cyan",141noSet: true,142category: "license",143description: "Purchase of a license from the store.",144},145"edit-license": {146display: "Edit License",147color: "gold",148noSet: true,149category: "license",150description:151"Charge or credit resulting from changing a license, which includes you manually editing the license, or the license being edited to extend the validity date on subscription renewal.",152},153voucher: {154display: "Voucher",155color: "#00238b",156noSet: true,157category: "money",158description: "Charge for purchasing a voucher.",159},160// ATTN: LLMs comes below this line, the quotas above are the important ones to show first!161"openai-gpt-4": { display: "OpenAI GPT-4", color: "#10a37f", category: "ai" },162"openai-gpt-3.5-turbo": {163display: "OpenAI GPT-3.5",164color: "#10a37f",165category: "ai",166},167"openai-gpt-3.5-turbo-16k": {168display: "OpenAI GPT-3.5 16k",169color: "#10a37f",170category: "ai",171},172"openai-text-embedding-ada-002": {173display: "OpenAI Text Embedding Ada 002",174color: "#10a37f",175noSet: true, // because this model is not user visible yet176category: "ai",177},178"openai-gpt-4-32k": {179display: "OpenAI GPT-4 32k",180color: "#10a37f",181category: "ai",182},183"openai-gpt-4-turbo-preview": GPT_TURBO_128k, // the "preview" is over184"openai-gpt-4-turbo-preview-8k": GPT_TURBO_8K, // the "preview" is over185"openai-gpt-4-turbo": GPT_TURBO_128k,186"openai-gpt-4-turbo-8k": GPT_TURBO_8K,187"openai-gpt-4o": GPT_OMNI_128k,188"openai-gpt-4o-8k": GPT_OMNI_8K,189"openai-gpt-4o-mini": GPT_OMNI_MINI_128k,190"openai-gpt-4o-mini-8k": GPT_OMNI_MINI_8K,191"openai-gpt-4.1": GPT_41_8K,192"openai-gpt-4.1-mini": GPT_41_MINI_8K,193"openai-o1-mini-8k": GPT_O1_8K,194"openai-o1-8k": GPT_O1_MINI_8K,195"openai-o1-mini": GPT_O1_8K,196"openai-o1": GPT_O1_MINI_8K,197"google-text-bison-001": {198display: "Google Palm 2 (Text)",199color: GOOGLE_AI_COLOR,200noSet: true, // deprecated, will be removed201category: "ai",202},203"google-chat-bison-001": {204display: "Google Palm 2 (Chat)",205color: GOOGLE_AI_COLOR,206noSet: true, // deprecated, will be removed207category: "ai",208},209"google-embedding-gecko-001": {210display: "Google Gecko (Embedding)",211color: GOOGLE_AI_COLOR,212noSet: true, // deprecated, will be removed213category: "ai",214},215"google-gemini-1.5-flash-8k": {216display: "Google Gemini 1.5 Flash",217color: GOOGLE_AI_COLOR,218category: "ai",219},220"google-gemini-pro": {221display: "Google Gemini 1.0 Pro",222color: GOOGLE_AI_COLOR,223category: "ai",224},225"google-gemini-1.0-ultra": {226display: "Google Gemini 1.0 Ultra",227color: GOOGLE_AI_COLOR,228category: "ai",229},230"google-gemini-1.5-pro-8k": {231display: LLM_USERNAMES["gemini-1.5-pro-8k"],232color: GOOGLE_AI_COLOR,233category: "ai",234},235"google-gemini-1.5-pro": {236display: LLM_USERNAMES["gemini-1.5-pro"],237color: GOOGLE_AI_COLOR,238category: "ai",239},240"google-gemini-2.0-flash-8k": {241display: LLM_USERNAMES["gemini-2.0-flash-8k"],242color: GOOGLE_AI_COLOR,243category: "ai",244},245"google-gemini-2.0-flash-lite-8k": {246display: LLM_USERNAMES["gemini-2.0-flash-lite-8k"],247color: GOOGLE_AI_COLOR,248category: "ai",249},250"anthropic-claude-3-opus": {251display: LLM_USERNAMES["claude-3-opus"],252color: "#181818",253category: "ai",254},255"anthropic-claude-3-opus-8k": {256display: LLM_USERNAMES["claude-3-opus-8k"],257color: "#181818",258category: "ai",259},260"anthropic-claude-3-sonnet": {261display: LLM_USERNAMES["claude-3-sonnet"],262color: "#181818",263category: "ai",264},265"anthropic-claude-3-sonnet-4k": {266display: LLM_USERNAMES["claude-3-sonnet-4k"],267color: "#181818",268category: "ai",269},270"anthropic-claude-3-5-sonnet": {271display: LLM_USERNAMES["claude-3-5-sonnet"],272color: "#181818",273category: "ai",274},275"anthropic-claude-3-5-sonnet-4k": {276display: LLM_USERNAMES["claude-3-5-sonnet-4k"],277color: "#181818",278category: "ai",279},280"anthropic-claude-3-haiku": {281display: LLM_USERNAMES["claude-3-haiku"],282color: "#181818",283category: "ai",284},285"anthropic-claude-3-haiku-8k": {286display: LLM_USERNAMES["claude-3-haiku-8k"],287color: "#181818",288category: "ai",289},290"mistralai-mistral-small-latest": {291display: LLM_USERNAMES["mistral-small-latest"],292color: "#ff7000", // the orange from their website293category: "ai",294},295"mistralai-mistral-medium-latest": {296display: LLM_USERNAMES["mistral-medium-latest"],297color: "#ff7000", // the orange from their website298category: "ai",299},300"mistralai-mistral-large-latest": {301display: LLM_USERNAMES["mistral-large-latest"],302color: "#ff7000", // the orange from their website303category: "ai",304},305"project-upgrade": {306display: "Project Upgrade",307color: "#5bc0de",308category: "compute",309description:310"Charge resulting from using pay as you go upgrades to a project.",311},312} as const;313314// For pay-as-you-go project quota upgrades315export interface ProjectQuota {316cost?: number; // dollars per hour317enabled?: number;318cores?: number;319disk_quota?: number;320memory?: number;321mintime?: number;322network?: number;323member_host?: number;324always_running?: number;325}326327export const PROJECT_QUOTA_KEYS = new Set<string>([328"enabled",329"cost",330"cores",331"disk_quota",332"memory",333"mintime",334"network",335"member_host",336"always_running",337]);338339export function serviceToDisplay(service: Service): string {340return QUOTA_SPEC[service]?.display ?? service;341}342343Table({344name: "purchase_quotas",345fields: {346id: ID,347account_id: CREATED_BY,348service: {349title: "Service Category",350desc: "The service being charged for, e.g., openai-gpt-4, project-upgrade, etc.",351type: "string",352pg_type: "varchar(127)",353},354value: {355title: "Value",356desc: "The maximum amount that user can be charged for this service during one month billing period, in US dollars.",357type: "number", // actually comes back as string in queries.358pg_type: "REAL",359},360},361rules: {362desc: "Purchase Quotas",363primary_key: "id",364// make it fast to find all quotas for a given account365pg_indexes: ["account_id"],366// enforce that there is only one quota for each service for a given account367pg_unique_indexes: ["(account_id,service)"],368user_query: {369// set happens though v2 api only to enforce global quota370get: {371pg_where: [{ "account_id = $::UUID": "account_id" }],372fields: {373id: null,374account_id: null,375service: null,376value: null,377},378},379},380},381});382383Table({384name: "crm_purchase_quotas",385rules: {386virtual: "purchase_quotas",387primary_key: "id",388user_query: {389get: {390pg_where: [],391admin: true,392fields: {393id: null,394account_id: null,395service: null,396value: null,397},398},399set: {400admin: true,401fields: {402id: true,403account_id: true,404service: true,405value: true,406},407},408},409},410fields: schema.purchase_quotas.fields,411});412413414