@siact/sime-x-vue 0.0.18 → 0.0.20

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.
@@ -107,7 +107,7 @@
107
107
  const _hoisted_10$2 = { class: "ai-chat__messages-inner" };
108
108
  const _hoisted_11$2 = { class: "ai-chat__message-content" };
109
109
  const _hoisted_12$2 = ["innerHTML"];
110
- const _hoisted_13$2 = {
110
+ const _hoisted_13$1 = {
111
111
  key: 1,
112
112
  class: "ai-chat__reasoning"
113
113
  };
@@ -470,7 +470,7 @@
470
470
  innerHTML: renderMarkdown(part.text)
471
471
  }, null, 8, _hoisted_12$2)
472
472
  ])
473
- ], 2)) : part.type === "reasoning" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_13$2, [
473
+ ], 2)) : part.type === "reasoning" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_13$1, [
474
474
  vue.createElementVNode("button", {
475
475
  class: "ai-chat__reasoning-trigger",
476
476
  onClick: ($event) => toggleReasoning(message.id)
@@ -1465,7 +1465,7 @@
1465
1465
  };
1466
1466
  const _hoisted_11$1 = { class: "input-bar" };
1467
1467
  const _hoisted_12$1 = ["disabled"];
1468
- const _hoisted_13$1 = ["disabled"];
1468
+ const _hoisted_13 = ["disabled"];
1469
1469
  const _hoisted_14 = {
1470
1470
  key: 0,
1471
1471
  class: "btn-spinner",
@@ -1512,6 +1512,12 @@
1512
1512
  scrollToBottom: () => {
1513
1513
  }
1514
1514
  };
1515
+ const test = () => {
1516
+ aiChatbotX.speakText("你好,世界,今天是想起五天气横扫的缺点");
1517
+ };
1518
+ const test1 = () => {
1519
+ aiChatbotX.abortInvoke();
1520
+ };
1515
1521
  const endpoint = `/sime/proxy/organizations/${aiChatbotX.organizationId()}/agents/${props.agentId}/stream-invoke`;
1516
1522
  const agent = useAgentInvoke({
1517
1523
  endpoint,
@@ -1550,6 +1556,8 @@
1550
1556
  class: "command-test",
1551
1557
  "data-theme": currentTheme$1
1552
1558
  }, [
1559
+ vue.createElementVNode("button", { onClick: test }, "测试"),
1560
+ vue.createElementVNode("button", { onClick: test1 }, "测试1"),
1553
1561
  vue.createVNode(vue.Transition, { name: "bubble-fade" }, {
1554
1562
  default: vue.withCtx(() => [
1555
1563
  vue.unref(showBubble) ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -1664,14 +1672,14 @@
1664
1672
  "stroke-linejoin": "round"
1665
1673
  }, null, -1)
1666
1674
  ])]))
1667
- ], 8, _hoisted_13$1)
1675
+ ], 8, _hoisted_13)
1668
1676
  ])
1669
1677
  ]);
1670
1678
  };
1671
1679
  }
1672
1680
  });
1673
1681
 
1674
- const commandTest = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-5c7468c4"]]);
1682
+ const commandTest = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-2d2cea1f"]]);
1675
1683
 
1676
1684
  class CommandManager {
1677
1685
  commands = /* @__PURE__ */ new Map();
@@ -1732,7 +1740,8 @@
1732
1740
  __name: "sime-provider",
1733
1741
  props: {
1734
1742
  appToken: {},
1735
- organizationId: {}
1743
+ organizationId: {},
1744
+ projectId: {}
1736
1745
  },
1737
1746
  setup(__props) {
1738
1747
  const props = __props;
@@ -1743,6 +1752,7 @@
1743
1752
  });
1744
1753
  const stopBroadcastRef = vue.shallowRef(async () => {
1745
1754
  });
