@siact/sime-x-vue 0.0.20 → 0.0.22
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/dist/sime-x-vue.mjs +95 -16
- package/dist/sime-x-vue.mjs.map +1 -1
- package/dist/sime-x-vue.umd.js +95 -16
- package/dist/sime-x-vue.umd.js.map +1 -1
- package/dist/style.css +109 -109
- package/package.json +1 -1
- package/types/composables/use-tts.d.ts +1 -0
package/dist/sime-x-vue.mjs
CHANGED
|
@@ -106,7 +106,7 @@ const _hoisted_9$2 = ["onClick"];
|
|
|
106
106
|
const _hoisted_10$2 = { class: "ai-chat__messages-inner" };
|
|
107
107
|
const _hoisted_11$2 = { class: "ai-chat__message-content" };
|
|
108
108
|
const _hoisted_12$2 = ["innerHTML"];
|
|
109
|
-
const _hoisted_13$
|
|
109
|
+
const _hoisted_13$2 = {
|
|
110
110
|
key: 1,
|
|
111
111
|
class: "ai-chat__reasoning"
|
|
112
112
|
};
|
|
@@ -469,7 +469,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
469
469
|
innerHTML: renderMarkdown(part.text)
|
|
470
470
|
}, null, 8, _hoisted_12$2)
|
|
471
471
|
])
|
|
472
|
-
], 2)) : part.type === "reasoning" ? (openBlock(), createElementBlock("div", _hoisted_13$
|
|
472
|
+
], 2)) : part.type === "reasoning" ? (openBlock(), createElementBlock("div", _hoisted_13$2, [
|
|
473
473
|
createElementVNode("button", {
|
|
474
474
|
class: "ai-chat__reasoning-trigger",
|
|
475
475
|
onClick: ($event) => toggleReasoning(message.id)
|
|
@@ -1464,7 +1464,7 @@ const _hoisted_10$1 = {
|
|
|
1464
1464
|
};
|
|
1465
1465
|
const _hoisted_11$1 = { class: "input-bar" };
|
|
1466
1466
|
const _hoisted_12$1 = ["disabled"];
|
|
1467
|
-
const _hoisted_13 = ["disabled"];
|
|
1467
|
+
const _hoisted_13$1 = ["disabled"];
|
|
1468
1468
|
const _hoisted_14 = {
|
|
1469
1469
|
key: 0,
|
|
1470
1470
|
class: "btn-spinner",
|
|
@@ -1512,7 +1512,15 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
1512
1512
|
}
|
|
1513
1513
|
};
|
|
1514
1514
|
const test = () => {
|
|
1515
|
-
|
|
1515
|
+
[
|
|
1516
|
+
"1你好,世界,今天是想起五天气横扫的缺点",
|
|
1517
|
+
"2你好,世界,今天是想起五天气横扫的缺点",
|
|
1518
|
+
"3你好,世界,今天是想起五天气横扫的缺点"
|
|
1519
|
+
].forEach((text, index) => {
|
|
1520
|
+
setTimeout(() => {
|
|
1521
|
+
aiChatbotX.speakText(text);
|
|
1522
|
+
}, index * 1e3);
|
|
1523
|
+
});
|
|
1516
1524
|
};
|
|
1517
1525
|
const test1 = () => {
|
|
1518
1526
|
aiChatbotX.abortInvoke();
|
|
@@ -1671,14 +1679,14 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
1671
1679
|
"stroke-linejoin": "round"
|
|
1672
1680
|
}, null, -1)
|
|
1673
1681
|
])]))
|
|
1674
|
-
], 8, _hoisted_13)
|
|
1682
|
+
], 8, _hoisted_13$1)
|
|
1675
1683
|
])
|
|
1676
1684
|
]);
|
|
1677
1685
|
};
|
|
1678
1686
|
}
|
|
1679
1687
|
});
|
|
1680
1688
|
|
|
1681
|
-
const commandTest = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-
|
|
1689
|
+
const commandTest = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-36096054"]]);
|
|
1682
1690
|
|
|
1683
1691
|
class CommandManager {
|
|
1684
1692
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -1922,6 +1930,37 @@ function useTTS(getVoiceConfig) {
|
|
|
1922
1930
|
console.error("[TTS] speak 失败:", err);
|
|
1923
1931
|
}
|
|
1924
1932
|
};
|
|
1933
|
+
const speakAndWait = async (text) => {
|
|
1934
|
+
const clean = normalizeSpeakText(text);
|
|
1935
|
+
if (!clean.trim()) return;
|
|
1936
|
+
hasPendingAudio.value = true;
|
|
1937
|
+
const ttsInst = await ensureInstance();
|
|
1938
|
+
if (!ttsInst) {
|
|
1939
|
+
hasPendingAudio.value = false;
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
return new Promise((resolve) => {
|
|
1943
|
+
let settled = false;
|
|
1944
|
+
const settle = () => {
|
|
1945
|
+
if (settled) return;
|
|
1946
|
+
settled = true;
|
|
1947
|
+
clearTimeout(safetyTimer);
|
|
1948
|
+
onQueueEmptyCb = null;
|
|
1949
|
+
resolve();
|
|
1950
|
+
};
|
|
1951
|
+
const safetyTimer = setTimeout(() => {
|
|
1952
|
+
console.warn("[TTS] speakAndWait 安全超时,强制 resolve");
|
|
1953
|
+
settle();
|
|
1954
|
+
}, 6e4);
|
|
1955
|
+
onQueueEmptyCb = settle;
|
|
1956
|
+
try {
|
|
1957
|
+
ttsInst.speak(clean);
|
|
1958
|
+
} catch (err) {
|
|
1959
|
+
console.error("[TTS] speak 失败:", err);
|
|
1960
|
+
settle();
|
|
1961
|
+
}
|
|
1962
|
+
});
|
|
1963
|
+
};
|
|
1925
1964
|
const feed = (delta) => {
|
|
1926
1965
|
sentenceBuffer += delta;
|
|
1927
1966
|
while (true) {
|
|
@@ -1944,6 +1983,11 @@ function useTTS(getVoiceConfig) {
|
|
|
1944
1983
|
sentenceBuffer = "";
|
|
1945
1984
|
isSpeaking.value = false;
|
|
1946
1985
|
hasPendingAudio.value = false;
|
|
1986
|
+
if (onQueueEmptyCb) {
|
|
1987
|
+
const cb = onQueueEmptyCb;
|
|
1988
|
+
onQueueEmptyCb = null;
|
|
1989
|
+
cb();
|
|
1990
|
+
}
|
|
1947
1991
|
if (instance) {
|
|
1948
1992
|
try {
|
|
1949
1993
|
instance.stop();
|
|
@@ -1976,6 +2020,7 @@ function useTTS(getVoiceConfig) {
|
|
|
1976
2020
|
hasPendingAudio,
|
|
1977
2021
|
warmUpAudio,
|
|
1978
2022
|
speak,
|
|
2023
|
+
speakAndWait,
|
|
1979
2024
|
feed,
|
|
1980
2025
|
flush,
|
|
1981
2026
|
stop,
|
|
@@ -2254,8 +2299,12 @@ const _hoisted_10 = {
|
|
|
2254
2299
|
key: 2,
|
|
2255
2300
|
class: "agent-text"
|
|
2256
2301
|
};
|
|
2257
|
-
const _hoisted_11 = {
|
|
2258
|
-
|
|
2302
|
+
const _hoisted_11 = {
|
|
2303
|
+
key: 0,
|
|
2304
|
+
class: "status-pill"
|
|
2305
|
+
};
|
|
2306
|
+
const _hoisted_12 = { class: "fab-avatar-wrapper" };
|
|
2307
|
+
const _hoisted_13 = ["src"];
|
|
2259
2308
|
const currentTheme = "dark";
|
|
2260
2309
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
2261
2310
|
__name: "voice-assistant",
|
|
@@ -2326,10 +2375,39 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
2326
2375
|
tts.stop();
|
|
2327
2376
|
bubble.hide();
|
|
2328
2377
|
};
|
|
2378
|
+
const speakQueue = [];
|
|
2379
|
+
let isProcessingSpeakQueue = false;
|
|
2380
|
+
const processSpeakQueue = async () => {
|
|
2381
|
+
if (isProcessingSpeakQueue) return;
|
|
2382
|
+
isProcessingSpeakQueue = true;
|
|
2383
|
+
tts.hasPendingAudio.value = true;
|
|
2384
|
+
while (speakQueue.length > 0) {
|
|
2385
|
+
const text = speakQueue.shift();
|
|
2386
|
+
bubble.open();
|
|
2387
|
+
agent.currentTextContent.value = text;
|
|
2388
|
+
try {
|
|
2389
|
+
await tts.speakAndWait(text);
|
|
2390
|
+
} catch (e) {
|
|
2391
|
+
console.error("[speakQueue] 播报失败:", e);
|
|
2392
|
+
}
|
|
2393
|
+
if (speakQueue.length > 0) {
|
|
2394
|
+
tts.hasPendingAudio.value = true;
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
isProcessingSpeakQueue = false;
|
|
2398
|
+
tts.hasPendingAudio.value = false;
|
|
2399
|
+
bubble.scheduleDismiss();
|
|
2400
|
+
};
|
|
2329
2401
|
const speakTextWithBubble = (text) => {
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2402
|
+
speakQueue.push(text);
|
|
2403
|
+
if (!isProcessingSpeakQueue) {
|
|
2404
|
+
processSpeakQueue();
|
|
2405
|
+
}
|
|
2406
|
+
};
|
|
2407
|
+
const stopSpeak = () => {
|
|
2408
|
+
speakQueue.length = 0;
|
|
2409
|
+
isProcessingSpeakQueue = false;
|
|
2410
|
+
tts.stop();
|
|
2333
2411
|
};
|
|
2334
2412
|
const voice = useVoiceRecognition({
|
|
2335
2413
|
modelPath: props.modelPath,
|
|
@@ -2349,7 +2427,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
2349
2427
|
tts.warmUpAudio();
|
|
2350
2428
|
await voice.toggleVoiceMode(targetState);
|
|
2351
2429
|
};
|
|
2352
|
-
const { voiceStatus, wakeAnimating, isTranscribing } = voice;
|
|
2430
|
+
const { voiceStatus, transcriptionText, wakeAnimating, isTranscribing } = voice;
|
|
2353
2431
|
const { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;
|
|
2354
2432
|
aiChatbotX?.registerVoiceMethods({
|
|
2355
2433
|
stopBroadcast: async () => interruptCurrentResponse(),
|
|
@@ -2360,7 +2438,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
2360
2438
|
agentInvoke: agent.invoke,
|
|
2361
2439
|
agentAbort: agent.abort,
|
|
2362
2440
|
speakText: speakTextWithBubble,
|
|
2363
|
-
stopSpeak
|
|
2441
|
+
stopSpeak
|
|
2364
2442
|
});
|
|
2365
2443
|
onBeforeUnmount(async () => {
|
|
2366
2444
|
bubble.destroy();
|
|
@@ -2449,14 +2527,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
2449
2527
|
class: "assistant-fab",
|
|
2450
2528
|
onClick: _cache[0] || (_cache[0] = ($event) => toggleVoiceMode())
|
|
2451
2529
|
}, [
|
|
2452
|
-
|
|
2530
|
+
unref(transcriptionText) || unref(isInvoking) ? (openBlock(), createElementBlock("div", _hoisted_11, toDisplayString(unref(isInvoking) ? "正在思考中..." : unref(transcriptionText)), 1)) : createCommentVNode("", true),
|
|
2531
|
+
createElementVNode("div", _hoisted_12, [
|
|
2453
2532
|
createElementVNode("img", {
|
|
2454
2533
|
src: __props.xLogo ? __props.xLogo : "/x.png",
|
|
2455
2534
|
alt: "voice assistant",
|
|
2456
2535
|
style: normalizeStyle({
|
|
2457
2536
|
width: `${__props.xSize?.width || 88}px`
|
|
2458
2537
|
})
|
|
2459
|
-
}, null, 12,
|
|
2538
|
+
}, null, 12, _hoisted_13),
|
|
2460
2539
|
createVNode(Transition, { name: "indicator-fade" }, {
|
|
2461
2540
|
default: withCtx(() => [
|
|
2462
2541
|
unref(voiceStatus) === "listening" ? (openBlock(), createElementBlock("div", {
|
|
@@ -2498,7 +2577,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
2498
2577
|
}
|
|
2499
2578
|
});
|
|
2500
2579
|
|
|
2501
|
-
const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
2580
|
+
const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d15c792e"]]);
|
|
2502
2581
|
|
|
2503
2582
|
var clientCommandKey = /* @__PURE__ */ ((clientCommandKey2) => {
|
|
2504
2583
|
clientCommandKey2["SET_THEME"] = "SiMeAgent_setTheme";
|