Co-authored-by: StyleZhang <jasonapring2015@outlook.com>tags/0.4.8
| pull_request: | pull_request: | ||||
| branches: | branches: | ||||
| - main | - main | ||||
| push: | |||||
| branches: | |||||
| - deploy/dev | |||||
| - feat/model-runtime | |||||
| jobs: | jobs: | ||||
| test: | test: |
| pull_request: | pull_request: | ||||
| branches: | branches: | ||||
| - main | - main | ||||
| push: | |||||
| branches: | |||||
| - deploy/dev | |||||
| concurrency: | concurrency: | ||||
| group: dep-${{ github.head_ref || github.run_id }} | group: dep-${{ github.head_ref || github.run_id }} |
| NOTION_INTERNAL_SECRET=you-internal-secret | NOTION_INTERNAL_SECRET=you-internal-secret | ||||
| # Hosted Model Credentials | # Hosted Model Credentials | ||||
| HOSTED_OPENAI_ENABLED=false | |||||
| HOSTED_OPENAI_API_KEY= | HOSTED_OPENAI_API_KEY= | ||||
| HOSTED_OPENAI_API_BASE= | HOSTED_OPENAI_API_BASE= | ||||
| HOSTED_OPENAI_API_ORGANIZATION= | HOSTED_OPENAI_API_ORGANIZATION= | ||||
| HOSTED_OPENAI_TRIAL_ENABLED=false | |||||
| HOSTED_OPENAI_QUOTA_LIMIT=200 | HOSTED_OPENAI_QUOTA_LIMIT=200 | ||||
| HOSTED_OPENAI_PAID_ENABLED=false | HOSTED_OPENAI_PAID_ENABLED=false | ||||
| HOSTED_AZURE_OPENAI_API_BASE= | HOSTED_AZURE_OPENAI_API_BASE= | ||||
| HOSTED_AZURE_OPENAI_QUOTA_LIMIT=200 | HOSTED_AZURE_OPENAI_QUOTA_LIMIT=200 | ||||
| HOSTED_ANTHROPIC_ENABLED=false | |||||
| HOSTED_ANTHROPIC_API_BASE= | HOSTED_ANTHROPIC_API_BASE= | ||||
| HOSTED_ANTHROPIC_API_KEY= | HOSTED_ANTHROPIC_API_KEY= | ||||
| HOSTED_ANTHROPIC_TRIAL_ENABLED=false | |||||
| HOSTED_ANTHROPIC_QUOTA_LIMIT=600000 | HOSTED_ANTHROPIC_QUOTA_LIMIT=600000 | ||||
| HOSTED_ANTHROPIC_PAID_ENABLED=false | HOSTED_ANTHROPIC_PAID_ENABLED=false | ||||
| 'CELERY_BACKEND': 'database', | 'CELERY_BACKEND': 'database', | ||||
| 'LOG_LEVEL': 'INFO', | 'LOG_LEVEL': 'INFO', | ||||
| 'HOSTED_OPENAI_QUOTA_LIMIT': 200, | 'HOSTED_OPENAI_QUOTA_LIMIT': 200, | ||||
| 'HOSTED_OPENAI_ENABLED': 'False', | |||||
| 'HOSTED_OPENAI_TRIAL_ENABLED': 'False', | |||||
| 'HOSTED_OPENAI_PAID_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_ENABLED': 'False', | ||||
| 'HOSTED_AZURE_OPENAI_QUOTA_LIMIT': 200, | 'HOSTED_AZURE_OPENAI_QUOTA_LIMIT': 200, | ||||
| 'HOSTED_ANTHROPIC_QUOTA_LIMIT': 600000, | 'HOSTED_ANTHROPIC_QUOTA_LIMIT': 600000, | ||||
| 'HOSTED_ANTHROPIC_ENABLED': 'False', | |||||
| 'HOSTED_ANTHROPIC_TRIAL_ENABLED': 'False', | |||||
| 'HOSTED_ANTHROPIC_PAID_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_ENABLED': 'False', | ||||
| 'HOSTED_MODERATION_PROVIDERS': '', | 'HOSTED_MODERATION_PROVIDERS': '', | ||||
| 'CLEAN_DAY_SETTING': 30, | 'CLEAN_DAY_SETTING': 30, | ||||
| def get_bool_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): | def get_cors_allow_origins(env, default): | ||||
| # ------------------------ | # ------------------------ | ||||
| # Platform Configurations. | # 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_KEY = get_env('HOSTED_OPENAI_API_KEY') | ||||
| self.HOSTED_OPENAI_API_BASE = get_env('HOSTED_OPENAI_API_BASE') | 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_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_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_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_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_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_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_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_BASE = get_env('HOSTED_ANTHROPIC_API_BASE') | ||||
| self.HOSTED_ANTHROPIC_API_KEY = get_env('HOSTED_ANTHROPIC_API_KEY') | 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_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_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_ENABLED = get_bool_env('HOSTED_MODERATION_ENABLED') | ||||
| self.HOSTED_MODERATION_PROVIDERS = get_env('HOSTED_MODERATION_PROVIDERS') | self.HOSTED_MODERATION_PROVIDERS = get_env('HOSTED_MODERATION_PROVIDERS') |
| import os | |||||
| from typing import Optional | from typing import Optional | ||||
| from core.entities.provider_entities import QuotaUnit, RestrictModel | from core.entities.provider_entities import QuotaUnit, RestrictModel | ||||
| from core.model_runtime.entities.model_entities import ModelType | from core.model_runtime.entities.model_entities import ModelType | ||||
| from flask import Flask | |||||
| from flask import Flask, Config | |||||
| from models.provider import ProviderQuotaType | from models.provider import ProviderQuotaType | ||||
| from pydantic import BaseModel | from pydantic import BaseModel | ||||
| moderation_config: HostedModerationConfig = None | moderation_config: HostedModerationConfig = None | ||||
| def init_app(self, app: Flask) -> None: | def init_app(self, app: Flask) -> None: | ||||
| if app.config.get('EDITION') != 'CLOUD': | |||||
| config = app.config | |||||
| if config.get('EDITION') != 'CLOUD': | |||||
| return | 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 | 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 = { | 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" | "base_model_name": "gpt-35-turbo" | ||||
| } | } | ||||
| quotas = [] | 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( | return HostingProvider( | ||||
| enabled=True, | enabled=True, | ||||
| quota_unit=quota_unit, | quota_unit=quota_unit, | ||||
| ) | ) | ||||
| def init_openai(self) -> HostingProvider: | |||||
| def init_openai(self, app_config: Config) -> HostingProvider: | |||||
| quota_unit = QuotaUnit.TIMES | 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 = { | 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 os.environ.get("HOSTED_OPENAI_API_ORGANIZATION"): | |||||
| credentials["openai_organization"] = os.environ.get("HOSTED_OPENAI_API_ORGANIZATION") | |||||
| if app_config.get("HOSTED_OPENAI_API_BASE"): | |||||
| credentials["openai_api_base"] = app_config.get("HOSTED_OPENAI_API_BASE") | |||||
| 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( | return HostingProvider( | ||||
| enabled=True, | enabled=True, | ||||
| quota_unit=quota_unit, | quota_unit=quota_unit, | ||||
| ) | ) | ||||
| def init_anthropic(self) -> HostingProvider: | |||||
| def init_anthropic(self, app_config: Config) -> HostingProvider: | |||||
| quota_unit = QuotaUnit.TOKENS | 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 = { | 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( | return HostingProvider( | ||||
| enabled=True, | enabled=True, | ||||
| quota_unit=quota_unit, | quota_unit=quota_unit, | ||||
| ) | ) | ||||
| def init_minimax(self) -> HostingProvider: | |||||
| def init_minimax(self, app_config: Config) -> HostingProvider: | |||||
| quota_unit = QuotaUnit.TOKENS | 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()] | quotas = [FreeHostingQuota()] | ||||
| return HostingProvider( | return HostingProvider( | ||||
| quota_unit=quota_unit, | quota_unit=quota_unit, | ||||
| ) | ) | ||||
| def init_spark(self) -> HostingProvider: | |||||
| def init_spark(self, app_config: Config) -> HostingProvider: | |||||
| quota_unit = QuotaUnit.TOKENS | 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()] | quotas = [FreeHostingQuota()] | ||||
| return HostingProvider( | return HostingProvider( | ||||
| quota_unit=quota_unit, | quota_unit=quota_unit, | ||||
| ) | ) | ||||
| def init_zhipuai(self) -> HostingProvider: | |||||
| def init_zhipuai(self, app_config: Config) -> HostingProvider: | |||||
| quota_unit = QuotaUnit.TOKENS | 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()] | quotas = [FreeHostingQuota()] | ||||
| return HostingProvider( | return HostingProvider( | ||||
| quota_unit=quota_unit, | 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( | return HostedModerationConfig( | ||||
| enabled=True, | enabled=True, | ||||
| providers=os.environ.get("HOSTED_MODERATION_PROVIDERS").split(',') | |||||
| providers=app_config.get("HOSTED_MODERATION_PROVIDERS").split(',') | |||||
| ) | ) | ||||
| return HostedModerationConfig( | return HostedModerationConfig( |
| quota_configurations = [] | quota_configurations = [] | ||||
| for provider_quota in provider_hosting_configuration.quotas: | for provider_quota in provider_hosting_configuration.quotas: | ||||
| if provider_quota.quota_type not in quota_type_to_provider_records_dict: | if provider_quota.quota_type not in quota_type_to_provider_records_dict: | ||||
| continue | |||||
| 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 | |||||
| ) | |||||
| 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] | |||||
| 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) | quota_configurations.append(quota_configuration) | ||||
| current_using_credentials = cached_provider_credentials | current_using_credentials = cached_provider_credentials | ||||
| else: | else: | ||||
| current_using_credentials = {} | current_using_credentials = {} | ||||
| quota_configurations = [] | |||||
| return SystemConfiguration( | return SystemConfiguration( | ||||
| enabled=True, | enabled=True, |
| for quota_configuration in system_configuration.quota_configurations: | for quota_configuration in system_configuration.quota_configurations: | ||||
| if quota_configuration.quota_type == system_configuration.current_quota_type: | if quota_configuration.quota_type == system_configuration.current_quota_type: | ||||
| quota_unit = quota_configuration.quota_unit | quota_unit = quota_configuration.quota_unit | ||||
| if quota_configuration.quota_limit == -1: | |||||
| return | |||||
| break | break | ||||
| used_quota = None | used_quota = None | ||||
| if quota_unit: | 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: | else: | ||||
| used_quota = 1 | used_quota = 1 | ||||
| const notConfigedProviders: ModelProvider[] = [] | const notConfigedProviders: ModelProvider[] = [] | ||||
| providers.forEach((provider) => { | 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) | configedProviders.push(provider) | ||||
| else | else | ||||
| notConfigedProviders.push(provider) | notConfigedProviders.push(provider) |
| import { ConfigurateMethodEnum } from '../declarations' | import { ConfigurateMethodEnum } from '../declarations' | ||||
| import { | import { | ||||
| DEFAULT_BACKGROUND_COLOR, | DEFAULT_BACKGROUND_COLOR, | ||||
| MODEL_PROVIDER_QUOTA_GET_FREE, | |||||
| MODEL_PROVIDER_QUOTA_GET_PAID, | |||||
| modelTypeFormat, | modelTypeFormat, | ||||
| } from '../utils' | } from '../utils' | ||||
| import ProviderIcon from '../provider-icon' | import ProviderIcon from '../provider-icon' | ||||
| const configurateMethods = provider.configurate_methods.filter(method => method !== ConfigurateMethodEnum.fetchFromRemote) | const configurateMethods = provider.configurate_methods.filter(method => method !== ConfigurateMethodEnum.fetchFromRemote) | ||||
| const systemConfig = provider.system_configuration | const systemConfig = provider.system_configuration | ||||
| const hasModelList = fetched && !!modelList.length | 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) => { | const getModelList = async (providerName: string) => { | ||||
| if (loading) | if (loading) |
| useFreeQuota, | useFreeQuota, | ||||
| useUpdateModelProviders, | useUpdateModelProviders, | ||||
| } from '../hooks' | } from '../hooks' | ||||
| import { | |||||
| MODEL_PROVIDER_QUOTA_GET_FREE, | |||||
| MODEL_PROVIDER_QUOTA_GET_PAID, | |||||
| } from '../utils' | |||||
| import PriorityUseTip from './priority-use-tip' | import PriorityUseTip from './priority-use-tip' | ||||
| import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general' | import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| const priorityUseType = provider.preferred_provider_type | const priorityUseType = provider.preferred_provider_type | ||||
| const systemConfig = provider.system_configuration | const systemConfig = provider.system_configuration | ||||
| const currentQuota = systemConfig.enabled && systemConfig.quota_configurations.find(item => item.quota_type === systemConfig.current_quota_type) | 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 ( | return ( | ||||
| <div className='group relative shrink-0 min-w-[112px] px-3 py-2 rounded-lg bg-white/[0.3] border-[0.5px] border-black/5'> | <div className='group relative shrink-0 min-w-[112px] px-3 py-2 rounded-lg bg-white/[0.3] border-[0.5px] border-black/5'> | ||||
| ) | ) | ||||
| } | } | ||||
| { | { | ||||
| !currentQuota && ['minimax', 'spark', 'zhipuai'].includes(provider.provider) && ( | |||||
| !currentQuota && MODEL_PROVIDER_QUOTA_GET_FREE.includes(provider.provider) && ( | |||||
| <Button | <Button | ||||
| className='h-6 bg-white text-xs font-medium rounded-md' | className='h-6 bg-white text-xs font-medium rounded-md' | ||||
| onClick={() => handleFreeQuota(provider.provider)} | onClick={() => handleFreeQuota(provider.provider)} |
| import { ConfigurateMethodEnum } from '../declarations' | import { ConfigurateMethodEnum } from '../declarations' | ||||
| import { | import { | ||||
| DEFAULT_BACKGROUND_COLOR, | DEFAULT_BACKGROUND_COLOR, | ||||
| MODEL_PROVIDER_QUOTA_GET_FREE, | |||||
| modelTypeFormat, | modelTypeFormat, | ||||
| } from '../utils' | } from '../utils' | ||||
| import { | import { | ||||
| } | } | ||||
| const handleFreeQuota = useFreeQuota(handleFreeQuotaSuccess) | const handleFreeQuota = useFreeQuota(handleFreeQuotaSuccess) | ||||
| const configurateMethods = provider.configurate_methods.filter(method => method !== ConfigurateMethodEnum.fetchFromRemote) | const configurateMethods = provider.configurate_methods.filter(method => method !== ConfigurateMethodEnum.fetchFromRemote) | ||||
| const canGetFreeQuota = ['mininmax', 'spark', 'zhipuai'].includes(provider.provider) && !IS_CE_EDITION | |||||
| const canGetFreeQuota = MODEL_PROVIDER_QUOTA_GET_FREE.includes(provider.provider) && !IS_CE_EDITION && provider.system_configuration.enabled | |||||
| return ( | return ( | ||||
| <div | <div |
| 'zh-Hans': 'zh_Hans' | 'zh-Hans': 'zh_Hans' | ||||
| } | } | ||||
| export const MODEL_PROVIDER_QUOTA_GET_FREE = ['minimax', 'spark', 'zhipuai'] | |||||
| export const MODEL_PROVIDER_QUOTA_GET_PAID = ['anthropic', 'openai'] | |||||
| export const DEFAULT_BACKGROUND_COLOR = '#F3F4F6' | export const DEFAULT_BACKGROUND_COLOR = '#F3F4F6' | ||||
| export const isNullOrUndefined = (value: any) => { | export const isNullOrUndefined = (value: any) => { |