byt-lingxiao-ai 0.3.5 → 0.3.8

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.
@@ -28450,7 +28450,7 @@ if (typeof window !== 'undefined') {
28450
28450
  var es_iterator_constructor = __webpack_require__(8111);
28451
28451
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.for-each.js
28452
28452
  var es_iterator_for_each = __webpack_require__(7588);
28453
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=0e3e6d50&scoped=true
28453
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=template&id=244aa1c1&scoped=true
28454
28454
  var render = function render() {
28455
28455
  var _vm = this,
28456
28456
  _c = _vm._self._c;
@@ -28803,8 +28803,8 @@ var ChatWindowDialogvue_type_template_id_23a76780_scoped_true_render = function
28803
28803
  };
28804
28804
  var ChatWindowDialogvue_type_template_id_23a76780_scoped_true_staticRenderFns = [];
28805
28805
 
28806
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindowHeader.vue?vue&type=template&id=90d9b166&scoped=true
28807
- var ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_render = function render() {
28806
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindowHeader.vue?vue&type=template&id=7683371c&scoped=true
28807
+ var ChatWindowHeadervue_type_template_id_7683371c_scoped_true_render = function render() {
28808
28808
  var _vm = this,
28809
28809
  _c = _vm._self._c;
28810
28810
  return _c('div', {
@@ -28889,7 +28889,7 @@ var ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_render = function
28889
28889
  }
28890
28890
  })])])]);
28891
28891
  };
28892
- var ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_staticRenderFns = [];
28892
+ var ChatWindowHeadervue_type_template_id_7683371c_scoped_true_staticRenderFns = [];
28893
28893
 
28894
28894
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindowHeader.vue?vue&type=script&lang=js
28895
28895
  /* harmony default export */ var ChatWindowHeadervue_type_script_lang_js = ({
@@ -28902,17 +28902,17 @@ var ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_staticRenderFns =
28902
28902
  },
28903
28903
  methods: {
28904
28904
  handleOpen() {
28905
- const baseUrl = window.location.protocol + '//' + window.location.hostname + ':3100/c/' + this.chatId;
28905
+ const baseUrl = window.location.origin + '/chat/c/' + this.chatId;
28906
28906
  window.open(baseUrl, '_blank');
28907
28907
  }
28908
28908
  }
28909
28909
  });
28910
28910
  ;// ./components/ChatWindowHeader.vue?vue&type=script&lang=js
28911
28911
  /* harmony default export */ var components_ChatWindowHeadervue_type_script_lang_js = (ChatWindowHeadervue_type_script_lang_js);
28912
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindowHeader.vue?vue&type=style&index=0&id=90d9b166&prod&scoped=true&lang=css
28912
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindowHeader.vue?vue&type=style&index=0&id=7683371c&prod&scoped=true&lang=css
28913
28913
  // extracted by mini-css-extract-plugin
28914
28914
 
28915
- ;// ./components/ChatWindowHeader.vue?vue&type=style&index=0&id=90d9b166&prod&scoped=true&lang=css
28915
+ ;// ./components/ChatWindowHeader.vue?vue&type=style&index=0&id=7683371c&prod&scoped=true&lang=css
28916
28916
 
28917
28917
  ;// ./components/ChatWindowHeader.vue
28918
28918
 
@@ -28925,11 +28925,11 @@ var ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_staticRenderFns =
28925
28925
 
28926
28926
  var ChatWindowHeader_component = normalizeComponent(
28927
28927
  components_ChatWindowHeadervue_type_script_lang_js,
28928
- ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_render,
28929
- ChatWindowHeadervue_type_template_id_90d9b166_scoped_true_staticRenderFns,
28928
+ ChatWindowHeadervue_type_template_id_7683371c_scoped_true_render,
28929
+ ChatWindowHeadervue_type_template_id_7683371c_scoped_true_staticRenderFns,
28930
28930
  false,
28931
28931
  null,
28932
- "90d9b166",
28932
+ "7683371c",
28933
28933
  null
28934
28934
 
28935
28935
  )
@@ -29017,8 +29017,8 @@ var UserMessage_component = normalizeComponent(
29017
29017
  )
29018
29018
 
29019
29019
  /* harmony default export */ var UserMessage = (UserMessage_component.exports);