1755
+ const voiceAssistantRef = vue.shallowRef(null);
1746
1756
  vue.provide(AiChatbotXKey, {
1747
1757
  appToken: () => props.appToken,
1748
1758
  organizationId: () => props.organizationId,
@@ -1754,6 +1764,9 @@
1754
1764
  if (methods.start) startListeningRef.value = methods.start;
1755
1765
  if (methods.stop) stopListeningRef.value = methods.stop;
1756
1766
  },
1767
+ registerVoiceAssistant: (methods) => {
1768
+ voiceAssistantRef.value = methods;
1769
+ },
1757
1770
  getCommads: async () => commandManager.value.getCommands(),
1758
1771
  registerCommand: (cmd) => {
1759
1772
  commandManager.value.registerCommand(cmd);
@@ -1763,6 +1776,18 @@
1763
1776
  },
1764
1777
  async executeCommand(commandName, args = []) {
1765
1778
  return await commandManager.value.executeCommand(commandName, args);
1779
+ },
1780
+ sendMessage: async (text) => {
1781
+ voiceAssistantRef.value?.agentInvoke(text);
1782
+ },
1783
+ speakText: (text) => {
1784
+ voiceAssistantRef.value?.speakText(text);
1785
+ },
1786
+ stopSpeak: () => {
1787
+ voiceAssistantRef.value?.stopSpeak();
1788
+ },
1789
+ abortInvoke: () => {
1790
+ voiceAssistantRef.value?.agentAbort();
1766
1791
  }
1767
1792
  });
1768
1793
  return (_ctx, _cache) => {
@@ -1790,7 +1815,27 @@
1790
1815
  }
1791
1816
  return -1;
1792
1817
  };
