fix(stage-web|stage-tamagotchi): duckdb-wasm import url
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/solar": "^1.2.2",
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"superjson": "^2.2.2",
|
||||
"unplugin-vue-router": "^0.12.0",
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
"author": "LemonNekoGH",
|
||||
"scripts": {
|
||||
"typecheck": "vue-tsc --noEmit --composite false",
|
||||
"start": "electron-vite preview",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"tauri": "tauri",
|
||||
"build:unpack": "tauri build --no-bundle"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -76,7 +77,7 @@
|
||||
"vaul-vue": "^0.4.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-demi": "^0.14.10",
|
||||
"vue-i18n": "^11.1.2",
|
||||
"vue-i18n": "^11.1.3",
|
||||
"vue-router": "^4.5.0",
|
||||
"xsschema": "catalog:",
|
||||
"yauzl": "^3.2.0",
|
||||
@@ -105,11 +106,11 @@
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/three": "^0.175.0",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vue-macros/volar": "^3.0.0-beta.7",
|
||||
"@vueuse/motion": "^3.0.3",
|
||||
"less": "^4.2.2",
|
||||
"less": "^4.3.0",
|
||||
"markdown-it-link-attributes": "^4.0.1",
|
||||
"unocss-preset-scrollbar": "^3.2.0",
|
||||
"unplugin-auto-import": "^19.1.2",
|
||||
|
||||
@@ -14,12 +14,14 @@ export default defineConfig({
|
||||
optimizeDeps: {
|
||||
exclude: [
|
||||
'@proj-airi/stage-ui/*',
|
||||
'@proj-airi/drizzle-duckdb-wasm',
|
||||
'@proj-airi/drizzle-duckdb-wasm/*',
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@proj-airi/stage-ui': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'dist')),
|
||||
'@proj-airi/stage-ui/stores': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'dist', 'stores')),
|
||||
'@proj-airi/stage-ui': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'src')),
|
||||
'@proj-airi/stage-ui/stores': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'src', 'stores')),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
"vaul-vue": "^0.4.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-demi": "^0.14.10",
|
||||
"vue-i18n": "^11.1.2",
|
||||
"vue-i18n": "^11.1.3",
|
||||
"vue-router": "^4.5.0",
|
||||
"xsschema": "catalog:",
|
||||
"yauzl": "^3.2.0",
|
||||
@@ -113,12 +113,12 @@
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/three": "^0.175.0",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vue-macros/volar": "^3.0.0-beta.7",
|
||||
"@vueuse/motion": "^3.0.3",
|
||||
"hfup": "^0.5.0",
|
||||
"less": "^4.2.2",
|
||||
"less": "^4.3.0",
|
||||
"markdown-it-link-attributes": "^4.0.1",
|
||||
"unplugin-auto-import": "^19.1.2",
|
||||
"unplugin-vue-components": "^28.4.1",
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
<script setup lang="ts">
|
||||
import type { AssistantMessage, Message } from '@xsai/shared-chat'
|
||||
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { streamText } from '@xsai/stream-text'
|
||||
import { createWorkflow, workflowEvent } from 'fluere'
|
||||
import { promiseHandler } from 'fluere/interrupter/promise'
|
||||
import { withValidation } from 'fluere/middleware/validation'
|
||||
import { ref, toRaw } from 'vue'
|
||||
|
||||
const baseUrl = useLocalStorage('settings/llm/baseUrl', 'https://openrouter.ai/api/v1/')
|
||||
const apiKey = useLocalStorage('settings/llm/apiKey', '')
|
||||
const model = useLocalStorage('settings/llm/model', 'openai/gpt-4o-mini')
|
||||
const sendingMessage = ref('')
|
||||
const messages = ref<Message[]>([])
|
||||
const streamingMessage = ref<AssistantMessage>({ role: 'assistant', content: '' })
|
||||
const loading = ref(false)
|
||||
|
||||
const sendingEvent = workflowEvent<void, 'sending'>()
|
||||
const tokenEvent = workflowEvent<string, 'token'>()
|
||||
const textEvent = workflowEvent<string, 'text'>()
|
||||
const sentenceEvent = workflowEvent<string, 'sentence'>()
|
||||
const doneEvent = workflowEvent<void, 'done'>()
|
||||
|
||||
async function handleChatSendMessage() {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const streamWorkflow = withValidation(createWorkflow(), [
|
||||
[[sendingEvent], [tokenEvent, doneEvent]],
|
||||
[[tokenEvent], [textEvent]],
|
||||
[[textEvent], [sentenceEvent]],
|
||||
])
|
||||
|
||||
streamWorkflow.handle([sendingEvent], async (sendEvent) => {
|
||||
streamingMessage.value = { role: 'assistant', content: '' }
|
||||
messages.value.push({ role: 'user', content: sendingMessage.value })
|
||||
messages.value.push(streamingMessage.value)
|
||||
|
||||
const response = await streamText({
|
||||
baseURL: baseUrl.value,
|
||||
apiKey: apiKey.value,
|
||||
model: model.value,
|
||||
messages: messages.value.slice(0, messages.value.length - 1).map(msg => toRaw(msg)),
|
||||
})
|
||||
|
||||
for await (const chunk of response.chunkStream)
|
||||
sendEvent(tokenEvent.with(chunk.choices[0].delta.content || ''))
|
||||
|
||||
return doneEvent.with()
|
||||
})
|
||||
|
||||
streamWorkflow.handle([tokenEvent], async (_sendEvent, token) => {
|
||||
if (!streamingMessage.value.content)
|
||||
streamingMessage.value.content = token.data
|
||||
else
|
||||
streamingMessage.value.content += token.data
|
||||
})
|
||||
|
||||
await promiseHandler(streamWorkflow, sendingEvent.with(), doneEvent)
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// function useMessageTerminationWorkflow(parentWorkflow: WithValidationWorkflow<[[[typeof textEvent], [typeof sentenceEvent]]]>) {
|
||||
// let processed = ''
|
||||
|
||||
// parentWorkflow.handle([textEvent], async (sendEvent, text) => {
|
||||
// const endMarker = /[.?!]/
|
||||
// processed += text.data
|
||||
|
||||
// while (processed) {
|
||||
// const endMarkerExecArray = endMarker.exec(processed)
|
||||
// if (!endMarkerExecArray || typeof endMarkerExecArray.index === 'undefined')
|
||||
// break
|
||||
|
||||
// const before = processed.slice(0, endMarkerExecArray.index + 1)
|
||||
// const after = processed.slice(endMarkerExecArray.index + 1)
|
||||
|
||||
// sendEvent(sentenceEvent.with(before))
|
||||
// processed = after
|
||||
// }
|
||||
// })
|
||||
|
||||
// parentWorkflow.handle([doneEvent], async () => {
|
||||
// const { sendEvent } = getContext()
|
||||
|
||||
// const content = processed.trim()
|
||||
// if (content)
|
||||
// sendEvent(sentenceEvent.with(content))
|
||||
|
||||
// processed = ''
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div flex flex-col gap-2>
|
||||
<!-- <h2 text-xl>
|
||||
Storage
|
||||
</h2> -->
|
||||
<div flex="~ col" gap-2>
|
||||
<div flex flex-col gap-2>
|
||||
<div>
|
||||
<span text-neutral-500 dark:text-neutral-400>LLM</span>
|
||||
</div>
|
||||
<div grid grid-cols-2 gap-2>
|
||||
<label flex items-center gap-2>
|
||||
<span text-nowrap>
|
||||
Base URL
|
||||
</span>
|
||||
<input
|
||||
v-model="baseUrl"
|
||||
border="focus:primary-100 dark:focus:primary-400/50 2 solid neutral-200 dark:neutral-800"
|
||||
transition="all duration-200 ease-in-out" text="disabled:neutral-400 dark:disabled:neutral-600"
|
||||
cursor="disabled:not-allowed" w-full rounded-lg px-2 py-1 text-nowrap text-sm outline-none shadow="sm"
|
||||
bg="neutral-100 dark:neutral-800 focus:neutral-50 dark:focus:neutral-900"
|
||||
>
|
||||
</label>
|
||||
<label flex items-center gap-2>
|
||||
<span text-nowrap>
|
||||
API Key
|
||||
</span>
|
||||
<input
|
||||
v-model="apiKey"
|
||||
type="password"
|
||||
border="focus:primary-100 dark:focus:primary-400/50 2 solid neutral-200 dark:neutral-800"
|
||||
transition="all duration-200 ease-in-out" text="disabled:neutral-400 dark:disabled:neutral-600"
|
||||
cursor="disabled:not-allowed" w-full rounded-lg px-2 py-1 text-nowrap text-sm outline-none shadow="sm"
|
||||
bg="neutral-100 dark:neutral-800 focus:neutral-50 dark:focus:neutral-900"
|
||||
>
|
||||
</label>
|
||||
<label flex items-center gap-2>
|
||||
<span text-nowrap>
|
||||
Model
|
||||
</span>
|
||||
<input
|
||||
v-model="model"
|
||||
border="focus:primary-100 dark:focus:primary-400/50 2 solid neutral-200 dark:neutral-800"
|
||||
transition="all duration-200 ease-in-out" text="disabled:neutral-400 dark:disabled:neutral-600"
|
||||
cursor="disabled:not-allowed" w-full rounded-lg px-2 py-1 text-nowrap text-sm outline-none shadow="sm"
|
||||
bg="neutral-100 dark:neutral-800 focus:neutral-50 dark:focus:neutral-900"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<textarea
|
||||
v-model="sendingMessage"
|
||||
border="focus:primary-100 dark:focus:primary-400/50 2 solid neutral-200 dark:neutral-800"
|
||||
transition="all duration-200 ease-in-out" text="disabled:neutral-400 dark:disabled:neutral-600"
|
||||
cursor="disabled:not-allowed" w-full rounded-lg px-2 py-1 text-nowrap text-sm outline-none shadow="sm"
|
||||
bg="neutral-100 dark:neutral-800 focus:neutral-50 dark:focus:neutral-900"
|
||||
/>
|
||||
</div>
|
||||
<button rounded-lg bg="blue-100 dark:blue-900" px-4 py-2 @click="handleChatSendMessage">
|
||||
Send
|
||||
</button>
|
||||
<div>
|
||||
<div v-for="(message, index) of messages" :key="index">
|
||||
<div v-if="message.role === 'user'">
|
||||
<span>
|
||||
{{ message.content }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="message.role === 'assistant'">
|
||||
<span>
|
||||
{{ message.content }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -24,6 +24,8 @@ export default defineConfig({
|
||||
optimizeDeps: {
|
||||
exclude: [
|
||||
'@proj-airi/stage-ui/*',
|
||||
'@proj-airi/drizzle-duckdb-wasm',
|
||||
'@proj-airi/drizzle-duckdb-wasm/*',
|
||||
'public/assets/*',
|
||||
'@framework/live2dcubismframework',
|
||||
'@framework/math/cubismmatrix44',
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"98.css": "^0.1.20",
|
||||
"@astrojs/starlight": "^0.32.5",
|
||||
"@astrojs/starlight": "^0.32.6",
|
||||
"@fontsource/fusion-pixel-12px-proportional-sc": "^5.2.5",
|
||||
"@fontsource/quicksand": "^5.2.6",
|
||||
"astro": "^5.6.1",
|
||||
|
||||
+3
-3
@@ -36,8 +36,8 @@
|
||||
"@antfu/ni": "^24.3.0",
|
||||
"@cspell/dict-ru_ru": "^2.2.4",
|
||||
"@types/node": "^22.14.0",
|
||||
"@unocss/eslint-config": "^66.1.0-beta.9",
|
||||
"@unocss/eslint-plugin": "^66.1.0-beta.9",
|
||||
"@unocss/eslint-config": "^66.1.0-beta.10",
|
||||
"@unocss/eslint-plugin": "^66.1.0-beta.10",
|
||||
"@vitest/coverage-v8": "3.0.5",
|
||||
"bumpp": "^10.1.0",
|
||||
"changelogithub": "^13.13.0",
|
||||
@@ -51,7 +51,7 @@
|
||||
"taze": "^19.0.4",
|
||||
"typescript": "~5.8.3",
|
||||
"unbuild": "3.0.0-rc.11",
|
||||
"unocss": "^66.1.0-beta.9",
|
||||
"unocss": "^66.1.0-beta.10",
|
||||
"vite": "^6.2.5",
|
||||
"vite-plugin-inspect": "^11.0.0",
|
||||
"vitest": "^3.1.1"
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/solar": "^1.2.2",
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vueuse/core": "^13.0.0",
|
||||
"vite": "^6.2.5",
|
||||
|
||||
@@ -72,11 +72,11 @@
|
||||
"@histoire/plugin-vue": "1.0.0-alpha.2",
|
||||
"@proj-airi/provider-transformers": "workspace:^",
|
||||
"@proj-airi/utils-transformers": "workspace:^",
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@xsai/embed": "catalog:",
|
||||
"histoire": "1.0.0-alpha.2",
|
||||
"unocss": "^66.1.0-beta.9",
|
||||
"unocss": "^66.1.0-beta.10",
|
||||
"vite": "^6.2.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { SpeechProviderWithExtraOptions } from '@xsai-ext/shared-providers'
|
||||
import type { Emotion } from '../../constants/emotions'
|
||||
|
||||
import { drizzle } from '@proj-airi/drizzle-duckdb-wasm'
|
||||
import { getImportUrlBundles } from '@proj-airi/drizzle-duckdb-wasm/bundles/import-url-browser'
|
||||
// import { createTransformers } from '@proj-airi/provider-transformers'
|
||||
// import embedWorkerURL from '@proj-airi/provider-transformers/worker?worker&url'
|
||||
// import { embed } from '@xsai/embed'
|
||||
@@ -235,7 +236,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
db.value = drizzle('duckdb-wasm://?bundles=import-url')
|
||||
db.value = drizzle({ connection: { bundles: getImportUrlBundles() } })
|
||||
await db.value.execute(sql`CREATE TABLE memory_test (vec FLOAT[768]);`)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@unocss/reset": "^66.1.0-beta.9",
|
||||
"@unocss/reset": "^66.1.0-beta.10",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"unplugin-vue-router": "^0.12.0",
|
||||
"vite-plugin-vue-devtools": "^7.7.2",
|
||||
|
||||
Generated
+385
-370
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -7,7 +7,7 @@ packages:
|
||||
- '!**/dist/**'
|
||||
|
||||
catalog:
|
||||
'@proj-airi/drizzle-duckdb-wasm': ^0.4.20
|
||||
'@proj-airi/drizzle-duckdb-wasm': ^0.4.21
|
||||
'@xsai/shared': &xsai ^0.2.0-beta.3
|
||||
'@xsai-ext/providers-cloud': *xsai
|
||||
'@xsai-ext/providers-local': *xsai
|
||||
|
||||
Reference in New Issue
Block a user