mirror of
https://github.com/langgenius/dify.git
synced 2026-01-03 13:07:19 +00:00
Compare commits
5 Commits
copilot/re
...
fix/unsele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb97a93508 | ||
|
|
407d66c62d | ||
|
|
9d75d3d04c | ||
|
|
02852ee543 | ||
|
|
32b2d19622 |
@@ -175,6 +175,22 @@ class ModelProviderCredentialSwitchApi(Resource):
|
|||||||
return {"result": "success"}
|
return {"result": "success"}
|
||||||
|
|
||||||
|
|
||||||
|
class ModelProviderCredentialCancelApi(Resource):
|
||||||
|
@setup_required
|
||||||
|
@login_required
|
||||||
|
@account_initialization_required
|
||||||
|
def post(self, provider: str):
|
||||||
|
if not current_user.is_admin_or_owner:
|
||||||
|
raise Forbidden()
|
||||||
|
|
||||||
|
service = ModelProviderService()
|
||||||
|
service.cancel_provider_credential(
|
||||||
|
tenant_id=current_user.current_tenant_id,
|
||||||
|
provider=provider,
|
||||||
|
)
|
||||||
|
return {"result": "success"}
|
||||||
|
|
||||||
|
|
||||||
class ModelProviderValidateApi(Resource):
|
class ModelProviderValidateApi(Resource):
|
||||||
@setup_required
|
@setup_required
|
||||||
@login_required
|
@login_required
|
||||||
@@ -289,6 +305,9 @@ api.add_resource(ModelProviderCredentialApi, "/workspaces/current/model-provider
|
|||||||
api.add_resource(
|
api.add_resource(
|
||||||
ModelProviderCredentialSwitchApi, "/workspaces/current/model-providers/<path:provider>/credentials/switch"
|
ModelProviderCredentialSwitchApi, "/workspaces/current/model-providers/<path:provider>/credentials/switch"
|
||||||
)
|
)
|
||||||
|
api.add_resource(
|
||||||
|
ModelProviderCredentialCancelApi, "/workspaces/current/model-providers/<path:provider>/credentials/cancel"
|
||||||
|
)
|
||||||
api.add_resource(ModelProviderValidateApi, "/workspaces/current/model-providers/<path:provider>/credentials/validate")
|
api.add_resource(ModelProviderValidateApi, "/workspaces/current/model-providers/<path:provider>/credentials/validate")
|
||||||
|
|
||||||
api.add_resource(
|
api.add_resource(
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ from core.plugin.entities.plugin import ModelProviderID
|
|||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from libs.datetime_utils import naive_utc_now
|
from libs.datetime_utils import naive_utc_now
|
||||||
from models.provider import (
|
from models.provider import (
|
||||||
|
CredentialStatus,
|
||||||
LoadBalancingModelConfig,
|
LoadBalancingModelConfig,
|
||||||
Provider,
|
Provider,
|
||||||
ProviderCredential,
|
ProviderCredential,
|
||||||
@@ -43,6 +44,7 @@ from models.provider import (
|
|||||||
TenantPreferredModelProvider,
|
TenantPreferredModelProvider,
|
||||||
)
|
)
|
||||||
from services.enterprise.plugin_manager_service import PluginCredentialType
|
from services.enterprise.plugin_manager_service import PluginCredentialType
|
||||||
|
from services.entities.model_provider_entities import CustomConfigurationStatus
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -189,6 +191,22 @@ class ProviderConfiguration(BaseModel):
|
|||||||
else SystemConfigurationStatus.QUOTA_EXCEEDED
|
else SystemConfigurationStatus.QUOTA_EXCEEDED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_custom_configuration_status(self) -> Optional[CustomConfigurationStatus]:
|
||||||
|
"""
|
||||||
|
Get custom configuration status.
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self.is_custom_configuration_available():
|
||||||
|
return CustomConfigurationStatus.ACTIVE
|
||||||
|
|
||||||
|
provider = self.custom_configuration.provider
|
||||||
|
if provider and hasattr(provider, "current_credential_status"):
|
||||||
|
status = provider.current_credential_status
|
||||||
|
if status:
|
||||||
|
return status
|
||||||
|
|
||||||
|
return CustomConfigurationStatus.NO_CONFIGURE
|
||||||
|
|
||||||
def is_custom_configuration_available(self) -> bool:
|
def is_custom_configuration_available(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Check custom configuration available.
|
Check custom configuration available.
|
||||||
@@ -643,6 +661,7 @@ class ProviderConfiguration(BaseModel):
|
|||||||
self.switch_preferred_provider_type(provider_type=ProviderType.SYSTEM, session=session)
|
self.switch_preferred_provider_type(provider_type=ProviderType.SYSTEM, session=session)
|
||||||
elif provider_record and provider_record.credential_id == credential_id:
|
elif provider_record and provider_record.credential_id == credential_id:
|
||||||
provider_record.credential_id = None
|
provider_record.credential_id = None
|
||||||
|
provider_record.credential_status = CredentialStatus.REMOVED.value
|
||||||
provider_record.updated_at = naive_utc_now()
|
provider_record.updated_at = naive_utc_now()
|
||||||
|
|
||||||
provider_model_credentials_cache = ProviderCredentialsCache(
|
provider_model_credentials_cache = ProviderCredentialsCache(
|
||||||
@@ -681,6 +700,34 @@ class ProviderConfiguration(BaseModel):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
provider_record.credential_id = credential_record.id
|
provider_record.credential_id = credential_record.id
|
||||||
|
provider_record.credential_status = CredentialStatus.ACTIVE.value
|
||||||
|
provider_record.updated_at = naive_utc_now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
provider_model_credentials_cache = ProviderCredentialsCache(
|
||||||
|
tenant_id=self.tenant_id,
|
||||||
|
identity_id=provider_record.id,
|
||||||
|
cache_type=ProviderCredentialsCacheType.PROVIDER,
|
||||||
|
)
|
||||||
|
provider_model_credentials_cache.delete()
|
||||||
|
self.switch_preferred_provider_type(ProviderType.CUSTOM, session=session)
|
||||||
|
except Exception:
|
||||||
|
session.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
def cancel_provider_credential(self):
|
||||||
|
"""
|
||||||
|
Cancel select the active provider credential.
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
with Session(db.engine) as session:
|
||||||
|
provider_record = self._get_provider_record(session)
|
||||||
|
if not provider_record:
|
||||||
|
raise ValueError("Provider record not found.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
provider_record.credential_id = None
|
||||||
|
provider_record.credential_status = CredentialStatus.CANCELED.value
|
||||||
provider_record.updated_at = naive_utc_now()
|
provider_record.updated_at = naive_utc_now()
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from core.entities.parameter_entities import (
|
|||||||
)
|
)
|
||||||
from core.model_runtime.entities.model_entities import ModelType
|
from core.model_runtime.entities.model_entities import ModelType
|
||||||
from core.tools.entities.common_entities import I18nObject
|
from core.tools.entities.common_entities import I18nObject
|
||||||
|
from models.provider import CredentialStatus
|
||||||
|
|
||||||
|
|
||||||
class ProviderQuotaType(Enum):
|
class ProviderQuotaType(Enum):
|
||||||
@@ -97,6 +98,7 @@ class CustomProviderConfiguration(BaseModel):
|
|||||||
credentials: dict
|
credentials: dict
|
||||||
current_credential_id: Optional[str] = None
|
current_credential_id: Optional[str] = None
|
||||||
current_credential_name: Optional[str] = None
|
current_credential_name: Optional[str] = None
|
||||||
|
current_credential_status: Optional[CredentialStatus] = None
|
||||||
available_credentials: list[CredentialConfiguration] = []
|
available_credentials: list[CredentialConfiguration] = []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -711,6 +711,7 @@ class ProviderManager:
|
|||||||
credentials=provider_credentials,
|
credentials=provider_credentials,
|
||||||
current_credential_name=custom_provider_record.credential_name,
|
current_credential_name=custom_provider_record.credential_name,
|
||||||
current_credential_id=custom_provider_record.credential_id,
|
current_credential_id=custom_provider_record.credential_id,
|
||||||
|
current_credential_status=custom_provider_record.credential_status,
|
||||||
available_credentials=self.get_provider_available_credentials(
|
available_credentials=self.get_provider_available_credentials(
|
||||||
tenant_id, custom_provider_record.provider_name
|
tenant_id, custom_provider_record.provider_name
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
"""Add credential status for provider table
|
||||||
|
|
||||||
|
Revision ID: cf7c38a32b2d
|
||||||
|
Revises: c20211f18133
|
||||||
|
Create Date: 2025-09-11 15:37:17.771298
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import models as models
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'cf7c38a32b2d'
|
||||||
|
down_revision = 'c20211f18133'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('providers', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('credential_status', sa.String(length=20), server_default=sa.text("'active'::character varying"), nullable=True))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('providers', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('credential_status')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum, StrEnum
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
@@ -42,6 +42,12 @@ class ProviderQuotaType(Enum):
|
|||||||
raise ValueError(f"No matching enum found for value '{value}'")
|
raise ValueError(f"No matching enum found for value '{value}'")
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialStatus(StrEnum):
|
||||||
|
ACTIVE = "active"
|
||||||
|
CANCELED = "canceled"
|
||||||
|
REMOVED = "removed"
|
||||||
|
|
||||||
|
|
||||||
class Provider(Base):
|
class Provider(Base):
|
||||||
"""
|
"""
|
||||||
Provider model representing the API providers and their configurations.
|
Provider model representing the API providers and their configurations.
|
||||||
@@ -65,6 +71,9 @@ class Provider(Base):
|
|||||||
is_valid: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=text("false"))
|
is_valid: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=text("false"))
|
||||||
last_used: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
|
last_used: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
|
||||||
credential_id: Mapped[Optional[str]] = mapped_column(StringUUID, nullable=True)
|
credential_id: Mapped[Optional[str]] = mapped_column(StringUUID, nullable=True)
|
||||||
|
credential_status: Mapped[Optional[str]] = mapped_column(
|
||||||
|
String(20), nullable=True, server_default=text("'active'::character varying")
|
||||||
|
)
|
||||||
|
|
||||||
quota_type: Mapped[Optional[str]] = mapped_column(
|
quota_type: Mapped[Optional[str]] = mapped_column(
|
||||||
String(40), nullable=True, server_default=text("''::character varying")
|
String(40), nullable=True, server_default=text("''::character varying")
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class CustomConfigurationStatus(Enum):
|
|||||||
|
|
||||||
ACTIVE = "active"
|
ACTIVE = "active"
|
||||||
NO_CONFIGURE = "no-configure"
|
NO_CONFIGURE = "no-configure"
|
||||||
|
CANCELED = "canceled"
|
||||||
|
REMOVED = "removed"
|
||||||
|
|
||||||
|
|
||||||
class CustomConfigurationResponse(BaseModel):
|
class CustomConfigurationResponse(BaseModel):
|
||||||
|
|||||||
@@ -89,9 +89,7 @@ class ModelProviderService:
|
|||||||
model_credential_schema=provider_configuration.provider.model_credential_schema,
|
model_credential_schema=provider_configuration.provider.model_credential_schema,
|
||||||
preferred_provider_type=provider_configuration.preferred_provider_type,
|
preferred_provider_type=provider_configuration.preferred_provider_type,
|
||||||
custom_configuration=CustomConfigurationResponse(
|
custom_configuration=CustomConfigurationResponse(
|
||||||
status=CustomConfigurationStatus.ACTIVE
|
status=provider_configuration.get_custom_configuration_status(),
|
||||||
if provider_configuration.is_custom_configuration_available()
|
|
||||||
else CustomConfigurationStatus.NO_CONFIGURE,
|
|
||||||
current_credential_id=getattr(provider_config, "current_credential_id", None),
|
current_credential_id=getattr(provider_config, "current_credential_id", None),
|
||||||
current_credential_name=getattr(provider_config, "current_credential_name", None),
|
current_credential_name=getattr(provider_config, "current_credential_name", None),
|
||||||
available_credentials=getattr(provider_config, "available_credentials", []),
|
available_credentials=getattr(provider_config, "available_credentials", []),
|
||||||
@@ -214,6 +212,16 @@ class ModelProviderService:
|
|||||||
provider_configuration = self._get_provider_configuration(tenant_id, provider)
|
provider_configuration = self._get_provider_configuration(tenant_id, provider)
|
||||||
provider_configuration.switch_active_provider_credential(credential_id=credential_id)
|
provider_configuration.switch_active_provider_credential(credential_id=credential_id)
|
||||||
|
|
||||||
|
def cancel_provider_credential(self, tenant_id: str, provider: str):
|
||||||
|
"""
|
||||||
|
:param tenant_id: workspace id
|
||||||
|
:param provider: provider name
|
||||||
|
:param credential_id: credential id
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
provider_configuration = self._get_provider_configuration(tenant_id, provider)
|
||||||
|
provider_configuration.cancel_provider_credential()
|
||||||
|
|
||||||
def get_model_credential(
|
def get_model_credential(
|
||||||
self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str | None
|
self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str | None
|
||||||
) -> Optional[dict]:
|
) -> Optional[dict]:
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ export const MODEL_STATUS_TEXT: { [k: string]: TypeWithI18N } = {
|
|||||||
export enum CustomConfigurationStatusEnum {
|
export enum CustomConfigurationStatusEnum {
|
||||||
active = 'active',
|
active = 'active',
|
||||||
noConfigure = 'no-configure',
|
noConfigure = 'no-configure',
|
||||||
|
canceled = 'canceled',
|
||||||
|
removed = 'removed',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FormShowOnObject = {
|
export type FormShowOnObject = {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
|||||||
providers.forEach((provider) => {
|
providers.forEach((provider) => {
|
||||||
if (
|
if (
|
||||||
provider.custom_configuration.status === CustomConfigurationStatusEnum.active
|
provider.custom_configuration.status === CustomConfigurationStatusEnum.active
|
||||||
|
|| provider.custom_configuration.status === CustomConfigurationStatusEnum.removed
|
||||||
|| (
|
|| (
|
||||||
provider.system_configuration.enabled === true
|
provider.system_configuration.enabled === true
|
||||||
&& provider.system_configuration.quota_configurations.find(item => item.quota_type === provider.system_configuration.current_quota_type)
|
&& provider.system_configuration.quota_configurations.find(item => item.quota_type === provider.system_configuration.current_quota_type)
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ type AuthorizedProps = {
|
|||||||
showModelTitle?: boolean
|
showModelTitle?: boolean
|
||||||
disableDeleteButShowAction?: boolean
|
disableDeleteButShowAction?: boolean
|
||||||
disableDeleteTip?: string
|
disableDeleteTip?: string
|
||||||
|
showDeselect?: boolean
|
||||||
}
|
}
|
||||||
const Authorized = ({
|
const Authorized = ({
|
||||||
provider,
|
provider,
|
||||||
@@ -88,6 +89,7 @@ const Authorized = ({
|
|||||||
showModelTitle,
|
showModelTitle,
|
||||||
disableDeleteButShowAction,
|
disableDeleteButShowAction,
|
||||||
disableDeleteTip,
|
disableDeleteTip,
|
||||||
|
showDeselect,
|
||||||
}: AuthorizedProps) => {
|
}: AuthorizedProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [isLocalOpen, setIsLocalOpen] = useState(false)
|
const [isLocalOpen, setIsLocalOpen] = useState(false)
|
||||||
@@ -112,6 +114,7 @@ const Authorized = ({
|
|||||||
handleConfirmDelete,
|
handleConfirmDelete,
|
||||||
deleteCredentialId,
|
deleteCredentialId,
|
||||||
handleOpenModal,
|
handleOpenModal,
|
||||||
|
handleDeselect,
|
||||||
} = useAuth(
|
} = useAuth(
|
||||||
provider,
|
provider,
|
||||||
configurationMethod,
|
configurationMethod,
|
||||||
@@ -171,8 +174,15 @@ const Authorized = ({
|
|||||||
)}>
|
)}>
|
||||||
{
|
{
|
||||||
popupTitle && (
|
popupTitle && (
|
||||||
<div className='system-xs-medium px-3 pb-0.5 pt-[10px] text-text-tertiary'>
|
<div className='system-xs-medium flex items-center justify-between px-3 pb-0.5 pt-[10px] text-text-tertiary'>
|
||||||
{popupTitle}
|
{popupTitle}
|
||||||
|
{
|
||||||
|
showDeselect && (
|
||||||
|
<div onClick={() => handleDeselect()} className='cursor-pointer'>
|
||||||
|
{t('common.modelProvider.auth.deselect')}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ const ConfigProvider = ({
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const {
|
const {
|
||||||
hasCredential,
|
hasCredential,
|
||||||
authorized,
|
|
||||||
current_credential_id,
|
current_credential_id,
|
||||||
current_credential_name,
|
current_credential_name,
|
||||||
available_credentials,
|
available_credentials,
|
||||||
|
authorized,
|
||||||
|
unAuthorized,
|
||||||
} = useCredentialStatus(provider)
|
} = useCredentialStatus(provider)
|
||||||
const notAllowCustomCredential = provider.allow_custom_token === false
|
const notAllowCustomCredential = provider.allow_custom_token === false
|
||||||
|
|
||||||
@@ -41,11 +42,11 @@ const ConfigProvider = ({
|
|||||||
<Button
|
<Button
|
||||||
className='grow'
|
className='grow'
|
||||||
size='small'
|
size='small'
|
||||||
variant={!authorized ? 'secondary-accent' : 'secondary'}
|
variant={unAuthorized ? 'secondary-accent' : 'secondary'}
|
||||||
>
|
>
|
||||||
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
||||||
{hasCredential && t('common.operation.config')}
|
{!unAuthorized && t('common.operation.config')}
|
||||||
{!hasCredential && t('common.operation.setup')}
|
{unAuthorized && t('common.operation.setup')}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
if (notAllowCustomCredential && !hasCredential) {
|
if (notAllowCustomCredential && !hasCredential) {
|
||||||
@@ -59,7 +60,7 @@ const ConfigProvider = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
return Item
|
return Item
|
||||||
}, [authorized, hasCredential, notAllowCustomCredential, t])
|
}, [hasCredential, notAllowCustomCredential, t])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Authorized
|
<Authorized
|
||||||
@@ -68,7 +69,6 @@ const ConfigProvider = ({
|
|||||||
currentCustomConfigurationModelFixedFields={currentCustomConfigurationModelFixedFields}
|
currentCustomConfigurationModelFixedFields={currentCustomConfigurationModelFixedFields}
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
title: t('common.modelProvider.auth.apiKeys'),
|
|
||||||
credentials: available_credentials ?? [],
|
credentials: available_credentials ?? [],
|
||||||
selectedCredential: {
|
selectedCredential: {
|
||||||
credential_id: current_credential_id ?? '',
|
credential_id: current_credential_id ?? '',
|
||||||
@@ -77,9 +77,10 @@ const ConfigProvider = ({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
showItemSelectedIcon
|
showItemSelectedIcon
|
||||||
showModelTitle
|
|
||||||
renderTrigger={renderTrigger}
|
renderTrigger={renderTrigger}
|
||||||
triggerOnlyOpenModal={!hasCredential && !notAllowCustomCredential}
|
triggerOnlyOpenModal={!hasCredential && !notAllowCustomCredential}
|
||||||
|
showDeselect={authorized}
|
||||||
|
popupTitle={t('common.modelProvider.auth.apiKeys')}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ import {
|
|||||||
useModelModalHandler,
|
useModelModalHandler,
|
||||||
useRefreshModel,
|
useRefreshModel,
|
||||||
} from '@/app/components/header/account-setting/model-provider-page/hooks'
|
} from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||||
import { useDeleteModel } from '@/service/use-models'
|
import {
|
||||||
|
useDeleteModel,
|
||||||
|
useDeselectModelCredential,
|
||||||
|
} from '@/service/use-models'
|
||||||
|
|
||||||
export const useAuth = (
|
export const useAuth = (
|
||||||
provider: ModelProvider,
|
provider: ModelProvider,
|
||||||
@@ -46,6 +49,7 @@ export const useAuth = (
|
|||||||
getAddCredentialService,
|
getAddCredentialService,
|
||||||
} = useAuthService(provider.provider)
|
} = useAuthService(provider.provider)
|
||||||
const { mutateAsync: deleteModelService } = useDeleteModel(provider.provider)
|
const { mutateAsync: deleteModelService } = useDeleteModel(provider.provider)
|
||||||
|
const { mutateAsync: deselectModelCredentialService } = useDeselectModelCredential(provider.provider)
|
||||||
const handleOpenModelModal = useModelModalHandler()
|
const handleOpenModelModal = useModelModalHandler()
|
||||||
const { handleRefreshModel } = useRefreshModel()
|
const { handleRefreshModel } = useRefreshModel()
|
||||||
const pendingOperationCredentialId = useRef<string | null>(null)
|
const pendingOperationCredentialId = useRef<string | null>(null)
|
||||||
@@ -177,6 +181,11 @@ export const useAuth = (
|
|||||||
mode,
|
mode,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const handleDeselect = useCallback(async () => {
|
||||||
|
await deselectModelCredentialService()
|
||||||
|
handleRefreshModel(provider, configurationMethod, undefined)
|
||||||
|
}, [deselectModelCredentialService, handleRefreshModel, provider, configurationMethod])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pendingOperationCredentialId,
|
pendingOperationCredentialId,
|
||||||
pendingOperationModel,
|
pendingOperationModel,
|
||||||
@@ -189,5 +198,6 @@ export const useAuth = (
|
|||||||
deleteModel,
|
deleteModel,
|
||||||
handleSaveCredential,
|
handleSaveCredential,
|
||||||
handleOpenModal,
|
handleOpenModal,
|
||||||
|
handleDeselect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,19 @@ import { useMemo } from 'react'
|
|||||||
import type {
|
import type {
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '../../declarations'
|
} from '../../declarations'
|
||||||
|
import { CustomConfigurationStatusEnum } from '../../declarations'
|
||||||
|
|
||||||
export const useCredentialStatus = (provider: ModelProvider) => {
|
export const useCredentialStatus = (provider: ModelProvider) => {
|
||||||
const {
|
const {
|
||||||
current_credential_id,
|
current_credential_id,
|
||||||
current_credential_name,
|
current_credential_name,
|
||||||
available_credentials,
|
available_credentials,
|
||||||
|
status: customConfigurationStatus,
|
||||||
} = provider.custom_configuration
|
} = provider.custom_configuration
|
||||||
const hasCredential = !!available_credentials?.length
|
const hasCredential = !!available_credentials?.length
|
||||||
const authorized = current_credential_id && current_credential_name
|
const authorized = customConfigurationStatus === CustomConfigurationStatusEnum.active
|
||||||
const authRemoved = hasCredential && !current_credential_id && !current_credential_name
|
const authRemoved = customConfigurationStatus === CustomConfigurationStatusEnum.removed
|
||||||
|
const unAuthorized = customConfigurationStatus === CustomConfigurationStatusEnum.noConfigure || customConfigurationStatus === CustomConfigurationStatusEnum.canceled
|
||||||
const currentCredential = available_credentials?.find(credential => credential.credential_id === current_credential_id)
|
const currentCredential = available_credentials?.find(credential => credential.credential_id === current_credential_id)
|
||||||
|
|
||||||
return useMemo(() => ({
|
return useMemo(() => ({
|
||||||
@@ -21,6 +24,8 @@ export const useCredentialStatus = (provider: ModelProvider) => {
|
|||||||
current_credential_id,
|
current_credential_id,
|
||||||
current_credential_name,
|
current_credential_name,
|
||||||
available_credentials,
|
available_credentials,
|
||||||
|
customConfigurationStatus,
|
||||||
notAllowedToUse: currentCredential?.not_allowed_to_use,
|
notAllowedToUse: currentCredential?.not_allowed_to_use,
|
||||||
|
unAuthorized,
|
||||||
}), [hasCredential, authorized, authRemoved, current_credential_id, current_credential_name, available_credentials])
|
}), [hasCredential, authorized, authRemoved, current_credential_id, current_credential_name, available_credentials])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const CredentialPanel = ({
|
|||||||
authRemoved,
|
authRemoved,
|
||||||
current_credential_name,
|
current_credential_name,
|
||||||
notAllowedToUse,
|
notAllowedToUse,
|
||||||
|
unAuthorized,
|
||||||
} = useCredentialStatus(provider)
|
} = useCredentialStatus(provider)
|
||||||
|
|
||||||
const handleChangePriority = async (key: PreferredProviderTypeEnum) => {
|
const handleChangePriority = async (key: PreferredProviderTypeEnum) => {
|
||||||
@@ -70,23 +71,23 @@ const CredentialPanel = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const credentialLabel = useMemo(() => {
|
const credentialLabel = useMemo(() => {
|
||||||
if (!hasCredential)
|
if (unAuthorized)
|
||||||
return t('common.modelProvider.auth.unAuthorized')
|
return t('common.modelProvider.auth.unAuthorized')
|
||||||
if (authorized)
|
|
||||||
return current_credential_name
|
|
||||||
if (authRemoved)
|
if (authRemoved)
|
||||||
return t('common.modelProvider.auth.authRemoved')
|
return t('common.modelProvider.auth.authRemoved')
|
||||||
|
if (authorized)
|
||||||
|
return current_credential_name
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
}, [authorized, authRemoved, current_credential_name, hasCredential])
|
}, [authorized, authRemoved, current_credential_name, unAuthorized])
|
||||||
|
|
||||||
const color = useMemo(() => {
|
const color = useMemo(() => {
|
||||||
if (authRemoved || !hasCredential)
|
if (authRemoved || !hasCredential || unAuthorized)
|
||||||
return 'red'
|
return 'red'
|
||||||
if (notAllowedToUse)
|
if (notAllowedToUse)
|
||||||
return 'gray'
|
return 'gray'
|
||||||
return 'green'
|
return 'green'
|
||||||
}, [authRemoved, notAllowedToUse, hasCredential])
|
}, [authRemoved, notAllowedToUse, hasCredential, unAuthorized])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -523,6 +523,7 @@ const translation = {
|
|||||||
removeModel: 'Remove Model',
|
removeModel: 'Remove Model',
|
||||||
selectModelCredential: 'Select a model credential',
|
selectModelCredential: 'Select a model credential',
|
||||||
customModelCredentialsDeleteTip: 'Credential is in use and cannot be deleted',
|
customModelCredentialsDeleteTip: 'Credential is in use and cannot be deleted',
|
||||||
|
deselect: 'Deselect',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dataSource: {
|
dataSource: {
|
||||||
|
|||||||
@@ -517,6 +517,7 @@ const translation = {
|
|||||||
removeModel: '移除模型',
|
removeModel: '移除模型',
|
||||||
selectModelCredential: '选择模型凭据',
|
selectModelCredential: '选择模型凭据',
|
||||||
customModelCredentialsDeleteTip: '模型凭据正在使用中,无法删除',
|
customModelCredentialsDeleteTip: '模型凭据正在使用中,无法删除',
|
||||||
|
deselect: '取消选择',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dataSource: {
|
dataSource: {
|
||||||
|
|||||||
@@ -153,3 +153,9 @@ export const useUpdateModelLoadBalancingConfig = (provider: string) => {
|
|||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useDeselectModelCredential = (provider: string) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: () => post<{ result: string }>(`/workspaces/current/model-providers/${provider}/credentials/cancel`),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user