1793
- const stripMarkdown = (text) => text.replace(/```[\s\S]*?```/g, "").replace(/\|[^\n]*\|/g, "").replace(/#{1,6}\s*/g, "").replace(/\*\*(.*?)\*\*/g, "$1").replace(/\*(.*?)\*/g, "$1").replace(/`([^`]*)`/g, "$1").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/^[-*+]\s+/gm, "").replace(/^>\s+/gm, "").replace(/\s*\+\s*/g, "加").replace(/\s*-\s*/g, "减").replace(/\s*×\s*/g, "乘").replace(/\s*÷\s*/g, "除").replace(/\s*=\s*/g, "等于").replace(/(\d)\.(\d)/g, "$1点$2").replace(/\n{2,}/g, "。").replace(/\n/g, ",").trim();
1818
+ const normalizeNumbers = (text) => {
1819
+ return text.replace(/(-?\d[\d,]*\.?\d*)\s*%/g, (_, num) => {
1820
+ const cleanNum = num.replace(/,/g, "");
1821
+ const n = parseFloat(cleanNum);
1822
+ const spoken = cleanNum.replace(".", "点");
1823
+ if (n < 0) return `负百分之${spoken.replace("-", "")}`;
1824
+ return `百分之${spoken}`;
1825
+ }).replace(/(-?\d[\d,]*)\.(\d+)/g, (_, intPart, decPart) => {
1826
+ const cleanInt = intPart.replace(/,/g, "");
1827
+ if (cleanInt.startsWith("-")) {
1828
+ return `负${cleanInt.slice(1)}点${decPart}`;
1829
+ }
1830
+ return `${cleanInt}点${decPart}`;
1831
+ }).replace(/-(\d)/g, "负$1");
1832
+ };
1833
+ const stripMarkdown = (text) => {
1834
+ let result = text.replace(/```[\s\S]*?```/g, "").replace(/\|[^\n]*\|/g, "").replace(/#{1,6}\s*/g, "").replace(/\*\*(.*?)\*\*/g, "$1").replace(/\*(.*?)\*/g, "$1").replace(/`([^`]*)`/g, "$1").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/^[-*+]\s+/gm, "").replace(/^>\s+/gm, "");
1835
+ result = normalizeNumbers(result);
1836
+ result = result.replace(/\s*\+\s*(?=\d)/g, "加").replace(/\s*\+\s*/g, "加").replace(/\s*-\s*(?=\d)/g, "减").replace(/\s*-\s*/g, "减").replace(/\s*×\s*/g, "乘").replace(/\s*÷\s*/g, "除").replace(/\s*=\s*/g, "等于").replace(/\n{2,}/g, "。").replace(/\n/g, ",").trim();
1837
+ return result;
1838
+ };
1794
1839
  const normalizeSpeakText = (text, options) => {
1795
1840
  const clean = stripMarkdown(text).replace(LEADING_WEAK_PUNCTUATION, "").trim();
1796
1841
  if (!clean) return "";
@@ -2210,12 +2255,8 @@
2210
2255
  key: 2,
2211
2256
  class: "agent-text"
2212
2257
  };
2213
- const _hoisted_11 = {
2214
- key: 0,
2215
- class: "status-pill"
2216
- };
2217
- const _hoisted_12 = { class: "fab-avatar-wrapper" };
2218
- const _hoisted_13 = ["src"];
2258
+ const _hoisted_11 = { class: "fab-avatar-wrapper" };
2259
+ const _hoisted_12 = ["src"];
2219
2260
  const currentTheme = "dark";
2220
2261
  const _sfc_main = /* @__PURE__ */ vue.defineComponent({
2221
2262
  __name: "voice-assistant",
@@ -2286,6 +2327,11 @@
2286
2327
  tts.stop();
2287
2328
  bubble.hide();
2288
2329
  };
2330
+ const speakTextWithBubble = (text) => {
2331
+ bubble.open();
2332
+ agent.currentTextContent.value = text;
2333
+ tts.speak(text);
2334
+ };
2289
2335
  const voice = useVoiceRecognition({
2290
2336
  modelPath: props.modelPath,
2291
2337
  wakeWords: props.wakeWords,
@@ -2304,13 +2350,19 @@
2304
2350
  tts.warmUpAudio();
2305
2351
  await voice.toggleVoiceMode(targetState);
2306
2352
  };
2307
- const { voiceStatus, transcriptionText, wakeAnimating, isTranscribing } = voice;
2353
+ const { voiceStatus, wakeAnimating, isTranscribing } = voice;
2308
2354
  const { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;
2309
2355
  aiChatbotX?.registerVoiceMethods({
2310
2356
  stopBroadcast: async () => interruptCurrentResponse(),
2311
2357
  start: () => toggleVoiceMode(true),
2312
2358
  stop: () => toggleVoiceMode(false)
2313
2359
  });
2360
+ aiChatbotX?.registerVoiceAssistant({
2361
+ agentInvoke: agent.invoke,
2362
+ agentAbort: agent.abort,
2363
+ speakText: speakTextWithBubble,
2364
+ stopSpeak: tts.stop
2365
+ });
2314
2366
  vue.onBeforeUnmount(async () => {
2315
2367
  bubble.destroy();
2316
2368
  agent.abort();
@@ -2398,15 +2450,14 @@
2398
2450
  class: "assistant-fab",
2399
2451
  onClick: _cache[0] || (_cache[0] = ($event) => toggleVoiceMode())
2400
2452
  }, [
2401
- vue.unref(transcriptionText) || vue.unref(isInvoking) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_11, vue.toDisplayString(vue.unref(isInvoking) ? "正在思考中..." : vue.unref(transcriptionText)), 1)) : vue.createCommentVNode("", true),
2402
- vue.createElementVNode("div", _hoisted_12, [
2453
+ vue.createElementVNode("div", _hoisted_11, [
2403
2454
  vue.createElementVNode("img", {
2404
2455
  src: __props.xLogo ? __props.xLogo : "/x.png",
2405
2456
  alt: "voice assistant",
2406
2457
  style: vue.normalizeStyle({
2407
2458
  width: `${__props.xSize?.width || 88}px`
2408
2459
  })
2409
- }, null, 12, _hoisted_13),
2460
+ }, null, 12, _hoisted_12),
2410
2461
  vue.createVNode(vue.Transition, { name: "indicator-fade" }, {
2411
2462
  default: vue.withCtx(() => [
2412
2463
  vue.unref(voiceStatus) === "listening" ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -2448,7 +2499,7 @@
2448
2499
  }
2449
2500
  });
2450
2501
 
2451
- const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-59d72f34"]]);
2502
+ const voiceAssistant = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5f5506a2"]]);
2452
2503
 
2453
2504
  var clientCommandKey = /* @__PURE__ */ ((clientCommandKey2) => {
2454
2505
  clientCommandKey2["SET_THEME"] = "SiMeAgent_setTheme";