@siact/sime-x-vue 0.0.8 → 0.0.10
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 +50 -18
- package/dist/sime-x-vue.mjs.map +1 -1
- package/dist/sime-x-vue.umd.js +50 -18
- package/dist/sime-x-vue.umd.js.map +1 -1
- package/dist/style.css +60 -60
- package/package.json +1 -1
- package/types/composables/use-bubble.d.ts +3 -1
- package/types/composables/use-tts.d.ts +1 -0
- package/types/types.d.ts +9 -0
package/dist/sime-x-vue.umd.js
CHANGED
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
});
|
|
50
50
|
const stopListeningRef = vue.shallowRef(async () => {
|
|
51
51
|
});
|
|
52
|
+
const stopBroadcastRef = vue.shallowRef(async () => {
|
|
53
|
+
});
|
|
52
54
|
const toggleCollapseRef = vue.shallowRef(async () => {
|
|
53
55
|
});
|
|
54
56
|
const openDialogRef = vue.shallowRef(async () => {
|
|
@@ -62,12 +64,14 @@
|
|
|
62
64
|
voiceConfig: () => props.voiceConfig || { appId: "", apiKey: "", websocketUrl: "" },
|
|
63
65
|
startListening: () => startListeningRef.value(),
|
|
64
66
|
stopListening: () => stopListeningRef.value(),
|
|
67
|
+
stopBroadcast: () => stopBroadcastRef.value(),
|
|
65
68
|
toggleCollapse: () => toggleCollapseRef.value(),
|
|
66
69
|
openDialog: () => openDialogRef.value(),
|
|
67
70
|
closeDialog: () => closeDialogRef.value(),
|
|
68
71
|
registerVoiceMethods: (methods) => {
|
|
69
72
|
startListeningRef.value = methods.start;
|
|
70
73
|
stopListeningRef.value = methods.stop;
|
|
74
|
+
if (methods.stopBroadcast) stopBroadcastRef.value = methods.stopBroadcast;
|
|
71
75
|
toggleCollapseRef.value = methods.toggleCollapse;
|
|
72
76
|
openDialogRef.value = methods.openDialog;
|
|
73
77
|
closeDialogRef.value = methods.closeDialog;
|
|
@@ -999,6 +1003,7 @@
|
|
|
999
1003
|
|
|
1000
1004
|
function useTTS(getVoiceConfig) {
|
|
1001
1005
|
const isSpeaking = vue.ref(false);
|
|
1006
|
+
const hasPendingAudio = vue.ref(false);
|
|
1002
1007
|
let instance = null;
|
|
1003
1008
|
let initPromise = null;
|
|
1004
1009
|
let audioCtx = null;
|
|
@@ -1034,9 +1039,9 @@
|
|
|
1034
1039
|
apiSecret: vc.apiSecret,
|
|
1035
1040
|
websocketUrl: vc.ttsWebsocketUrl || "wss://tts-api.xfyun.cn/v2/tts",
|
|
1036
1041
|
vcn: vc.ttsVcn || "xiaoyan",
|
|
1037
|
-
speed:
|
|
1038
|
-
volume:
|
|
1039
|
-
pitch: 50,
|
|
1042
|
+
speed: vc.speed || 55,
|
|
1043
|
+
volume: vc.volume || 90,
|
|
1044
|
+
pitch: vc.pitch || 50,
|
|
1040
1045
|
aue: "raw",
|
|
1041
1046
|
auf: "audio/L16;rate=16000",
|
|
1042
1047
|
tte: "UTF8",
|
|
@@ -1049,6 +1054,7 @@
|
|
|
1049
1054
|
});
|
|
1050
1055
|
tts.onQueueEmpty(() => {
|
|
1051
1056
|
isSpeaking.value = false;
|
|
1057
|
+
hasPendingAudio.value = false;
|
|
1052
1058
|
onQueueEmptyCb?.();
|
|
1053
1059
|
});
|
|
1054
1060
|
tts.onError((err) => {
|
|
@@ -1074,6 +1080,7 @@
|
|
|
1074
1080
|
const speak = async (text) => {
|
|
1075
1081
|
const clean = stripMarkdown(text);
|
|
1076
1082
|
if (!clean.trim()) return;
|
|
1083
|
+
hasPendingAudio.value = true;
|
|
1077
1084
|
const tts = await ensureInstance();
|
|
1078
1085
|
if (!tts) return;
|
|
1079
1086
|
try {
|
|
@@ -1100,6 +1107,7 @@
|
|
|
1100
1107
|
const stop = () => {
|
|
1101
1108
|
sentenceBuffer = "";
|
|
1102
1109
|
isSpeaking.value = false;
|
|
1110
|
+
hasPendingAudio.value = false;
|
|
1103
1111
|
if (instance) {
|
|
1104
1112
|
try {
|
|
1105
1113
|
instance.stop();
|
|
@@ -1129,6 +1137,7 @@
|
|
|
1129
1137
|
};
|
|
1130
1138
|
return {
|
|
1131
1139
|
isSpeaking,
|
|
1140
|
+
hasPendingAudio,
|
|
1132
1141
|
warmUpAudio,
|
|
1133
1142
|
speak,
|
|
1134
1143
|
feed,
|
|
@@ -1144,7 +1153,14 @@
|
|
|
1144
1153
|
const fadingOut = vue.ref(false);
|
|
1145
1154
|
const stackRef = vue.ref(null);
|
|
1146
1155
|
let dismissTimer = null;
|
|
1147
|
-
const
|
|
1156
|
+
const hasOpened = vue.ref(false);
|
|
1157
|
+
const isTTSActive = () => !!(options.isSpeaking?.value || options.hasPendingAudio?.value);
|
|
1158
|
+
const isBusy = () => !!(options.isInvoking?.value || isTTSActive());
|
|
1159
|
+
const show = vue.computed(() => {
|
|
1160
|
+
if (!hasOpened.value) return false;
|
|
1161
|
+
if (isTTSActive()) return true;
|
|
1162
|
+
return visible.value && !fadingOut.value;
|
|
1163
|
+
});
|
|
1148
1164
|
const style = vue.computed(() => ({
|
|
1149
1165
|
width: options.bubbleSize?.width || void 0,
|
|
1150
1166
|
maxHeight: options.bubbleSize?.maxHeight || void 0
|
|
@@ -1153,6 +1169,7 @@
|
|
|
1153
1169
|
cancelDismiss();
|
|
1154
1170
|
fadingOut.value = false;
|
|
1155
1171
|
visible.value = true;
|
|
1172
|
+
hasOpened.value = true;
|
|
1156
1173
|
};
|
|
1157
1174
|
const cancelDismiss = () => {
|
|
1158
1175
|
if (dismissTimer) {
|
|
@@ -1162,21 +1179,39 @@
|
|
|
1162
1179
|
};
|
|
1163
1180
|
const scheduleDismiss = () => {
|
|
1164
1181
|
cancelDismiss();
|
|
1165
|
-
if (
|
|
1166
|
-
if (options.isInvoking?.value) return;
|
|
1182
|
+
if (isBusy()) return;
|
|
1167
1183
|
const delay = options.dismissDelay ?? 4e3;
|
|
1168
1184
|
dismissTimer = setTimeout(() => {
|
|
1185
|
+
if (isBusy()) return;
|
|
1169
1186
|
fadingOut.value = true;
|
|
1170
1187
|
setTimeout(() => {
|
|
1188
|
+
if (isBusy()) {
|
|
1189
|
+
fadingOut.value = false;
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1171
1192
|
visible.value = false;
|
|
1172
1193
|
fadingOut.value = false;
|
|
1194
|
+
hasOpened.value = false;
|
|
1173
1195
|
}, 400);
|
|
1174
1196
|
}, delay);
|
|
1175
1197
|
};
|
|
1198
|
+
const watchTTSRef = (ttsRef) => {
|
|
1199
|
+
vue.watch(ttsRef, (active) => {
|
|
1200
|
+
if (active && hasOpened.value) {
|
|
1201
|
+
cancelDismiss();
|
|
1202
|
+
if (fadingOut.value) fadingOut.value = false;
|
|
1203
|
+
} else if (!active && hasOpened.value && !isBusy()) {
|
|
1204
|
+
scheduleDismiss();
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
};
|
|
1208
|
+
if (options.isSpeaking) watchTTSRef(options.isSpeaking);
|
|
1209
|
+
if (options.hasPendingAudio) watchTTSRef(options.hasPendingAudio);
|
|
1176
1210
|
const hide = () => {
|
|
1177
1211
|
cancelDismiss();
|
|
1178
1212
|
fadingOut.value = false;
|
|
1179
1213
|
visible.value = false;
|
|
1214
|
+
hasOpened.value = false;
|
|
1180
1215
|
};
|
|
1181
1216
|
const scrollToBottom = () => {
|
|
1182
1217
|
vue.nextTick(() => {
|
|
@@ -1806,7 +1841,7 @@
|
|
|
1806
1841
|
const processedToolResults = /* @__PURE__ */ new Set();
|
|
1807
1842
|
abortController = new AbortController();
|
|
1808
1843
|
const commands = await aiChatbotX.hostCommads();
|
|
1809
|
-
|
|
1844
|
+
conversationHistory.value.length > 0 ? [...conversationHistory.value] : void 0;
|
|
1810
1845
|
try {
|
|
1811
1846
|
const response = await fetch(options.endpoint.value, {
|
|
1812
1847
|
method: "POST",
|
|
@@ -1814,8 +1849,8 @@
|
|
|
1814
1849
|
body: JSON.stringify({
|
|
1815
1850
|
input: content,
|
|
1816
1851
|
projectId: options.projectId || "",
|
|
1817
|
-
commands: commands.length > 0 ? commands : void 0
|
|
1818
|
-
messages: historyToSend
|
|
1852
|
+
commands: commands.length > 0 ? commands : void 0
|
|
1853
|
+
// messages: historyToSend,
|
|
1819
1854
|
}),
|
|
1820
1855
|
signal: abortController.signal
|
|
1821
1856
|
});
|
|
@@ -1994,7 +2029,7 @@
|
|
|
1994
2029
|
const endpoint = vue.computed(() => {
|
|
1995
2030
|
return props.invokeUrl || "http://localhost:3001/agent/zyy55sw40nrl801056m0o/stream-invoke";
|
|
1996
2031
|
});
|
|
1997
|
-
const wakeResponses = ["
|
|
2032
|
+
const wakeResponses = ["在呢"];
|
|
1998
2033
|
const tts = useTTS(getVoiceConfig);
|
|
1999
2034
|
const bubbleBridge = {
|
|
2000
2035
|
open: () => {
|
|
@@ -2023,6 +2058,7 @@
|
|
|
2023
2058
|
const bubble = useBubble({
|
|
2024
2059
|
dismissDelay: props.bubbleDismissDelay,
|
|
2025
2060
|
isSpeaking: tts.isSpeaking,
|
|
2061
|
+
hasPendingAudio: tts.hasPendingAudio,
|
|
2026
2062
|
isInvoking: agent.isInvoking,
|
|
2027
2063
|
bubbleSize: props.bubbleSize
|
|
2028
2064
|
});
|
|
@@ -2030,11 +2066,6 @@
|
|
|
2030
2066
|
bubbleBridge.scheduleDismiss = bubble.scheduleDismiss;
|
|
2031
2067
|
bubbleBridge.scrollToBottom = bubble.scrollToBottom;
|
|
2032
2068
|
const { show: showBubble, style: bubbleStyle, stackRef: bubbleStackRef } = bubble;
|
|
2033
|
-
tts.setOnQueueEmpty(() => {
|
|
2034
|
-
if (!agent.isInvoking.value) {
|
|
2035
|
-
bubble.scheduleDismiss();
|
|
2036
|
-
}
|
|
2037
|
-
});
|
|
2038
2069
|
const interruptCurrentResponse = () => {
|
|
2039
2070
|
agent.abort();
|
|
2040
2071
|
agent.resetState();
|
|
@@ -2059,11 +2090,12 @@
|
|
|
2059
2090
|
tts.warmUpAudio();
|
|
2060
2091
|
await voice.toggleVoiceMode(targetState);
|
|
2061
2092
|
};
|
|
2062
|
-
const { voiceStatus, transcriptionText, wakeAnimating } = voice;
|
|
2093
|
+
const { voiceStatus, transcriptionText, wakeAnimating, isTranscribing } = voice;
|
|
2063
2094
|
const { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;
|
|
2064
2095
|
aiChatbotX?.registerVoiceMethods({
|
|
2065
2096
|
start: () => toggleVoiceMode(true),
|
|
2066
2097
|
stop: () => toggleVoiceMode(false),
|
|
2098
|
+
stopBroadcast: async () => interruptCurrentResponse(),
|
|
2067
2099
|
openDialog: async () => Promise.resolve(),
|
|
2068
2100
|
closeDialog: async () => Promise.resolve(),
|
|
2069
2101
|
toggleCollapse: async () => Promise.resolve()
|
|
@@ -2168,7 +2200,7 @@
|
|
|
2168
2200
|
default: vue.withCtx(() => [
|
|
2169
2201
|
vue.unref(voiceStatus) === "listening" ? (vue.openBlock(), vue.createElementBlock("div", {
|
|
2170
2202
|
key: 0,
|
|
2171
|
-
class: vue.normalizeClass(["listening-badge", { "wake-active": vue.unref(wakeAnimating) }])
|
|
2203
|
+
class: vue.normalizeClass(["listening-badge", { "wake-active": vue.unref(wakeAnimating) || vue.unref(isTranscribing) || vue.unref(isInvoking) }])
|
|
2172
2204
|
}, [..._cache[5] || (_cache[5] = [
|
|
2173
2205
|
vue.createElementVNode("div", { class: "listening-waves" }, [
|
|
2174
2206
|
vue.createElementVNode("div", { class: "wave wave-1" }),
|
|
@@ -2205,7 +2237,7 @@
|
|
|
2205
2237
|
}
|
|
2206
2238
|
});
|
|
2207
2239
|
|
|
2208
|
-
const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
2240
|
+
const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-77c6ae95"]]);
|
|
2209
2241
|
|
|
2210
2242
|
exports.AiChatbotProvider = _sfc_main$4;
|
|
2211
2243
|
exports.AiChatbotVoiceAssistant = voiceAssistant;
|