29020
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=template&id=2422d7c0&scoped=true
29021
- var AiMessagevue_type_template_id_2422d7c0_scoped_true_render = function render() {
29020
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=template&id=6cbccb01&scoped=true
29021
+ var AiMessagevue_type_template_id_6cbccb01_scoped_true_render = function render() {
29022
29022
  var _vm = this,
29023
29023
  _c = _vm._self._c;
29024
29024
  return _c('div', {
@@ -29051,10 +29051,8 @@ var AiMessagevue_type_template_id_2422d7c0_scoped_true_render = function render(
29051
29051
  }
29052
29052
  })])]);
29053
29053
  };
29054
- var AiMessagevue_type_template_id_2422d7c0_scoped_true_staticRenderFns = [];
29054
+ var AiMessagevue_type_template_id_6cbccb01_scoped_true_staticRenderFns = [];
29055
29055
 
29056
- // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.filter.js
29057
- var es_iterator_filter = __webpack_require__(2489);
29058
29056
  ;// ./node_modules/@babel/runtime/helpers/esm/typeof.js
29059
29057
  function _typeof(o) {
29060
29058
  "@babel/helpers - typeof";
@@ -29098,6 +29096,8 @@ function _defineProperty(e, r, t) {
29098
29096
  }) : e[r] = t, e;
29099
29097
  }
29100
29098
 
29099
+ // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.filter.js
29100
+ var es_iterator_filter = __webpack_require__(2489);
29101
29101
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.map.js
29102
29102
  var es_iterator_map = __webpack_require__(1701);
29103
29103
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.some.js
@@ -30827,10 +30827,6 @@ var lib = __webpack_require__(2750);
30827
30827
 
30828
30828
 
30829
30829
 
