feat(stage-web|stage-tamagotchi|server-sdk|server-runtime|server-shared|stage-ui): added new events for ui:configure, and module:configure, and added basic implementation of the memory-pgvector process holding, also adjusted the border style of radio set of card

This commit is contained in:
Neko Ayaka
2025-03-21 01:49:32 +08:00
parent 367d57f305
commit f3b93ab465
38 changed files with 408 additions and 87 deletions
@@ -67,6 +67,8 @@ settings:
models:
description: Live2D, VRM, etc.
title: Models
memory:
description: Where memories got stored, and organized
modules:
consciousness:
description: Personality, desired model, etc.
@@ -50,6 +50,9 @@ settings:
microphone: 麦克风
models: 模型
pages:
memory:
description: 存放记忆的地方,以及策略
title: 记忆体
models:
description: 切换角色的 Live2DVRM 模型
title: 角色模型
@@ -207,7 +207,7 @@ function handleLanguageChange(event: Event) {
</div>
</label>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div v-motion text="60" i-lucide:cog />
</div>
</div>
@@ -67,7 +67,7 @@ async function extractColorsFromModel() {
<Live2DSettings w="50%" h="80vh" :palette="palette" @extract-colors-from-model="extractColorsFromModel" />
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:person-standing />
</div>
</template>
@@ -214,7 +214,7 @@ function updateCustomModelName(value: string) {
</div>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:ghost />
</div>
</template>
@@ -142,7 +142,7 @@ const modulesList = computed<Module[]>(() => [
:configured="module.configured"
/>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:blocks />
</div>
</template>
@@ -50,7 +50,7 @@ const { allProvidersMetadata } = storeToRefs(providersStore)
:configured="provider.configured"
/>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:brain />
</div>
</template>
@@ -368,7 +368,7 @@ function isColorSelected(hexColor: string): boolean {
</Collapsable>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:paintbrush />
</div>
</template>
+2
View File
@@ -67,6 +67,8 @@ settings:
microphone: Microphone
models: Model
pages:
memory:
description: Where memories got stored, and organized
models:
description: Live2D, VRM, etc.
title: Models
+3
View File
@@ -53,6 +53,9 @@ settings:
microphone: 麦克风
models: 模型
pages:
memory:
description: 存放记忆的地方,以及策略
title: 记忆体
models:
description: 切换角色的 Live2DVRM 模型
title: 角色模型
+5 -4
View File
@@ -36,7 +36,12 @@
"@pixiv/three-vrm": "^3.3.6",
"@pixiv/three-vrm-animation": "^3.3.6",
"@pixiv/three-vrm-core": "^3.3.6",
"@proj-airi/drizzle-duckdb-wasm": "workspace:^",
"@proj-airi/elevenlabs": "workspace:^",
"@proj-airi/provider-transformers": "workspace:^",
"@proj-airi/server-sdk": "workspace:^",
"@proj-airi/stage-ui": "workspace:^",
"@proj-airi/ui-transitions": "workspace:^",
"@ricky0123/vad-web": "^0.0.22",
"@standard-schema/spec": "^1.0.0",
"@tresjs/cientos": "^4.2.0",
@@ -97,11 +102,7 @@
"@iconify-json/vscode-icons": "^1.2.16",
"@iconify/utils": "^2.3.0",
"@intlify/unplugin-vue-i18n": "^6.0.5",
"@proj-airi/drizzle-duckdb-wasm": "workspace:^",
"@proj-airi/elevenlabs": "workspace:^",
"@proj-airi/lobe-icons": "^1.0.4",
"@proj-airi/provider-transformers": "workspace:^",
"@proj-airi/ui-transitions": "workspace:^",
"@proj-airi/unplugin-fetch": "^0.1.4",
"@proj-airi/unplugin-live2d-sdk": "^0.1.2",
"@shikijs/markdown-it": "^3.2.1",
+12 -1
View File
@@ -56,6 +56,17 @@ function handleLanguageChange(event: Event) {
icon="i-lucide:person-standing"
to="/settings/models"
/>
<IconItem
v-motion
:initial="{ opacity: 0, y: 10 }"
:enter="{ opacity: 1, y: 0 }"
:duration="250"
:delay="100"
:title="t('settings.pages.memory.title')"
:description="t('settings.pages.memory.description')"
icon="i-lucide:sprout"
to="/settings/memory"
/>
<IconItem
v-motion
:initial="{ opacity: 0, y: 10 }"
@@ -207,7 +218,7 @@ function handleLanguageChange(event: Event) {
</div>
</label>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div v-motion text="60" i-lucide:cog />
</div>
</div>
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
const router = useRouter()
const { t } = useI18n()
</script>
<template>
<div
v-motion
flex="~ row" items-center gap-2
:initial="{ opacity: 0, x: 10 }"
:enter="{ opacity: 1, x: 0 }"
:leave="{ opacity: 0, x: -10 }"
:duration="250"
>
<button @click="router.back()">
<div i-solar:alt-arrow-left-line-duotone text-2xl />
</button>
<h1 relative>
<div absolute left-0 top-0 translate-y="[-80%]">
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
</div>
<div text-nowrap text-3xl font-semibold>
{{ t('settings.pages.memory.title') }}
</div>
</h1>
</div>
</template>
@@ -68,7 +68,7 @@ async function extractColorsFromModel() {
<Live2DSettings w="50%" h="80vh" :palette="palette" @extract-colors-from-model="extractColorsFromModel" />
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:person-standing />
</div>
</template>
@@ -214,7 +214,7 @@ function updateCustomModelName(value: string) {
</div>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:ghost />
</div>
</template>
@@ -57,7 +57,7 @@ const modulesList = computed<Module[]>(() => [
name: t('settings.pages.modules.memory-short-term.title'),
description: t('settings.pages.modules.memory-short-term.description'),
icon: 'i-lucide:book',
to: '',
to: '/settings/modules/memory-short-term',
configured: false,
},
{
@@ -65,7 +65,7 @@ const modulesList = computed<Module[]>(() => [
name: t('settings.pages.modules.memory-long-term.title'),
description: t('settings.pages.modules.memory-long-term.description'),
icon: 'i-lucide:book-copy',
to: '',
to: '/settings/modules/memory-long-term',
configured: false,
},
{
@@ -142,7 +142,7 @@ const modulesList = computed<Module[]>(() => [
:configured="module.configured"
/>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:blocks />
</div>
</template>
@@ -0,0 +1,33 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
const router = useRouter()
const { t } = useI18n()
// const serverStore = useServerStore()
</script>
<template>
<div
v-motion
flex="~ row" items-center gap-2
:initial="{ opacity: 0, x: 10 }"
:enter="{ opacity: 1, x: 0 }"
:leave="{ opacity: 0, x: -10 }"
:duration="250"
>
<button @click="router.back()">
<div i-solar:alt-arrow-left-line-duotone text-2xl />
</button>
<h1 relative>
<div absolute left-0 top-0 translate-y="[-80%]">
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
</div>
<div text-nowrap text-3xl font-semibold>
{{ t('settings.pages.modules.memory-long-term.title') }}
</div>
</h1>
</div>
</template>
@@ -0,0 +1,33 @@
<script setup lang="ts">
// import { useServerStore } from '@proj-airi/stage-ui/stores'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
const router = useRouter()
const { t } = useI18n()
// const serverStore = useServerStore()
</script>
<template>
<div
v-motion
flex="~ row" items-center gap-2
:initial="{ opacity: 0, x: 10 }"
:enter="{ opacity: 1, x: 0 }"
:leave="{ opacity: 0, x: -10 }"
:duration="250"
>
<button @click="router.back()">
<div i-solar:alt-arrow-left-line-duotone text-2xl />
</button>
<h1 relative>
<div absolute left-0 top-0 translate-y="[-80%]">
<span text="neutral-300 dark:neutral-500" text-nowrap>{{ t('settings.title') }}</span>
</div>
<div text-nowrap text-3xl font-semibold>
{{ t('settings.pages.modules.memory-short-term.title') }}
</div>
</h1>
</div>
</template>
@@ -50,7 +50,7 @@ const { allProvidersMetadata } = storeToRefs(providersStore)
:configured="provider.configured"
/>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:brain />
</div>
</template>
@@ -368,7 +368,7 @@ function isColorSelected(hexColor: string): boolean {
</Collapsable>
</div>
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" i-lucide:paintbrush />
</div>
</template>
+21
View File
@@ -0,0 +1,21 @@
{
"name": "@proj-airi/memory-pgvector",
"type": "module",
"version": "1.0.0",
"description": "",
"author": "",
"license": "MIT",
"keywords": [],
"scripts": {
"dev": "tsx src/index.ts"
},
"dependencies": {
"@guiiai/logg": "^1.0.7",
"@proj-airi/server-sdk": "workspace:^",
"drizzle-orm": "^0.40.1",
"postgres": "^3.4.5"
},
"devDependencies": {
"tsx": "^4.19.3"
}
}
+15
View File
@@ -0,0 +1,15 @@
import { Format, LogLevel, setGlobalFormat, setGlobalLogLevel } from '@guiiai/logg'
import { Client } from '@proj-airi/server-sdk'
import { runUntilSignal } from './utils/process'
setGlobalFormat(Format.Pretty)
setGlobalLogLevel(LogLevel.Log)
async function main() {
const _client = new Client<{ connectionString: string }>({ name: 'memory-pgvector' })
runUntilSignal()
}
main()
@@ -0,0 +1,30 @@
import process from 'node:process'
import { useLogg } from '@guiiai/logg'
const logger = useLogg('process').useGlobalConfig()
let running = true
function killProcess() {
running = false
}
process.on('SIGTERM', () => {
logger.log('SIGTERM received')
killProcess()
})
process.on('SIGINT', () => {
logger.log('SIGINT received')
killProcess()
})
process.on('uncaughtException', (e) => {
logger.withError(e).error('uncaught exception')
killProcess()
})
export function runUntilSignal() {
setTimeout(() => {
if (running)
runUntilSignal()
}, 10)
}
+18
View File
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext"
],
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
+22 -3
View File
@@ -30,11 +30,11 @@ function main() {
open: (peer) => {
const token = env.AUTHENTICATION_TOKEN || ''
if (token) {
peers.set(peer.id, { peer, authenticated: false })
peers.set(peer.id, { peer, authenticated: false, name: '' })
}
else {
send(peer, { type: 'module:authenticated', data: { authenticated: true } })
peers.set(peer.id, { peer, authenticated: true })
peers.set(peer.id, { peer, authenticated: true, name: '' })
}
websocketLogger.withFields({ peer: peer.id, activePeers: peers.size }).log('connected')
@@ -52,7 +52,26 @@ function main() {
}
send(peer, { type: 'module:authenticated', data: { authenticated: true } })
peers.set(peer.id, { peer, authenticated: true })
peers.set(peer.id, { peer, authenticated: true, name: '' })
return
case 'module:announce':
peers.set(peer.id, { peer, authenticated: true, name: event.data.name })
return
case 'ui:configure':
peers.forEach((p) => {
if (p.name === '') {
return
}
if ((typeof p.index !== 'undefined' && typeof event.data.moduleIndex !== 'undefined' && p.name === event.data.moduleName && p.index === event.data.moduleIndex)) {
return
}
if (p.name !== event.data.moduleName) {
return
}
p.peer.send(JSON.stringify({ type: 'module:configure', data: { config: event.data.config } } as WebSocketEvent))
})
return
}
if (!peers.get(peer.id)?.authenticated) {
+6 -1
View File
@@ -1,6 +1,11 @@
import type { Peer } from 'crossws'
export interface AuthenticatedPeer {
export interface NamedPeer {
name: string
index?: number
peer: Peer
}
export interface AuthenticatedPeer extends NamedPeer {
authenticated: boolean
}
+44 -18
View File
@@ -6,32 +6,47 @@ import { defu } from 'defu'
import { sleep } from './utils'
export interface ClientOptions {
export interface ClientOptions<C = undefined> {
url?: string
name: string
possibleEvents?: Array<(keyof WebSocketEvents)>
possibleEvents?: Array<(keyof WebSocketEvents<C>)>
token?: string
onError?: (error: unknown) => void
onClose?: () => void
autoConnect?: boolean
autoReconnect?: boolean
}
export class Client {
private opts: Required<ClientOptions>
export class Client<C = undefined> {
private connected = false
private opts: Required<ClientOptions<C>>
private websocket: WebSocket
private eventListeners: Map<
keyof WebSocketEvents,
Array<(data: WebSocketBaseEvent<
keyof WebSocketEvents,
WebSocketEvents[keyof WebSocketEvents]
>) => void | Promise<void>>
> = new Map()
private eventListeners: Map<keyof WebSocketEvents, Array<(data: WebSocketBaseEvent<keyof WebSocketEvents<C>, WebSocketEvents<C>[keyof WebSocketEvents<C>]>) => void | Promise<void>>> = new Map()
private authenticateAttempts = 0
constructor(options: ClientOptions) {
this.opts = defu<Required<ClientOptions>, Required<Omit<ClientOptions, 'name' | 'token'>>[]>(
constructor(options: ClientOptions<C>) {
this.opts = defu<Required<ClientOptions<C>>, Required<Omit<ClientOptions<C>, 'name' | 'token'>>[]>(
options,
{ url: 'ws://localhost:6121/ws', possibleEvents: [] },
{
url: 'ws://localhost:6121/ws',
possibleEvents: [],
onError: () => { },
onClose: () => { },
autoConnect: true,
autoReconnect: true,
},
)
if (this.opts.autoConnect) {
this.connect()
}
}
connect() {
if (this.connected)
return
this.websocket = new WebSocket(this.opts.url)
this.onEvent('module:authenticated', async (event) => {
@@ -46,6 +61,10 @@ export class Client {
}
})
this.websocket.onerror = (event) => {
this.opts.onError?.(event)
}
this.websocket.onmessage = this.handleMessage.bind(this)
this.websocket.onopen = () => {
@@ -55,10 +74,17 @@ export class Client {
else {
this.tryAnnounce()
}
this.connected = true
}
this.websocket.onclose = () => {
this.connected = false
this.authenticateAttempts = 0
this.opts.onClose?.()
if (this.opts.autoReconnect) {
this.connect()
}
}
}
@@ -79,7 +105,7 @@ export class Client {
}
private async handleMessage(event: any) {
const data = JSON.parse(event.data) as WebSocketEvent
const data = JSON.parse(event.data) as WebSocketEvent<C>
const listeners = this.eventListeners.get(data.type)
if (!listeners)
return
@@ -88,9 +114,9 @@ export class Client {
await listener(data)
}
onEvent<E extends keyof WebSocketEvents>(
onEvent<E extends keyof WebSocketEvents<C>>(
event: E,
callback: (data: WebSocketBaseEvent<E, WebSocketEvents[E]>) => void | Promise<void>,
callback: (data: WebSocketBaseEvent<E, WebSocketEvents<C>[E]>) => void | Promise<void>,
): void {
if (!this.eventListeners.get(event)) {
this.eventListeners.set(event, [])
@@ -101,7 +127,7 @@ export class Client {
this.eventListeners.set(event, listeners)
}
send(data: WebSocketEvent): void {
send(data: WebSocketEvent<C>): void {
this.websocket.send(JSON.stringify(data))
}
@@ -28,7 +28,7 @@ export type WithInputSource<Source extends keyof InputSource> = {
//
// A little hack for creating extensible discriminated unions : r/typescript
// https://www.reddit.com/r/typescript/comments/1064ibt/a_little_hack_for_creating_extensible/
export interface WebSocketEvents {
export interface WebSocketEvents<C = undefined> {
'error': {
message: string
}
@@ -40,7 +40,15 @@ export interface WebSocketEvents {
}
'module:announce': {
name: string
possibleEvents: Array<(keyof WebSocketEvents)>
possibleEvents: Array<(keyof WebSocketEvents<C>)>
}
'module:configure': {
config: C
}
'ui:configure': {
moduleName: string
moduleIndex?: number
config: C | Record<string, unknown>
}
'input:text': {
text: string
@@ -53,6 +61,6 @@ export interface WebSocketEvents {
} & Partial<WithInputSource<'browser' | 'discord'>>
}
export type WebSocketEvent = {
[K in keyof WebSocketEvents]: WebSocketBaseEvent<K, WebSocketEvents[K]>;
}[keyof WebSocketEvents]
export type WebSocketEvent<C = undefined> = {
[K in keyof WebSocketEvents<C>]: WebSocketBaseEvent<K, WebSocketEvents<C>[K]>;
}[keyof WebSocketEvents<C>]
+1
View File
@@ -57,6 +57,7 @@
},
"dependencies": {
"@formkit/auto-animate": "^0.8.2",
"@proj-airi/server-sdk": "workspace:^",
"@vueuse/motion": "^3.0.3",
"reka-ui": "^2.1.0",
"unist-builder": "^4.0.0",
@@ -21,7 +21,7 @@ const modelValue = defineModel<string>({ required: true })
:class="[
modelValue === value
? 'bg-primary-50 dark:bg-primary-900/20 border-primary-100 dark:border-primary-900 hover:border-primary-500/30 dark:hover:border-primary-400/30'
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-700 hover:border-primary-500/30 dark:hover:border-primary-400/30',
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-900 hover:border-primary-500/30 dark:hover:border-primary-400/30',
modelValue === value
? 'form_radio-active'
: '',
@@ -45,7 +45,7 @@ function toggleExpansion() {
:class="[
modelValue === value
? 'bg-primary-50 dark:bg-primary-900/20 border-primary-100 dark:border-primary-900 hover:border-primary-500/30 dark:hover:border-primary-400/30'
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-700 hover:border-primary-500/30 dark:hover:border-primary-400/30',
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-900 hover:border-primary-500/30 dark:hover:border-primary-400/30',
modelValue === value
? 'form_radio-card-detail-active'
: '',
@@ -19,7 +19,7 @@ const modelValue = defineModel<string>({ required: true })
:class="[
modelValue === value
? 'bg-primary-50 dark:bg-primary-900/20 border-primary-100 dark:border-primary-900 hover:border-primary-500/30 dark:hover:border-primary-400/30'
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-700 hover:border-primary-500/30 dark:hover:border-primary-400/30',
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-900 hover:border-primary-500/30 dark:hover:border-primary-400/30',
modelValue === value
? 'form_radio-card-simple-active'
: '',
@@ -95,7 +95,7 @@ function togglePlayback() {
:class="[
voiceId === props.voice.id
? 'bg-primary-50 dark:bg-primary-900/20 border-primary-100 dark:border-primary-900 hover:border-primary-500/30 dark:hover:border-primary-400/30'
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-700 hover:border-primary-500/30 dark:hover:border-primary-400/30',
: 'bg-white dark:bg-neutral-900/20 border-neutral-100 dark:border-neutral-900 hover:border-primary-500/30 dark:hover:border-primary-400/30',
voiceId === props.voice.id
? 'form_voice-card-active'
: '',
@@ -29,7 +29,7 @@ defineProps<{
</h1>
</div>
<slot />
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" :class="providerIcon || providerIconColor" />
</div>
</template>
@@ -120,7 +120,7 @@ function handleBackClick() {
<slot />
<!-- Background icon -->
<div text="neutral-200/50 dark:neutral-500/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="neutral-200/50 dark:neutral-600/20" pointer-events-none fixed bottom-0 right-0 z--1 translate-x-10 translate-y-10>
<div text="40" :class="providerIcon || providerIconColor" />
</div>
</div>
+1
View File
@@ -3,4 +3,5 @@ export * from './chat'
export * from './llm'
export * from './modules'
export * from './providers'
export * from './server'
export * from './settings'
+27
View File
@@ -0,0 +1,27 @@
import { Client } from '@proj-airi/server-sdk'
import { defineStore } from 'pinia'
import { onMounted, ref } from 'vue'
export const useServerStore = defineStore('server', () => {
const server = ref<Client>()
onMounted(() => {
server.value = new Client({
name: 'stage-web',
autoConnect: false,
autoReconnect: true,
onError: (error) => {
console.error(error)
},
})
})
function connect() {
server.value?.connect()
}
return {
server,
connect,
}
})
+68 -36
View File
@@ -309,7 +309,7 @@ importers:
version: 0.30.5
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
jszip:
specifier: ^3.10.1
version: 3.10.1
@@ -418,7 +418,7 @@ importers:
version: 2.3.0
'@intlify/unplugin-vue-i18n':
specifier: ^6.0.5
version: 6.0.5(@vue/compiler-dom@3.5.13)(eslint@9.22.0(jiti@2.4.2))(rollup@2.79.1)(typescript@5.8.2)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
version: 6.0.5(@vue/compiler-dom@3.5.13)(eslint@9.22.0(jiti@2.4.2))(rollup@4.36.0)(typescript@5.8.2)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
'@proj-airi/drizzle-duckdb-wasm':
specifier: workspace:^
version: link:../../packages/drizzle-duckdb-wasm
@@ -469,7 +469,7 @@ importers:
version: 3.0.0-beta.5(typescript@5.8.2)(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
'@vueuse/motion':
specifier: ^3.0.3
version: 3.0.3(magicast@0.3.5)(rollup@2.79.1)(vue@3.5.13(typescript@5.8.2))
version: 3.0.3(magicast@0.3.5)(rollup@4.36.0)(vue@3.5.13(typescript@5.8.2))
electron:
specifier: ^34.3.3
version: 34.3.3
@@ -490,13 +490,13 @@ importers:
version: 3.2.0(unocss@66.1.0-beta.6(postcss@8.5.3)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)))
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@13.0.0(vue@3.5.13(typescript@5.8.2)))
version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.36.0))(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))
unplugin-vue-components:
specifier: ^28.4.1
version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(vue@3.5.13(typescript@5.8.2))
version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.36.0))(vue@3.5.13(typescript@5.8.2))
unplugin-vue-macros:
specifier: ^2.14.5
version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@4.36.0)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
unplugin-vue-markdown:
specifier: ^28.3.1
version: 28.3.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
@@ -505,13 +505,13 @@ importers:
version: 0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
vite-bundle-visualizer:
specifier: ^1.2.1
version: 1.2.1(rollup@2.79.1)
version: 1.2.1(rollup@4.36.0)
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(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.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
version: 7.7.2(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.36.0))(rollup@4.36.0)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
vite-plugin-vue-layouts:
specifier: ^0.11.0
version: 0.11.0(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
@@ -578,9 +578,24 @@ importers:
'@pixiv/three-vrm-core':
specifier: ^3.3.6
version: 3.3.6(three@0.174.0)
'@proj-airi/drizzle-duckdb-wasm':
specifier: workspace:^
version: link:../../packages/drizzle-duckdb-wasm
'@proj-airi/elevenlabs':
specifier: workspace:^
version: link:../../packages/elevenlabs
'@proj-airi/provider-transformers':
specifier: workspace:^
version: link:../../packages/provider-transformers
'@proj-airi/server-sdk':
specifier: workspace:^
version: link:../../packages/server-sdk
'@proj-airi/stage-ui':
specifier: workspace:^
version: link:../../packages/stage-ui
'@proj-airi/ui-transitions':
specifier: workspace:^
version: link:../../packages/ui-transitions
'@ricky0123/vad-web':
specifier: ^0.0.22
version: 0.0.22
@@ -646,7 +661,7 @@ importers:
version: 0.30.5
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
jszip:
specifier: ^3.10.1
version: 3.10.1
@@ -755,22 +770,10 @@ importers:
version: 2.3.0
'@intlify/unplugin-vue-i18n':
specifier: ^6.0.5
version: 6.0.5(@vue/compiler-dom@3.5.13)(eslint@9.22.0(jiti@2.4.2))(rollup@4.36.0)(typescript@5.8.2)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
'@proj-airi/drizzle-duckdb-wasm':
specifier: workspace:^
version: link:../../packages/drizzle-duckdb-wasm
'@proj-airi/elevenlabs':
specifier: workspace:^
version: link:../../packages/elevenlabs
version: 6.0.5(@vue/compiler-dom@3.5.13)(eslint@9.22.0(jiti@2.4.2))(rollup@2.79.1)(typescript@5.8.2)(vue-i18n@11.1.2(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
'@proj-airi/lobe-icons':
specifier: ^1.0.4
version: 1.0.4
'@proj-airi/provider-transformers':
specifier: workspace:^
version: link:../../packages/provider-transformers
'@proj-airi/ui-transitions':
specifier: workspace:^
version: link:../../packages/ui-transitions
'@proj-airi/unplugin-fetch':
specifier: ^0.1.4
version: 0.1.4(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)
@@ -806,7 +809,7 @@ importers:
version: 3.0.0-beta.5(typescript@5.8.2)(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
'@vueuse/motion':
specifier: ^3.0.3
version: 3.0.3(magicast@0.3.5)(rollup@4.36.0)(vue@3.5.13(typescript@5.8.2))
version: 3.0.3(magicast@0.3.5)(rollup@2.79.1)(vue@3.5.13(typescript@5.8.2))
hfup:
specifier: workspace:^
version: link:../../packages/hfup
@@ -818,13 +821,13 @@ 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@4.36.0))(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))
version: 19.1.1(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))
unplugin-vue-components:
specifier: ^28.4.1
version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.36.0))(vue@3.5.13(typescript@5.8.2))
version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(vue@3.5.13(typescript@5.8.2))
unplugin-vue-macros:
specifier: ^2.14.5
version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@4.36.0)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.19.12)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
unplugin-vue-markdown:
specifier: ^28.3.1
version: 28.3.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
@@ -833,13 +836,13 @@ importers:
version: 0.12.0(vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
vite-bundle-visualizer:
specifier: ^1.2.1
version: 1.2.1(rollup@4.36.0)
version: 1.2.1(rollup@2.79.1)
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(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.36.0))(rollup@4.36.0)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.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.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
vite-plugin-vue-layouts:
specifier: ^0.11.0
version: 0.11.0(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)))(vue@3.5.13(typescript@5.8.2))
@@ -884,7 +887,7 @@ importers:
version: 6.1.4
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
es-toolkit:
specifier: ^1.33.0
version: 1.33.0
@@ -963,7 +966,7 @@ importers:
version: 6.1.4
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
es-toolkit:
specifier: ^1.33.0
version: 1.33.0
@@ -1006,6 +1009,25 @@ importers:
specifier: ^6.2.2
version: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)
packages/memory-pgvector:
dependencies:
'@guiiai/logg':
specifier: ^1.0.7
version: 1.0.7
'@proj-airi/server-sdk':
specifier: workspace:^
version: link:../server-sdk
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
postgres:
specifier: ^3.4.5
version: 3.4.5
devDependencies:
tsx:
specifier: ^4.19.3
version: 4.19.3
packages/provider-transformers:
dependencies:
'@huggingface/transformers':
@@ -1108,6 +1130,9 @@ importers:
'@formkit/auto-animate':
specifier: ^0.8.2
version: 0.8.2
'@proj-airi/server-sdk':
specifier: workspace:^
version: link:../server-sdk
'@vueuse/motion':
specifier: ^3.0.3
version: 3.0.3(magicast@0.3.5)(rollup@4.36.0)(vue@3.5.13(typescript@5.8.2))
@@ -1357,7 +1382,7 @@ importers:
version: 16.4.7
drizzle-orm:
specifier: ^0.40.1
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)
version: 0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5)
es-toolkit:
specifier: ^1.33.0
version: 1.33.0
@@ -9809,6 +9834,10 @@ packages:
postgres-range@1.1.4:
resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
postgres@3.4.5:
resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==}
engines: {node: '>=12'}
potpack@1.0.2:
resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==}
@@ -18209,11 +18238,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
drizzle-orm@0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1):
drizzle-orm@0.40.1(@types/pg@8.11.11)(gel@2.0.0)(pg@8.14.1)(postgres@3.4.5):
optionalDependencies:
'@types/pg': 8.11.11
gel: 2.0.0
pg: 8.14.1
postgres: 3.4.5
dset@3.1.4: {}
@@ -22185,6 +22215,8 @@ snapshots:
postgres-range@1.1.4: {}
postgres@3.4.5: {}
potpack@1.0.2: {}
prelude-ls@1.2.1: {}
@@ -24001,9 +24033,9 @@ snapshots:
'@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.36.0)
'@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2))
unplugin-combine@1.2.1(esbuild@0.25.0)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)):
unplugin-combine@1.2.1(esbuild@0.19.12)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)):
optionalDependencies:
esbuild: 0.25.0
esbuild: 0.19.12
rollup: 2.79.1
unplugin: 1.16.1
vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)
@@ -24062,7 +24094,7 @@ snapshots:
transitivePeerDependencies:
- vue
unplugin-vue-macros@2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)):
unplugin-vue-macros@2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.19.12)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)):
dependencies:
'@vue-macros/better-define': 1.11.4(vue@3.5.13(typescript@5.8.2))
'@vue-macros/boolean-prop': 0.5.5(vue@3.5.13(typescript@5.8.2))
@@ -24094,7 +24126,7 @@ snapshots:
'@vue-macros/short-vmodel': 1.5.5(vue@3.5.13(typescript@5.8.2))
'@vue-macros/volar': 0.30.15(typescript@5.8.2)(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2))
unplugin: 1.16.1
unplugin-combine: 1.2.1(esbuild@0.25.0)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
unplugin-combine: 1.2.1(esbuild@0.19.12)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))
unplugin-vue-define-options: 1.5.5(vue@3.5.13(typescript@5.8.2))
vue: 3.5.13(typescript@5.8.2)
transitivePeerDependencies: