feat(stage-ui,stage-pages) allow to "continue anyway" with failing provider validation (#811)
This commit is contained in:
@@ -421,6 +421,7 @@ pages:
|
||||
and behave properly. You could think of it as the brain of the
|
||||
characters living in AIRI system.
|
||||
common:
|
||||
continueAnyway: Continue Anyway
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI requiere que al menos un proveedor de {chat} esté configurado para pensar y comportarse correctamente. Podrías pensarlo como el cerebro de los personajes que viven en el sistema AIRI.
|
||||
common:
|
||||
continueAnyway: Continuar de todos modos
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI nécessite qu’au moins un fournisseur {chat} soit configuré pour penser et se comporter correctement. On peut le considérer comme le cerveau des personnages vivant dans le système AIRI.
|
||||
common:
|
||||
continueAnyway: Continuer quand même
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRIが正常に思考し動作するためには、少なくとも1つの{chat}プロバイダーの設定が必要です。 これはAIRIシステム内に存在するキャラクターの脳と考えることができます。
|
||||
common:
|
||||
continueAnyway: 続行する
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI requires at least one {chat} provider to be configured to think, and behave properly. You could think of it as the brain of the characters living in AIRI system.
|
||||
common:
|
||||
continueAnyway: 계속 진행
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI требует как минимум одного {chat}-провайдера для корректной работы. Можно считать его "мозгом" персонажей в системе AIRI.
|
||||
common:
|
||||
continueAnyway: Продолжить всё равно
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
{chat} AIRI cần ít nhất một nhà cung cấp để suy nghĩ và hoạt động đúng cách. Có thể coi nó như bộ não của nhân vật AIRI trong hệ thống.
|
||||
common:
|
||||
continueAnyway: Tiếp tục bất chấp
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI 需要配置至少一个 {chat} 服务来源,才能正常思考和运作。你可以把它看作是 AIRI 系统中角色的大脑。
|
||||
common:
|
||||
continueAnyway: 仍然继续
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -404,6 +404,7 @@ pages:
|
||||
description: >
|
||||
AIRI 需要設定至少一個 {chat} 服務來源,才能正常思考與運作。你可以把它看作是 AIRI 系統中角色的大腦。
|
||||
common:
|
||||
continueAnyway: 仍然繼續
|
||||
fields:
|
||||
field:
|
||||
api-key:
|
||||
|
||||
@@ -49,6 +49,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -81,7 +82,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
@@ -65,6 +65,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -114,7 +115,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
@@ -46,6 +46,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -79,7 +80,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
@@ -37,6 +37,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -61,7 +62,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
@@ -38,6 +38,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
|
||||
const headers = ref<{ key: string, value: string }[]>(Object.entries(providers.value[providerId]?.headers || {}).map(([key, value]) => ({ key, value } as { key: string, value: string })) || [{ key: '', value: '' }])
|
||||
@@ -151,7 +152,16 @@ onMounted(() => {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
+11
-1
@@ -98,6 +98,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -138,7 +139,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
+11
-1
@@ -115,6 +115,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
|
||||
function float32ToInt16(buffer: Float32Array) {
|
||||
@@ -397,7 +398,16 @@ onBeforeUnmount(async () => {
|
||||
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
+11
-1
@@ -79,6 +79,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -116,7 +117,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
+11
-1
@@ -79,6 +79,7 @@ const {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
@@ -116,7 +117,16 @@ const {
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<span>{{ t('settings.dialogs.onboarding.validationFailed') }}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-2 rounded bg-red-100 px-2 py-0.5 text-xs text-red-600 font-medium transition-colors dark:bg-red-800/30 hover:bg-red-200 dark:text-red-300 dark:hover:bg-red-700/40"
|
||||
@click="forceValid"
|
||||
>
|
||||
{{ t('settings.pages.providers.common.continueAnyway') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
|
||||
@@ -122,6 +122,12 @@ export function useProviderValidation(providerId: string) {
|
||||
isValidating.value = 0
|
||||
}
|
||||
|
||||
function forceValid() {
|
||||
isValid.value = true
|
||||
validationMessage.value = ''
|
||||
providersStore.forceProviderConfigured(providerId)
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
router,
|
||||
@@ -133,5 +139,6 @@ export function useProviderValidation(providerId: string) {
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
forceValid,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1936,6 +1936,15 @@ export const useProvidersStore = defineStore('providers', () => {
|
||||
const isLoadingModels = ref<Record<string, boolean>>({})
|
||||
const modelLoadError = ref<Record<string, string | null>>({})
|
||||
|
||||
function forceProviderConfigured(providerId: string) {
|
||||
configuredProviders.value[providerId] = true
|
||||
// Also cache the current config to prevent re-validation from overwriting
|
||||
const config = providerCredentials.value[providerId]
|
||||
if (config) {
|
||||
validatedCredentials.value[providerId] = JSON.stringify(config)
|
||||
}
|
||||
}
|
||||
|
||||
async function resetProviderSettings() {
|
||||
providerCredentials.value = {}
|
||||
configuredProviders.value = {}
|
||||
@@ -2150,6 +2159,7 @@ export const useProvidersStore = defineStore('providers', () => {
|
||||
loadModelsForConfiguredProviders,
|
||||
getProviderInstance,
|
||||
resetProviderSettings,
|
||||
forceProviderConfigured,
|
||||
availableProvidersMetadata,
|
||||
allChatProvidersMetadata,
|
||||
allAudioSpeechProvidersMetadata,
|
||||
|
||||
Reference in New Issue
Block a user