Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
8799c888
Unverified
Commit
8799c888
authored
Jan 17, 2024
by
takatost
Committed by
GitHub
Jan 17, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: free quota type apply button missing (#2069)
Co-authored-by:
StyleZhang
<
jasonapring2015@outlook.com
>
parent
d7209d90
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
174 additions
and
130 deletions
+174
-130
api-model-runtime-tests.yml
.github/workflows/api-model-runtime-tests.yml
+0
-4
style.yml
.github/workflows/style.yml
+0
-3
.env.example
api/.env.example
+2
-2
config.py
api/config.py
+24
-5
hosting_configuration.py
api/core/hosting_configuration.py
+98
-97
provider_manager.py
api/core/provider_manager.py
+23
-12
deduct_quota_when_messaeg_created.py
...vents/event_handlers/deduct_quota_when_messaeg_created.py
+6
-2
index.tsx
...ents/header/account-setting/model-provider-page/index.tsx
+7
-1
index.tsx
...setting/model-provider-page/provider-added-card/index.tsx
+3
-1
quota-panel.tsx
...g/model-provider-page/provider-added-card/quota-panel.tsx
+6
-2
index.tsx
...count-setting/model-provider-page/provider-card/index.tsx
+2
-1
utils.ts
...nents/header/account-setting/model-provider-page/utils.ts
+3
-0
No files found.
.github/workflows/api-model-runtime-tests.yml
View file @
8799c888
...
...
@@ -4,10 +4,6 @@ on:
pull_request
:
branches
:
-
main
push
:
branches
:
-
deploy/dev
-
feat/model-runtime
jobs
:
test
:
...
...
.github/workflows/style.yml
View file @
8799c888
...
...
@@ -4,9 +4,6 @@ on:
pull_request
:
branches
:
-
main
push
:
branches
:
-
deploy/dev
concurrency
:
group
:
dep-${{ github.head_ref || github.run_id }}
...
...
api/.env.example
View file @
8799c888
...
...
@@ -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
...
...
api/config.py
View file @
8799c888
...
...
@@ -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'
)
...
...
api/core/hosting_configuration.py
View file @
8799c888
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
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
(
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
(
...
...
api/core/provider_manager.py
View file @
8799c888
...
...
@@ -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
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
)
...
...
@@ -670,6 +680,7 @@ class ProviderManager:
current_using_credentials
=
cached_provider_credentials
else
:
current_using_credentials
=
{}
quota_configurations
=
[]
return
SystemConfiguration
(
enabled
=
True
,
...
...
api/events/event_handlers/deduct_quota_when_messaeg_created.py
View file @
8799c888
...
...
@@ -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
...
...
web/app/components/header/account-setting/model-provider-page/index.tsx
View file @
8799c888
...
...
@@ -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
)
...
...
web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx
View file @
8799c888
...
...
@@ -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<ProviderAddedCardProps> = ({
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
)
...
...
web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx
View file @
8799c888
...
...
@@ -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<QuotaPanelProps> = ({
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
(
<
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'
>
...
...
@@ -72,7 +76,7 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
)
}
{
!
currentQuota
&&
[
'minimax'
,
'spark'
,
'zhipuai'
]
.
includes
(
provider
.
provider
)
&&
(
!
currentQuota
&&
MODEL_PROVIDER_QUOTA_GET_FREE
.
includes
(
provider
.
provider
)
&&
(
<
Button
className=
'h-6 bg-white text-xs font-medium rounded-md'
onClick=
{
()
=>
handleFreeQuota
(
provider
.
provider
)
}
...
...
web/app/components/header/account-setting/model-provider-page/provider-card/index.tsx
View file @
8799c888
...
...
@@ -7,6 +7,7 @@ import type {
import
{
ConfigurateMethodEnum
}
from
'../declarations'
import
{
DEFAULT_BACKGROUND_COLOR
,
MODEL_PROVIDER_QUOTA_GET_FREE
,
modelTypeFormat
,
}
from
'../utils'
import
{
...
...
@@ -55,7 +56,7 @@ const ProviderCard: FC<ProviderCardProps> = ({
}
const
handleFreeQuota
=
useFreeQuota
(
handleFreeQuotaSuccess
)
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
(
<
div
...
...
web/app/components/header/account-setting/model-provider-page/utils.ts
View file @
8799c888
...
...
@@ -23,6 +23,9 @@ export const languageMaps = {
'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
isNullOrUndefined
=
(
value
:
any
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment