@@ -40,6 +40,7 @@ words:
|
||||
- clustr
|
||||
- collectblock
|
||||
- colorjs
|
||||
- cometapi
|
||||
- Comfortaa
|
||||
- composables
|
||||
- cooldown
|
||||
|
||||
@@ -568,6 +568,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: Transcription Playground
|
||||
|
||||
@@ -506,6 +506,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: Playground de Transcripción
|
||||
|
||||
@@ -509,6 +509,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: Terrain de test de transcription
|
||||
|
||||
@@ -490,6 +490,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: Песочница транскрипции
|
||||
|
||||
@@ -495,6 +495,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: Transcription Playground
|
||||
|
||||
@@ -500,6 +500,9 @@ pages:
|
||||
302-ai:
|
||||
description: 302.AI
|
||||
title: 302.AI
|
||||
comet-api:
|
||||
description: CometAPI.com
|
||||
title: Comet API
|
||||
transcriptions:
|
||||
playground:
|
||||
title: 实验平台
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
<script setup lang="ts">
|
||||
import type { RemovableRef } from '@vueuse/core'
|
||||
import type { SpeechProvider } from '@xsai-ext/shared-providers'
|
||||
|
||||
import {
|
||||
Alert,
|
||||
ProviderAdvancedSettings,
|
||||
ProviderApiKeyInput,
|
||||
ProviderBaseUrlInput,
|
||||
ProviderBasicSettings,
|
||||
ProviderSettingsContainer,
|
||||
ProviderSettingsLayout,
|
||||
SpeechPlaygroundOpenAICompatible,
|
||||
} from '@proj-airi/stage-ui/components'
|
||||
import { useProviderValidation } from '@proj-airi/stage-ui/composables/use-provider-validation'
|
||||
import { useSpeechStore } from '@proj-airi/stage-ui/stores/modules/speech'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
|
||||
import { FieldRange } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const speechStore = useSpeechStore()
|
||||
const providersStore = useProvidersStore()
|
||||
const { providers } = storeToRefs(providersStore) as { providers: RemovableRef<Record<string, any>> }
|
||||
|
||||
const defaultVoiceSettings = {
|
||||
speed: 1.0,
|
||||
}
|
||||
|
||||
// Get provider metadata
|
||||
const providerId = 'comet-api-speech'
|
||||
|
||||
// Settings refs
|
||||
const apiKey = computed({
|
||||
get: () => providers.value[providerId]?.apiKey || '',
|
||||
set: (value) => {
|
||||
if (providers.value[providerId])
|
||||
providers.value[providerId].apiKey = value
|
||||
},
|
||||
})
|
||||
|
||||
const baseUrl = computed({
|
||||
get: () => providers.value[providerId]?.baseUrl || '',
|
||||
set: (value) => {
|
||||
if (providers.value[providerId])
|
||||
providers.value[providerId].baseUrl = value
|
||||
},
|
||||
})
|
||||
|
||||
const model = computed({
|
||||
get: () => providers.value[providerId]?.model || 'tts-1',
|
||||
set: (value) => {
|
||||
if (providers.value[providerId])
|
||||
providers.value[providerId].model = value
|
||||
},
|
||||
})
|
||||
|
||||
const voice = computed({
|
||||
get: () => providers.value[providerId]?.voice || 'alloy',
|
||||
set: (value) => {
|
||||
if (providers.value[providerId])
|
||||
providers.value[providerId].voice = value
|
||||
},
|
||||
})
|
||||
|
||||
const speed = ref<number>(1.0)
|
||||
|
||||
// Check if API key is configured
|
||||
const apiKeyConfigured = computed(() => !!providers.value[providerId]?.apiKey)
|
||||
|
||||
// Generate speech with specific parameters
|
||||
async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean, modelId?: string) {
|
||||
const provider = await providersStore.getProviderInstance<SpeechProvider<string>>(providerId)
|
||||
if (!provider)
|
||||
throw new Error('Failed to initialize speech provider')
|
||||
|
||||
const providerConfig = providersStore.getProviderConfig(providerId)
|
||||
|
||||
return await speechStore.speech(
|
||||
provider,
|
||||
modelId || model.value,
|
||||
input,
|
||||
voiceId || voice.value,
|
||||
{
|
||||
...providerConfig,
|
||||
...defaultVoiceSettings,
|
||||
speed: speed.value,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Use the composable to get validation logic and state
|
||||
const {
|
||||
t,
|
||||
router,
|
||||
providerMetadata,
|
||||
isValidating,
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProviderSettingsLayout
|
||||
:provider-name="providerMetadata?.localizedName"
|
||||
:provider-icon-color="providerMetadata?.iconColor"
|
||||
:on-back="() => router.back()"
|
||||
>
|
||||
<ProviderSettingsContainer>
|
||||
<ProviderBasicSettings
|
||||
:title="t('settings.pages.providers.common.section.basic.title')"
|
||||
:description="t('settings.pages.providers.common.section.basic.description')"
|
||||
:on-reset="handleResetSettings"
|
||||
>
|
||||
<ProviderApiKeyInput
|
||||
v-model="apiKey"
|
||||
:required="false"
|
||||
:provider-name="providerMetadata?.localizedName"
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
</ProviderBasicSettings>
|
||||
|
||||
<ProviderAdvancedSettings :title="t('settings.pages.providers.common.section.advanced.title')">
|
||||
<ProviderBaseUrlInput
|
||||
v-model="baseUrl"
|
||||
:placeholder="providerMetadata?.defaultOptions?.().baseUrl as string || 'https://api.cometapi.com/v1/'"
|
||||
/>
|
||||
<FieldRange
|
||||
v-model="speed"
|
||||
:label="t('settings.pages.providers.provider.common.fields.field.speed.label')"
|
||||
:description="t('settings.pages.providers.provider.common.fields.field.speed.description')"
|
||||
:min="0.5"
|
||||
:max="2.0" :step="0.01"
|
||||
/>
|
||||
</ProviderAdvancedSettings>
|
||||
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
{{ validationMessage }}
|
||||
</div>
|
||||
</template>
|
||||
</Alert>
|
||||
<Alert v-if="isValid && isValidating === 0" type="success">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationSuccess') }}
|
||||
</template>
|
||||
</Alert>
|
||||
</ProviderSettingsContainer>
|
||||
|
||||
<SpeechPlaygroundOpenAICompatible
|
||||
v-model:model-value="model"
|
||||
v-model:voice="voice"
|
||||
:generate-speech="handleGenerateSpeech"
|
||||
:api-key-configured="apiKeyConfigured"
|
||||
default-text="Hello! This is a test of the Comet API Speech."
|
||||
/>
|
||||
</ProviderSettingsLayout>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: settings
|
||||
stageTransition:
|
||||
name: slide
|
||||
</route>
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
<script setup lang="ts">
|
||||
import type { RemovableRef } from '@vueuse/core'
|
||||
import type { TranscriptionProvider } from '@xsai-ext/shared-providers'
|
||||
|
||||
import {
|
||||
Alert,
|
||||
ProviderAdvancedSettings,
|
||||
ProviderApiKeyInput,
|
||||
ProviderBaseUrlInput,
|
||||
ProviderBasicSettings,
|
||||
ProviderSettingsContainer,
|
||||
ProviderSettingsLayout,
|
||||
TranscriptionPlayground,
|
||||
} from '@proj-airi/stage-ui/components'
|
||||
import { useProviderValidation } from '@proj-airi/stage-ui/composables/use-provider-validation'
|
||||
import { useHearingStore } from '@proj-airi/stage-ui/stores/modules/hearing'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
|
||||
import { FieldInput } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const providerId = 'comet-api-transcription'
|
||||
const hearingStore = useHearingStore()
|
||||
const providersStore = useProvidersStore()
|
||||
const { providers } = storeToRefs(providersStore) as { providers: RemovableRef<Record<string, any>> }
|
||||
|
||||
// Define computed properties for credentials
|
||||
const apiKey = computed({
|
||||
get: () => providers.value[providerId]?.apiKey || '',
|
||||
set: (value) => {
|
||||
if (!providers.value[providerId])
|
||||
providers.value[providerId] = {}
|
||||
providers.value[providerId].apiKey = value
|
||||
},
|
||||
})
|
||||
|
||||
const baseUrl = computed({
|
||||
get: () => providers.value[providerId]?.baseUrl || '',
|
||||
set: (value) => {
|
||||
if (!providers.value[providerId])
|
||||
providers.value[providerId] = {}
|
||||
providers.value[providerId].baseUrl = value
|
||||
},
|
||||
})
|
||||
|
||||
const model = computed({
|
||||
get: () => providers.value[providerId]?.model || '',
|
||||
set: (value) => {
|
||||
if (!providers.value[providerId])
|
||||
providers.value[providerId] = {}
|
||||
providers.value[providerId].model = value
|
||||
},
|
||||
})
|
||||
|
||||
// Check if API key is configured
|
||||
const apiKeyConfigured = computed(() => !!providers.value[providerId]?.apiKey)
|
||||
|
||||
// Generate transcription
|
||||
async function handleGenerateTranscription(file: File) {
|
||||
const provider = await providersStore.getProviderInstance<TranscriptionProvider<string>>(providerId)
|
||||
if (!provider)
|
||||
throw new Error('Failed to initialize transcription provider')
|
||||
|
||||
return await hearingStore.transcription(
|
||||
provider,
|
||||
model.value,
|
||||
file,
|
||||
'json',
|
||||
)
|
||||
}
|
||||
|
||||
// Use the composable to get validation logic and state
|
||||
const {
|
||||
t,
|
||||
router,
|
||||
providerMetadata,
|
||||
isValidating,
|
||||
isValid,
|
||||
validationMessage,
|
||||
handleResetSettings,
|
||||
} = useProviderValidation(providerId)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProviderSettingsLayout
|
||||
:provider-name="providerMetadata?.localizedName"
|
||||
:provider-icon-color="providerMetadata?.iconColor"
|
||||
:on-back="() => router.back()"
|
||||
>
|
||||
<ProviderSettingsContainer>
|
||||
<ProviderBasicSettings
|
||||
:title="t('settings.pages.providers.common.section.basic.title')"
|
||||
:description="t('settings.pages.providers.common.section.basic.description')"
|
||||
:on-reset="handleResetSettings"
|
||||
>
|
||||
<ProviderApiKeyInput
|
||||
v-model="apiKey"
|
||||
:provider-name="providerMetadata?.localizedName"
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
<FieldInput
|
||||
v-model="model"
|
||||
:label="t('settings.pages.modules.consciousness.sections.section.provider-model-selection.manual_model_name')"
|
||||
:placeholder="t('settings.pages.modules.consciousness.sections.section.provider-model-selection.manual_model_placeholder')"
|
||||
/>
|
||||
</ProviderBasicSettings>
|
||||
|
||||
<ProviderAdvancedSettings :title="t('settings.pages.providers.common.section.advanced.title')">
|
||||
<ProviderBaseUrlInput
|
||||
v-model="baseUrl"
|
||||
:placeholder="providerMetadata?.defaultOptions?.().baseUrl as string || 'https://api.cometapi.com/v1/'"
|
||||
/>
|
||||
</ProviderAdvancedSettings>
|
||||
|
||||
<!-- Validation Status -->
|
||||
<Alert v-if="!isValid && isValidating === 0 && validationMessage" type="error">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationFailed') }}
|
||||
</template>
|
||||
<template v-if="validationMessage" #content>
|
||||
<div class="whitespace-pre-wrap break-all">
|
||||
{{ validationMessage }}
|
||||
</div>
|
||||
</template>
|
||||
</Alert>
|
||||
<Alert v-if="isValid && isValidating === 0" type="success">
|
||||
<template #title>
|
||||
{{ t('settings.dialogs.onboarding.validationSuccess') }}
|
||||
</template>
|
||||
</Alert>
|
||||
</ProviderSettingsContainer>
|
||||
|
||||
<TranscriptionPlayground
|
||||
:generate-transcription="handleGenerateTranscription"
|
||||
:api-key-configured="apiKeyConfigured"
|
||||
/>
|
||||
</ProviderSettingsLayout>
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: settings
|
||||
stageTransition:
|
||||
name: slide
|
||||
</route>
|
||||
@@ -39,6 +39,8 @@ import {
|
||||
createEmbedProvider,
|
||||
createMetadataProvider,
|
||||
createModelProvider,
|
||||
createSpeechProvider,
|
||||
createTranscriptionProvider,
|
||||
merge,
|
||||
} from '@xsai-ext/shared-providers'
|
||||
import { listModels } from '@xsai/model'
|
||||
@@ -1250,6 +1252,38 @@ export const useProvidersStore = defineStore('providers', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
'comet-api-speech': buildOpenAICompatibleProvider({
|
||||
id: 'comet-api-speech',
|
||||
name: 'CometAPI Speech',
|
||||
nameKey: 'settings.pages.providers.provider.comet-api.title',
|
||||
descriptionKey: 'settings.pages.providers.provider.comet-api.description',
|
||||
icon: 'i-lobe-icons:cometapi',
|
||||
description: 'cometapi.com',
|
||||
category: 'speech',
|
||||
tasks: ['text-to-speech'],
|
||||
defaultBaseUrl: 'https://api.cometapi.com/v1/',
|
||||
creator: (apiKey, baseURL = 'https://api.cometapi.com/v1/') => merge(
|
||||
createModelProvider({ apiKey, baseURL }),
|
||||
createSpeechProvider({ apiKey, baseURL }),
|
||||
),
|
||||
validation: ['model_list'],
|
||||
}),
|
||||
'comet-api-transcription': buildOpenAICompatibleProvider({
|
||||
id: 'comet-api-transcription',
|
||||
name: 'CometAPI Transcription',
|
||||
nameKey: 'settings.pages.providers.provider.comet-api.title',
|
||||
descriptionKey: 'settings.pages.providers.provider.comet-api.description',
|
||||
icon: 'i-lobe-icons:cometapi',
|
||||
description: 'cometapi.com',
|
||||
category: 'transcription',
|
||||
tasks: ['speech-to-text', 'automatic-speech-recognition', 'asr', 'stt'],
|
||||
defaultBaseUrl: 'https://api.cometapi.com/v1/',
|
||||
creator: (apiKey, baseURL = 'https://api.cometapi.com/v1/') => merge(
|
||||
createModelProvider({ apiKey, baseURL }),
|
||||
createTranscriptionProvider({ apiKey, baseURL }),
|
||||
),
|
||||
validation: ['model_list'],
|
||||
}),
|
||||
'together-ai': buildOpenAICompatibleProvider({
|
||||
id: 'together-ai',
|
||||
name: 'Together.ai',
|
||||
@@ -1482,6 +1516,20 @@ export const useProvidersStore = defineStore('providers', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
'comet-api': buildOpenAICompatibleProvider({
|
||||
id: 'comet-api',
|
||||
name: 'CometAPI',
|
||||
nameKey: 'settings.pages.providers.provider.comet-api.title',
|
||||
descriptionKey: 'settings.pages.providers.provider.comet-api.description',
|
||||
icon: 'i-lobe-icons:cometapi',
|
||||
description: 'cometapi.com',
|
||||
defaultBaseUrl: 'https://api.cometapi.com/v1/',
|
||||
creator: (apiKey, baseURL = 'https://api.cometapi.com/v1/') => merge(
|
||||
createChatProvider({ apiKey, baseURL }),
|
||||
createModelProvider({ apiKey, baseURL }),
|
||||
),
|
||||
validation: ['model_list'],
|
||||
}),
|
||||
'perplexity-ai': buildOpenAICompatibleProvider({
|
||||
id: 'perplexity-ai',
|
||||
name: 'Perplexity',
|
||||
|
||||
Reference in New Issue
Block a user