From f471bec2d4cbaffa7d50e44717d89bd5582de862 Mon Sep 17 00:00:00 2001 From: Inoki Date: Mon, 21 Jul 2025 08:44:45 +0200 Subject: [PATCH] feat: Add Azure AI Foundry provider for consciousness (#272) --- .../src/components/InteractiveArea.vue | 2 +- .../src/pages/settings/modules/speech.vue | 2 +- .../providers/alibaba-cloud-model-studio.vue | 2 +- .../pages/settings/providers/elevenlabs.vue | 2 +- .../settings/providers/microsoft-speech.vue | 2 +- .../settings/providers/player2-speech.vue | 2 +- .../pages/settings/providers/volcengine.vue | 2 +- .../components/Layouts/InteractiveArea.vue | 4 +- .../Layouts/MobileInteractiveArea.vue | 2 +- .../src/pages/settings/modules/speech.vue | 2 +- .../providers/alibaba-cloud-model-studio.vue | 2 +- .../settings/providers/azure-ai-foundry.vue | 148 ++++++++++++++++++ .../pages/settings/providers/elevenlabs.vue | 2 +- .../settings/providers/microsoft-speech.vue | 2 +- .../settings/providers/player2-speech.vue | 2 +- .../pages/settings/providers/volcengine.vue | 2 +- .../stage-ui/src/components/Scenes/Stage.vue | 2 +- packages/stage-ui/src/stores/providers.ts | 101 ++++++++---- 18 files changed, 235 insertions(+), 48 deletions(-) create mode 100644 apps/stage-web/src/pages/settings/providers/azure-ai-foundry.vue diff --git a/apps/stage-tamagotchi/src/components/InteractiveArea.vue b/apps/stage-tamagotchi/src/components/InteractiveArea.vue index c1f069658..6675f1eb0 100644 --- a/apps/stage-tamagotchi/src/components/InteractiveArea.vue +++ b/apps/stage-tamagotchi/src/components/InteractiveArea.vue @@ -31,7 +31,7 @@ async function handleSend() { const providerConfig = providersStore.getProviderConfig(activeProvider.value) await send(messageInput.value, { model: activeModel.value, - chatProvider: providersStore.getProviderInstance(activeProvider.value) as ChatProvider, + chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider, providerConfig, }) } diff --git a/apps/stage-tamagotchi/src/pages/settings/modules/speech.vue b/apps/stage-tamagotchi/src/pages/settings/modules/speech.vue index f1cb28c79..5e5ecf6cc 100644 --- a/apps/stage-tamagotchi/src/pages/settings/modules/speech.vue +++ b/apps/stage-tamagotchi/src/pages/settings/modules/speech.vue @@ -81,7 +81,7 @@ async function generateTestSpeech() { return } - const provider = providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions if (!provider) { console.error('Failed to initialize speech provider') return diff --git a/apps/stage-tamagotchi/src/pages/settings/providers/alibaba-cloud-model-studio.vue b/apps/stage-tamagotchi/src/pages/settings/providers/alibaba-cloud-model-studio.vue index 51794e96d..6fbec0534 100644 --- a/apps/stage-tamagotchi/src/pages/settings/providers/alibaba-cloud-model-studio.vue +++ b/apps/stage-tamagotchi/src/pages/settings/providers/alibaba-cloud-model-studio.vue @@ -39,7 +39,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-tamagotchi/src/pages/settings/providers/elevenlabs.vue b/apps/stage-tamagotchi/src/pages/settings/providers/elevenlabs.vue index 0f4d99011..721aa2e66 100644 --- a/apps/stage-tamagotchi/src/pages/settings/providers/elevenlabs.vue +++ b/apps/stage-tamagotchi/src/pages/settings/providers/elevenlabs.vue @@ -47,7 +47,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-tamagotchi/src/pages/settings/providers/microsoft-speech.vue b/apps/stage-tamagotchi/src/pages/settings/providers/microsoft-speech.vue index 0fb2a7a31..8fe8b2cf4 100644 --- a/apps/stage-tamagotchi/src/pages/settings/providers/microsoft-speech.vue +++ b/apps/stage-tamagotchi/src/pages/settings/providers/microsoft-speech.vue @@ -65,7 +65,7 @@ watch([apiKeyConfigured, region], async () => { // Generate speech with Microsoft-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-tamagotchi/src/pages/settings/providers/player2-speech.vue b/apps/stage-tamagotchi/src/pages/settings/providers/player2-speech.vue index 6b685b50b..6ee4ef386 100644 --- a/apps/stage-tamagotchi/src/pages/settings/providers/player2-speech.vue +++ b/apps/stage-tamagotchi/src/pages/settings/providers/player2-speech.vue @@ -23,7 +23,7 @@ const availableVoices = computed(() => { }) // Generate speech with Player2-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-tamagotchi/src/pages/settings/providers/volcengine.vue b/apps/stage-tamagotchi/src/pages/settings/providers/volcengine.vue index 559125b1f..ffd017ce0 100644 --- a/apps/stage-tamagotchi/src/pages/settings/providers/volcengine.vue +++ b/apps/stage-tamagotchi/src/pages/settings/providers/volcengine.vue @@ -45,7 +45,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-web/src/components/Layouts/InteractiveArea.vue b/apps/stage-web/src/components/Layouts/InteractiveArea.vue index ed4764fb1..9b14d13d5 100644 --- a/apps/stage-web/src/components/Layouts/InteractiveArea.vue +++ b/apps/stage-web/src/components/Layouts/InteractiveArea.vue @@ -40,7 +40,7 @@ const { transcribe: generate, terminate } = useWhisper(WhisperWorker, { const providerConfig = providersStore.getProviderConfig(activeProvider.value) await send(res, { - chatProvider: providersStore.getProviderInstance(activeProvider.value) as ChatProvider, + chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider, model: activeModel.value, providerConfig, }) @@ -56,7 +56,7 @@ async function handleSend() { const providerConfig = providersStore.getProviderConfig(activeProvider.value) await send(messageInput.value, { - chatProvider: providersStore.getProviderInstance(activeProvider.value) as ChatProvider, + chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider, model: activeModel.value, providerConfig, }) diff --git a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue b/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue index f92311cfe..c853cf8dd 100644 --- a/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue +++ b/apps/stage-web/src/components/Layouts/MobileInteractiveArea.vue @@ -42,7 +42,7 @@ async function handleSend() { const providerConfig = providersStore.getProviderConfig(activeProvider.value) await send(messageInput.value, { - chatProvider: providersStore.getProviderInstance(activeProvider.value) as ChatProvider, + chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider, model: activeModel.value, providerConfig, }) diff --git a/apps/stage-web/src/pages/settings/modules/speech.vue b/apps/stage-web/src/pages/settings/modules/speech.vue index f7bb5971c..e7d19f08e 100644 --- a/apps/stage-web/src/pages/settings/modules/speech.vue +++ b/apps/stage-web/src/pages/settings/modules/speech.vue @@ -81,7 +81,7 @@ async function generateTestSpeech() { return } - const provider = providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions if (!provider) { console.error('Failed to initialize speech provider') return diff --git a/apps/stage-web/src/pages/settings/providers/alibaba-cloud-model-studio.vue b/apps/stage-web/src/pages/settings/providers/alibaba-cloud-model-studio.vue index 51794e96d..6fbec0534 100644 --- a/apps/stage-web/src/pages/settings/providers/alibaba-cloud-model-studio.vue +++ b/apps/stage-web/src/pages/settings/providers/alibaba-cloud-model-studio.vue @@ -39,7 +39,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-web/src/pages/settings/providers/azure-ai-foundry.vue b/apps/stage-web/src/pages/settings/providers/azure-ai-foundry.vue new file mode 100644 index 000000000..b844f071e --- /dev/null +++ b/apps/stage-web/src/pages/settings/providers/azure-ai-foundry.vue @@ -0,0 +1,148 @@ + + + + + + meta: + layout: settings + stageTransition: + name: slide + diff --git a/apps/stage-web/src/pages/settings/providers/elevenlabs.vue b/apps/stage-web/src/pages/settings/providers/elevenlabs.vue index 0f4d99011..721aa2e66 100644 --- a/apps/stage-web/src/pages/settings/providers/elevenlabs.vue +++ b/apps/stage-web/src/pages/settings/providers/elevenlabs.vue @@ -47,7 +47,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-web/src/pages/settings/providers/microsoft-speech.vue b/apps/stage-web/src/pages/settings/providers/microsoft-speech.vue index 177f3e436..8bb234ca5 100644 --- a/apps/stage-web/src/pages/settings/providers/microsoft-speech.vue +++ b/apps/stage-web/src/pages/settings/providers/microsoft-speech.vue @@ -65,7 +65,7 @@ watch([apiKeyConfigured, region], async () => { // Generate speech with Microsoft-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-web/src/pages/settings/providers/player2-speech.vue b/apps/stage-web/src/pages/settings/providers/player2-speech.vue index 727294b73..e4a0aba8d 100644 --- a/apps/stage-web/src/pages/settings/providers/player2-speech.vue +++ b/apps/stage-web/src/pages/settings/providers/player2-speech.vue @@ -26,7 +26,7 @@ const availableVoices = computed(() => { // Generate speech with Player2-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/apps/stage-web/src/pages/settings/providers/volcengine.vue b/apps/stage-web/src/pages/settings/providers/volcengine.vue index 559125b1f..ffd017ce0 100644 --- a/apps/stage-web/src/pages/settings/providers/volcengine.vue +++ b/apps/stage-web/src/pages/settings/providers/volcengine.vue @@ -45,7 +45,7 @@ const availableVoices = computed(() => { // Generate speech with ElevenLabs-specific parameters async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) { - const provider = providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions if (!provider) { throw new Error('Failed to initialize speech provider') } diff --git a/packages/stage-ui/src/components/Scenes/Stage.vue b/packages/stage-ui/src/components/Scenes/Stage.vue index aecf20351..86a7ec039 100644 --- a/packages/stage-ui/src/components/Scenes/Stage.vue +++ b/packages/stage-ui/src/components/Scenes/Stage.vue @@ -92,7 +92,7 @@ async function handleSpeechGeneration(ctx: { data: string }) { } // TODO: UnElevenLabsOptions - const provider = providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions + const provider = await providersStore.getProviderInstance(activeSpeechProvider.value) as SpeechProviderWithExtraOptions if (!provider) { console.error('Failed to initialize speech provider') return diff --git a/packages/stage-ui/src/stores/providers.ts b/packages/stage-ui/src/stores/providers.ts index a1cba5be4..ff43eb47c 100644 --- a/packages/stage-ui/src/stores/providers.ts +++ b/packages/stage-ui/src/stores/providers.ts @@ -20,6 +20,7 @@ import type { import { computedAsync, useLocalStorage } from '@vueuse/core' import { createAnthropic, + createAzure, createDeepSeek, createFireworks, createGoogleGenerativeAI, @@ -94,7 +95,7 @@ export interface ProviderMetadata { */ iconImage?: string defaultOptions?: () => Record - createProvider: (config: Record) => + createProvider: (config: Record) => Promise< | ChatProvider | ChatProviderWithExtraOptions | EmbedProvider @@ -103,6 +104,7 @@ export interface ProviderMetadata { | SpeechProviderWithExtraOptions | TranscriptionProvider | TranscriptionProviderWithExtraOptions + > capabilities: { listModels?: (config: Record) => Promise listVoices?: (config: Record) => Promise @@ -185,7 +187,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://openrouter.ai/api/v1/', }), - createProvider: config => createOpenRouter((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createOpenRouter((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return fetchOpenRouterModels(config) @@ -216,7 +218,7 @@ export const useProvidersStore = defineStore('providers', () => { description: 'https://github.com/huggingface/candle', icon: 'i-lobe-icons:huggingface', defaultOptions: () => ({}), - createProvider: config => createOpenAI((config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -264,7 +266,7 @@ export const useProvidersStore = defineStore('providers', () => { description: 'https://github.com/huggingface/candle', icon: 'i-lobe-icons:huggingface', defaultOptions: () => ({}), - createProvider: config => createOpenAI((config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -319,7 +321,7 @@ export const useProvidersStore = defineStore('providers', () => { description: 'https://github.com/moeru-ai/xsai-transformers', icon: 'i-lobe-icons:huggingface', defaultOptions: () => ({}), - createProvider: config => createOpenAI((config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -374,7 +376,7 @@ export const useProvidersStore = defineStore('providers', () => { description: 'https://github.com/moeru-ai/xsai-transformers', icon: 'i-lobe-icons:huggingface', defaultOptions: () => ({}), - createProvider: config => createOpenAI((config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -415,7 +417,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'http://localhost:11434/v1/', }), - createProvider: config => createOllama((config.baseUrl as string).trim()), + createProvider: async config => createOllama((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -456,7 +458,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'http://localhost:11434/v1/', }), - createProvider: config => createOllama((config.baseUrl as string).trim()), + createProvider: async config => createOllama((config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -488,7 +490,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.vllm.description', description: 'vllm.ai', iconColor: 'i-lobe-icons:vllm', - createProvider: config => createOllama((config.baseUrl as string).trim()), + createProvider: async config => createOllama((config.baseUrl as string).trim()), capabilities: { listModels: async () => { return [ @@ -555,7 +557,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.openai.com/v1/', }), - createProvider: config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -590,7 +592,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.openai.com/v1/', }), - createProvider: config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -695,7 +697,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.openai.com/v1/', }), - createProvider: config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -718,6 +720,43 @@ export const useProvidersStore = defineStore('providers', () => { }, }, }, + 'azure-ai-foundry': { + id: 'azure-ai-foundry', + category: 'chat', + tasks: ['text-generation'], + nameKey: 'settings.pages.providers.provider.azure_ai_foundry.title', + name: 'Azure AI Foundry', + descriptionKey: 'settings.pages.providers.provider.azure_ai_foundry.description', + description: 'azure.com', + icon: 'i-lobe-icons:microsoft', + defaultOptions: () => ({}), + createProvider: async (config) => { + return await createAzure({ + apiKey: async () => (config.apiKey as string).trim(), + resourceName: config.resourceName as string, + apiVersion: config.apiVersion as string, + }) + }, + capabilities: { + listModels: async (config) => { + return [{ id: config.modelId }].map((model) => { + return { + id: model.id as string, + name: model.id as string, + provider: 'azure-ai-foundry', + description: '', + contextLength: 0, + deprecated: false, + } satisfies ModelInfo + }) + }, + }, + validators: { + validateProviderConfig: (config) => { + return !!config.apiKey && !!config.resourceName && !!config.modelId + }, + }, + }, 'anthropic': { id: 'anthropic', category: 'chat', @@ -730,7 +769,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.anthropic.com/v1/', }), - createProvider: config => createAnthropic((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createAnthropic((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async () => { return [ @@ -803,7 +842,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai/', }), - createProvider: config => createGoogleGenerativeAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createGoogleGenerativeAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -835,7 +874,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.xai.description', description: 'x.ai', icon: 'i-lobe-icons:xai', - createProvider: config => createXAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createXAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -870,7 +909,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.deepseek.com/', }), - createProvider: config => createDeepSeek((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createDeepSeek((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -909,7 +948,7 @@ export const useProvidersStore = defineStore('providers', () => { stability: 0.5, }, }), - createProvider: config => createUnElevenLabs((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as SpeechProviderWithExtraOptions, + createProvider: async config => createUnElevenLabs((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as SpeechProviderWithExtraOptions, capabilities: { listModels: async () => { return elevenLabsModels.map((model) => { @@ -976,7 +1015,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://unspeech.hyp3r.link/v1/', }), - createProvider: config => createUnMicrosoft((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as SpeechProviderWithExtraOptions, + createProvider: async config => createUnMicrosoft((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as SpeechProviderWithExtraOptions, capabilities: { listModels: async () => { return [ @@ -1027,7 +1066,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://unspeech.hyp3r.link/v1/', }), - createProvider: config => createUnAlibabaCloud((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createUnAlibabaCloud((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listVoices: async (config) => { const provider = createUnAlibabaCloud((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as VoiceProviderWithExtraOptions @@ -1086,7 +1125,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://unspeech.hyp3r.link/v1/', }), - createProvider: config => createUnVolcengine((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createUnVolcengine((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listVoices: async (config) => { const provider = createUnVolcengine((config.apiKey as string).trim(), (config.baseUrl as string).trim()) as VoiceProviderWithExtraOptions @@ -1134,7 +1173,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.together.description', description: 'together.ai', iconColor: 'i-lobe-icons:together', - createProvider: config => createTogetherAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createTogetherAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1166,7 +1205,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.novita.description', description: 'novita.ai', iconColor: 'i-lobe-icons:novita', - createProvider: config => createNovita((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createNovita((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1198,7 +1237,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.fireworks.description', description: 'fireworks.ai', icon: 'i-lobe-icons:fireworks', - createProvider: config => createFireworks((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createFireworks((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1233,7 +1272,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.featherless.ai/v1/', }), - createProvider: config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createOpenAI((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1266,7 +1305,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.cloudflare-workers-ai.description', description: 'cloudflare.com', iconColor: 'i-lobe-icons:cloudflare', - createProvider: config => createWorkersAI((config.apiKey as string).trim(), config.accountId as string), + createProvider: async config => createWorkersAI((config.apiKey as string).trim(), config.accountId as string), capabilities: { listModels: async () => { return [] @@ -1290,7 +1329,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'https://api.perplexity.ai', }), - createProvider: config => createPerplexity((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createPerplexity((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async () => { return [ @@ -1347,7 +1386,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.mistral.description', description: 'mistral.ai', iconColor: 'i-lobe-icons:mistral', - createProvider: config => createMistral((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createMistral((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1379,7 +1418,7 @@ export const useProvidersStore = defineStore('providers', () => { descriptionKey: 'settings.pages.providers.provider.moonshot.description', description: 'moonshot.ai', icon: 'i-lobe-icons:moonshot', - createProvider: config => createMoonshot((config.apiKey as string).trim(), (config.baseUrl as string).trim()), + createProvider: async config => createMoonshot((config.apiKey as string).trim(), (config.baseUrl as string).trim()), capabilities: { listModels: async (config) => { return (await listModels({ @@ -1452,7 +1491,7 @@ export const useProvidersStore = defineStore('providers', () => { defaultOptions: () => ({ baseUrl: 'http://localhost:4315/v1/', }), - createProvider: config => createPlayer2((config.baseUrl as string).trim(), 'airi'), + createProvider: async config => createPlayer2((config.baseUrl as string).trim(), 'airi'), capabilities: { listVoices: async () => { return await fetch('http://localhost:4315/v1/tts/voices').then(res => res.json()).then(({ voices }) => (voices as { id: string, language: 'american_english' | 'british_english' | 'japanese' | 'mandarin_chinese' | 'spanish' | 'french' | 'hindi' | 'italian' | 'brazilian_portuguese', name: string, gender: string }[]).map(({ id, language, name, gender }) => ( @@ -1650,7 +1689,7 @@ export const useProvidersStore = defineStore('providers', () => { }) // Function to get provider object by provider id - function getProviderInstance(providerId: string) { + async function getProviderInstance(providerId: string) { const config = providerCredentials.value[providerId] if (!config) throw new Error(`Provider credentials for ${providerId} not found`) @@ -1660,7 +1699,7 @@ export const useProvidersStore = defineStore('providers', () => { throw new Error(`Provider metadata for ${providerId} not found`) try { - return metadata.createProvider(config) + return await metadata.createProvider(config) } catch (error) { console.error(`Error creating provider instance for ${providerId}:`, error)