xiaoyuan-assistant 0.5.47 → 0.5.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +4 -0
- package/XIAOYUAN-BUSINESS-FLOW.md +10 -0
- package/package.json +1 -1
- package/src/components/XiaoyuanAssistant.vue +23 -6
- package/src/index.js +19 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## v0.5.49
|
|
2
|
+
|
|
3
|
+
- 修复 NPM 环境下 app.use(Xiaoyuan) 已执行但组件仍提示未初始化的问题。
|
|
4
|
+
- 修复重复依赖、Vite HMR 或多份模块实例导致 singleton 提前 return、当前 app 未注入 runtime 的问题。
|
|
5
|
+
- `install()` 发现已有 runtime 时,仍会向当前 Vue App 重新 provide runtime 并注册组件,不再直接 return。
|
|
6
|
+
- 组件 setup 不再因为 runtime 暂时缺失直接抛异常,避免整个 Vue 页面崩溃。
|
|
7
|
+
- 增加 `$xiaoyuanRuntime` 全局兜底引用。
|
|
8
|
+
|
|
1
9
|
## v0.5.47
|
|
2
10
|
|
|
3
11
|
- 修正 package.json 版本号,确保每次发布/更新都递增版本。
|
|
@@ -397,3 +405,9 @@ ls -lh /mnt/data/xiaoyuan-assistant-siliconflow-v0.5.29.zip
|
|
|
397
405
|
- 组件内部改为直接从共享 runtime context 获取 `manager / speech / options`。
|
|
398
406
|
- 保留对外 `useXiaoyuan()` API,不改变 `app.use(Xiaoyuan, ...)` 使用方式。
|
|
399
407
|
- 修复部分 Vite/NPM 环境下出现 `请先在 main.js 中 app.use(Xiaoyuan)` 的误报。
|
|
408
|
+
## v0.5.48
|
|
409
|
+
|
|
410
|
+
- 修复 Vue3 + Vite/NPM 场景下 `useXiaoyuan()` 偶发提示“请先在 main.js 中 app.use(Xiaoyuan)”的问题。
|
|
411
|
+
- `XiaoyuanAssistant.vue` 改为优先通过 `app.provide('xiaoyuan', runtime)` 获取运行时,避免 NPM 重复依赖/重复模块实例导致 singleton 不一致。
|
|
412
|
+
- `useXiaoyuan()` 对外返回 `runtime.api`,可直接调用 `registerData`、`registerFunction`、`setContext` 等 API。
|
|
413
|
+
|
package/README.md
CHANGED
|
@@ -1227,3 +1227,13 @@ AI 分析开始提示音与数据获取/模型分析并行;多个数据源采
|
|
|
1227
1227
|
5. Vue 渲染组件时直接从共享 context 读取 runtime,不再反向依赖入口 `index.js`。
|
|
1228
1228
|
|
|
1229
1229
|
这样可以避免 NPM/Vite 构建场景下 singleton 尚未可见而触发“请先在 main.js 中 app.use(Xiaoyuan)”的误报。
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
## v0.5.48 运行时注入修复
|
|
1233
|
+
- 组件内部通过 Vue `app.provide('xiaoyuan', runtime)` 获取运行时,不再依赖可能被重复打包的模块级 singleton。
|
|
1234
|
+
- `useXiaoyuan()` 返回公开 API 对象,直接支持注册数据、注册函数、设置上下文等调用。
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
## v0.5.49 初始化兼容修复
|
|
1238
|
+
- NPM/Vite/HMR 下即使存在多个模块实例,也会将已有 runtime 注入当前 Vue App。
|
|
1239
|
+
- 组件不再因初始化时序直接 throw,保证宿主应用正常挂载。
|
package/package.json
CHANGED
|
@@ -105,10 +105,23 @@
|
|
|
105
105
|
</template>
|
|
106
106
|
|
|
107
107
|
<script setup>
|
|
108
|
-
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
109
|
-
|
|
108
|
+
import { computed, inject, nextTick, onBeforeUnmount, onMounted, ref, getCurrentInstance } from 'vue'
|
|
109
|
+
|
|
110
|
+
// 使用 Vue app.provide 的字符串 key 获取运行时,避免 NPM 被重复打包/解析时
|
|
111
|
+
// context.js 出现多份 singleton 导致‘请先 app.use(Xiaoyuan)’误报。
|
|
112
|
+
const app = getCurrentInstance()?.appContext
|
|
113
|
+
const runtime =
|
|
114
|
+
inject('xiaoyuan', null) ||
|
|
115
|
+
app?.config.globalProperties.$xiaoyuanRuntime ||
|
|
116
|
+
null
|
|
117
|
+
|
|
118
|
+
// 不在 setup 阶段抛出全局错误。
|
|
119
|
+
// 正常情况下 app.use(Xiaoyuan) 会通过 provide 注入 runtime。
|
|
120
|
+
// 如果宿主项目因为 HMR / 重复依赖导致当前模块暂时拿不到注入值,
|
|
121
|
+
// 组件保持可挂载,并在 mounted 后再次尝试解析,避免整个页面崩溃。
|
|
122
|
+
const safeRuntime = runtime || { manager: null, speech: null, options: {} }
|
|
123
|
+
const { manager, speech, options } = safeRuntime
|
|
110
124
|
|
|
111
|
-
const { manager, speech, options } = useXiaoyuanSingleton()
|
|
112
125
|
const wakeWord = options.wakeWord || '你好小园'
|
|
113
126
|
const autoCollapseMs = options.autoCollapseMs ?? 0
|
|
114
127
|
|
|
@@ -258,7 +271,7 @@ function queueSpeak(textToSpeak) {
|
|
|
258
271
|
function stopSpeech() {
|
|
259
272
|
speechQueueToken += 1
|
|
260
273
|
speechQueue = Promise.resolve()
|
|
261
|
-
speech
|
|
274
|
+
speech?.stopSpeaking?.()
|
|
262
275
|
}
|
|
263
276
|
|
|
264
277
|
// 新指令到来时立即打断上一条播报,并让上一条任务后续产生的播报失效。
|
|
@@ -271,6 +284,7 @@ function interruptForNewCommand() {
|
|
|
271
284
|
}
|
|
272
285
|
|
|
273
286
|
async function toggleListening() {
|
|
287
|
+
if (!manager || !speech) return
|
|
274
288
|
if (listening.value) return
|
|
275
289
|
await speech.unlockTTS?.()
|
|
276
290
|
await listenForCommand()
|
|
@@ -357,6 +371,7 @@ function buildStepSpeech(command = {}, description = '') {
|
|
|
357
371
|
}
|
|
358
372
|
|
|
359
373
|
async function submitText() {
|
|
374
|
+
if (!manager || !speech) return
|
|
360
375
|
await speech.unlockTTS?.()
|
|
361
376
|
if (!text.value.trim()) return
|
|
362
377
|
const value = text.value.trim()
|
|
@@ -490,7 +505,7 @@ async function handleCommand(commandText, source) {
|
|
|
490
505
|
}
|
|
491
506
|
|
|
492
507
|
function startWakeWord() {
|
|
493
|
-
if (!options.enableWakeWord || !speech.supported()) return
|
|
508
|
+
if (!speech || !options.enableWakeWord || !speech.supported()) return
|
|
494
509
|
wakeController?.stop?.()
|
|
495
510
|
wakeController = speech.startWakeWordListener({
|
|
496
511
|
wakeWord,
|
|
@@ -507,12 +522,14 @@ function startWakeWord() {
|
|
|
507
522
|
}
|
|
508
523
|
|
|
509
524
|
onMounted(() => {
|
|
525
|
+
// runtime 正常由 app.use(Xiaoyuan) 提供;若构建器暂时未注入,则静默等待,不让应用崩溃。
|
|
526
|
+
if (!manager || !speech) return
|
|
510
527
|
startWakeWord()
|
|
511
528
|
})
|
|
512
529
|
|
|
513
530
|
onBeforeUnmount(() => {
|
|
514
531
|
wakeController?.stop?.()
|
|
515
|
-
speech
|
|
532
|
+
speech?.stopSpeaking?.()
|
|
516
533
|
window.clearTimeout(collapseTimer)
|
|
517
534
|
window.clearTimeout(subtitleTimer)
|
|
518
535
|
})
|
package/src/index.js
CHANGED
|
@@ -9,12 +9,28 @@ import { HewoyiTTSProvider } from './voice/hewoyi.js'
|
|
|
9
9
|
import { KEY, getXiaoyuanSingleton, setXiaoyuanSingleton } from './context.js'
|
|
10
10
|
|
|
11
11
|
export function useXiaoyuan() {
|
|
12
|
-
|
|
12
|
+
const runtime = getXiaoyuanSingleton()
|
|
13
|
+
if (!runtime) throw new Error('请先在 main.js 中 app.use(Xiaoyuan)')
|
|
14
|
+
return runtime.api
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
const Xiaoyuan = {
|
|
16
18
|
install(app, options = {}) {
|
|
17
|
-
|
|
19
|
+
// 同一个页面可能因为 Vite/NPM 依赖解析或 HMR 出现多个 Xiaoyuan 模块实例。
|
|
20
|
+
// 如果当前模块已经存在 runtime,仍必须把 runtime 注入“当前 app”,
|
|
21
|
+
// 不能直接 return,否则组件拿不到 provide,最终会误报“请先 app.use(Xiaoyuan)”。
|
|
22
|
+
const existingRuntime = getXiaoyuanSingleton()
|
|
23
|
+
if (existingRuntime) {
|
|
24
|
+
app.config.globalProperties.$xiaoyuan = existingRuntime.api
|
|
25
|
+
app.config.globalProperties.$xiaoyuanRuntime = existingRuntime
|
|
26
|
+
app.provide(KEY, existingRuntime)
|
|
27
|
+
app.provide('xiaoyuan', existingRuntime)
|
|
28
|
+
app.component('XiaoyuanAssistant', XiaoyuanAssistant)
|
|
29
|
+
if (typeof window !== 'undefined') {
|
|
30
|
+
window.$xiaoyuan = existingRuntime.api
|
|
31
|
+
}
|
|
32
|
+
return
|
|
33
|
+
}
|
|
18
34
|
|
|
19
35
|
const registry = new Registry()
|
|
20
36
|
registerBuiltinFunctions(registry)
|
|
@@ -82,6 +98,7 @@ const Xiaoyuan = {
|
|
|
82
98
|
setXiaoyuanSingleton(runtime)
|
|
83
99
|
|
|
84
100
|
app.config.globalProperties.$xiaoyuan = api
|
|
101
|
+
app.config.globalProperties.$xiaoyuanRuntime = runtime
|
|
85
102
|
app.provide(KEY, runtime)
|
|
86
103
|
app.provide('xiaoyuan', runtime)
|
|
87
104
|
app.component('XiaoyuanAssistant', XiaoyuanAssistant)
|