diff --git a/apps/stage-web/package.json b/apps/stage-web/package.json
index f26a540a..ba093509 100644
--- a/apps/stage-web/package.json
+++ b/apps/stage-web/package.json
@@ -58,6 +58,8 @@
"@xsai/stream-text": "catalog:",
"@xsai/utils-chat": "catalog:",
"defu": "^6.1.4",
+ "drizzle-kit": "^0.30.5",
+ "drizzle-orm": "^0.40.0",
"jszip": "^3.10.1",
"nprogress": "^0.2.0",
"ofetch": "^1.4.1",
@@ -92,6 +94,7 @@
"@iconify-json/svg-spinners": "^1.2.2",
"@iconify/utils": "^2.3.0",
"@intlify/unplugin-vue-i18n": "^6.0.3",
+ "@proj-airi/drizzle-duckdb-wasm": "workspace:^",
"@proj-airi/elevenlabs": "workspace:^",
"@proj-airi/lobe-icons": "workspace:^",
"@proj-airi/provider-transformers": "workspace:^",
diff --git a/apps/stage-web/src/components/Widgets/ModelProviderSettings.vue b/apps/stage-web/src/components/Widgets/ModelProviderSettings.vue
index 34727fcd..6ec3daf5 100644
--- a/apps/stage-web/src/components/Widgets/ModelProviderSettings.vue
+++ b/apps/stage-web/src/components/Widgets/ModelProviderSettings.vue
@@ -1,8 +1,10 @@
diff --git a/packages/stage-ui/src/stores/chat.ts b/packages/stage-ui/src/stores/chat.ts
index ab374298..bec4e649 100644
--- a/packages/stage-ui/src/stores/chat.ts
+++ b/packages/stage-ui/src/stores/chat.ts
@@ -1,19 +1,19 @@
import type { AssistantMessage, Message } from '@xsai/shared-chat'
import { defineStore, storeToRefs } from 'pinia'
-import { ref } from 'vue'
+import { ref, toRaw } from 'vue'
import { useI18n } from 'vue-i18n'
import { useLlmmarkerParser } from '../composables/llmmarkerParser'
import SystemPromptV2 from '../constants/prompts/system-v2'
import { useLLM } from '../stores/llm'
-import { useSettings } from '../stores/settings'
+import { useProvidersStore } from '../stores/providers'
import { asyncIteratorFromReadableStream } from '../utils/iterator'
export const useChatStore = defineStore('chat', () => {
const { stream } = useLLM()
const { t } = useI18n()
- const { openAiApiBaseURL, openAiApiKey, openAiModel } = storeToRefs(useSettings())
+ const { providers: providerValues } = storeToRefs(useProvidersStore())
const onBeforeMessageComposedHooks = ref Promise>>([])
const onAfterMessageComposedHooks = ref Promise>>([])
@@ -22,6 +22,7 @@ export const useChatStore = defineStore('chat', () => {
const onTokenLiteralHooks = ref Promise>>([])
const onTokenSpecialHooks = ref Promise>>([])
const onStreamEndHooks = ref Promise>>([])
+ const onAssistantResponseEndHooks = ref Promise>>([])
function onBeforeMessageComposed(cb: (message: string) => Promise) {
onBeforeMessageComposedHooks.value.push(cb)
@@ -51,6 +52,10 @@ export const useChatStore = defineStore('chat', () => {
onStreamEndHooks.value.push(cb)
}
+ function onAssistantResponseEnd(cb: (message: string) => Promise) {
+ onAssistantResponseEndHooks.value.push(cb)
+ }
+
const messages = ref>([
SystemPromptV2(
t('prompt.prefix'),
@@ -73,15 +78,15 @@ export const useChatStore = defineStore('chat', () => {
}
const {
- baseUrl = openAiApiBaseURL.value,
- apiKey = openAiApiKey.value,
- model = openAiModel.value,
+ baseUrl = providerValues.value['openrouter-ai']?.baseUrl as string | undefined || '',
+ apiKey = providerValues.value['openrouter-ai']?.apiKey as string | undefined || '',
+ model = providerValues.value['openrouter-ai']?.model as { id: string } | undefined || { id: 'openai/gpt-4o-mini' },
} = options ?? { }
streamingMessage.value = { role: 'assistant', content: '' }
messages.value.push({ role: 'user', content: sendingMessage })
messages.value.push(streamingMessage.value)
- const newMessages = messages.value.slice(0, messages.value.length - 1)
+ const newMessages = messages.value.slice(0, messages.value.length - 1).map(msg => toRaw(msg))
for (const hook of onAfterMessageComposedHooks.value) {
await hook(sendingMessage)
@@ -125,6 +130,10 @@ export const useChatStore = defineStore('chat', () => {
await hook()
}
+ for (const hook of onAssistantResponseEndHooks.value) {
+ await hook(fullText)
+ }
+
// eslint-disable-next-line no-console
console.debug('LLM output:', fullText)
}
@@ -140,5 +149,6 @@ export const useChatStore = defineStore('chat', () => {
onTokenLiteral,
onTokenSpecial,
onStreamEnd,
+ onAssistantResponseEnd,
}
})
diff --git a/packages/stage-ui/src/stores/index.ts b/packages/stage-ui/src/stores/index.ts
index 436f44f3..ee50944d 100644
--- a/packages/stage-ui/src/stores/index.ts
+++ b/packages/stage-ui/src/stores/index.ts
@@ -1,4 +1,5 @@
export * from './audio'
export * from './chat'
export * from './llm'
+export * from './providers'
export * from './settings'
diff --git a/packages/stage-ui/src/stores/providers.ts b/packages/stage-ui/src/stores/providers.ts
new file mode 100644
index 00000000..309d8c27
--- /dev/null
+++ b/packages/stage-ui/src/stores/providers.ts
@@ -0,0 +1,10 @@
+import { useLocalStorage } from '@vueuse/core'
+import { defineStore } from 'pinia'
+
+export const useProvidersStore = defineStore('providers', () => {
+ const providers = useLocalStorage>>('settings/credentials/providers', {})
+
+ return {
+ providers,
+ }
+})
diff --git a/packages/stage-ui/tsconfig.json b/packages/stage-ui/tsconfig.json
index ca3eae4f..64e10f9d 100644
--- a/packages/stage-ui/tsconfig.json
+++ b/packages/stage-ui/tsconfig.json
@@ -10,7 +10,8 @@
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"types": [
- "vitest"
+ "vitest",
+ "vite/client"
],
"allowJs": true,
"strict": true,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9cd7aaae..3fc13ae6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -179,7 +179,7 @@ importers:
version: 0.8.2
'@gcornut/valibot-json-schema':
specifier: ^0.42.0
- version: 0.42.0(esbuild@0.25.0)(typescript@5.7.3)
+ version: 0.42.0(esbuild@0.24.2)(typescript@5.7.3)
'@huggingface/transformers':
specifier: ^3.3.3
version: 3.3.3
@@ -248,7 +248,7 @@ importers:
version: 2.10.3
'@typeschema/valibot':
specifier: ^0.14.0
- version: 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.25.0)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
+ version: 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.2)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
'@unhead/vue':
specifier: ^2.0.0-alpha.27
version: 2.0.0-alpha.27(vue@3.5.13(typescript@5.7.3))
@@ -378,7 +378,7 @@ importers:
version: 2.3.0
'@intlify/unplugin-vue-i18n':
specifier: ^6.0.3
- version: 6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.21.0(jiti@2.4.2))(rollup@4.34.8)(typescript@5.7.3)(vue-i18n@11.1.1(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
+ version: 6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.21.0(jiti@2.4.2))(rollup@2.79.1)(typescript@5.7.3)(vue-i18n@11.1.1(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
'@proj-airi/elevenlabs':
specifier: workspace:^
version: link:../../packages/elevenlabs
@@ -405,10 +405,10 @@ importers:
version: 5.2.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
'@vue-macros/volar':
specifier: ^0.30.14
- version: 0.30.14(rollup@4.34.8)(typescript@5.7.3)(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
+ version: 0.30.14(rollup@2.79.1)(typescript@5.7.3)(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
'@vueuse/motion':
specifier: ^2.2.6
- version: 2.2.6(magicast@0.3.5)(rollup@4.34.8)(vue@3.5.13(typescript@5.7.3))
+ version: 2.2.6(magicast@0.3.5)(rollup@2.79.1)(vue@3.5.13(typescript@5.7.3))
electron:
specifier: ^34.3.0
version: 34.3.0
@@ -426,28 +426,28 @@ importers:
version: 3.2.0(unocss@66.1.0-beta.3(postcss@8.5.3)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3)))
unplugin-auto-import:
specifier: ^19.1.1
- version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(@vueuse/core@12.7.0(typescript@5.7.3))
+ version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(@vueuse/core@12.7.0(typescript@5.7.3))
unplugin-vue-components:
specifier: ^28.4.1
- version: 28.4.1(@babel/parser@7.26.7)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(vue@3.5.13(typescript@5.7.3))
+ version: 28.4.1(@babel/parser@7.26.7)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(vue@3.5.13(typescript@5.7.3))
unplugin-vue-macros:
specifier: ^2.14.4
- version: 2.14.4(@vueuse/core@12.7.0(typescript@5.7.3))(esbuild@0.25.0)(rollup@4.34.8)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
+ version: 2.14.4(@vueuse/core@12.7.0(typescript@5.7.3))(esbuild@0.24.2)(rollup@2.79.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
unplugin-vue-markdown:
specifier: ^28.3.1
version: 28.3.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
unplugin-vue-router:
specifier: ^0.11.2
- version: 0.11.2(rollup@4.34.8)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
+ version: 0.11.2(rollup@2.79.1)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
vite-bundle-visualizer:
specifier: ^1.2.1
- version: 1.2.1(rollup@4.34.8)
+ version: 1.2.1(rollup@2.79.1)
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(workbox-build@7.3.0)(workbox-window@7.3.0)
vite-plugin-vue-devtools:
specifier: ^7.7.2
- version: 7.7.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(rollup@4.34.8)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
+ version: 7.7.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(rollup@2.79.1)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
vite-plugin-vue-layouts:
specifier: ^0.11.0
version: 0.11.0(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
@@ -465,7 +465,7 @@ importers:
version: 0.8.2
'@gcornut/valibot-json-schema':
specifier: ^0.42.0
- version: 0.42.0(esbuild@0.24.2)(typescript@5.7.3)
+ version: 0.42.0(esbuild@0.25.0)(typescript@5.7.3)
'@huggingface/transformers':
specifier: ^3.3.3
version: 3.3.3
@@ -537,7 +537,7 @@ importers:
version: 2.10.3
'@typeschema/valibot':
specifier: ^0.14.0
- version: 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.2)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
+ version: 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.25.0)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
'@unhead/vue':
specifier: ^2.0.0-alpha.27
version: 2.0.0-alpha.27(vue@3.5.13(typescript@5.7.3))
@@ -580,6 +580,12 @@ importers:
defu:
specifier: ^6.1.4
version: 6.1.4
+ drizzle-kit:
+ specifier: ^0.30.5
+ version: 0.30.5
+ drizzle-orm:
+ specifier: ^0.40.0
+ version: 0.40.0(@types/pg@8.11.11)(gel@2.0.0)(pg@8.13.3)
jszip:
specifier: ^3.10.1
version: 3.10.1
@@ -676,7 +682,10 @@ importers:
version: 2.3.0
'@intlify/unplugin-vue-i18n':
specifier: ^6.0.3
- version: 6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.21.0(jiti@2.4.2))(rollup@2.79.1)(typescript@5.7.3)(vue-i18n@11.1.1(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
+ version: 6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.21.0(jiti@2.4.2))(rollup@4.34.8)(typescript@5.7.3)(vue-i18n@11.1.1(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
+ '@proj-airi/drizzle-duckdb-wasm':
+ specifier: workspace:^
+ version: link:../../packages/drizzle-duckdb-wasm
'@proj-airi/elevenlabs':
specifier: workspace:^
version: link:../../packages/elevenlabs
@@ -709,10 +718,10 @@ importers:
version: 5.2.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
'@vue-macros/volar':
specifier: ^0.30.14
- version: 0.30.14(rollup@2.79.1)(typescript@5.7.3)(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
+ version: 0.30.14(rollup@4.34.8)(typescript@5.7.3)(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
'@vueuse/motion':
specifier: ^2.2.6
- version: 2.2.6(magicast@0.3.5)(rollup@2.79.1)(vue@3.5.13(typescript@5.7.3))
+ version: 2.2.6(magicast@0.3.5)(rollup@4.34.8)(vue@3.5.13(typescript@5.7.3))
hfup:
specifier: workspace:^
version: link:../../packages/hfup
@@ -721,28 +730,28 @@ importers:
version: 4.0.1
unplugin-auto-import:
specifier: ^19.1.1
- version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(@vueuse/core@12.7.0(typescript@5.7.3))
+ version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(@vueuse/core@12.7.0(typescript@5.7.3))
unplugin-vue-components:
specifier: ^28.4.1
- version: 28.4.1(@babel/parser@7.26.7)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(vue@3.5.13(typescript@5.7.3))
+ version: 28.4.1(@babel/parser@7.26.7)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(vue@3.5.13(typescript@5.7.3))
unplugin-vue-macros:
specifier: ^2.14.4
- version: 2.14.4(@vueuse/core@12.7.0(typescript@5.7.3))(esbuild@0.24.2)(rollup@2.79.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
+ version: 2.14.4(@vueuse/core@12.7.0(typescript@5.7.3))(esbuild@0.25.0)(rollup@4.34.8)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@2.2.4(typescript@5.7.3))(vue@3.5.13(typescript@5.7.3))
unplugin-vue-markdown:
specifier: ^28.3.1
version: 28.3.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
unplugin-vue-router:
specifier: ^0.11.2
- version: 0.11.2(rollup@2.79.1)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
+ version: 0.11.2(rollup@4.34.8)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
vite-bundle-visualizer:
specifier: ^1.2.1
- version: 1.2.1(rollup@2.79.1)
+ version: 1.2.1(rollup@4.34.8)
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.1(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(workbox-build@7.3.0)(workbox-window@7.3.0)
vite-plugin-vue-devtools:
specifier: ^7.7.2
- version: 7.7.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(rollup@2.79.1)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
+ version: 7.7.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.34.8))(rollup@4.34.8)(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
vite-plugin-vue-layouts:
specifier: ^0.11.0
version: 0.11.0(vite@6.2.0(@types/node@22.13.5)(jiti@2.4.2)(less@4.2.1)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
@@ -1017,6 +1026,15 @@ importers:
'@electron-toolkit/preload':
specifier: ^3.0.1
version: 3.0.1(electron@34.3.0)
+ '@proj-airi/provider-transformers':
+ specifier: workspace:^
+ version: link:../provider-transformers
+ '@proj-airi/utils-transformers':
+ specifier: workspace:^
+ version: link:../utils-transformers
+ '@xsai/embed':
+ specifier: 'catalog:'
+ version: 0.1.0-beta.9
packages/unplugin-download:
dependencies:
@@ -14576,7 +14594,7 @@ snapshots:
dependencies:
'@typeschema/core': 0.14.0(@types/json-schema@7.0.15)
optionalDependencies:
- '@typeschema/valibot': 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.25.0)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
+ '@typeschema/valibot': 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.2)(typescript@5.7.3))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.3))
'@typeschema/zod': 0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.3(zod@3.24.2))(zod@3.24.2)
transitivePeerDependencies:
- '@types/json-schema'
diff --git a/vitest.workspace.ts b/vitest.workspace.ts
index c1c57f06..121ea02d 100644
--- a/vitest.workspace.ts
+++ b/vitest.workspace.ts
@@ -5,5 +5,4 @@ export default defineWorkspace([
'apps/*',
'services/*',
'examples/*',
- 'docs/*',
])