From 8799c888e308b74061cc869d3a716d6105db03d3 Mon Sep 17 00:00:00 2001 From: takatost Date: Wed, 17 Jan 2024 15:02:27 +0800 Subject: [PATCH] fix: free quota type apply button missing (#2069) Co-authored-by: StyleZhang --- .github/workflows/api-model-runtime-tests.yml | 4 - .github/workflows/style.yml | 3 - api/.env.example | 4 +- api/config.py | 29 ++- api/core/hosting_configuration.py | 195 +++++++++--------- api/core/provider_manager.py | 33 ++- .../deduct_quota_when_messaeg_created.py | 8 +- .../model-provider-page/index.tsx | 8 +- .../provider-added-card/index.tsx | 4 +- .../provider-added-card/quota-panel.tsx | 8 +- .../provider-card/index.tsx | 3 +- .../model-provider-page/utils.ts | 3 + 12 files changed, 173 insertions(+), 129 deletions(-) diff --git a/.github/workflows/api-model-runtime-tests.yml b/.github/workflows/api-model-runtime-tests.yml index c2bd992f66..4366c842a9 100644 --- a/.github/workflows/api-model-runtime-tests.yml +++ b/.github/workflows/api-model-runtime-tests.yml @@ -4,10 +4,6 @@ on: pull_request: branches: - main - push: - branches: - - deploy/dev - - feat/model-runtime jobs: test: diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 926ea40b74..5b48e20f16 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -4,9 +4,6 @@ on: pull_request: branches: - main - push: - branches: - - deploy/dev concurrency: group: dep-${{ github.head_ref || github.run_id }} diff --git a/api/.env.example b/api/.env.example index 18c449a48b..a9d405e5db 100644 --- a/api/.env.example +++ b/api/.env.example @@ -102,10 +102,10 @@ NOTION_CLIENT_ID=you-client-id NOTION_INTERNAL_SECRET=you-internal-secret # Hosted Model Credentials -HOSTED_OPENAI_ENABLED=false HOSTED_OPENAI_API_KEY= HOSTED_OPENAI_API_BASE= HOSTED_OPENAI_API_ORGANIZATION= +HOSTED_OPENAI_TRIAL_ENABLED=false HOSTED_OPENAI_QUOTA_LIMIT=200 HOSTED_OPENAI_PAID_ENABLED=false @@ -114,9 +114,9 @@ HOSTED_AZURE_OPENAI_API_KEY= HOSTED_AZURE_OPENAI_API_BASE= HOSTED_AZURE_OPENAI_QUOTA_LIMIT=200 -HOSTED_ANTHROPIC_ENABLED=false HOSTED_ANTHROPIC_API_BASE= HOSTED_ANTHROPIC_API_KEY= +HOSTED_ANTHROPIC_TRIAL_ENABLED=false HOSTED_ANTHROPIC_QUOTA_LIMIT=600000 HOSTED_ANTHROPIC_PAID_ENABLED=false diff --git a/api/config.py b/api/config.py index f121761306..157d012991 100644 --- a/api/config.py +++ b/api/config.py @@ -39,13 +39,19 @@ DEFAULTS = { 'CELERY_BACKEND': 'database', 'LOG_LEVEL': 'INFO', 'HOSTED_OPENAI_QUOTA_LIMIT': 200, - 'HOSTED_OPENAI_ENABLED': 'False', + 'HOSTED_OPENAI_TRIAL_ENABLED': 'False', 'HOSTED_OPENAI_PAID_ENABLED': 'False', + 'HOSTED_OPENAI_PAID_INCREASE_QUOTA': 1, + 'HOSTED_OPENAI_PAID_MIN_QUANTITY': 1, + 'HOSTED_OPENAI_PAID_MAX_QUANTITY': 1, 'HOSTED_AZURE_OPENAI_ENABLED': 'False', 'HOSTED_AZURE_OPENAI_QUOTA_LIMIT': 200, 'HOSTED_ANTHROPIC_QUOTA_LIMIT': 600000, - 'HOSTED_ANTHROPIC_ENABLED': 'False', + 'HOSTED_ANTHROPIC_TRIAL_ENABLED': 'False', 'HOSTED_ANTHROPIC_PAID_ENABLED': 'False', + 'HOSTED_ANTHROPIC_PAID_INCREASE_QUOTA': 1, + 'HOSTED_ANTHROPIC_PAID_MIN_QUANTITY': 1, + 'HOSTED_ANTHROPIC_PAID_MAX_QUANTITY': 1, 'HOSTED_MODERATION_ENABLED': 'False', 'HOSTED_MODERATION_PROVIDERS': '', 'CLEAN_DAY_SETTING': 30, @@ -66,7 +72,8 @@ def get_env(key): def get_bool_env(key): - return get_env(key).lower() == 'true' + value = get_env(key) + return value.lower() == 'true' if value is not None else False def get_cors_allow_origins(env, default): @@ -260,23 +267,35 @@ class Config: # ------------------------ # Platform Configurations. # ------------------------ - self.HOSTED_OPENAI_ENABLED = get_bool_env('HOSTED_OPENAI_ENABLED') self.HOSTED_OPENAI_API_KEY = get_env('HOSTED_OPENAI_API_KEY') self.HOSTED_OPENAI_API_BASE = get_env('HOSTED_OPENAI_API_BASE') self.HOSTED_OPENAI_API_ORGANIZATION = get_env('HOSTED_OPENAI_API_ORGANIZATION') + self.HOSTED_OPENAI_TRIAL_ENABLED = get_bool_env('HOSTED_OPENAI_TRIAL_ENABLED') self.HOSTED_OPENAI_QUOTA_LIMIT = int(get_env('HOSTED_OPENAI_QUOTA_LIMIT')) self.HOSTED_OPENAI_PAID_ENABLED = get_bool_env('HOSTED_OPENAI_PAID_ENABLED') + self.HOSTED_OPENAI_PAID_STRIPE_PRICE_ID = get_env('HOSTED_OPENAI_PAID_STRIPE_PRICE_ID') + self.HOSTED_OPENAI_PAID_INCREASE_QUOTA = int(get_env('HOSTED_OPENAI_PAID_INCREASE_QUOTA')) + self.HOSTED_OPENAI_PAID_MIN_QUANTITY = int(get_env('HOSTED_OPENAI_PAID_MIN_QUANTITY')) + self.HOSTED_OPENAI_PAID_MAX_QUANTITY = int(get_env('HOSTED_OPENAI_PAID_MAX_QUANTITY')) self.HOSTED_AZURE_OPENAI_ENABLED = get_bool_env('HOSTED_AZURE_OPENAI_ENABLED') self.HOSTED_AZURE_OPENAI_API_KEY = get_env('HOSTED_AZURE_OPENAI_API_KEY') self.HOSTED_AZURE_OPENAI_API_BASE = get_env('HOSTED_AZURE_OPENAI_API_BASE') self.HOSTED_AZURE_OPENAI_QUOTA_LIMIT = int(get_env('HOSTED_AZURE_OPENAI_QUOTA_LIMIT')) - self.HOSTED_ANTHROPIC_ENABLED = get_bool_env('HOSTED_ANTHROPIC_ENABLED') self.HOSTED_ANTHROPIC_API_BASE = get_env('HOSTED_ANTHROPIC_API_BASE') self.HOSTED_ANTHROPIC_API_KEY = get_env('HOSTED_ANTHROPIC_API_KEY') + self.HOSTED_ANTHROPIC_TRIAL_ENABLED = get_bool_env('HOSTED_ANTHROPIC_TRIAL_ENABLED') self.HOSTED_ANTHROPIC_QUOTA_LIMIT = int(get_env('HOSTED_ANTHROPIC_QUOTA_LIMIT')) self.HOSTED_ANTHROPIC_PAID_ENABLED = get_bool_env('HOSTED_ANTHROPIC_PAID_ENABLED') + self.HOSTED_ANTHROPIC_PAID_STRIPE_PRICE_ID = get_env('HOSTED_ANTHROPIC_PAID_STRIPE_PRICE_ID') + self.HOSTED_ANTHROPIC_PAID_INCREASE_QUOTA = int(get_env('HOSTED_ANTHROPIC_PAID_INCREASE_QUOTA')) + self.HOSTED_ANTHROPIC_PAID_MIN_QUANTITY = int(get_env('HOSTED_ANTHROPIC_PAID_MIN_QUANTITY')) + self.HOSTED_ANTHROPIC_PAID_MAX_QUANTITY = int(get_env('HOSTED_ANTHROPIC_PAID_MAX_QUANTITY')) + + self.HOSTED_MINIMAX_ENABLED = get_bool_env('HOSTED_MINIMAX_ENABLED') + self.HOSTED_SPARK_ENABLED = get_bool_env('HOSTED_SPARK_ENABLED') + self.HOSTED_ZHIPUAI_ENABLED = get_bool_env('HOSTED_ZHIPUAI_ENABLED') self.HOSTED_MODERATION_ENABLED = get_bool_env('HOSTED_MODERATION_ENABLED') self.HOSTED_MODERATION_PROVIDERS = get_env('HOSTED_MODERATION_PROVIDERS') diff --git a/api/core/hosting_configuration.py b/api/core/hosting_configuration.py index 2273287cdc..124d57354e 100644 --- a/api/core/hosting_configuration.py +++ b/api/core/hosting_configuration.py @@ -1,9 +1,8 @@ -import os from typing import Optional from core.entities.provider_entities import QuotaUnit, RestrictModel from core.model_runtime.entities.model_entities import ModelType -from flask import Flask +from flask import Flask, Config from models.provider import ProviderQuotaType from pydantic import BaseModel @@ -48,46 +47,47 @@ class HostingConfiguration: moderation_config: HostedModerationConfig = None def init_app(self, app: Flask) -> None: - if app.config.get('EDITION') != 'CLOUD': + config = app.config + + if config.get('EDITION') != 'CLOUD': return - self.provider_map["azure_openai"] = self.init_azure_openai() - self.provider_map["openai"] = self.init_openai() - self.provider_map["anthropic"] = self.init_anthropic() - self.provider_map["minimax"] = self.init_minimax() - self.provider_map["spark"] = self.init_spark() - self.provider_map["zhipuai"] = self.init_zhipuai() + self.provider_map["azure_openai"] = self.init_azure_openai(config) + self.provider_map["openai"] = self.init_openai(config) + self.provider_map["anthropic"] = self.init_anthropic(config) + self.provider_map["minimax"] = self.init_minimax(config) + self.provider_map["spark"] = self.init_spark(config) + self.provider_map["zhipuai"] = self.init_zhipuai(config) - self.moderation_config = self.init_moderation_config() + self.moderation_config = self.init_moderation_config(config) - def init_azure_openai(self) -> HostingProvider: + def init_azure_openai(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TIMES - if os.environ.get("HOSTED_AZURE_OPENAI_ENABLED") and os.environ.get("HOSTED_AZURE_OPENAI_ENABLED").lower() == 'true': + if app_config.get("HOSTED_AZURE_OPENAI_ENABLED"): credentials = { - "openai_api_key": os.environ.get("HOSTED_AZURE_OPENAI_API_KEY"), - "openai_api_base": os.environ.get("HOSTED_AZURE_OPENAI_API_BASE"), + "openai_api_key": app_config.get("HOSTED_AZURE_OPENAI_API_KEY"), + "openai_api_base": app_config.get("HOSTED_AZURE_OPENAI_API_BASE"), "base_model_name": "gpt-35-turbo" } quotas = [] - hosted_quota_limit = int(os.environ.get("HOSTED_AZURE_OPENAI_QUOTA_LIMIT", "1000")) - if hosted_quota_limit != -1 or hosted_quota_limit > 0: - trial_quota = TrialHostingQuota( - quota_limit=hosted_quota_limit, - restrict_models=[ - RestrictModel(model="gpt-4", base_model_name="gpt-4", model_type=ModelType.LLM), - RestrictModel(model="gpt-4-32k", base_model_name="gpt-4-32k", model_type=ModelType.LLM), - RestrictModel(model="gpt-4-1106-preview", base_model_name="gpt-4-1106-preview", model_type=ModelType.LLM), - RestrictModel(model="gpt-4-vision-preview", base_model_name="gpt-4-vision-preview", model_type=ModelType.LLM), - RestrictModel(model="gpt-35-turbo", base_model_name="gpt-35-turbo", model_type=ModelType.LLM), - RestrictModel(model="gpt-35-turbo-1106", base_model_name="gpt-35-turbo-1106", model_type=ModelType.LLM), - RestrictModel(model="gpt-35-turbo-instruct", base_model_name="gpt-35-turbo-instruct", model_type=ModelType.LLM), - RestrictModel(model="gpt-35-turbo-16k", base_model_name="gpt-35-turbo-16k", model_type=ModelType.LLM), - RestrictModel(model="text-davinci-003", base_model_name="text-davinci-003", model_type=ModelType.LLM), - RestrictModel(model="text-embedding-ada-002", base_model_name="text-embedding-ada-002", model_type=ModelType.TEXT_EMBEDDING), - ] - ) - quotas.append(trial_quota) + hosted_quota_limit = int(app_config.get("HOSTED_AZURE_OPENAI_QUOTA_LIMIT", "1000")) + trial_quota = TrialHostingQuota( + quota_limit=hosted_quota_limit, + restrict_models=[ + RestrictModel(model="gpt-4", base_model_name="gpt-4", model_type=ModelType.LLM), + RestrictModel(model="gpt-4-32k", base_model_name="gpt-4-32k", model_type=ModelType.LLM), + RestrictModel(model="gpt-4-1106-preview", base_model_name="gpt-4-1106-preview", model_type=ModelType.LLM), + RestrictModel(model="gpt-4-vision-preview", base_model_name="gpt-4-vision-preview", model_type=ModelType.LLM), + RestrictModel(model="gpt-35-turbo", base_model_name="gpt-35-turbo", model_type=ModelType.LLM), + RestrictModel(model="gpt-35-turbo-1106", base_model_name="gpt-35-turbo-1106", model_type=ModelType.LLM), + RestrictModel(model="gpt-35-turbo-instruct", base_model_name="gpt-35-turbo-instruct", model_type=ModelType.LLM), + RestrictModel(model="gpt-35-turbo-16k", base_model_name="gpt-35-turbo-16k", model_type=ModelType.LLM), + RestrictModel(model="text-davinci-003", base_model_name="text-davinci-003", model_type=ModelType.LLM), + RestrictModel(model="text-embedding-ada-002", base_model_name="text-embedding-ada-002", model_type=ModelType.TEXT_EMBEDDING), + ] + ) + quotas.append(trial_quota) return HostingProvider( enabled=True, @@ -101,43 +101,44 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_openai(self) -> HostingProvider: + def init_openai(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TIMES - if os.environ.get("HOSTED_OPENAI_ENABLED") and os.environ.get("HOSTED_OPENAI_ENABLED").lower() == 'true': + quotas = [] + + if app_config.get("HOSTED_OPENAI_TRIAL_ENABLED"): + hosted_quota_limit = int(app_config.get("HOSTED_OPENAI_QUOTA_LIMIT", "200")) + trial_quota = TrialHostingQuota( + quota_limit=hosted_quota_limit, + restrict_models=[ + RestrictModel(model="gpt-3.5-turbo", model_type=ModelType.LLM), + RestrictModel(model="gpt-3.5-turbo-1106", model_type=ModelType.LLM), + RestrictModel(model="gpt-3.5-turbo-instruct", model_type=ModelType.LLM), + RestrictModel(model="gpt-3.5-turbo-16k", model_type=ModelType.LLM), + RestrictModel(model="text-davinci-003", model_type=ModelType.LLM), + RestrictModel(model="whisper-1", model_type=ModelType.SPEECH2TEXT), + ] + ) + quotas.append(trial_quota) + + if app_config.get("HOSTED_OPENAI_PAID_ENABLED"): + paid_quota = PaidHostingQuota( + stripe_price_id=app_config.get("HOSTED_OPENAI_PAID_STRIPE_PRICE_ID"), + increase_quota=int(app_config.get("HOSTED_OPENAI_PAID_INCREASE_QUOTA", "1")), + min_quantity=int(app_config.get("HOSTED_OPENAI_PAID_MIN_QUANTITY", "1")), + max_quantity=int(app_config.get("HOSTED_OPENAI_PAID_MAX_QUANTITY", "1")) + ) + quotas.append(paid_quota) + + if len(quotas) > 0: credentials = { - "openai_api_key": os.environ.get("HOSTED_OPENAI_API_KEY"), + "openai_api_key": app_config.get("HOSTED_OPENAI_API_KEY"), } - if os.environ.get("HOSTED_OPENAI_API_BASE"): - credentials["openai_api_base"] = os.environ.get("HOSTED_OPENAI_API_BASE") + if app_config.get("HOSTED_OPENAI_API_BASE"): + credentials["openai_api_base"] = app_config.get("HOSTED_OPENAI_API_BASE") - if os.environ.get("HOSTED_OPENAI_API_ORGANIZATION"): - credentials["openai_organization"] = os.environ.get("HOSTED_OPENAI_API_ORGANIZATION") - - quotas = [] - hosted_quota_limit = int(os.environ.get("HOSTED_OPENAI_QUOTA_LIMIT", "200")) - if hosted_quota_limit != -1 or hosted_quota_limit > 0: - trial_quota = TrialHostingQuota( - quota_limit=hosted_quota_limit, - restrict_models=[ - RestrictModel(model="gpt-3.5-turbo", model_type=ModelType.LLM), - RestrictModel(model="gpt-3.5-turbo-1106", model_type=ModelType.LLM), - RestrictModel(model="gpt-3.5-turbo-instruct", model_type=ModelType.LLM), - RestrictModel(model="gpt-3.5-turbo-16k", model_type=ModelType.LLM), - RestrictModel(model="text-davinci-003", model_type=ModelType.LLM), - ] - ) - quotas.append(trial_quota) - - if os.environ.get("HOSTED_OPENAI_PAID_ENABLED") and os.environ.get( - "HOSTED_OPENAI_PAID_ENABLED").lower() == 'true': - paid_quota = PaidHostingQuota( - stripe_price_id=os.environ.get("HOSTED_OPENAI_PAID_STRIPE_PRICE_ID"), - increase_quota=int(os.environ.get("HOSTED_OPENAI_PAID_INCREASE_QUOTA", "1")), - min_quantity=int(os.environ.get("HOSTED_OPENAI_PAID_MIN_QUANTITY", "1")), - max_quantity=int(os.environ.get("HOSTED_OPENAI_PAID_MAX_QUANTITY", "1")) - ) - quotas.append(paid_quota) + if app_config.get("HOSTED_OPENAI_API_ORGANIZATION"): + credentials["openai_organization"] = app_config.get("HOSTED_OPENAI_API_ORGANIZATION") return HostingProvider( enabled=True, @@ -151,33 +152,33 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_anthropic(self) -> HostingProvider: + def init_anthropic(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TOKENS - if os.environ.get("HOSTED_ANTHROPIC_ENABLED") and os.environ.get("HOSTED_ANTHROPIC_ENABLED").lower() == 'true': + quotas = [] + + if app_config.get("HOSTED_ANTHROPIC_TRIAL_ENABLED"): + hosted_quota_limit = int(app_config.get("HOSTED_ANTHROPIC_QUOTA_LIMIT", "0")) + trial_quota = TrialHostingQuota( + quota_limit=hosted_quota_limit + ) + quotas.append(trial_quota) + + if app_config.get("HOSTED_ANTHROPIC_PAID_ENABLED"): + paid_quota = PaidHostingQuota( + stripe_price_id=app_config.get("HOSTED_ANTHROPIC_PAID_STRIPE_PRICE_ID"), + increase_quota=int(app_config.get("HOSTED_ANTHROPIC_PAID_INCREASE_QUOTA", "1000000")), + min_quantity=int(app_config.get("HOSTED_ANTHROPIC_PAID_MIN_QUANTITY", "20")), + max_quantity=int(app_config.get("HOSTED_ANTHROPIC_PAID_MAX_QUANTITY", "100")) + ) + quotas.append(paid_quota) + + if len(quotas) > 0: credentials = { - "anthropic_api_key": os.environ.get("HOSTED_ANTHROPIC_API_KEY"), + "anthropic_api_key": app_config.get("HOSTED_ANTHROPIC_API_KEY"), } - if os.environ.get("HOSTED_ANTHROPIC_API_BASE"): - credentials["anthropic_api_url"] = os.environ.get("HOSTED_ANTHROPIC_API_BASE") - - quotas = [] - hosted_quota_limit = int(os.environ.get("HOSTED_ANTHROPIC_QUOTA_LIMIT", "0")) - if hosted_quota_limit != -1 or hosted_quota_limit > 0: - trial_quota = TrialHostingQuota( - quota_limit=hosted_quota_limit - ) - quotas.append(trial_quota) - - if os.environ.get("HOSTED_ANTHROPIC_PAID_ENABLED") and os.environ.get( - "HOSTED_ANTHROPIC_PAID_ENABLED").lower() == 'true': - paid_quota = PaidHostingQuota( - stripe_price_id=os.environ.get("HOSTED_ANTHROPIC_PAID_STRIPE_PRICE_ID"), - increase_quota=int(os.environ.get("HOSTED_ANTHROPIC_PAID_INCREASE_QUOTA", "1000000")), - min_quantity=int(os.environ.get("HOSTED_ANTHROPIC_PAID_MIN_QUANTITY", "20")), - max_quantity=int(os.environ.get("HOSTED_ANTHROPIC_PAID_MAX_QUANTITY", "100")) - ) - quotas.append(paid_quota) + if app_config.get("HOSTED_ANTHROPIC_API_BASE"): + credentials["anthropic_api_url"] = app_config.get("HOSTED_ANTHROPIC_API_BASE") return HostingProvider( enabled=True, @@ -191,9 +192,9 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_minimax(self) -> HostingProvider: + def init_minimax(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TOKENS - if os.environ.get("HOSTED_MINIMAX_ENABLED") and os.environ.get("HOSTED_MINIMAX_ENABLED").lower() == 'true': + if app_config.get("HOSTED_MINIMAX_ENABLED"): quotas = [FreeHostingQuota()] return HostingProvider( @@ -208,9 +209,9 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_spark(self) -> HostingProvider: + def init_spark(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TOKENS - if os.environ.get("HOSTED_SPARK_ENABLED") and os.environ.get("HOSTED_SPARK_ENABLED").lower() == 'true': + if app_config.get("HOSTED_SPARK_ENABLED"): quotas = [FreeHostingQuota()] return HostingProvider( @@ -225,9 +226,9 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_zhipuai(self) -> HostingProvider: + def init_zhipuai(self, app_config: Config) -> HostingProvider: quota_unit = QuotaUnit.TOKENS - if os.environ.get("HOSTED_ZHIPUAI_ENABLED") and os.environ.get("HOSTED_ZHIPUAI_ENABLED").lower() == 'true': + if app_config.get("HOSTED_ZHIPUAI_ENABLED"): quotas = [FreeHostingQuota()] return HostingProvider( @@ -242,12 +243,12 @@ class HostingConfiguration: quota_unit=quota_unit, ) - def init_moderation_config(self) -> HostedModerationConfig: - if os.environ.get("HOSTED_MODERATION_ENABLED") and os.environ.get("HOSTED_MODERATION_ENABLED").lower() == 'true' \ - and os.environ.get("HOSTED_MODERATION_PROVIDERS"): + def init_moderation_config(self, app_config: Config) -> HostedModerationConfig: + if app_config.get("HOSTED_MODERATION_ENABLED") \ + and app_config.get("HOSTED_MODERATION_PROVIDERS"): return HostedModerationConfig( enabled=True, - providers=os.environ.get("HOSTED_MODERATION_PROVIDERS").split(',') + providers=app_config.get("HOSTED_MODERATION_PROVIDERS").split(',') ) return HostedModerationConfig( diff --git a/api/core/provider_manager.py b/api/core/provider_manager.py index 12176dd608..fb20a87460 100644 --- a/api/core/provider_manager.py +++ b/api/core/provider_manager.py @@ -597,18 +597,28 @@ class ProviderManager: quota_configurations = [] for provider_quota in provider_hosting_configuration.quotas: if provider_quota.quota_type not in quota_type_to_provider_records_dict: - continue + if provider_quota.quota_type == ProviderQuotaType.FREE: + quota_configuration = QuotaConfiguration( + quota_type=provider_quota.quota_type, + quota_unit=provider_hosting_configuration.quota_unit, + quota_used=0, + quota_limit=0, + is_valid=False, + restrict_models=provider_quota.restrict_models + ) + else: + continue + else: + provider_record = quota_type_to_provider_records_dict[provider_quota.quota_type] - provider_record = quota_type_to_provider_records_dict[provider_quota.quota_type] - - quota_configuration = QuotaConfiguration( - quota_type=provider_quota.quota_type, - quota_unit=provider_hosting_configuration.quota_unit, - quota_used=provider_record.quota_used, - quota_limit=provider_record.quota_limit, - is_valid=provider_record.quota_limit > provider_record.quota_used or provider_record.quota_limit == -1, - restrict_models=provider_quota.restrict_models - ) + quota_configuration = QuotaConfiguration( + quota_type=provider_quota.quota_type, + quota_unit=provider_hosting_configuration.quota_unit, + quota_used=provider_record.quota_used, + quota_limit=provider_record.quota_limit, + is_valid=provider_record.quota_limit > provider_record.quota_used or provider_record.quota_limit == -1, + restrict_models=provider_quota.restrict_models + ) quota_configurations.append(quota_configuration) @@ -670,6 +680,7 @@ class ProviderManager: current_using_credentials = cached_provider_credentials else: current_using_credentials = {} + quota_configurations = [] return SystemConfiguration( enabled=True, diff --git a/api/events/event_handlers/deduct_quota_when_messaeg_created.py b/api/events/event_handlers/deduct_quota_when_messaeg_created.py index 848c79802b..dbd88fdb1c 100644 --- a/api/events/event_handlers/deduct_quota_when_messaeg_created.py +++ b/api/events/event_handlers/deduct_quota_when_messaeg_created.py @@ -23,12 +23,16 @@ def handle(sender, **kwargs): for quota_configuration in system_configuration.quota_configurations: if quota_configuration.quota_type == system_configuration.current_quota_type: quota_unit = quota_configuration.quota_unit + + if quota_configuration.quota_limit == -1: + return + break used_quota = None if quota_unit: - if quota_unit == QuotaUnit.TOKENS.value: - used_quota = message.message_tokens + message.prompt_tokens + if quota_unit == QuotaUnit.TOKENS: + used_quota = message.message_tokens + message.answer_tokens else: used_quota = 1 diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index fe6e8440df..b5c7d59013 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -38,7 +38,13 @@ const ModelProviderPage = () => { const notConfigedProviders: ModelProvider[] = [] providers.forEach((provider) => { - if (provider.custom_configuration.status === CustomConfigurationStatusEnum.active || provider.system_configuration.enabled === true) + if ( + provider.custom_configuration.status === CustomConfigurationStatusEnum.active + || ( + provider.system_configuration.enabled === true + && provider.system_configuration.quota_configurations.find(item => item.quota_type === provider.system_configuration.current_quota_type) + ) + ) configedProviders.push(provider) else notConfigedProviders.push(provider) diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx index e575448209..b8bce1d05c 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx @@ -9,6 +9,8 @@ import type { import { ConfigurateMethodEnum } from '../declarations' import { DEFAULT_BACKGROUND_COLOR, + MODEL_PROVIDER_QUOTA_GET_FREE, + MODEL_PROVIDER_QUOTA_GET_PAID, modelTypeFormat, } from '../utils' import ProviderIcon from '../provider-icon' @@ -41,7 +43,7 @@ const ProviderAddedCard: FC = ({ const configurateMethods = provider.configurate_methods.filter(method => method !== ConfigurateMethodEnum.fetchFromRemote) const systemConfig = provider.system_configuration const hasModelList = fetched && !!modelList.length - const showQuota = systemConfig.enabled && ['minimax', 'spark', 'zhipuai', 'anthropic', 'openai'].includes(provider.provider) && !IS_CE_EDITION + const showQuota = systemConfig.enabled && [...MODEL_PROVIDER_QUOTA_GET_FREE, ...MODEL_PROVIDER_QUOTA_GET_PAID].includes(provider.provider) && !IS_CE_EDITION const getModelList = async (providerName: string) => { if (loading) diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx index 8e60ae9c14..e13e2bc29c 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx @@ -11,6 +11,10 @@ import { useFreeQuota, useUpdateModelProviders, } from '../hooks' +import { + MODEL_PROVIDER_QUOTA_GET_FREE, + MODEL_PROVIDER_QUOTA_GET_PAID, +} from '../utils' import PriorityUseTip from './priority-use-tip' import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general' import Button from '@/app/components/base/button' @@ -34,7 +38,7 @@ const QuotaPanel: FC = ({ const priorityUseType = provider.preferred_provider_type const systemConfig = provider.system_configuration const currentQuota = systemConfig.enabled && systemConfig.quota_configurations.find(item => item.quota_type === systemConfig.current_quota_type) - const openaiOrAnthropic = ['openai', 'anthropic'].includes(provider.provider) + const openaiOrAnthropic = MODEL_PROVIDER_QUOTA_GET_PAID.includes(provider.provider) return (
@@ -72,7 +76,7 @@ const QuotaPanel: FC = ({ ) } { - !currentQuota && ['minimax', 'spark', 'zhipuai'].includes(provider.provider) && ( + !currentQuota && MODEL_PROVIDER_QUOTA_GET_FREE.includes(provider.provider) && (