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