30830
-
30831
-
30832
-
30833
-
30834
30830
  d.setOptions({
30835
30831
  highlight: function (code, lang) {
30836
30832
  if (lang && es.getLanguage(lang)) {
@@ -30843,115 +30839,6 @@ d.setOptions({
30843
30839
  breaks: true,
30844
30840
  gfm: true
30845
30841
  });
30846
- function parseMarkdown(text) {
30847
- if (!text) return '';
30848
- let html = text;
30849
- html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
30850
- return `<pre><code class="language-${lang || 'text'}">${escapeHtml(code.trim())}</code></pre>`;
30851
- });
30852
- html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
30853
- html = parseTable(html);
30854
- html = html.replace(/^#### (.*$)/gm, '<h4>$1</h4>');
30855
- html = html.replace(/^### (.*$)/gm, '<h3>$1</h3>');
30856
- html = html.replace(/^## (.*$)/gm, '<h2>$1</h2>');
30857
- html = html.replace(/^# (.*$)/gm, '<h1>$1</h1>');
30858
- html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
30859
- html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
30860
- html = html.replace(/~~(.*?)~~/g, '<del>$1</del>');
30861
- html = html.replace(/^\s*[-*+]\s+(.+)$/gm, '<li>$1</li>');
30862
- html = html.replace(/(<li>.*?<\/li>)/gs, '<ul>$1</ul>');
30863
- html = html.replace(/^\s*\d+\.\s+(.+)$/gm, '<li>$1</li>');
30864
- html = html.replace(/^>\s+(.+)$/gm, '<blockquote>$1</blockquote>');
30865
- // 解析Markdown链接
30866
- html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" aria-current="page">$1</a>');
30867
- html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" />');
30868
- html = html.replace(/^-{3,}$/gm, '<hr>');
30869
- // 解析简单URL
30870
- // const simpleUrlRegex = /(https?:\/\/[^\s<>"']+)/g;
30871
- // html = html.replace(simpleUrlRegex, (match) => {
30872
- // return `<a href="${match}" aria-current="page">${match}</a>`;
30873
- // });
30874
-
30875
- // html = html.replace(/\n/g, '<br>');
30876
-
30877
- return html;
30878
- }
30879
- // 解析表格
30880
- function parseTable(text) {
30881
- const lines = text.split('\n');
30882
- let result = [];
30883
- let inTable = false;
30884
- let tableRows = [];
30885
- for (let i = 0; i < lines.length; i++) {
30886
- const line = lines[i].trim();
30887
-
30888
- // 检测表格行
30889
- if (line.includes('|') && line.split('|').length >= 3) {
30890
- if (!inTable) {
30891
- inTable = true;
30892
- tableRows = [];
30893
- }
30894
- tableRows.push(line);
30895
-
30896
- // 检查下一行是否还是表格
30897
- if (i === lines.length - 1 || !lines[i + 1].includes('|')) {
30898
- // 表格结束
30899
- result.push(renderTable(tableRows));
30900
- inTable = false;
30901
- tableRows = [];
30902
- }
30903
- } else {
30904
- if (inTable) {
30905
- // 表格意外结束
30906
- result.push(renderTable(tableRows));
30907
- inTable = false;
30908
- tableRows = [];
30909
- }
30910
- result.push(line);
30911
- }
30912
- }
30913
- return result.join('\n');
30914
- }
30915
- // 渲染表格
30916
- function renderTable(rows) {
30917
- if (rows.length < 2) return rows.join('\n');
30918
- let html = '<div class="table-wrapper"><table class="markdown-table">';
30919
-
30920
- // 表头
30921
- const headerCells = rows[0].split('|').filter(cell => cell.trim());
30922
- html += '<thead><tr>';
30923
- headerCells.forEach(cell => {
30924
- html += `<th>${cell.trim()}</th>`;
30925
- });
30926
- html += '</tr></thead>';
30927
-
30928
- // 表体(跳过分隔行)
30929
- html += '<tbody>';
30930
- for (let i = 2; i < rows.length; i++) {
30931
- const cells = rows[i].split('|').filter(cell => cell.trim());
30932
- if (cells.length > 0) {
30933
- html += '<tr>';
30934
- cells.forEach(cell => {
30935
- html += `<td><div class="table-cell">${cell.trim()}</div></td>`;
30936
- });
30937
- html += '</tr>';
30938
- }
30939
- }
30940
- html += '</tbody>';
30941
- html += '</table></div>';
30942
- return html;
30943
- }
30944
- // HTML 转义
30945
- function escapeHtml(text) {
30946
- const map = {
30947
- '&': '&amp;',
30948
- '<': '&lt;',
30949
- '>': '&gt;',
30950
- '"': '&quot;',
30951
- "'": '&#039;'
30952
- };
30953
- return text.replace(/[&<>"']/g, m => map[m]);
30954
- }
30955
30842
  /* harmony default export */ var AiMessagevue_type_script_lang_js = ({
30956
30843
  name: 'AiMessage',
30957
30844
  props: {
@@ -30965,7 +30852,7 @@ function escapeHtml(text) {
30965
30852
  return this.message.thinkingExpanded !== false;
30966
30853
  },
30967
30854
  renderedContent() {
30968
- return parseMarkdown(this.message.content);
30855
+ return d.parse(this.message.content || '');
30969
30856
  },
30970
30857
  isLoading() {
30971
30858
  return this.message.loading === true;
@@ -30979,10 +30866,10 @@ function escapeHtml(text) {
30979
30866
  });
30980
30867
  ;// ./components/AiMessage.vue?vue&type=script&lang=js
30981
30868
  /* harmony default export */ var components_AiMessagevue_type_script_lang_js = (AiMessagevue_type_script_lang_js);
30982
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=style&index=0&id=2422d7c0&prod&scoped=true&lang=css
30869
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/AiMessage.vue?vue&type=style&index=0&id=6cbccb01&prod&scoped=true&lang=css
30983
30870
  // extracted by mini-css-extract-plugin
30984
30871
 
30985
- ;// ./components/AiMessage.vue?vue&type=style&index=0&id=2422d7c0&prod&scoped=true&lang=css
30872
+ ;// ./components/AiMessage.vue?vue&type=style&index=0&id=6cbccb01&prod&scoped=true&lang=css
30986
30873
 
30987
30874
  ;// ./components/AiMessage.vue
30988
30875
 
@@ -30995,11 +30882,11 @@ function escapeHtml(text) {
30995
30882
 
30996
30883
  var AiMessage_component = normalizeComponent(
30997
30884
  components_AiMessagevue_type_script_lang_js,
30998
- AiMessagevue_type_template_id_2422d7c0_scoped_true_render,
30999
- AiMessagevue_type_template_id_2422d7c0_scoped_true_staticRenderFns,
30885
+ AiMessagevue_type_template_id_6cbccb01_scoped_true_render,
30886
+ AiMessagevue_type_template_id_6cbccb01_scoped_true_staticRenderFns,
31000
30887
  false,
31001
30888
  null,
31002
- "2422d7c0",
30889
+ "6cbccb01",
31003
30890
  null
31004
30891
 
31005
30892
  )
@@ -31297,9 +31184,7 @@ var es_typed_array_with = __webpack_require__(9577);
31297
31184
  audioContext: null,
31298
31185
  microphone: null,
31299
31186
  processor: null,
31300
- audioBuffer: new Float32Array(0),
31301
- // 优化
31302
- int16Buffer: null
31187
+ audioBuffer: new Float32Array(0)
31303
31188
  };
31304
31189
  },
31305
31190
  methods: {
@@ -31311,21 +31196,16 @@ var es_typed_array_with = __webpack_require__(9577);
31311
31196
  audio: {
31312
31197
  sampleRate: this.SAMPLE_RATE,
31313
31198
  channelCount: 1,
31314
- noiseSuppression: true,
31315
- echoCancellation: true
31199
+ noiseSuppression: false,
31200
+ echoCancellation: false,
31201
+ autoGainControl: false
31316
31202
  }
31317
31203
  });
31318
31204
  this.audioContext = new AudioContext({
31319
31205
  sampleRate: this.SAMPLE_RATE
31320
31206
  });
31321
-
31322
- // 优化 处理 AudioContext 挂起
31323
- if (this.audioContext.state === 'suspended') {
31324
- await this.audioContext.resume();
31325
- }
31326
31207
  this.microphone = this.audioContext.createMediaStreamSource(stream);
31327
31208
  this.processor = this.audioContext.createScriptProcessor(this.FRAME_SIZE, 1, 1);
31328
- this.int16Buffer = new Int16Array(this.FRAME_SIZE);
31329
31209
  this.processor.onaudioprocess = this.processAudio;
31330
31210
  this.microphone.connect(this.processor);
31331
31211
  this.processor.connect(this.audioContext.destination);
@@ -31340,19 +31220,17 @@ var es_typed_array_with = __webpack_require__(9577);
31340
31220
  processAudio(event) {
31341
31221
  if (!this.isRecording) return;
31342
31222
  const inputData = event.inputBuffer.getChannelData(0);
31343
- if (this.ws && this.ws.readyState === this.ws.OPEN) {
31344
- if (inputData.length !== this.int16Buffer.length) {
31345
- this.int16Buffer = new Int16Array(inputData.length);
31223
+ const tempBuffer = new Float32Array(this.audioBuffer.length + inputData.length);
31224
+ tempBuffer.set(this.audioBuffer, 0);
31225
+ tempBuffer.set(inputData, this.audioBuffer.length);
31226
+ this.audioBuffer = tempBuffer;
31227
+ while (this.audioBuffer.length >= this.FRAME_SIZE) {
31228
+ const frame = this.audioBuffer.slice(0, this.FRAME_SIZE);
31229
+ this.audioBuffer = this.audioBuffer.slice(this.FRAME_SIZE);
31230
+ const pcmData = this.floatTo16BitPCM(frame);
31231
+ if (this.ws && this.ws.readyState === this.ws.OPEN) {
31232
+ this.ws.send(pcmData);
31346
31233
  }
31347
- for (let i = 0; i < inputData.length; i++) {
31348
- let s = inputData[i];
31349
- // 简单的 clamp
31350
- s = s < -1 ? -1 : s > 1 ? 1 : s;
31351
- this.int16Buffer[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
31352
- }
31353
-
31354
- // 4. 发送数据
31355
- this.ws.send(this.int16Buffer.buffer);
31356
31234
  }
31357
31235
  },
31358
31236
  floatTo16BitPCM(input) {
@@ -31380,6 +31258,7 @@ var es_typed_array_with = __webpack_require__(9577);
31380
31258
  this.$refs.audioPlayer.play();
31381
31259
  },
31382
31260
  pause() {
31261
+ console.log('暂停播放');
31383
31262
  this.robotStatus = 'waiting';
31384
31263
  this.$refs.audioPlayer.pause();
31385
31264
  },
@@ -31405,19 +31284,18 @@ var es_typed_array_with = __webpack_require__(9577);
31405
31284
  this.pause();
31406
31285
  } else if (command === 'C6') {
31407
31286
  this.robotStatus = 'leaving';
31287
+ this.avaterStatus = 'normal';
31408
31288
  this.stop();
31409
31289
  }
31410
31290
  }
31411
31291
  }
31412
31292
  });
31413
31293
  ;// ./components/config/index.js
31414
- const baseUrl = window.location.protocol + '//' + window.location.hostname;
31415
- const chatPort = '3100';
31416
- console.log(baseUrl, chatPort);
31417
- const API_URL = `${baseUrl}:${chatPort}/lingxiao-byt/api/v1/mcp/ask`;
31418
- const WS_URL = 'ws://192.168.8.9:9999/ai_model/ws/voice-stream';
31419
- const AUDIO_URL = '/minio/lingxiaoai/byt.mp3';
31420
- const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json';
31294
+ const baseUrl = window.location.origin;
31295
+ const API_URL = `/chat/lingxiao-byt/api/v1/mcp/ask`; // 对话
31296
+ const WS_URL = `ws://${baseUrl}/audio/ws/voice-stream`; // 语音
31297
+ const AUDIO_URL = '/minio/lingxiaoai/byt.mp3'; // 导览
31298
+ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json'; // 语音url跳转节点
31421
31299
  ;// ./components/mixins/webSocketMixin.js
31422
31300
 
31423
31301
 
@@ -31491,6 +31369,10 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json';
31491
31369
  handleWebSocketMessage(data) {
31492
31370
  if (data.type === 'detection') {
31493
31371
  console.log('检测到唤醒词');
31372
+ console.log('当前状态:', this.avaterStatus);
31373
+ if (this.robotStatus === 'speaking') {
31374
+ this.robotStatus = 'waiting';
31375
+ }
31494
31376
  this.avaterStatus = 'normal';
31495
31377
 
31496
31378
  // 性能检测起点
@@ -31511,6 +31393,8 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json';
31511
31393
  this.analyzeAudioCommand(data.category);
31512
31394
  } else {
31513
31395
  console.log('状态: 其他');
31396
+ this.avaterStatus = 'normal';
31397
+ this.robotStatus = 'leaving';
31514
31398
  }
31515
31399
  },
31516
31400
  closeWebSocket() {
@@ -31522,222 +31406,99 @@ const TIME_JUMP_POINTS_URL = '/minio/lingxiaoai/timeJumpPoints.json';
31522
31406
  });
31523
31407
  ;// ./components/utils/StreamParser.js
31524
31408
 
31525
-
31526
31409
  class StreamParser {
31527
31410
  constructor(options = {}) {
31528
31411
  this.options = {
31529
31412
  updateInterval: 16,
31530
- // 更新间隔(ms),默认约60fps
31531
- batchSize: 100,
31532
- // 批处理大小
31413
+ // 每16ms刷新一次(约60fps
31533
31414
  debug: false,
31534
- // 是否开启调试
31535
31415
  ...options
31536
31416
  };
31537
31417
  this.reset();
31538
31418
  }
31539
31419
 
31540
- /**
31541
- * 重置解析器状态
31542
- */
31420
+ // 重置解析器状态
31543
31421
  reset() {
31544
31422
  this.buffer = '';
31545
- this.contentBuffer = []; // 使用数组缓冲,避免频繁字符串拼接
31423
+ this.contentBuffer = [];
31546
31424
  this.thinkingBuffer = [];
31547
31425
  this.inTag = false;
31548
31426
  this.tagBuffer = '';
31549
31427
  this.updateTimer = null;
31550
31428
  this.status = 'output'; // thinking | output
31551
- this.metrics = {
31552
- startTime: Date.now(),
31553
- chunks: 0,
31554
- events: 0,
31555
- chars: 0
31556
- };
31557
31429
  }
31558
31430
 
31559
- /**
31560
- * 处理流数据块
31561
- * @param {string} chunk - 接收到的数据块
31562
- * @param {Function} callback - 更新回调函数
31563
- */
31431
+ // 处理接收到的流数据块
31564
31432
  processChunk(chunk, callback) {
31565
- this.metrics.chunks++;
31566
- this.buffer += chunk;
31567
- if (this.options.debug) {
31568
- console.log('[StreamParser] 收到chunk:', chunk.substring(0, 100));
31569
- }
31570
- if (!this.buffer.includes('data:') && !this.buffer.includes('\n\n')) {
31571
- // 纯文本流,直接处理
31572
- if (this.options.debug) {
31573
- console.log('[StreamParser] 检测到纯文本流');
31574
- }
31575
- this.processPlainText(callback);
31576
- return;
31577
- }
31578
-
31579
- // 尝试解析为 SSE 格式
31580
- if (this.buffer.includes('data:')) {
31581
- this.processSSEFormat(callback);
31582
- } else {
31583
- // 直接处理纯文本流
31584
- this.processPlainText(callback);
31585
- }
31586
- }
31587
-
31588
- /**
31589
- * 处理标准 SSE 格式
31590
- */
31591
- processSSEFormat(callback) {
31592
- // SSE 格式:事件由双换行符分隔
31593
- const events = this.buffer.split('\n\n');
31594
-
31595
- // 保留最后一个可能不完整的事件
31596
- this.buffer = events.pop() || '';
31597
-
31598
- // 处理完整的事件
31599
- for (const event of events) {
31600
- if (event.trim()) {
31601
- this.metrics.events++;
31602
- this.processSSEEvent(event, callback);
31603
- }
31604
- }
31433
+ if (!chunk) return;
31434
+ this.parseContent(chunk, callback);
31605
31435
  }
31606
31436
 
31607
- /**
31608
- * 处理纯文本流格式
31609
- */
31610
- processPlainText(callback) {
31611
- const content = this.buffer;
31612
- this.buffer = ''; // 清空缓冲区
31613
-
31614
- if (content) {
31615
- this.metrics.chars += content.length;
31616
- if (this.options.debug) {
31617
- console.log('[StreamParser] 处理纯文本:', content);
31618
- }
31619
- this.parseContent(content, callback);
31620
- }
31621
- }
31622
-
31623
- /**
31624
- * 处理单个SSE事件
31625
- */
31626
- processSSEEvent(eventStr, callback) {
31627
- const lines = eventStr.split('\n');
31628
- for (const line of lines) {
31629
- // 解析 data: 行
31630
- if (line.startsWith('data:')) {
31631
- const data = line.substring(5).trim();
31632
- if (data === '[DONE]') {
31633
- this.flush(callback);
31634
- return;
31635
- }
31636
- try {
31637
- const parsed = JSON.parse(data);
31638
- const content = parsed?.choices?.[0]?.delta?.content;
31639
- if (content) {
31640
- this.metrics.chars += content.length;
31641
- if (this.options.debug) {
31642
- console.log('[StreamParser] 解析SSE内容:', content);
31643
- }
31644
- this.parseContent(content, callback);
31645
- }
31646
- } catch (error) {
31647
- if (this.options.debug) {
31648
- console.warn('[StreamParser] JSON解析失败:', data, error);
31649
- }
31650
- }
31651
- }
31652
- }
31653
- }
31654
-
31655
- /**
31656
- * 使用状态机解析内容和标签
31657
- */
31437
+ // 核心内容解析,支持 <think> 标签
31658
31438
  parseContent(content, callback) {
31659
31439
  let i = 0;
31660
31440
  while (i < content.length) {
31661
31441
  if (this.inTag) {
31662
- // 在标签内部,查找标签结束
31663
31442
  const endIndex = content.indexOf('>', i);
31664
31443
  if (endIndex !== -1) {
31665
- // 找到标签结束
31666
31444
  this.tagBuffer += content.substring(i, endIndex + 1);
31667
31445
  this.handleTag(this.tagBuffer);
31668
31446
  this.tagBuffer = '';
31669
31447
  this.inTag = false;
31670
31448
  i = endIndex + 1;
31671
31449
  } else {
31672
- // 标签未结束,缓存剩余部分
31450
+ // 标签未闭合,超过50字符强制输出,防止阻塞
31673
31451
  this.tagBuffer += content.substring(i);
31452
+ if (this.tagBuffer.length > 50) {
31453
+ this.appendText(this.tagBuffer);
31454
+ this.tagBuffer = '';
31455
+ this.inTag = false;
31456
+ }
31674
31457
  break;
31675
31458
  }
31676
31459
  } else {
31677
- // 不在标签内,查找标签开始
31678
31460
  const startIndex = content.indexOf('<', i);
31679
31461
  if (startIndex !== -1) {
31680
- // 找到标签开始,先处理前面的文本
31681
- if (startIndex > i) {
31682
- this.appendText(content.substring(i, startIndex));
31683
- }
31684
-
31685
- // 检查是否是完整标签
31462
+ if (startIndex > i) this.appendText(content.substring(i, startIndex));
31686
31463
  const endIndex = content.indexOf('>', startIndex);
31687
31464
  if (endIndex !== -1) {
31688
- // 完整标签
31689
31465
  const tag = content.substring(startIndex, endIndex + 1);
31690
31466
  this.handleTag(tag);
31691
31467
  i = endIndex + 1;
31692
31468
  } else {
31693
- // 不完整标签,标记进入标签状态
31694
- this.inTag = true;
31695
- this.tagBuffer = content.substring(startIndex);
31696
- break;
31469
+ const nextChar = content[startIndex + 1];
31470
+ if (!/[a-zA-Z/]/.test(nextChar)) {
31471
+ // 很可能不是标签,直接当文本输出
31472
+ this.appendText('<');
31473
+ i = startIndex + 1;
31474
+ } else {
31475
+ this.inTag = true;
31476
+ this.tagBuffer = content.substring(startIndex);
31477
+ break;
31478
+ }
31697
31479
  }
31698
31480
  } else {
31699
- // 没有标签,全部是文本
31700
31481
  this.appendText(content.substring(i));
31701
31482
  break;
31702
31483
  }
31703
31484
  }
31704
31485
  }
31705
-
31706
- // 定时批量更新
31707
31486
  this.scheduleUpdate(callback);
31708
31487
  }
31709
31488
 
31710
- /**
31711
- * 处理标签
31712
- */
31489
+ // 处理标签
31713
31490
  handleTag(tag) {
31714
- const tagName = tag.toLowerCase();
31715
- if (this.options.debug) {
31716
- console.log('[StreamParser] 处理标签:', tag);
31717
- }
31718
- if (tagName === '<think>') {
31719
- this.status = 'thinking';
31720
- } else if (tagName === '</think>') {
31721
- this.status = 'output';
31722
- }
31723
- // 可扩展:支持更多标签类型
31491
+ const t = tag.toLowerCase();
31492
+ if (t === '<think>') this.status = 'thinking';else if (t === '</think>') this.status = 'output';
31724
31493
  }
31725
31494
 
31726
- /**
31727
- * 添加文本到缓冲区
31728
- */
31495
+ // 添加文本到缓冲区
31729
31496
  appendText(text) {
31730
31497
  if (!text) return;
31731
- if (this.status === 'thinking') {
31732
- this.thinkingBuffer.push(text);
31733
- } else {
31734
- this.contentBuffer.push(text);
31735
- }
31498
+ if (this.status === 'thinking') this.thinkingBuffer.push(text);else this.contentBuffer.push(text);
31736
31499
  }
31737
31500
 
31738
- /**
31739
- * 计划更新(防抖)
31740
- */
31501
+ // 防抖刷新
31741
31502
  scheduleUpdate(callback) {
31742
31503
  if (this.updateTimer) return;
31743
31504
  this.updateTimer = setTimeout(() => {
@@ -31746,74 +31507,33 @@ class StreamParser {
31746
31507
  }, this.options.updateInterval);
31747
31508
  }
31748
31509
 
31749
- /**
31750
- * 立即刷新缓冲区
31751
- */
31510
+ // 刷新缓冲区
31752
31511
  flush(callback) {
31753
- if (!callback) {
31754
- console.warn('[StreamParser] flush: callback 为空');
31755
- return;
31756
- }
31757
- const hasThinking = this.thinkingBuffer.length > 0;
31758
- const hasContent = this.contentBuffer.length > 0;
31759
- if (!hasThinking && !hasContent) return;
31760
-
31761
- // 使用 join 比字符串拼接性能更好
31512
+ if (!callback) return;
31762
31513
  const result = {
31763
- thinking: hasThinking ? this.thinkingBuffer.join('') : null,
31764
- content: hasContent ? this.contentBuffer.join('') : null,
31514
+ thinking: this.thinkingBuffer.length ? this.thinkingBuffer.join('') : null,
31515
+ content: this.contentBuffer.length ? this.contentBuffer.join('') : null,
31765
31516
  status: this.status
31766
31517
  };
31767
- if (this.options.debug) {
31768
- console.log('[StreamParser] 刷新缓冲区:', {
31769
- thinking: result.thinking?.length || 0,
31770
- content: result.content?.length || 0,
31771
- status: result.status,
31772
- thinkingPreview: result.thinking?.substring(0, 50),
31773
- contentPreview: result.content?.substring(0, 50)
31774
- });
31775
- }
31776
-
31777
- // 清空缓冲区
31778
31518
  this.thinkingBuffer = [];
31779
31519
  this.contentBuffer = [];
31780
-
31781
- // 回调更新
31782
- try {
31783
- callback(result);
31784
- } catch (error) {
31785
- console.error('[StreamParser] 回调执行错误:', error);
31786
- }
31520
+ callback(result);
31787
31521
  }
31788
31522
 
31789
- /**
31790
- * 完成解析
31791
- */
31523
+ // 完成解析
31792
31524
  finish(callback) {
31793
- this.flush(callback);
31794
- if (this.updateTimer) {
31795
- clearTimeout(this.updateTimer);
31796
- this.updateTimer = null;
31797
- }
31798
- if (this.options.debug) {
31799
- const duration = Date.now() - this.metrics.startTime;
31800
- console.log('[StreamParser] 解析完成:', {
31801
- 耗时: `${duration}ms`,
31802
- 数据块: this.metrics.chunks,
31803
- 事件数: this.metrics.events,
31804
- 字符数: this.metrics.chars,
31805
- 平均速度: `${(this.metrics.chars / duration * 1000).toFixed(0)} chars/s`
31806
- });
31525
+ if (this.inTag && this.tagBuffer) {
31526
+ this.appendText(this.tagBuffer);
31527
+ this.tagBuffer = '';
31528
+ this.inTag = false;
31807
31529
  }
31530
+ this.flush(callback);
31531
+ if (this.updateTimer) clearTimeout(this.updateTimer);
31808
31532
  }
31809
31533
 
31810
- /**
31811
- * 销毁解析器
31812
- */
31534
+ // 销毁解析器
31813
31535
  destroy() {
31814
- if (this.updateTimer) {
31815
- clearTimeout(this.updateTimer);
31816
- }
31536
+ if (this.updateTimer) clearTimeout(this.updateTimer);
31817
31537
  this.reset();
31818
31538
  }
31819
31539
  }
@@ -31895,7 +31615,7 @@ const getCookie = cname => {
31895
31615
  this.streamParser.reset();
31896
31616
  try {
31897
31617
  const startTime = Date.now();
31898
- const token = getCookie('bonyear-access_token') || `e298f087-85bc-48c2-afb9-7c69ffc911aa`;
31618
+ const token = getCookie('bonyear-access_token') || `44e7f112-63f3-429d-908d-2c97ec380de2`;
31899
31619
  const response = await fetch(API_URL, {
31900
31620
  method: 'POST',
31901
31621
  headers: {
@@ -31904,7 +31624,7 @@ const getCookie = cname => {
31904
31624
  },
31905
31625
  body: JSON.stringify({
31906
31626
  content: message,
31907
- chatId: this.chatId
31627
+ chat_id: this.chatId
31908
31628
  })
31909
31629
  });
31910
31630
  if (!response.ok) {
@@ -31958,9 +31678,10 @@ const getCookie = cname => {
31958
31678
  const chunk = decoder.decode(value, {
31959
31679
  stream: true
31960
31680
  });
31961
-
31681
+ console.log('收到数据块:', chunk);
31962
31682
  // 使用解析器处理数据块,确保this指向正确
31963
31683
  this.streamParser.processChunk(chunk, function (result) {
31684
+ console.log('处理数据块:', result);
31964
31685
  self.handleStreamUpdate(result);
31965
31686
  });
31966
31687
  }
@@ -31983,6 +31704,7 @@ const getCookie = cname => {
31983
31704
  }
31984
31705
 
31985
31706
  // 更新回复内容
31707
+ console.log('更新回复内容:', result.content);
31986
31708
  if (result.content) {
31987
31709
  this.currentMessage.content += result.content;
31988
31710
  }
@@ -32117,6 +31839,7 @@ const startTime = null;
32117
31839
  },
32118
31840
  methods: {
32119
31841
  toggleWindow() {
31842
+ if (this.avaterStatus === 'thinking') return;
32120
31843
  this.visible = !this.visible;
32121
31844
  if (this.visible) {
32122
31845
  this.currentX = this.initialX;
@@ -32237,10 +31960,10 @@ const startTime = null;
32237
31960
  });
32238
31961
  ;// ./components/ChatWindow.vue?vue&type=script&lang=js
32239
31962
  /* harmony default export */ var components_ChatWindowvue_type_script_lang_js = (ChatWindowvue_type_script_lang_js);
32240
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=0e3e6d50&prod&scoped=true&lang=css
31963
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./components/ChatWindow.vue?vue&type=style&index=0&id=244aa1c1&prod&scoped=true&lang=css
32241
31964
  // extracted by mini-css-extract-plugin
32242
31965
 
32243
- ;// ./components/ChatWindow.vue?vue&type=style&index=0&id=0e3e6d50&prod&scoped=true&lang=css
31966
+ ;// ./components/ChatWindow.vue?vue&type=style&index=0&id=244aa1c1&prod&scoped=true&lang=css
32244
31967
 
32245
31968
  ;// ./components/ChatWindow.vue
32246
31969
 
@@ -32257,7 +31980,7 @@ var ChatWindow_component = normalizeComponent(
32257
31980
  staticRenderFns,
32258
31981
  false,
32259
31982
  null,
32260
- "0e3e6d50",
31983
+ "244aa1c1",
32261
31984
  null
32262
31985
 
32263
31986
  )